Component cleanup

This commit is contained in:
adilallo
2026-04-29 07:20:16 -06:00
parent 252848eba9
commit e6127f1a3f
267 changed files with 2087 additions and 2196 deletions
+9
View File
@@ -25,6 +25,15 @@ export function getAssetPath(assetPath: string): string {
return assetPath.startsWith("/") ? assetPath : `/${assetPath}`;
}
/**
* Decorative vector marks in `public/assets/vector/<kebab-case>.svg`
* (Figma Asset / Vector). Same folder pattern as governance template marks
* under `assets/template-mark/`.
*/
export function vectorMarkPath(slug: string): string {
return `assets/vector/${slug}.svg`;
}
/**
* Asset paths for common components
*/
+1 -1
View File
@@ -231,7 +231,7 @@ export function buildFinalReviewCategoryRowsDetailed(
}
/**
* Derive the final-review RuleCard category rows from the current
* Derive the final-review Rule category rows from the current
* {@link CreateFlowState}.
*
* Two-mode contract, mirroring the two template entry points:
+7 -10
View File
@@ -6,7 +6,7 @@ import type {
DecisionApproachDetailEntry,
MembershipMethodDetailEntry,
} from "../../app/(app)/create/types";
import type { CommunityRuleDocumentSection } from "../../app/components/sections/CommunityRuleDocument/CommunityRuleDocument.types";
import type { CommunityRuleSection } from "../../app/components/type/CommunityRule/CommunityRule.types";
import {
communicationPresetFor,
conflictManagementPresetFor,
@@ -14,14 +14,11 @@ import {
membershipPresetFor,
methodLabelFor,
} from "./finalReviewChipPresets";
import { isDocumentEntry } from "./documentEntryGuards";
function isDocumentEntry(x: unknown): x is { title: string; body: string } {
if (!x || typeof x !== "object") return false;
const o = x as Record<string, unknown>;
return typeof o.title === "string" && typeof o.body === "string";
}
export { isDocumentEntry } from "./documentEntryGuards";
function isDocumentSection(x: unknown): x is CommunityRuleDocumentSection {
function isDocumentSection(x: unknown): x is CommunityRuleSection {
if (!x || typeof x !== "object") return false;
const o = x as Record<string, unknown>;
if (typeof o.categoryName !== "string") return false;
@@ -32,10 +29,10 @@ function isDocumentSection(x: unknown): x is CommunityRuleDocumentSection {
/** Narrow `CreateFlowState.sections` into Community Rule document sections. */
export function parseSectionsFromCreateFlowState(
state: CreateFlowState,
): CommunityRuleDocumentSection[] {
): CommunityRuleSection[] {
const raw = state.sections;
if (!Array.isArray(raw)) return [];
const out: CommunityRuleDocumentSection[] = [];
const out: CommunityRuleSection[] = [];
for (const x of raw) {
if (isDocumentSection(x)) out.push(x);
}
@@ -233,7 +230,7 @@ export function buildMethodSelectionsForDocument(
/** Read `document.sections` from a stored published payload for display. */
export function parseDocumentSectionsForDisplay(
document: unknown,
): CommunityRuleDocumentSection[] {
): CommunityRuleSection[] {
if (!document || typeof document !== "object") return [];
const sections = (document as Record<string, unknown>).sections;
if (!Array.isArray(sections)) return [];
+26
View File
@@ -0,0 +1,26 @@
import type {
CommunityRuleEntry,
CommunityRuleLabeledBlock,
} from "../../app/components/type/CommunityRule/CommunityRule.types";
function isLabeledBlock(x: unknown): x is CommunityRuleLabeledBlock {
if (!x || typeof x !== "object") return false;
const o = x as Record<string, unknown>;
return typeof o.label === "string" && typeof o.body === "string";
}
/** Shared by publish payload parsing and template body parsing — keep in sync. */
export function isDocumentEntry(x: unknown): x is CommunityRuleEntry {
if (!x || typeof x !== "object") return false;
const o = x as Record<string, unknown>;
if (typeof o.title !== "string" || o.title.trim().length === 0) {
return false;
}
if (typeof o.body !== "string") return false;
if (o.blocks !== undefined) {
if (!Array.isArray(o.blocks) || !o.blocks.every(isLabeledBlock)) {
return false;
}
}
return true;
}
+10 -16
View File
@@ -1,18 +1,9 @@
import type { Category } from "../../app/components/cards/RuleCard/RuleCard.types";
import type { Category } from "../../app/components/cards/Rule";
import type { ChipOption } from "../../app/components/controls/MultiSelect/MultiSelect.types";
import type { CommunityRuleSection } from "../../app/components/type/CommunityRule/CommunityRule.types";
import { isDocumentEntry } from "./documentEntryGuards";
function isDocumentEntry(x: unknown): x is { title: string; body: string } {
if (!x || typeof x !== "object") return false;
const o = x as Record<string, unknown>;
return typeof o.title === "string" && typeof o.body === "string";
}
function isDocumentSection(
x: unknown,
): x is {
categoryName: string;
entries: { title: string; body: string }[];
} {
function isDocumentSection(x: unknown): x is CommunityRuleSection {
if (!x || typeof x !== "object") return false;
const o = x as Record<string, unknown>;
if (typeof o.categoryName !== "string") return false;
@@ -79,7 +70,7 @@ export interface TemplateChipDetail {
}
/**
* Maps API template `body` (published-rule document shape) to RuleCard category
* Maps API template `body` (published-rule document shape) to Rule category
* rows **plus** a chipId → detail lookup for wiring chip clicks to the
* read-only detail modal.
*/
@@ -144,8 +135,11 @@ export function templateSummaryFromBody(
for (const s of sections) {
if (!isDocumentSection(s)) continue;
const first = s.entries[0];
if (isDocumentEntry(first) && first.body.trim()) {
return first.body.trim();
if (isDocumentEntry(first)) {
const main = first.body.trim();
if (main.length > 0) return main;
const fromBlock = first.blocks?.[0]?.body?.trim();
if (fromBlock && fromBlock.length > 0) return fromBlock;
}
}
return "";
+13 -21
View File
@@ -72,14 +72,14 @@ export type AlertSizeValue = (typeof ALERT_SIZE_OPTIONS)[number];
export const TOOLTIP_POSITION_OPTIONS = ["top", "bottom"] as const;
export type TooltipPositionValue = (typeof TOOLTIP_POSITION_OPTIONS)[number];
export const MENU_BAR_SIZE_OPTIONS = [
export const MENU_SIZE_OPTIONS = [
"X Small",
"Small",
"Medium",
"Large",
"X Large",
] as const;
export type MenuBarSizeValue = (typeof MENU_BAR_SIZE_OPTIONS)[number];
export type MenuSizeValue = (typeof MENU_SIZE_OPTIONS)[number];
export const NAVIGATION_ITEM_VARIANT_OPTIONS = ["default"] as const;
export type NavigationItemVariantValue =
@@ -145,13 +145,13 @@ export const QUOTE_BLOCK_VARIANT_OPTIONS = [
export type QuoteBlockVariantValue =
(typeof QUOTE_BLOCK_VARIANT_OPTIONS)[number];
export const NUMBER_CARD_SIZE_OPTIONS = [
export const STEP_SIZE_OPTIONS = [
"small",
"medium",
"large",
"xlarge",
] as const;
export type NumberCardSizeValue = (typeof NUMBER_CARD_SIZE_OPTIONS)[number];
export type StepSizeValue = (typeof STEP_SIZE_OPTIONS)[number];
export const ASK_ORGANIZER_VARIANT_OPTIONS = [
"centered",
@@ -162,14 +162,6 @@ export const ASK_ORGANIZER_VARIANT_OPTIONS = [
export type AskOrganizerVariantValue =
(typeof ASK_ORGANIZER_VARIANT_OPTIONS)[number];
export const CONTEXT_MENU_ITEM_SIZE_OPTIONS = [
"small",
"medium",
"large",
] as const;
export type ContextMenuItemSizeValue =
(typeof CONTEXT_MENU_ITEM_SIZE_OPTIONS)[number];
export const TOGGLE_GROUP_POSITION_OPTIONS = [
"left",
"middle",
@@ -185,8 +177,8 @@ export const TEXT_AREA_APPEARANCE_OPTIONS = ["default", "embedded"] as const;
export type TextAreaAppearanceValue =
(typeof TEXT_AREA_APPEARANCE_OPTIONS)[number];
export const RULE_CARD_SIZE_OPTIONS = ["XS", "S", "M", "L"] as const;
export type RuleCardSizeValue = (typeof RULE_CARD_SIZE_OPTIONS)[number];
export const RULE_SIZE_OPTIONS = ["XS", "S", "M", "L"] as const;
export type RuleSizeValue = (typeof RULE_SIZE_OPTIONS)[number];
export const CHIP_STATE_OPTIONS = [
"unselected",
@@ -212,19 +204,19 @@ export const INPUT_LABEL_PALETTE_OPTIONS = ["default", "inverse"] as const;
export type InputLabelPaletteValue =
(typeof INPUT_LABEL_PALETTE_OPTIONS)[number];
export const MENU_BAR_ITEM_STATE_OPTIONS = [
export const MENU_ITEM_STATE_OPTIONS = [
"default",
"hover",
"selected",
] as const;
export type MenuBarItemStateValue =
(typeof MENU_BAR_ITEM_STATE_OPTIONS)[number];
export type MenuItemStateValue =
(typeof MENU_ITEM_STATE_OPTIONS)[number];
export const MENU_BAR_ITEM_MODE_OPTIONS = ["default", "inverse"] as const;
export type MenuBarItemModeValue = (typeof MENU_BAR_ITEM_MODE_OPTIONS)[number];
export const MENU_ITEM_MODE_OPTIONS = ["default", "inverse"] as const;
export type MenuItemModeValue = (typeof MENU_ITEM_MODE_OPTIONS)[number];
export const MENU_BAR_ITEM_SIZE_OPTIONS = MENU_BAR_SIZE_OPTIONS;
export type MenuBarItemSizeValue = MenuBarSizeValue;
export const MENU_ITEM_SIZE_OPTIONS = MENU_SIZE_OPTIONS;
export type MenuItemSizeValue = MenuSizeValue;
export const BUTTON_TYPE_OPTIONS = [
"filled",