@exxatdesignux/ui 0.5.11 → 0.5.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/bin/cli.mjs +70 -1
- package/bin/init.mjs +18 -4
- package/bin/sync-extras.mjs +28 -4
- package/consumer-extras/README.md +41 -5
- package/consumer-extras/cursor-rules/exxat-accessibility.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-board-cards.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +4 -2
- package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-command-menu.mdc +3 -2
- package/consumer-extras/cursor-rules/exxat-data-tables.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +7 -0
- package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-hub-supported-views.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +6 -5
- package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +6 -2
- package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-nav-single-active.mdc +4 -3
- package/consumer-extras/cursor-rules/exxat-no-image-pixel-copy.mdc +25 -14
- package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +8 -2
- package/consumer-extras/cursor-rules/exxat-no-toast.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-no-vaul.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-page-header-actions.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-sidebar-shell.mdc +13 -7
- package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-table-row-preview.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-tabs-chrome.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +6 -0
- package/consumer-extras/cursor-rules/exxat-ux-discovery-protocol.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-ux-principles.mdc +1 -0
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-kpi-trends/SKILL.md +5 -3
- package/consumer-extras/patterns/command-menu-pattern.md +2 -2
- package/consumer-extras/patterns/consumer-upgrade-checklist.md +1 -1
- package/consumer-extras/patterns/jobs/README.md +1 -1
- package/consumer-extras/patterns/perf-memory-pattern.md +115 -150
- package/consumer-extras/scripts/dev-guard.mjs +156 -0
- package/consumer-extras/templates/README.md +23 -0
- package/consumer-extras/templates/handoff.md +190 -0
- package/package.json +2 -2
- package/{template → template-vite}/.claude/skills/exxat-ds-skill/SKILL.md +184 -23
- package/template-vite/.cursor/rules/exxat-accessibility.mdc +40 -0
- package/template-vite/.cursor/rules/exxat-board-cards.mdc +28 -0
- package/template-vite/.cursor/rules/exxat-breadcrumbs-no-back.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-card-vs-list-rows.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-centralized-list-dataset.mdc +46 -0
- package/template-vite/.cursor/rules/exxat-collaboration-access.mdc +33 -0
- package/{template → template-vite}/.cursor/rules/exxat-command-menu.mdc +5 -5
- package/template-vite/.cursor/rules/exxat-data-tables.mdc +47 -0
- package/template-vite/.cursor/rules/exxat-dedicated-search-surfaces.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-drawer-vs-dialog.mdc +23 -0
- package/template-vite/.cursor/rules/exxat-ds-agents.mdc +87 -0
- package/template-vite/.cursor/rules/exxat-fontawesome-icons.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-hub-supported-views.mdc +56 -0
- package/{template → template-vite}/.cursor/rules/exxat-kbd-shortcuts.mdc +1 -0
- package/template-vite/.cursor/rules/exxat-kpi-flat-band.mdc +29 -0
- package/template-vite/.cursor/rules/exxat-kpi-max-four.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-kpi-trends.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-library-hub-header.mdc +29 -0
- package/template-vite/.cursor/rules/exxat-list-page-connected-views.mdc +28 -0
- package/template-vite/.cursor/rules/exxat-list-page-view-shells.mdc +32 -0
- package/{template → template-vite}/.cursor/rules/exxat-mono-ids.mdc +1 -0
- package/template-vite/.cursor/rules/exxat-nav-single-active.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-no-image-pixel-copy.mdc +46 -0
- package/template-vite/.cursor/rules/exxat-no-slds-leakage.mdc +84 -0
- package/{template → template-vite}/.cursor/rules/exxat-no-toast.mdc +2 -2
- package/template-vite/.cursor/rules/exxat-no-vaul.mdc +26 -0
- package/template-vite/.cursor/rules/exxat-page-header-actions.mdc +33 -0
- package/{template → template-vite}/.cursor/rules/exxat-page-vs-drawer.mdc +5 -3
- package/template-vite/.cursor/rules/exxat-person-identity-display.mdc +48 -0
- package/template-vite/.cursor/rules/exxat-primary-nav-secondary-panel.mdc +53 -0
- package/template-vite/.cursor/rules/exxat-reuse-before-custom.mdc +37 -0
- package/template-vite/.cursor/rules/exxat-sidebar-shell.mdc +41 -0
- package/template-vite/.cursor/rules/exxat-table-properties-drawer.mdc +79 -0
- package/template-vite/.cursor/rules/exxat-table-row-preview.mdc +25 -0
- package/template-vite/.cursor/rules/exxat-tabs-chrome.mdc +33 -0
- package/template-vite/.cursor/rules/exxat-token-discipline.mdc +109 -0
- package/template-vite/.cursor/rules/exxat-ux-discovery-protocol.mdc +202 -0
- package/template-vite/.cursor/rules/exxat-ux-principles.mdc +187 -0
- package/template-vite/.cursor/skills/exxat-accessibility/SKILL.md +282 -0
- package/template-vite/.cursor/skills/exxat-board-cards/SKILL.md +68 -0
- package/template-vite/.cursor/skills/exxat-card-vs-list-rows/SKILL.md +20 -0
- package/template-vite/.cursor/skills/exxat-centralized-list-dataset/SKILL.md +99 -0
- package/template-vite/.cursor/skills/exxat-collaboration-access/SKILL.md +35 -0
- package/template-vite/.cursor/skills/exxat-dedicated-search-surfaces/SKILL.md +45 -0
- package/template-vite/.cursor/skills/exxat-drawer-vs-dialog/SKILL.md +20 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/SKILL.md +893 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/accessibility.md +142 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/coach-marks.md +169 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/data-table-pattern.md +392 -0
- package/template-vite/.cursor/skills/exxat-fontawesome-icons/SKILL.md +31 -0
- package/template-vite/.cursor/skills/exxat-kpi-flat-band/SKILL.md +38 -0
- package/template-vite/.cursor/skills/exxat-kpi-max-four/SKILL.md +19 -0
- package/template-vite/.cursor/skills/exxat-kpi-trends/SKILL.md +29 -0
- package/template-vite/.cursor/skills/exxat-list-page-view-shells/SKILL.md +36 -0
- package/template-vite/.cursor/skills/exxat-mono-ids/SKILL.md +56 -0
- package/template-vite/.cursor/skills/exxat-primary-nav-secondary-panel/SKILL.md +49 -0
- package/template-vite/.cursor/skills/exxat-senior-ux/SKILL.md +198 -0
- package/template-vite/.cursor/skills/exxat-token-economy/SKILL.md +287 -0
- package/template-vite/.cursor/skills/exxat-ux-audit/SKILL.md +303 -0
- package/{template → template-vite}/components/ask-leo-sidebar.tsx +10 -8
- package/{template → template-vite}/components/command-menu.tsx +1 -1
- package/{template → template-vite}/components/data-views/library-folder-tree-branch.tsx +1 -1
- package/{template → template-vite}/components/dedicated-search-recents.tsx +1 -1
- package/{template → template-vite}/components/dedicated-search-url-composer.tsx +1 -1
- package/{template → template-vite}/components/library-client.tsx +1 -1
- package/{template → template-vite}/components/library-hub-client.tsx +2 -2
- package/{template → template-vite}/components/library-secondary-nav.tsx +2 -2
- package/{template → template-vite}/components/library-table.tsx +35 -27
- package/{template → template-vite}/components/new-library-item-form.tsx +1 -1
- package/{template → template-vite}/components/page-breadcrumb-trail.tsx +1 -1
- package/{template → template-vite}/components/settings-client.tsx +1 -1
- package/{template → template-vite}/components/sidebar/app-sidebar.tsx +2 -2
- package/{template → template-vite}/components/sidebar/nav-main.tsx +1 -1
- package/{template → template-vite}/components/sidebar/nav-user.tsx +1 -1
- package/{template → template-vite}/components/sidebar/secondary-nav.tsx +1 -1
- package/{template → template-vite}/components/system-banner-slot.tsx +1 -1
- package/{template → template-vite}/components/templates/discovery-hub-template.tsx +2 -2
- package/{template → template-vite}/components/templates/new-focus-template.tsx +1 -1
- package/{template → template-vite}/components/tokens-secondary-nav.tsx +2 -2
- package/{template → template-vite}/components/tokens-themes-client.tsx +1 -1
- package/{template → template-vite}/hooks/use-secondary-panel-hub-nav.ts +1 -1
- package/template-vite/index.html +49 -0
- package/template-vite/lib/next-compat.tsx +98 -0
- package/{template → template-vite}/package.json +15 -27
- package/template-vite/scripts/port-next-imports.mjs +70 -0
- package/template-vite/src/App.tsx +103 -0
- package/template-vite/src/main.tsx +50 -0
- package/{template/app/(app)/error.tsx → template-vite/src/pages/_error.tsx} +12 -24
- package/{template/app/(app)/loading.tsx → template-vite/src/pages/_loading.tsx} +4 -2
- package/template-vite/src/pages/_not-found.tsx +17 -0
- package/template-vite/src/pages/dashboard.tsx +48 -0
- package/{template/app/(app)/help/page.tsx → template-vite/src/pages/help.tsx} +3 -2
- package/{template/app/(app)/library/layout.tsx → template-vite/src/pages/library/_layout.tsx} +18 -16
- package/{template/app/(app)/library/all/page.tsx → template-vite/src/pages/library/all.tsx} +1 -1
- package/{template/app/(app)/library/new/page.tsx → template-vite/src/pages/library/new.tsx} +12 -18
- package/template-vite/src/routes.tsx +72 -0
- package/{template/app → template-vite/src/styles}/globals.css +6 -2
- package/{template → template-vite}/tsconfig.json +5 -14
- package/template-vite/vite.config.ts +52 -0
- package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +0 -53
- package/template/.agents/skills/shadcn/SKILL.md +0 -242
- package/template/.agents/skills/shadcn/agents/openai.yml +0 -5
- package/template/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
- package/template/.agents/skills/shadcn/assets/shadcn.png +0 -0
- package/template/.agents/skills/shadcn/cli.md +0 -257
- package/template/.agents/skills/shadcn/customization.md +0 -202
- package/template/.agents/skills/shadcn/evals/evals.json +0 -47
- package/template/.agents/skills/shadcn/mcp.md +0 -94
- package/template/.agents/skills/shadcn/rules/base-vs-radix.md +0 -306
- package/template/.agents/skills/shadcn/rules/composition.md +0 -195
- package/template/.agents/skills/shadcn/rules/forms.md +0 -192
- package/template/.agents/skills/shadcn/rules/icons.md +0 -101
- package/template/.agents/skills/shadcn/rules/styling.md +0 -162
- package/template/.cursor/rules/exxat-accessibility.mdc +0 -33
- package/template/.cursor/rules/exxat-data-tables.mdc +0 -32
- package/template/.cursor/rules/exxat-ds-agents.mdc +0 -26
- package/template/.cursor/rules/exxat-list-page-connected-views.mdc +0 -16
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +0 -40
- package/template/.nvmrc +0 -1
- package/template/.prettierignore +0 -7
- package/template/Logo/Exxat_Prism.svg +0 -39
- package/template/Logo/Exxat_one.svg +0 -36
- package/template/app/(app)/dashboard/loading.tsx +0 -18
- package/template/app/(app)/dashboard/page.tsx +0 -36
- package/template/app/(app)/layout.tsx +0 -77
- package/template/app/global-error.tsx +0 -63
- package/template/app/layout.tsx +0 -133
- package/template/app/page.tsx +0 -9
- package/template/docs/HANDBOOK.md +0 -187
- package/template/docs/blueprints/README.md +0 -86
- package/template/docs/blueprints/_template.md +0 -91
- package/template/docs/blueprints/board-card.md +0 -123
- package/template/docs/blueprints/data-table.md +0 -139
- package/template/docs/blueprints/key-metrics.md +0 -128
- package/template/docs/blueprints/list-page-template.md +0 -123
- package/template/docs/blueprints/page-header.md +0 -130
- package/template/docs/card-vs-rows-pattern.md +0 -36
- package/template/docs/collaboration-access-pattern.md +0 -116
- package/template/docs/command-menu-pattern.md +0 -45
- package/template/docs/component-selection-guide.md +0 -224
- package/template/docs/components-audit-2026-05.md +0 -158
- package/template/docs/consumer-upgrade-checklist.md +0 -52
- package/template/docs/data-views-pattern.md +0 -185
- package/template/docs/drawer-vs-dialog-pattern.md +0 -50
- package/template/docs/glossary.md +0 -59
- package/template/docs/hub-supported-views-pattern.md +0 -53
- package/template/docs/jobs/README.md +0 -59
- package/template/docs/jobs/record-detail.md +0 -177
- package/template/docs/kpi-flat-band-pattern.md +0 -57
- package/template/docs/kpi-strip-max-four-pattern.md +0 -30
- package/template/docs/kpi-trend-pattern.md +0 -58
- package/template/docs/large-dataset-strategy.md +0 -155
- package/template/docs/library-hub-header-pattern.md +0 -25
- package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +0 -95
- package/template/docs/migrations/0002-exxat-token-namespace.md +0 -154
- package/template/docs/migrations/0003-globals-css-canonical.md +0 -110
- package/template/docs/migrations/README.md +0 -100
- package/template/docs/migrations/_template.md +0 -64
- package/template/docs/modern-saas-patterns.md +0 -165
- package/template/docs/perf-memory-pattern.md +0 -206
- package/template/docs/reference-implementations.md +0 -153
- package/template/docs/shell-surface-elevation-pattern.md +0 -52
- package/template/docs/token-taxonomy.md +0 -416
- package/template/docs/voice-and-tone.md +0 -262
- package/template/ecosystem.config.cjs +0 -32
- package/template/next.config.mjs +0 -216
- package/template/postcss.config.mjs +0 -8
- package/template/public/favicon/favicon.ico +0 -0
- package/template/tests/setup.ts +0 -26
- package/template/vitest.config.ts +0 -18
- /package/{template → template-vite}/.cursor/rules/exxat-dashboard-view-charts.mdc +0 -0
- /package/{template → template-vite}/.prettierrc +0 -0
- /package/{template → template-vite}/AGENTS.md +0 -0
- /package/{template → template-vite}/README.md +0 -0
- /package/{template → template-vite}/components/.gitkeep +0 -0
- /package/{template → template-vite}/components/ask-leo-composer.tsx +0 -0
- /package/{template → template-vite}/components/brand-color-picker.tsx +0 -0
- /package/{template → template-vite}/components/chart-area-interactive.tsx +0 -0
- /package/{template → template-vite}/components/charts-overview.tsx +0 -0
- /package/{template → template-vite}/components/collaboration-access-flow.tsx +0 -0
- /package/{template → template-vite}/components/columns-client.tsx +0 -0
- /package/{template → template-vite}/components/columns-showcase.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-promo-banner.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-quota-progress-card.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-report-charts.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-section-heading.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-tabs.tsx +0 -0
- /package/{template → template-vite}/components/data-table/filter-date-calendar.tsx +0 -0
- /package/{template → template-vite}/components/data-table/filter-text-value-input.tsx +0 -0
- /package/{template → template-vite}/components/data-table/index.tsx +0 -0
- /package/{template → template-vite}/components/data-table/pagination.tsx +0 -0
- /package/{template → template-vite}/components/data-table/types.ts +0 -0
- /package/{template → template-vite}/components/data-table/use-table-state.test.ts +0 -0
- /package/{template → template-vite}/components/data-table/use-table-state.ts +0 -0
- /package/{template → template-vite}/components/data-views/board-card-primitives.tsx +0 -0
- /package/{template → template-vite}/components/data-views/data-row-list.tsx +0 -0
- /package/{template → template-vite}/components/data-views/finder-panel-view.tsx +0 -0
- /package/{template → template-vite}/components/data-views/folder-grid-view.tsx +0 -0
- /package/{template → template-vite}/components/data-views/hub-table.tsx +0 -0
- /package/{template → template-vite}/components/data-views/index.ts +0 -0
- /package/{template → template-vite}/components/data-views/list-page-board-card.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-board-template.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-connected-view-body.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-details-placeholder.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-hub-chrome.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-hub-tokens.ts +0 -0
- /package/{template → template-vite}/components/data-views/list-page-tree-column-header.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-tree-panel-shell.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-view-frame.tsx +0 -0
- /package/{template → template-vite}/components/data-views/os-folder-glyph.tsx +0 -0
- /package/{template → template-vite}/components/data-views/outline-tree-menu.tsx +0 -0
- /package/{template → template-vite}/components/data-views/table-cells.tsx +0 -0
- /package/{template → template-vite}/components/dev-chunk-load-recovery.tsx +0 -0
- /package/{template → template-vite}/components/export-drawer.test.tsx +0 -0
- /package/{template → template-vite}/components/export-drawer.tsx +0 -0
- /package/{template → template-vite}/components/exxat-product-logo.tsx +0 -0
- /package/{template → template-vite}/components/folder-details-shell.tsx +0 -0
- /package/{template → template-vite}/components/form-layout-01.tsx +0 -0
- /package/{template → template-vite}/components/hub-tree-panel-view.tsx +0 -0
- /package/{template → template-vite}/components/invite-collaborators-drawer.tsx +0 -0
- /package/{template → template-vite}/components/key-metrics-ask-leo-bridge.tsx +0 -0
- /package/{template → template-vite}/components/key-metrics.tsx +0 -0
- /package/{template → template-vite}/components/leo-insight-indicator.tsx +0 -0
- /package/{template → template-vite}/components/leo-typing-dots.tsx +0 -0
- /package/{template → template-vite}/components/library-board-view.tsx +0 -0
- /package/{template → template-vite}/components/library-dashboard-charts.tsx +0 -0
- /package/{template → template-vite}/components/library-favorite-button.tsx +0 -0
- /package/{template → template-vite}/components/library-new-folder-sheet.tsx +0 -0
- /package/{template → template-vite}/components/library-os-folder-view.tsx +0 -0
- /package/{template → template-vite}/components/library-page-header.tsx +0 -0
- /package/{template → template-vite}/components/library-panel-activator.tsx +0 -0
- /package/{template → template-vite}/components/list-hub-status-badge.tsx +0 -0
- /package/{template → template-vite}/components/list-page-dashboard-charts.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/getting-started.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/index.ts +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-01.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-02.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-03.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-04.tsx +0 -0
- /package/{template → template-vite}/components/page-header.tsx +0 -0
- /package/{template → template-vite}/components/product-switcher.tsx +0 -0
- /package/{template → template-vite}/components/product-wordmark.tsx +0 -0
- /package/{template → template-vite}/components/settings-appearance-card.tsx +0 -0
- /package/{template → template-vite}/components/settings-form-row.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/app-sidebar-dynamic.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/index.ts +0 -0
- /package/{template → template-vite}/components/sidebar/nav-documents.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/nav-secondary.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/secondary-panel.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-auto-collapse.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-auto-open.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-shell.tsx +0 -0
- /package/{template → template-vite}/components/site-header.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/column-row.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/draggable-list.ts +0 -0
- /package/{template → template-vite}/components/table-properties/drawer-button.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/drawer.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/filter-card.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/index.ts +0 -0
- /package/{template → template-vite}/components/table-properties/sort-card.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/types.ts +0 -0
- /package/{template → template-vite}/components/task-list-panel.tsx +0 -0
- /package/{template → template-vite}/components/task-priority-badge.tsx +0 -0
- /package/{template → template-vite}/components/templates/dedicated-search-landing-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/dedicated-search-results-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/list-page.tsx +0 -0
- /package/{template → template-vite}/components/templates/nested-secondary-panel-shell.tsx +0 -0
- /package/{template → template-vite}/components/templates/primary-page-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/secondary-panel-hub-template.tsx +0 -0
- /package/{template → template-vite}/components/theme-color-sync.tsx +0 -0
- /package/{template → template-vite}/components/theme-provider.tsx +0 -0
- /package/{template → template-vite}/components/tinted-icon-disc.tsx +0 -0
- /package/{template → template-vite}/components/tokens-hub-auxiliary-views.tsx +0 -0
- /package/{template → template-vite}/components/tokens-themes-section.tsx +0 -0
- /package/{template → template-vite}/components/ui/accordion.tsx +0 -0
- /package/{template → template-vite}/components/ui/ai-thinking-surface.tsx +0 -0
- /package/{template → template-vite}/components/ui/alert-dialog.tsx +0 -0
- /package/{template → template-vite}/components/ui/avatar.tsx +0 -0
- /package/{template → template-vite}/components/ui/badge.tsx +0 -0
- /package/{template → template-vite}/components/ui/banner.tsx +0 -0
- /package/{template → template-vite}/components/ui/breadcrumb.tsx +0 -0
- /package/{template → template-vite}/components/ui/button.tsx +0 -0
- /package/{template → template-vite}/components/ui/calendar.tsx +0 -0
- /package/{template → template-vite}/components/ui/card.tsx +0 -0
- /package/{template → template-vite}/components/ui/chart.tsx +0 -0
- /package/{template → template-vite}/components/ui/checkbox.tsx +0 -0
- /package/{template → template-vite}/components/ui/coach-mark.tsx +0 -0
- /package/{template → template-vite}/components/ui/collapsible.tsx +0 -0
- /package/{template → template-vite}/components/ui/command.tsx +0 -0
- /package/{template → template-vite}/components/ui/context-menu.tsx +0 -0
- /package/{template → template-vite}/components/ui/date-picker-field.tsx +0 -0
- /package/{template → template-vite}/components/ui/dialog.tsx +0 -0
- /package/{template → template-vite}/components/ui/dot-pattern.tsx +0 -0
- /package/{template → template-vite}/components/ui/drag-handle-grip.tsx +0 -0
- /package/{template → template-vite}/components/ui/dropdown-menu.tsx +0 -0
- /package/{template → template-vite}/components/ui/field.tsx +0 -0
- /package/{template → template-vite}/components/ui/form.tsx +0 -0
- /package/{template → template-vite}/components/ui/hover-card.tsx +0 -0
- /package/{template → template-vite}/components/ui/input-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/input-mask.tsx +0 -0
- /package/{template → template-vite}/components/ui/input.tsx +0 -0
- /package/{template → template-vite}/components/ui/kbd.tsx +0 -0
- /package/{template → template-vite}/components/ui/label.tsx +0 -0
- /package/{template → template-vite}/components/ui/leo-icon.tsx +0 -0
- /package/{template → template-vite}/components/ui/payment-card-fields.tsx +0 -0
- /package/{template → template-vite}/components/ui/popover.tsx +0 -0
- /package/{template → template-vite}/components/ui/radio-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/resizable.tsx +0 -0
- /package/{template → template-vite}/components/ui/scroll-area.tsx +0 -0
- /package/{template → template-vite}/components/ui/select.tsx +0 -0
- /package/{template → template-vite}/components/ui/selection-tile-grid.tsx +0 -0
- /package/{template → template-vite}/components/ui/separator.tsx +0 -0
- /package/{template → template-vite}/components/ui/sheet.tsx +0 -0
- /package/{template → template-vite}/components/ui/sidebar.tsx +0 -0
- /package/{template → template-vite}/components/ui/skeleton.tsx +0 -0
- /package/{template → template-vite}/components/ui/slider.tsx +0 -0
- /package/{template → template-vite}/components/ui/sonner.tsx +0 -0
- /package/{template → template-vite}/components/ui/status-badge.tsx +0 -0
- /package/{template → template-vite}/components/ui/table.tsx +0 -0
- /package/{template → template-vite}/components/ui/tabs.tsx +0 -0
- /package/{template → template-vite}/components/ui/textarea.tsx +0 -0
- /package/{template → template-vite}/components/ui/tip.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle-switch.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle.tsx +0 -0
- /package/{template → template-vite}/components/ui/tooltip.tsx +0 -0
- /package/{template → template-vite}/components/ui/view-segmented-control.tsx +0 -0
- /package/{template → template-vite}/components.json +0 -0
- /package/{template → template-vite}/contexts/chart-variant-context.tsx +0 -0
- /package/{template → template-vite}/contexts/command-menu-context.tsx +0 -0
- /package/{template → template-vite}/contexts/dashboard-view-context.tsx +0 -0
- /package/{template → template-vite}/contexts/product-context.tsx +0 -0
- /package/{template → template-vite}/contexts/system-banner-context.tsx +0 -0
- /package/{template → template-vite}/eslint.config.mjs +0 -0
- /package/{template → template-vite}/fontawesome-subset.manifest.json +0 -0
- /package/{template → template-vite}/hooks/.gitkeep +0 -0
- /package/{template → template-vite}/hooks/use-app-theme.ts +0 -0
- /package/{template → template-vite}/hooks/use-coach-mark.ts +0 -0
- /package/{template → template-vite}/hooks/use-location-hash.ts +0 -0
- /package/{template → template-vite}/hooks/use-mobile.ts +0 -0
- /package/{template → template-vite}/hooks/use-mod-key-label.ts +0 -0
- /package/{template → template-vite}/hooks/use-sidebar-reflow-zoom.ts +0 -0
- /package/{template → template-vite}/lib/.gitkeep +0 -0
- /package/{template → template-vite}/lib/ask-leo-route-context.ts +0 -0
- /package/{template → template-vite}/lib/chart-keyboard-selection.test.ts +0 -0
- /package/{template → template-vite}/lib/chart-keyboard-selection.ts +0 -0
- /package/{template → template-vite}/lib/chart-line-dash.ts +0 -0
- /package/{template → template-vite}/lib/chunk-load-error.ts +0 -0
- /package/{template → template-vite}/lib/coach-mark-registry.ts +0 -0
- /package/{template → template-vite}/lib/collaborator-access.ts +0 -0
- /package/{template → template-vite}/lib/command-menu-config.ts +0 -0
- /package/{template → template-vite}/lib/command-menu-search-data.ts +0 -0
- /package/{template → template-vite}/lib/conditional-rule-match.ts +0 -0
- /package/{template → template-vite}/lib/dashboard-customize-coach-mark.ts +0 -0
- /package/{template → template-vite}/lib/dashboard-layout-merge.ts +0 -0
- /package/{template → template-vite}/lib/data-list-display-options.ts +0 -0
- /package/{template → template-vite}/lib/data-list-persistence.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view-registry.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view-surface.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view.ts +0 -0
- /package/{template → template-vite}/lib/data-view-dashboard-storage.ts +0 -0
- /package/{template → template-vite}/lib/date-filter.ts +0 -0
- /package/{template → template-vite}/lib/dedicated-search-recents.ts +0 -0
- /package/{template → template-vite}/lib/dedicated-search-url.ts +0 -0
- /package/{template → template-vite}/lib/dev-log.test.ts +0 -0
- /package/{template → template-vite}/lib/dev-log.ts +0 -0
- /package/{template → template-vite}/lib/discovery-hub.ts +0 -0
- /package/{template → template-vite}/lib/editable-target.ts +0 -0
- /package/{template → template-vite}/lib/exxat-palette.json +0 -0
- /package/{template → template-vite}/lib/exxat-palette.ts +0 -0
- /package/{template → template-vite}/lib/floating-sheet-panel.ts +0 -0
- /package/{template → template-vite}/lib/full-hub-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/hub-connected-view-renderers.ts +0 -0
- /package/{template → template-vite}/lib/initials-from-name.ts +0 -0
- /package/{template → template-vite}/lib/library-authoring.ts +0 -0
- /package/{template → template-vite}/lib/library-dedicated-search.ts +0 -0
- /package/{template → template-vite}/lib/library-hub-search.ts +0 -0
- /package/{template → template-vite}/lib/library-nav.ts +0 -0
- /package/{template → template-vite}/lib/library-recent-searches.ts +0 -0
- /package/{template → template-vite}/lib/library-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/list-hub-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/list-page-table-properties.ts +0 -0
- /package/{template → template-vite}/lib/list-status-badges.ts +0 -0
- /package/{template → template-vite}/lib/logo-dev.ts +0 -0
- /package/{template → template-vite}/lib/mailto.ts +0 -0
- /package/{template → template-vite}/lib/mock/dashboard.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-folders.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-header-collaborators.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-inspector.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-kpi.ts +0 -0
- /package/{template → template-vite}/lib/mock/library.ts +0 -0
- /package/{template → template-vite}/lib/mock/navigation.tsx +0 -0
- /package/{template → template-vite}/lib/motion-ui.ts +0 -0
- /package/{template → template-vite}/lib/product-brand.ts +0 -0
- /package/{template → template-vite}/lib/raf-throttle.ts +0 -0
- /package/{template → template-vite}/lib/row-height.ts +0 -0
- /package/{template → template-vite}/lib/sidebar-state-cookie.ts +0 -0
- /package/{template → template-vite}/lib/stock-portrait.ts +0 -0
- /package/{template → template-vite}/lib/table-state-lifecycle.ts +0 -0
- /package/{template → template-vite}/lib/utils.test.ts +0 -0
- /package/{template → template-vite}/lib/utils.ts +0 -0
- /package/{template → template-vite}/public/.gitkeep +0 -0
- /package/{template → template-vite}/public/Illustration/Rotation.svg +0 -0
- /package/{template → template-vite}/public/avatars/user.svg +0 -0
- /package/{template/public → template-vite/public/favicon}/favicon.ico +0 -0
- /package/{template/app → template-vite/public}/favicon.ico +0 -0
- /package/{template → template-vite}/public/folders/icons8-folder-windows-11.svg +0 -0
- /package/{template → template-vite}/public/logos/exxat-one.svg +0 -0
- /package/{template → template-vite}/public/logos/exxat-prism.svg +0 -0
- /package/{template → template-vite}/public/mock-schools/emory.svg +0 -0
- /package/{template → template-vite}/public/mock-schools/rush.svg +0 -0
- /package/{template → template-vite}/scripts/fontawesome-subset-audit.mjs +0 -0
- /package/{template → template-vite}/scripts/pm2-startup-macos.sh +0 -0
- /package/{template → template-vite}/skills-lock.json +0 -0
- /package/{template/app/(app)/columns/page.tsx → template-vite/src/pages/columns.tsx} +0 -0
- /package/{template/app/(app)/library/find/page.tsx → template-vite/src/pages/library/find.tsx} +0 -0
- /package/{template/app/(app)/library/page.tsx → template-vite/src/pages/library/index.tsx} +0 -0
- /package/{template/app/(app)/library/list/page.tsx → template-vite/src/pages/library/list.tsx} +0 -0
- /package/{template/app/(app)/settings/page.tsx → template-vite/src/pages/settings.tsx} +0 -0
- /package/{template/app/(app)/tokens-themes/page.tsx → template-vite/src/pages/tokens-themes.tsx} +0 -0
- /package/{template → template-vite}/stores/app-store.ts +0 -0
- /package/{template → template-vite}/types/react-payment-inputs.d.ts +0 -0
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { cookies } from "next/headers"
|
|
2
|
-
import {
|
|
3
|
-
AppSidebar,
|
|
4
|
-
SidebarShell,
|
|
5
|
-
SecondaryPanelProvider,
|
|
6
|
-
SecondaryPanel,
|
|
7
|
-
} from "@/components/sidebar"
|
|
8
|
-
import {
|
|
9
|
-
SIDEBAR_STATE_COOKIE_NAME,
|
|
10
|
-
sidebarDefaultOpenFromCookie,
|
|
11
|
-
} from "@/lib/sidebar-state-cookie"
|
|
12
|
-
import { DashboardViewProvider } from "@/contexts/dashboard-view-context"
|
|
13
|
-
import { ChartVariantProvider } from "@/contexts/chart-variant-context"
|
|
14
|
-
import { AskLeoProvider, AskLeoSidebar } from "@/components/ask-leo-sidebar"
|
|
15
|
-
import { KeyMetricsAskLeoBridge } from "@/components/key-metrics-ask-leo-bridge"
|
|
16
|
-
import { SystemBannerProvider } from "@/contexts/system-banner-context"
|
|
17
|
-
import { SystemBannerSlot } from "@/components/system-banner-slot"
|
|
18
|
-
import { CommandMenu } from "@/components/command-menu"
|
|
19
|
-
import { CommandMenuProvider } from "@/contexts/command-menu-context"
|
|
20
|
-
import { buildCommandMenuConfig } from "@/lib/command-menu-config"
|
|
21
|
-
import { COMMAND_MENU_SEARCH_DATA_GROUPS } from "@/lib/command-menu-search-data"
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Shared app layout:
|
|
25
|
-
* [ SystemBanner (main-page width) ]
|
|
26
|
-
* [AppSidebar] [SecondaryPanel?] [page] [AskLeo?]
|
|
27
|
-
*
|
|
28
|
-
* The SystemBanner is configured from Settings (persisted to localStorage
|
|
29
|
-
* via SystemBannerProvider) — no hardcoded copy here.
|
|
30
|
-
*/
|
|
31
|
-
export default async function AppLayout({ children }: { children: React.ReactNode }) {
|
|
32
|
-
const cookieStore = await cookies()
|
|
33
|
-
const sidebarDefaultOpen = sidebarDefaultOpenFromCookie(
|
|
34
|
-
cookieStore.get(SIDEBAR_STATE_COOKIE_NAME)?.value,
|
|
35
|
-
)
|
|
36
|
-
const commandMenuConfig = buildCommandMenuConfig({
|
|
37
|
-
dataGroups: COMMAND_MENU_SEARCH_DATA_GROUPS,
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<DashboardViewProvider>
|
|
42
|
-
<ChartVariantProvider>
|
|
43
|
-
<AskLeoProvider>
|
|
44
|
-
<KeyMetricsAskLeoBridge>
|
|
45
|
-
<SystemBannerProvider>
|
|
46
|
-
<CommandMenuProvider value={commandMenuConfig}>
|
|
47
|
-
|
|
48
|
-
<SidebarShell defaultOpen={sidebarDefaultOpen} wrapperClassName="flex min-h-svh flex-col">
|
|
49
|
-
{/* ⌘K command palette */}
|
|
50
|
-
<CommandMenu />
|
|
51
|
-
<SystemBannerSlot />
|
|
52
|
-
|
|
53
|
-
{/* Sidebar + content row — flex-1 min-h-0 below min-h-svh shell; SidebarInset self-stretch + PrimaryPageTemplate flex-1 fills viewport when page body is short. */}
|
|
54
|
-
{/* suppressHydrationWarning: the Cursor IDE browser preview injects a
|
|
55
|
-
`data-cursor-ref` attribute on this layout root before React hydrates.
|
|
56
|
-
Scoped to this element's own attributes only. See companion comment
|
|
57
|
-
in components/templates/nested-secondary-panel-shell.tsx. */}
|
|
58
|
-
<div
|
|
59
|
-
className="flex min-h-0 w-full flex-1 items-stretch has-data-[variant=inset]:bg-sidebar"
|
|
60
|
-
suppressHydrationWarning
|
|
61
|
-
>
|
|
62
|
-
<SecondaryPanelProvider>
|
|
63
|
-
<AppSidebar variant="inset" />
|
|
64
|
-
<SecondaryPanel />
|
|
65
|
-
{children}
|
|
66
|
-
</SecondaryPanelProvider>
|
|
67
|
-
<AskLeoSidebar />
|
|
68
|
-
</div>
|
|
69
|
-
</SidebarShell>
|
|
70
|
-
</CommandMenuProvider>
|
|
71
|
-
</SystemBannerProvider>
|
|
72
|
-
</KeyMetricsAskLeoBridge>
|
|
73
|
-
</AskLeoProvider>
|
|
74
|
-
</ChartVariantProvider>
|
|
75
|
-
</DashboardViewProvider>
|
|
76
|
-
)
|
|
77
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
|
|
5
|
-
import "./globals.css"
|
|
6
|
-
import { isChunkLoadError } from "@/lib/chunk-load-error"
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Root error boundary — catches failures outside the (app) segment layout.
|
|
10
|
-
*/
|
|
11
|
-
export default function GlobalError({
|
|
12
|
-
error,
|
|
13
|
-
reset,
|
|
14
|
-
}: {
|
|
15
|
-
error: Error & { digest?: string }
|
|
16
|
-
reset: () => void
|
|
17
|
-
}) {
|
|
18
|
-
const chunkStale = isChunkLoadError(error)
|
|
19
|
-
|
|
20
|
-
React.useEffect(() => {
|
|
21
|
-
if (process.env.NODE_ENV === "development") {
|
|
22
|
-
console.error(error)
|
|
23
|
-
}
|
|
24
|
-
}, [error])
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<html lang="en">
|
|
28
|
-
<body className="bg-background font-sans text-foreground">
|
|
29
|
-
<div
|
|
30
|
-
className="flex min-h-svh flex-col items-center justify-center gap-4 px-4 py-12 text-center"
|
|
31
|
-
role="alert"
|
|
32
|
-
>
|
|
33
|
-
<h1 className="text-lg font-semibold">Something went wrong</h1>
|
|
34
|
-
<p className="max-w-md text-sm text-muted-foreground">
|
|
35
|
-
{chunkStale
|
|
36
|
-
? "The app loaded an outdated script bundle (common after a dev-server rebuild). Reload the page to fetch the latest chunks."
|
|
37
|
-
: process.env.NODE_ENV === "development"
|
|
38
|
-
? error.message
|
|
39
|
-
: "Please try again. If the problem continues, contact support."}
|
|
40
|
-
</p>
|
|
41
|
-
<div className="flex flex-wrap items-center justify-center gap-2">
|
|
42
|
-
{chunkStale ? (
|
|
43
|
-
<button
|
|
44
|
-
type="button"
|
|
45
|
-
className="inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground"
|
|
46
|
-
onClick={() => window.location.reload()}
|
|
47
|
-
>
|
|
48
|
-
Reload page
|
|
49
|
-
</button>
|
|
50
|
-
) : null}
|
|
51
|
-
<button
|
|
52
|
-
type="button"
|
|
53
|
-
className="inline-flex h-9 items-center justify-center rounded-md border border-input bg-background px-4 text-sm font-medium"
|
|
54
|
-
onClick={() => reset()}
|
|
55
|
-
>
|
|
56
|
-
Try again
|
|
57
|
-
</button>
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
-
</body>
|
|
61
|
-
</html>
|
|
62
|
-
)
|
|
63
|
-
}
|
package/template/app/layout.tsx
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import type { Metadata, Viewport } from "next"
|
|
2
|
-
import { Inter } from "next/font/google"
|
|
3
|
-
import Script from "next/script"
|
|
4
|
-
|
|
5
|
-
import "./globals.css"
|
|
6
|
-
import { ThemeProvider } from "@/components/theme-provider"
|
|
7
|
-
import { TooltipProvider } from "@/components/ui/tooltip"
|
|
8
|
-
import { ProductProvider } from "@/contexts/product-context"
|
|
9
|
-
import { DevChunkLoadRecovery } from "@/components/dev-chunk-load-recovery"
|
|
10
|
-
import { ThemeColorSync } from "@/components/theme-color-sync"
|
|
11
|
-
import { cn } from "@/lib/utils"
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Inter — primary brand typeface for Exxat One (Lavender) and Exxat Prism (Rose).
|
|
15
|
-
* Loaded via next/font for zero layout shift and optimal subsetting.
|
|
16
|
-
*/
|
|
17
|
-
const inter = Inter({
|
|
18
|
-
subsets: ["latin"],
|
|
19
|
-
weight: ["300", "400", "500", "600", "700", "800"],
|
|
20
|
-
variable: "--font-sans",
|
|
21
|
-
display: "swap",
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
export const metadata: Metadata = {
|
|
25
|
-
title: "Exxat Design System",
|
|
26
|
-
description:
|
|
27
|
-
"Shared UI component library for Exxat One and Exxat Prism — built to WCAG 2.1 Level AA.",
|
|
28
|
-
icons: {
|
|
29
|
-
icon: "/favicon.ico",
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export const viewport: Viewport = {
|
|
34
|
-
width: "device-width",
|
|
35
|
-
initialScale: 1,
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export default function RootLayout({
|
|
39
|
-
children,
|
|
40
|
-
}: Readonly<{
|
|
41
|
-
children: React.ReactNode
|
|
42
|
-
}>) {
|
|
43
|
-
return (
|
|
44
|
-
/**
|
|
45
|
-
* RTL: dir="rtl" mirrors layout for right-to-left languages.
|
|
46
|
-
* lang="en" is the default; override per-page for localised content.
|
|
47
|
-
*
|
|
48
|
-
* WCAG notes:
|
|
49
|
-
* - suppressHydrationWarning prevents theme-flicker false positives.
|
|
50
|
-
* - Theme classes (theme-one / theme-prism / dark) are managed by
|
|
51
|
-
* ThemeProvider and applied to <html>.
|
|
52
|
-
* - "theme-one" sets Exxat One Lavender as the default brand.
|
|
53
|
-
* Replace with "theme-prism" to switch to Exxat Prism Rose.
|
|
54
|
-
*/
|
|
55
|
-
<html
|
|
56
|
-
lang="en"
|
|
57
|
-
suppressHydrationWarning
|
|
58
|
-
className={cn(inter.variable)}
|
|
59
|
-
>
|
|
60
|
-
<head>
|
|
61
|
-
{/* Default until ThemeColorSync hydrates (brand + mode override client-side) */}
|
|
62
|
-
<meta name="theme-color" content="#f6f3ff" />
|
|
63
|
-
{/*
|
|
64
|
-
* Adobe Fonts — preconnect + preload Ivy Presto · Kit ID: wuk5wqn.
|
|
65
|
-
*
|
|
66
|
-
* Trust model & Subresource Integrity (SRI):
|
|
67
|
-
* - Adobe Typekit serves *dynamically subsetted* CSS that hashes
|
|
68
|
-
* differently per response, so SRI cannot be applied — the kit URL
|
|
69
|
-
* is locked to a single Adobe-owned origin instead.
|
|
70
|
-
* - `crossOrigin=""` (anonymous CORS) is set on both the preconnect
|
|
71
|
-
* and the stylesheet so the browser uses one CORS-correct
|
|
72
|
-
* connection for preconnect + preload + fetch, and so styles
|
|
73
|
-
* cannot read first-party cookies or credentials.
|
|
74
|
-
* - The same origins are pinned in `style-src` / `font-src` /
|
|
75
|
-
* `connect-src` of the Content-Security-Policy declared in
|
|
76
|
-
* `next.config.mjs`, which is what actually prevents arbitrary
|
|
77
|
-
* third-party CSS/fonts from loading.
|
|
78
|
-
*/}
|
|
79
|
-
<link rel="preconnect" href="https://use.typekit.net" crossOrigin="" />
|
|
80
|
-
<link rel="preconnect" href="https://p.typekit.net" crossOrigin="" />
|
|
81
|
-
<link
|
|
82
|
-
rel="preload"
|
|
83
|
-
href="https://use.typekit.net/wuk5wqn.css"
|
|
84
|
-
as="style"
|
|
85
|
-
crossOrigin=""
|
|
86
|
-
/>
|
|
87
|
-
<link
|
|
88
|
-
rel="stylesheet"
|
|
89
|
-
href="https://use.typekit.net/wuk5wqn.css"
|
|
90
|
-
crossOrigin=""
|
|
91
|
-
/>
|
|
92
|
-
</head>
|
|
93
|
-
<body className="bg-sidebar text-foreground font-sans">
|
|
94
|
-
<DevChunkLoadRecovery />
|
|
95
|
-
{/*
|
|
96
|
-
* Font Awesome Pro Kit — subset via fontawesome-subset.manifest.json +
|
|
97
|
-
* fontawesome.com/kits (Icon Selection).
|
|
98
|
-
*
|
|
99
|
-
* Trust model & SRI: the kit loader URL is content-versioned by
|
|
100
|
-
* fontawesome.com and rotates whenever the subset changes, so SRI
|
|
101
|
-
* cannot be pinned. We instead:
|
|
102
|
-
* - Restrict the script to kit.fontawesome.com (and font/data fetch
|
|
103
|
-
* to ka-f.fontawesome.com) via CSP `script-src` / `font-src` /
|
|
104
|
-
* `connect-src` in `next.config.mjs`.
|
|
105
|
-
* - Load with `crossOrigin="anonymous"` so the script runs with
|
|
106
|
-
* CORS semantics and no credentials.
|
|
107
|
-
*/}
|
|
108
|
-
<Script
|
|
109
|
-
src="https://kit.fontawesome.com/d9bd5774e0.js"
|
|
110
|
-
crossOrigin="anonymous"
|
|
111
|
-
strategy="afterInteractive"
|
|
112
|
-
/>
|
|
113
|
-
<ThemeProvider
|
|
114
|
-
attribute="class"
|
|
115
|
-
defaultTheme="system"
|
|
116
|
-
enableSystem
|
|
117
|
-
disableTransitionOnChange
|
|
118
|
-
>
|
|
119
|
-
<ProductProvider>
|
|
120
|
-
<ThemeColorSync />
|
|
121
|
-
<TooltipProvider delayDuration={300}>
|
|
122
|
-
{/* Skip to main content — WCAG 2.4.1 (Bypass Blocks) */}
|
|
123
|
-
<a href="#main-content" className="skip-to-content">
|
|
124
|
-
Skip to main content
|
|
125
|
-
</a>
|
|
126
|
-
{children}
|
|
127
|
-
</TooltipProvider>
|
|
128
|
-
</ProductProvider>
|
|
129
|
-
</ThemeProvider>
|
|
130
|
-
</body>
|
|
131
|
-
</html>
|
|
132
|
-
)
|
|
133
|
-
}
|
package/template/app/page.tsx
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
# Exxat DS — Handbook
|
|
2
|
-
|
|
3
|
-
> **Start here.** One page. Read in 10 minutes. Links out to everything else.
|
|
4
|
-
>
|
|
5
|
-
> **Audience:** designers, engineers, contributors, AI agents — anyone shipping UI in the Exxat product.
|
|
6
|
-
>
|
|
7
|
-
> **Working with an AI assistant?** Read [`.cursor/skills/exxat-token-economy/SKILL.md`](../../.cursor/skills/exxat-token-economy/SKILL.md) **first** (or `.claude/skills/exxat-token-economy/SKILL.md` for Claude Code). It's a one-page pre-flight that cuts token usage by ~50%: a task → minimum-file-set table, the five-question rule check, and tiny scaffolds that mean the assistant never has to re-read this handbook for the common case.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## 1. Five principles
|
|
12
|
-
|
|
13
|
-
Every screen, primitive, and pattern in this design system serves one or more of these. When in doubt, the principle wins over the convenience.
|
|
14
|
-
|
|
15
|
-
1. **Clarity over decoration.** Users see one product, one shell, one rhythm. Surprise (mystery icons, hidden states, novel layouts) is a tax on attention.
|
|
16
|
-
2. **Progressive disclosure.** Beginners see what they need. Power users reach what they want. Default to the simpler surface; expose density on opt-in (Properties drawer, view tabs, secondary panel).
|
|
17
|
-
3. **Same-shaped tools.** A hub looks like a hub. A drawer looks like a drawer. A KPI looks like a KPI. Pick the canonical primitive (§5 reference pages) before composing your own.
|
|
18
|
-
4. **Accessibility is non-negotiable.** WCAG 2.1 AA is the **floor**, not the goal. Keyboard, screen-reader, contrast, touch-target, format hints — all enforced by rules, lints, and a checklist.
|
|
19
|
-
5. **The data drives the chrome.** KPIs, status, trend polarity, descriptions — they come from the dataset (or the product) and are honest. No spin arrows, no decorative placeholders.
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 2. How to build a hub in 6 steps
|
|
24
|
-
|
|
25
|
-
This is the **happy path** for the most common task: "I have an entity (records, library items, tokens, …); ship a hub for it." Follow these in order and the page lands at "best UX/UI", not "random design".
|
|
26
|
-
|
|
27
|
-
| Step | What to do | Where it lives | Rule |
|
|
28
|
-
|---|---|---|---|
|
|
29
|
-
| 1 | Add typed mock rows in `lib/mock/<entity>.ts`. Aim for ~12 realistic records. | `apps/web/lib/mock/` | `.cursor/rules/exxat-centralized-list-dataset.mdc` |
|
|
30
|
-
| 2 | Write **one** KPI helper `lib/mock/<entity>-kpi.ts` returning `MetricItem[]` (≤ 4 tiles). | same | `exxat-kpi-max-four.mdc`, `exxat-kpi-trends.mdc` |
|
|
31
|
-
| 3 | Build the column defs (`ColumnDef[]`). Set `filter:` per column to get filter chips automatically. | `apps/web/components/<entity>-table.tsx` | `exxat-data-tables.mdc` |
|
|
32
|
-
| 4 | Mount **`HubTable`** (NOT raw `<DataTable>`) inside `ListPageTemplate.renderContent`. `HubTable` wires `useTableState`, toolbar (search + filter chips + sort), and the **Properties drawer** in one place. | `apps/web/components/<entity>-table.tsx` | `exxat-data-tables.mdc` |
|
|
33
|
-
| 5 | Compose the page client with `PrimaryPageTemplate` → `ListPageTemplate` (KPIs in `metrics`, view tabs in `defaultTabs`, the `HubTable` in `renderContent`). | `apps/web/components/<entity>-client.tsx` | `exxat-list-page-connected-views.mdc` |
|
|
34
|
-
| 6 | Add to nav (`lib/mock/navigation.tsx`). If the hub needs scoped sub-navigation (e.g. categories), declare `secondaryPanel: "<id>"` and register the panel. | `apps/web/lib/mock/navigation.tsx`, `apps/web/components/sidebar/secondary-panel.tsx` | `exxat-primary-nav-secondary-panel.mdc` |
|
|
35
|
-
|
|
36
|
-
**Reference pages to copy:** `apps/web/components/library-table.tsx` + `library-client.tsx` (canonical seven-view hub), `apps/web/components/columns-showcase.tsx` (custom columns + same Add view via `LibraryTable`), `apps/web/components/tokens-themes-client.tsx` + `tokens-hub-auxiliary-views.tsx`. See **`hub-supported-views-pattern.md`** before changing Add view.
|
|
37
|
-
|
|
38
|
-
> **Stop signs.** If you find yourself building a parallel table stack, a second metrics strip, a custom filter row, or pasting raw `<DataTable>` into `renderContent` — **stop and re-read** `.cursor/rules/exxat-reuse-before-custom.mdc`.
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## 3. Where everything lives
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
┌─────────────────────────────────────────────────────────────────────┐
|
|
46
|
-
│ PRINCIPLES + HANDBOOK → docs/HANDBOOK.md (this file) │
|
|
47
|
-
│ │
|
|
48
|
-
│ FOUNDATIONS │
|
|
49
|
-
│ tokens → docs/token-taxonomy.md │
|
|
50
|
-
│ icons (Font Awesome) → .cursor/rules/exxat-fontawesome-icons │
|
|
51
|
-
│ typography → docs/token-taxonomy.md (font-* tokens) │
|
|
52
|
-
│ spacing / radius → docs/token-taxonomy.md (--exxat-*) │
|
|
53
|
-
│ color & themes → apps/web/components/tokens-themes-* │
|
|
54
|
-
│ voice & tone → docs/voice-and-tone.md │
|
|
55
|
-
│ glossary → docs/glossary.md │
|
|
56
|
-
│ reference pages → docs/reference-implementations.md │
|
|
57
|
-
│ │
|
|
58
|
-
│ DECIDING (selection guides) │
|
|
59
|
-
│ which component? → docs/component-selection-guide.md │
|
|
60
|
-
│ page vs drawer vs → docs/drawer-vs-dialog-pattern.md │
|
|
61
|
-
│ dialog vs route + .cursor/rules/exxat-{drawer-vs-dialog, │
|
|
62
|
-
│ page-vs-drawer}.mdc │
|
|
63
|
-
│ card vs row vs list → docs/card-vs-rows-pattern.md │
|
|
64
|
-
│ │
|
|
65
|
-
│ BLUEPRINTS (framework-agnostic specs — one per pattern) │
|
|
66
|
-
│ → docs/blueprints/ │
|
|
67
|
-
│ page-header · data-table · │
|
|
68
|
-
│ list-page-template · board-card · │
|
|
69
|
-
│ key-metrics │
|
|
70
|
-
│ │
|
|
71
|
-
│ PATTERNS (long-form narrative — the "why" + the "how") │
|
|
72
|
-
│ → docs/*.md (data-views-pattern, │
|
|
73
|
-
│ kpi-trend-pattern, drawer-vs-dialog- │
|
|
74
|
-
│ pattern, dedicated-search, │
|
|
75
|
-
│ command-menu, …) │
|
|
76
|
-
│ │
|
|
77
|
-
│ RULES (binding MUST / MUST NOT — for AI agents + reviewers) │
|
|
78
|
-
│ → .cursor/rules/*.mdc │
|
|
79
|
-
│ │
|
|
80
|
-
│ SKILLS (workflows + checklists — for AI agents doing a task) │
|
|
81
|
-
│ → .cursor/skills/ + .claude/skills/ │
|
|
82
|
-
│ │
|
|
83
|
-
│ MIGRATIONS (deprecation history, every breaking change) │
|
|
84
|
-
│ → docs/migrations/ │
|
|
85
|
-
│ │
|
|
86
|
-
│ AGENT HANDBOOK (authoritative §-numbered manual) │
|
|
87
|
-
│ → apps/web/AGENTS.md │
|
|
88
|
-
└─────────────────────────────────────────────────────────────────────┘
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Quick "which file should I open?" cheat-sheet
|
|
92
|
-
|
|
93
|
-
| You want to… | Open this |
|
|
94
|
-
|---|---|
|
|
95
|
-
| Pick the right component for a job | [`docs/component-selection-guide.md`](./component-selection-guide.md) |
|
|
96
|
-
| Know what "hub" / "view tab" / "KPI band" mean | [`docs/glossary.md`](./glossary.md) |
|
|
97
|
-
| Write empty-state / error / button copy | [`docs/voice-and-tone.md`](./voice-and-tone.md) |
|
|
98
|
-
| Find the canonical reference page to copy | [`docs/reference-implementations.md`](./reference-implementations.md) |
|
|
99
|
-
| Know the spec for a pattern | [`docs/blueprints/`](./blueprints/) |
|
|
100
|
-
| Understand the "why" of a pattern | [`docs/<pattern>-pattern.md`](.) |
|
|
101
|
-
| Know the binding MUST / MUST NOT | [`.cursor/rules/`](../../../.cursor/rules/) |
|
|
102
|
-
| Run a recurring agent workflow | [`.cursor/skills/`](../../../.cursor/skills/) or [`.claude/skills/`](../../../.claude/skills/) |
|
|
103
|
-
| Token name & semantics | [`docs/token-taxonomy.md`](./token-taxonomy.md) |
|
|
104
|
-
| Full authoritative handbook | [`apps/web/AGENTS.md`](../AGENTS.md) |
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
## 4. Rule precedence (when sources conflict)
|
|
109
|
-
|
|
110
|
-
If two docs say different things, **the higher row wins**:
|
|
111
|
-
|
|
112
|
-
1. **`.cursor/rules/*.mdc`** — these are MUST / MUST NOT; they bind the AI agent and the reviewer.
|
|
113
|
-
2. **`apps/web/AGENTS.md`** — authoritative §-numbered handbook. The rules above are summaries of this.
|
|
114
|
-
3. **`docs/blueprints/*.md`** — framework-agnostic specs for a single pattern.
|
|
115
|
-
4. **`docs/*-pattern.md`** — long-form narrative for a pattern.
|
|
116
|
-
5. **Reference page in code** (`apps/web/components/<reference>.tsx`) — the working implementation.
|
|
117
|
-
6. **This handbook** — orientation only. If it conflicts with rules or AGENTS, the rules/AGENTS win.
|
|
118
|
-
|
|
119
|
-
> **Found a conflict?** Open a PR that updates the *binding* layer (rule or AGENTS section) first, then propagate down. Don't fork the truth.
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## 5. The canonical primitives (memorize these)
|
|
124
|
-
|
|
125
|
-
These are the ones you'll use on >90% of screens. If a screen needs something else, it almost certainly already exists — search `components/` before building.
|
|
126
|
-
|
|
127
|
-
| Need | Primitive | Lives in |
|
|
128
|
-
|---|---|---|
|
|
129
|
-
| Page chrome (breadcrumbs, site header, max-width content rail) | `PrimaryPageTemplate` | `apps/web/components/templates/primary-page-template.tsx` |
|
|
130
|
-
| Hub frame (header + metrics + view tabs + content) | `ListPageTemplate` | `packages/ui` |
|
|
131
|
-
| **Hub view body** (table + search + filters + Properties drawer + bulk-actions) | **`HubTable`** | `packages/ui` (re-exported from `@/components/data-views`) |
|
|
132
|
-
| Page header (title + subtitle + actions + collaborators rail) | `PageHeader` | `apps/web/components/page-header.tsx` |
|
|
133
|
-
| KPI strip / band | `KeyMetrics` (`variant="flat"` on hubs) | `packages/ui` |
|
|
134
|
-
| Status chip + icon | `ListHubStatusBadge` + `lib/list-status-badges.ts` | `apps/web/components/` |
|
|
135
|
-
| Board / kanban card | `ListPageBoardCard` + primitives | `packages/ui` |
|
|
136
|
-
| Side overlay | `Sheet` floating panels (NOT toast — `exxat-no-toast.mdc`) | `packages/ui` |
|
|
137
|
-
| Persistent banner | `LocalBanner` / `SystemBanner` | `packages/ui` |
|
|
138
|
-
| Inline status / format hint | `FormDescription`, inline `<small>` | `packages/ui` |
|
|
139
|
-
| Tooltip | `Tip` / `Tooltip` | `packages/ui` |
|
|
140
|
-
| Keyboard shortcut hint | `Kbd` (`variant="bare"` inside buttons) | `packages/ui` |
|
|
141
|
-
| Global search | `CommandMenu` (⌘K) | `apps/web/components/command-menu.tsx` |
|
|
142
|
-
| AI assistant chrome | Ask Leo side panel (⌘⌥K) | `apps/web/components/` |
|
|
143
|
-
|
|
144
|
-
For a fuller decision tree see [`docs/component-selection-guide.md`](./component-selection-guide.md).
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## 6. The shortest accessibility checklist
|
|
149
|
-
|
|
150
|
-
Run this on every PR. If you can't tick every box, the change isn't ready. (Full list: `.cursor/skills/exxat-accessibility/SKILL.md` and [`AGENTS.md` §8](../AGENTS.md).)
|
|
151
|
-
|
|
152
|
-
- [ ] **Keyboard.** Every interactive thing reachable via Tab + activatable via Enter / Space. Focus ring visible (≥ 3:1).
|
|
153
|
-
- [ ] **Touch target ≥ 24×24 CSS px** (or 24 px spacing) per WCAG 2.5.8.
|
|
154
|
-
- [ ] **Icons that mean something** have a text alt — either adjacent label (Case A, `aria-hidden`), or `role="img" + aria-label + Tooltip` (Case B), or `aria-label + Tooltip` on the button (Case C). No silent icons.
|
|
155
|
-
- [ ] **Contrast.** Text ≥ 4.5:1; UI components ≥ 3:1. Don't encode state with color alone — pair with icon or label.
|
|
156
|
-
- [ ] **Format hints are persistent**, never placeholder-only. Use `FormDescription`.
|
|
157
|
-
- [ ] **Dialogs / drawers / sheets** have a `Title` (use `sr-only` if visually hidden).
|
|
158
|
-
- [ ] **Tabs** use `role="tablist"` correctly (no mixed children); composite switchers use `role="toolbar"` instead.
|
|
159
|
-
- [ ] **No toast.** Use banners, inline status, or dialogs (`exxat-no-toast.mdc`).
|
|
160
|
-
- [ ] **HC modes.** Forced-colors and `data-contrast="high"` covered for any fill-only state (progress, gauge, pill).
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
## 7. The "you're done" definition
|
|
165
|
-
|
|
166
|
-
A hub or screen is **done** when:
|
|
167
|
-
|
|
168
|
-
1. It uses `PrimaryPageTemplate` + `ListPageTemplate` (or another canonical template).
|
|
169
|
-
2. The data surface is `HubTable` (or, for non-hubs, the right primitive from §5).
|
|
170
|
-
3. KPIs use `KeyMetrics` with `delta` for counts, `description` for prose, ≤ 4 tiles, polarity set correctly.
|
|
171
|
-
4. The §6 accessibility checklist is green.
|
|
172
|
-
5. Copy passes [`docs/voice-and-tone.md`](./voice-and-tone.md).
|
|
173
|
-
6. No new shared primitives were added without `.cursor/rules/exxat-reuse-before-custom.mdc` approval.
|
|
174
|
-
7. The §13 PR-review checklist in [`AGENTS.md`](../AGENTS.md#section-13) is green.
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
## 8. Where to ask for help
|
|
179
|
-
|
|
180
|
-
- **Code-level questions** — open the file referenced in a rule's "See also" section.
|
|
181
|
-
- **Pattern-level questions** — open the matching `docs/*-pattern.md`.
|
|
182
|
-
- **"Is this the right approach?"** — read [`.cursor/rules/exxat-reuse-before-custom.mdc`](../../../.cursor/rules/exxat-reuse-before-custom.mdc). If still unsure, ask before building.
|
|
183
|
-
- **AGENTS.md is too long** — that's why this handbook exists. Bring the §-number you're stuck on; we'll split it out.
|
|
184
|
-
|
|
185
|
-
---
|
|
186
|
-
|
|
187
|
-
*This file is intentionally short. If you want to add something, ask whether it belongs in a rule, a pattern, a blueprint, or the glossary instead.*
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# Exxat DS — Blueprints
|
|
2
|
-
|
|
3
|
-
**Audience:** humans + AI agents.
|
|
4
|
-
**Inspired by:** [SLDS Component Blueprints](https://www.lightningdesignsystem.com/components).
|
|
5
|
-
|
|
6
|
-
A **blueprint** is a **framework-agnostic spec** for a UI pattern. It says
|
|
7
|
-
*what* the pattern is, *what it must do*, and *what tokens it consumes* —
|
|
8
|
-
**without committing to any one implementation**.
|
|
9
|
-
|
|
10
|
-
A **component** is the React + Tailwind implementation that satisfies the
|
|
11
|
-
blueprint inside this app.
|
|
12
|
-
|
|
13
|
-
| Blueprint says… | Component does… |
|
|
14
|
-
|---|---|
|
|
15
|
-
| "A page header has a title, optional icon, optional meta line, optional action slot, optional `+ N collaborators` rail" | `PageHeader` renders that with `variant="object-home" / "record-home" / "collaboration"` etc. |
|
|
16
|
-
| "A data list is a sortable, filterable, columnable grid of records with search, properties drawer, and view tabs" | `DataTable` + `ListPageTemplate` + `TablePropertiesDrawer` compose to satisfy this |
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## Why blueprints exist
|
|
21
|
-
|
|
22
|
-
1. **They survive framework changes.** If we ever ship a second consumer
|
|
23
|
-
(mobile, embed widget, design-token export to Figma), the blueprint stays
|
|
24
|
-
true; only the implementation changes.
|
|
25
|
-
2. **They make the design language explicit.** New contributors can read a
|
|
26
|
-
single page that says "this is what a page header **is** at Exxat" without
|
|
27
|
-
spelunking through React props.
|
|
28
|
-
3. **They let designers, engineers, and AI agents share one vocabulary.** The
|
|
29
|
-
blueprint is the contract; the React component is the receipt.
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Anatomy of a blueprint doc
|
|
34
|
-
|
|
35
|
-
Each blueprint follows the same template. Copy it from
|
|
36
|
-
[`_template.md`](./_template.md) when adding a new one.
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
# <Blueprint name>
|
|
40
|
-
|
|
41
|
-
## 1. Intent → What user need does this solve? When NOT to use it.
|
|
42
|
-
## 2. Anatomy → Required + optional slots, with an ASCII or markdown sketch.
|
|
43
|
-
## 3. States → Default, hover, active, disabled, loading, empty, error, RTL.
|
|
44
|
-
## 4. Tokens consumed → Exact token names from `docs/token-taxonomy.md`.
|
|
45
|
-
## 5. Accessibility → Roles, focus order, keyboard, screen-reader.
|
|
46
|
-
## 6. Variants → Named families that share anatomy but swap layout/density.
|
|
47
|
-
## 7. Implementation → Table of frameworks → component(s); React is required.
|
|
48
|
-
## 8. Do / Don't → Anti-patterns + correct alternatives.
|
|
49
|
-
## 9. References → Linked AGENTS.md sections, cursor rules, related blueprints.
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
The React row in §7 is **required**; other frameworks are listed as `—` until
|
|
53
|
-
they ship.
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## Authoritative file pointers
|
|
58
|
-
|
|
59
|
-
For most patterns, the blueprint complements an existing narrative doc — it
|
|
60
|
-
does **not** replace it. The blueprint is the spec; the narrative is the deep
|
|
61
|
-
dive.
|
|
62
|
-
|
|
63
|
-
| Blueprint | Narrative doc | Cursor rule(s) | React component(s) |
|
|
64
|
-
|---|---|---|---|
|
|
65
|
-
| [page-header](./page-header.md) | `apps/web/docs/data-views-pattern.md` (Page header section) | `exxat-collaboration-access.mdc` (variant), `exxat-mono-ids.mdc` (subtitle IDs) | `PageHeader`, `PlacementsPageHeader`, `TeamPageHeader`, `LibraryPageHeader` |
|
|
66
|
-
| [data-table](./data-table.md) | `apps/web/docs/data-views-pattern.md` | `exxat-data-tables.mdc`, `exxat-list-page-connected-views.mdc`, `exxat-centralized-list-dataset.mdc`, `exxat-table-properties-drawer.mdc` | `DataTable`, `DataTablePaginated`, `useTableState`, `TablePropertiesDrawer` |
|
|
67
|
-
| [list-page-template](./list-page-template.md) | `apps/web/docs/data-views-pattern.md`, `kpi-flat-band-pattern.md` | `exxat-list-page-connected-views.mdc`, `exxat-centralized-list-dataset.mdc`, `exxat-table-properties-drawer.mdc`, `exxat-list-page-view-shells.mdc` | `ListPageTemplate`, `HubTable`, `useTableState`, `TablePropertiesDrawer` |
|
|
68
|
-
| [board-card](./board-card.md) | `apps/web/docs/data-views-pattern.md` (board UI section) | `exxat-board-cards.mdc`, `exxat-centralized-list-dataset.mdc`, `exxat-card-vs-list-rows.mdc` | `ListPageBoardCard`, `ListPageBoardCardTitleRow`, `ListPageBoardCardBadgeRow`, `BoardCardTwoLineBlock`, `BoardCardIconRow`, `ListHubStatusBadge` |
|
|
69
|
-
| [key-metrics](./key-metrics.md) | `apps/web/docs/kpi-flat-band-pattern.md`, `kpi-strip-max-four-pattern.md`, `kpi-trend-pattern.md` | `exxat-kpi-flat-band.mdc`, `exxat-kpi-max-four.mdc`, `exxat-kpi-trends.mdc` | `KeyMetrics`, `MetricItem`, `MetricInsight`, `KeyMetricsProvider` |
|
|
70
|
-
|
|
71
|
-
Future blueprints to write (open a PR when adding one):
|
|
72
|
-
|
|
73
|
-
- `drawer-vs-dialog.md` — overlay decision (already in `docs/drawer-vs-dialog-pattern.md`, formalize as blueprint)
|
|
74
|
-
- `command-menu.md` — global ⌘K palette + Ask Leo split
|
|
75
|
-
- `dedicated-search.md` — landing vs results
|
|
76
|
-
- `sidebar.md` — primary nav + secondary panel + product switcher
|
|
77
|
-
- `coach-mark.md` — onboarding tours
|
|
78
|
-
- `status-badge.md` — `ListHubStatusBadge` + `lib/list-status-badges.ts`
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## See also
|
|
83
|
-
|
|
84
|
-
- [`apps/web/docs/token-taxonomy.md`](../token-taxonomy.md) — the design-token namespace these blueprints reference
|
|
85
|
-
- [`apps/web/docs/component-selection-guide.md`](../component-selection-guide.md) — decision tree across blueprints
|
|
86
|
-
- [`apps/web/AGENTS.md`](../../AGENTS.md) §9 architecture pointers (component reuse table)
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# Blueprint: <Name>
|
|
2
|
-
|
|
3
|
-
> **Status:** Draft / Stable. **Owner:** <team or person>. **Implements:** <SC refs>.
|
|
4
|
-
|
|
5
|
-
## 1. Intent
|
|
6
|
-
|
|
7
|
-
What user need does this pattern solve? In one paragraph.
|
|
8
|
-
|
|
9
|
-
**Use when:**
|
|
10
|
-
- Bullet
|
|
11
|
-
- Bullet
|
|
12
|
-
|
|
13
|
-
**Do NOT use when:**
|
|
14
|
-
- Bullet
|
|
15
|
-
|
|
16
|
-
## 2. Anatomy
|
|
17
|
-
|
|
18
|
-
ASCII / markdown sketch with labelled slots. List every named slot and whether
|
|
19
|
-
it is required, optional, or conditional.
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
┌──────────────────────────────────────────┐
|
|
23
|
-
│ [icon] Title [actions] │ ← slot: title-row (required)
|
|
24
|
-
│ ─────────────────────────────────────── │
|
|
25
|
-
│ subtitle · ID · meta │ ← slot: meta (optional)
|
|
26
|
-
└──────────────────────────────────────────┘
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
| Slot | Required? | What it carries |
|
|
30
|
-
|---|---|---|
|
|
31
|
-
| `title` | required | Single H1 string |
|
|
32
|
-
| `icon` | optional | FA glyph or product mark |
|
|
33
|
-
| `actions` | optional | Primary CTA + optional `⋯` overflow |
|
|
34
|
-
| `meta` | optional | Count · freshness · sort summary |
|
|
35
|
-
|
|
36
|
-
## 3. States
|
|
37
|
-
|
|
38
|
-
| State | Visual / behavior |
|
|
39
|
-
|---|---|
|
|
40
|
-
| Default | … |
|
|
41
|
-
| Loading | … |
|
|
42
|
-
| Empty | … |
|
|
43
|
-
| Error | … |
|
|
44
|
-
| RTL | … |
|
|
45
|
-
|
|
46
|
-
## 4. Tokens consumed
|
|
47
|
-
|
|
48
|
-
List every token the blueprint references from
|
|
49
|
-
[`docs/token-taxonomy.md`](../token-taxonomy.md). Be precise — no "a brand
|
|
50
|
-
color"; name `--brand-color`.
|
|
51
|
-
|
|
52
|
-
| Token | Used for |
|
|
53
|
-
|---|---|
|
|
54
|
-
| `--background` / `--foreground` | Surface + ink |
|
|
55
|
-
| … | … |
|
|
56
|
-
|
|
57
|
-
## 5. Accessibility
|
|
58
|
-
|
|
59
|
-
| WCAG SC | How this blueprint complies |
|
|
60
|
-
|---|---|
|
|
61
|
-
| 1.1.1 Non-text content | Icons are decorative (Case A) when adjacent to text; standalone icons follow Case B (label + tooltip) |
|
|
62
|
-
| 1.3.1 Info & relationships | … |
|
|
63
|
-
| 2.1.1 Keyboard | Tab order: … |
|
|
64
|
-
| 2.4.6 Headings / labels | The title slot is the `<h1>` for the route |
|
|
65
|
-
| 2.4.11 Focus visible | Inherits `:focus-visible` ring (≥ 3:1) |
|
|
66
|
-
|
|
67
|
-
## 6. Variants
|
|
68
|
-
|
|
69
|
-
| Variant | When to use | Differences from default |
|
|
70
|
-
|---|---|---|
|
|
71
|
-
| `base` | … | — |
|
|
72
|
-
|
|
73
|
-
## 7. Implementation
|
|
74
|
-
|
|
75
|
-
| Framework | Component(s) | File |
|
|
76
|
-
|---|---|---|
|
|
77
|
-
| **React (this app)** | `PrimaryComponent` + `RelatedComponent` | `apps/web/components/<file>.tsx` |
|
|
78
|
-
| Mobile | — | — |
|
|
79
|
-
| Figma | — | — |
|
|
80
|
-
|
|
81
|
-
## 8. Do / Don't
|
|
82
|
-
|
|
83
|
-
| ✅ Do | ❌ Don't |
|
|
84
|
-
|---|---|
|
|
85
|
-
| Bullet | Bullet |
|
|
86
|
-
|
|
87
|
-
## 9. References
|
|
88
|
-
|
|
89
|
-
- `apps/web/docs/<related-narrative>.md`
|
|
90
|
-
- `.cursor/rules/<related-rule>.mdc`
|
|
91
|
-
- `apps/web/AGENTS.md` §<section>
|