@exxatdesignux/ui 0.5.2 → 0.5.4

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.
Files changed (104) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +1 -1
  3. package/consumer-extras/cursor-rules/exxat-accessibility.mdc +1 -1
  4. package/consumer-extras/cursor-rules/exxat-data-tables.mdc +8 -6
  5. package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +4 -4
  6. package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +6 -1
  7. package/consumer-extras/cursor-rules/exxat-hub-supported-views.mdc +54 -0
  8. package/consumer-extras/cursor-rules/exxat-nav-single-active.mdc +31 -0
  9. package/consumer-extras/cursor-rules/exxat-no-vaul.mdc +25 -0
  10. package/consumer-extras/cursor-rules/exxat-page-header-actions.mdc +31 -0
  11. package/consumer-extras/cursor-rules/exxat-table-row-preview.mdc +24 -0
  12. package/consumer-extras/cursor-rules/exxat-tabs-chrome.mdc +31 -0
  13. package/consumer-extras/cursor-skills/exxat-drawer-vs-dialog/SKILL.md +5 -5
  14. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +10 -5
  15. package/consumer-extras/cursor-skills/exxat-ds-skill/references/accessibility.md +1 -1
  16. package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +15 -5
  17. package/consumer-extras/cursor-skills/exxat-token-economy/SKILL.md +14 -5
  18. package/consumer-extras/handbook/HANDBOOK.md +1 -1
  19. package/consumer-extras/handbook/reference-implementations.md +2 -2
  20. package/consumer-extras/patterns/consumer-upgrade-checklist.md +14 -1
  21. package/consumer-extras/patterns/data-views-pattern.md +6 -0
  22. package/consumer-extras/patterns/drawer-vs-dialog-pattern.md +50 -0
  23. package/consumer-extras/patterns/hub-supported-views-pattern.md +53 -0
  24. package/dist/components/data-table/index.js +13 -9
  25. package/dist/components/data-table/index.js.map +1 -1
  26. package/dist/components/data-table/pagination.js +13 -9
  27. package/dist/components/data-table/pagination.js.map +1 -1
  28. package/dist/components/data-views/hub-table.d.ts +8 -4
  29. package/dist/components/data-views/hub-table.js +25 -10
  30. package/dist/components/data-views/hub-table.js.map +1 -1
  31. package/dist/components/data-views/index.d.ts +1 -1
  32. package/dist/components/data-views/index.js +25 -10
  33. package/dist/components/data-views/index.js.map +1 -1
  34. package/dist/components/data-views/list-page-connected-view-body.d.ts +1 -1
  35. package/dist/components/data-views/list-page-connected-view-body.js +1 -0
  36. package/dist/components/data-views/list-page-connected-view-body.js.map +1 -1
  37. package/dist/components/table-properties/drawer-button.js +1 -0
  38. package/dist/components/table-properties/drawer-button.js.map +1 -1
  39. package/dist/components/table-properties/drawer.js +1 -0
  40. package/dist/components/table-properties/drawer.js.map +1 -1
  41. package/dist/components/table-properties/index.d.ts +1 -1
  42. package/dist/components/table-properties/index.js +1 -0
  43. package/dist/components/table-properties/index.js.map +1 -1
  44. package/dist/components/templates/index.d.ts +1 -1
  45. package/dist/components/templates/index.js +12 -2
  46. package/dist/components/templates/index.js.map +1 -1
  47. package/dist/components/templates/list-page.d.ts +4 -2
  48. package/dist/components/templates/list-page.js +12 -2
  49. package/dist/components/templates/list-page.js.map +1 -1
  50. package/dist/{data-list-view-registry-CyBoBML4.d.ts → data-list-view-registry-BstmlfQ3.d.ts} +16 -1
  51. package/dist/index.d.ts +2 -3
  52. package/dist/index.js +135 -126
  53. package/dist/index.js.map +1 -1
  54. package/dist/lib/data-list-view-registry.d.ts +1 -1
  55. package/dist/lib/data-list-view-registry.js +17 -1
  56. package/dist/lib/data-list-view-registry.js.map +1 -1
  57. package/dist/lib/data-list-view-surface.d.ts +1 -1
  58. package/dist/lib/data-list-view-surface.js +1 -0
  59. package/dist/lib/data-list-view-surface.js.map +1 -1
  60. package/dist/lib/list-page-table-properties.d.ts +1 -1
  61. package/dist/lib/list-page-table-properties.js +1 -0
  62. package/dist/lib/list-page-table-properties.js.map +1 -1
  63. package/dist/lib/nav-active.d.ts +38 -0
  64. package/dist/lib/nav-active.js +104 -0
  65. package/dist/lib/nav-active.js.map +1 -0
  66. package/package.json +1 -2
  67. package/src/components/data-table/index.tsx +25 -17
  68. package/src/components/data-views/hub-table.tsx +9 -3
  69. package/src/components/templates/list-page.tsx +9 -3
  70. package/src/index.ts +1 -1
  71. package/src/lib/data-list-view-registry.ts +31 -0
  72. package/src/lib/nav-active.ts +162 -0
  73. package/template/.claude/skills/exxat-ds-skill/SKILL.md +2 -1
  74. package/template/.cursor/rules/exxat-accessibility.mdc +1 -1
  75. package/template/AGENTS.md +18 -3
  76. package/template/components/columns-client.tsx +3 -2
  77. package/template/components/columns-showcase.tsx +22 -18
  78. package/template/components/exxat-product-logo.tsx +1 -1
  79. package/template/components/library-table.tsx +62 -23
  80. package/template/components/new-library-item-form.tsx +0 -7
  81. package/template/components/product-wordmark.tsx +1 -1
  82. package/template/components/sidebar/app-sidebar.tsx +14 -106
  83. package/template/components/sidebar/secondary-nav.tsx +22 -4
  84. package/template/components/site-header.tsx +1 -1
  85. package/template/components/tokens-hub-auxiliary-views.tsx +301 -0
  86. package/template/components/tokens-themes-client.tsx +44 -16
  87. package/template/docs/HANDBOOK.md +2 -2
  88. package/template/docs/component-selection-guide.md +1 -1
  89. package/template/docs/consumer-upgrade-checklist.md +51 -0
  90. package/template/docs/data-views-pattern.md +6 -0
  91. package/template/docs/drawer-vs-dialog-pattern.md +8 -8
  92. package/template/docs/glossary.md +2 -1
  93. package/template/docs/hub-supported-views-pattern.md +53 -0
  94. package/template/docs/reference-implementations.md +2 -2
  95. package/template/lib/full-hub-supported-views.ts +8 -0
  96. package/template/lib/library-supported-views.ts +5 -12
  97. package/template/lib/motion-ui.ts +2 -2
  98. package/template/package.json +1 -1
  99. package/tokens/hooks-index.json +2 -2
  100. package/dist/components/ui/drawer.d.ts +0 -16
  101. package/dist/components/ui/drawer.js +0 -125
  102. package/dist/components/ui/drawer.js.map +0 -1
  103. package/src/components/ui/drawer.tsx +0 -134
  104. package/template/components/ui/drawer.tsx +0 -1
@@ -0,0 +1,51 @@
1
+ # Upgrading `@exxatdesignux/ui` (human + AI checklist)
2
+
3
+ Use this after **`npm install @exxatdesignux/ui@…`** / **`pnpm add @exxatdesignux/ui@…`**. It is copied into **`docs/exxat-ds/`** when you run **`exxat-ui sync-extras`**, so Cursor and other tools can find it beside other DS pattern docs.
4
+
5
+ ## 1. See what changed
6
+
7
+ | Source | Purpose |
8
+ |--------|---------|
9
+ | **`node_modules/@exxatdesignux/ui/CHANGELOG.md`** | Release notes for the installed version (and peers). |
10
+ | **`npx --package=@exxatdesignux/ui@latest exxat-ui changelog`** | Print the changelog from the package on disk / npx extract. |
11
+
12
+ ## 2. Refresh AI / pattern docs (optional but recommended)
13
+
14
+ ```bash
15
+ npx --package=@exxatdesignux/ui@latest exxat-ui sync-extras
16
+ ```
17
+
18
+ Overwrites only **`.cursor/skills/exxat-*`** and **`docs/exxat-ds/*.md`** (including this file). Does **not** change your app routes or product code.
19
+
20
+ ## 3. Align app code with the reference template
21
+
22
+ The npm package includes a full Next.js reference under:
23
+
24
+ **`node_modules/@exxatdesignux/ui/template/`**
25
+
26
+ Use it when you need to know **what files exist**, **how shims re-export** `@exxatdesignux/ui`, or **what AGENTS / layout** patterns look like for the current release. Porting is manual: diff template vs your repo and apply intentional changes (imports, new components, CSS entrypoints).
27
+
28
+ ## 4. Dependency and Node
29
+
30
+ - Keep **`@exxatdesignux/ui`** on the same semver your team tested; prefer explicit **`^x.y.z`** or pinned **`x.y.z`**.
31
+ - Match **`engines.node`** in your app to the value declared in **`node_modules/@exxatdesignux/ui/package.json`** (see CHANGELOG if it changed).
32
+ - **≥ 0.5.3:** Remove **`vaul`** from your app `package.json` and delete any `components/ui/drawer.tsx` shim — side panels use **`Sheet`** only (**`.cursor/rules/exxat-no-vaul.mdc`**).
33
+
34
+ ## 5. Consumer UI audit (after sync-extras)
35
+
36
+ If the app was built before current agent rules, verify:
37
+
38
+ | Symptom | Fix |
39
+ |---------|-----|
40
+ | Full-width tab bar on list hub | Use **`ListPageTemplate`** view toolbar — **`exxat-tabs-chrome.mdc`** |
41
+ | Full-width Overview / Academics tabs | **`TabsList`** must stay **`w-fit`** — no `w-full` / `flex-1` stretch |
42
+ | Grey custom header buttons | **`PageHeader`** + **`Button`** variants — **`exxat-page-header-actions.mdc`** |
43
+ | Bespoke student popover in table | **`HoverCard`** + shared cells/badges — **`exxat-table-row-preview.mdc`** |
44
+ | Custom hub table / trimmed Add view | **`HubTable`** + **`FULL_HUB_SUPPORTED_VIEWS`** — **`exxat-hub-supported-views.mdc`** |
45
+
46
+ ## 6. Still stuck?
47
+
48
+ - **`npx --package=@exxatdesignux/ui@latest exxat-ui doctor`** — compares local CLI version vs npm **`latest`**.
49
+ - **`npx --package=@exxatdesignux/ui@latest exxat-ui update`** — install commands and reminders.
50
+
51
+ Maintainers publish from the design-system monorepo with git tags **`ui-v<version>`**; registry **`latest`** follows those tags.
@@ -6,6 +6,12 @@
6
6
 
7
7
  This document describes how list pages combine **views**, **toolbar** behavior, **filters**, **properties**, and **persistence** in this codebase.
8
8
 
9
+ ## Add view parity (seven views)
10
+
11
+ **Binding:** `.cursor/rules/exxat-hub-supported-views.mdc`. **Detail:** `docs/hub-supported-views-pattern.md`.
12
+
13
+ Every list hub **should** use **`FULL_HUB_SUPPORTED_VIEWS`** (table, list, board, dashboard, folder, panel, tree-panel) on both **`ListPageTemplate`** and **`HubTable`**, with a working renderer per view. **Library** (`library-table.tsx`) is the reference. Do not ship table-only or four-view allowlists on showcase/catalog hubs unless product documents an exception.
14
+
9
15
  ## Reuse existing components (required)
10
16
 
11
17
  **Prefer composing what already exists** over rebuilding one-off tabs, search, filters, or property panels. The **Placements** flow is the reference implementation; new list/table/board pages should wire the same building blocks with new data and column definitions.
@@ -1,8 +1,8 @@
1
- # Drawer vs dialog vs route
1
+ # Sheet panel vs dialog vs route
2
2
 
3
- > **Related:** `docs/data-views-pattern.md` (Page vs drawer), **`AGENTS.md` §6.4**, **`.cursor/rules/exxat-page-vs-drawer.mdc`**. **This doc** splits **drawer/sheet** vs **modal dialog** when both stay on the same route.
3
+ > **Related:** `docs/data-views-pattern.md` (Page vs drawer), **`AGENTS.md` §6.4**, **`.cursor/rules/exxat-page-vs-drawer.mdc`**. **This doc** splits **floating `Sheet` panels** vs **modal dialog** when both stay on the same route.
4
4
 
5
- ## Drawer / sheet (side panel)
5
+ ## Sheet (side panel — product “drawers”)
6
6
 
7
7
  **Use when:**
8
8
 
@@ -10,7 +10,7 @@
10
10
  - The flow is **medium length** — export options, table/column properties, invite collaborators, filters that mirror the grid.
11
11
  - **Width** helps — tables of options, multi-field forms that would feel cramped in a narrow dialog.
12
12
 
13
- **Examples in repo:** `TablePropertiesDrawer`, `ExportDrawer`, `InviteCollaboratorsDrawer`, `Drawer` shells that slide from the edge.
13
+ **Implementation:** **`Sheet`** from `@exxatdesignux/ui/components/sheet` with the floating inset pattern (`showOverlay={false}`, `getFloatingSheetInsetProps`) see `ExportDrawer`, `TablePropertiesDrawer`, `InviteCollaboratorsDrawer`, `LibraryNewFolderSheet`.
14
14
 
15
15
  **Avoid when:** The task is the **only** thing the user should focus on and the parent would distract (prefer **dialog** for a sharp confirm, or **route** for a full wizard).
16
16
 
@@ -24,7 +24,7 @@
24
24
 
25
25
  **Examples:** `AlertDialog`, confirm-before-remove, “Save changes?” when navigating away.
26
26
 
27
- **Avoid when:** Users need to **reference** the grid or copy values from the page while the panel is open — use a **drawer** or **inline** pattern instead.
27
+ **Avoid when:** Users need to **reference** the grid or copy values from the page while the panel is open — use a **sheet panel** or **inline** pattern instead.
28
28
 
29
29
  ## Route (new page)
30
30
 
@@ -32,7 +32,7 @@ Use when the work is **primary**, **long**, **multi-step**, or deserves its **ow
32
32
 
33
33
  ## Quick matrix
34
34
 
35
- | Need | Drawer | Dialog | Route |
35
+ | Need | Sheet panel | Dialog | Route |
36
36
  | --- | --- | --- | --- |
37
37
  | Keep hub visible | Yes | No (blocks) | No |
38
38
  | Short confirm / alert | Rare | Yes | Overkill |
@@ -41,8 +41,8 @@ Use when the work is **primary**, **long**, **multi-step**, or deserves its **ow
41
41
 
42
42
  ## Accessibility
43
43
 
44
- - **Dialog / drawer / sheet:** Must expose a **title** (`DialogTitle`, `SheetTitle`, `DrawerTitle`) — use `sr-only` if visually hidden.
45
- - **Focus trap** is expected in dialogs; drawers should still **restore focus** on close to the invoking control.
44
+ - **Dialog / sheet:** Must expose a **title** (`DialogTitle`, `SheetTitle`) — use `sr-only` if visually hidden.
45
+ - **Focus trap** is expected in dialogs; sheet panels should still **restore focus** on close to the invoking control.
46
46
 
47
47
  ## See also
48
48
 
@@ -46,7 +46,8 @@
46
46
  | **Secondary panel** | A scoped navigation rail (e.g. "Library → All / Mine / Tree", "Tokens & themes → Colors / Radius / Motion / …") that sits between the main sidebar and the page. Opening one collapses the main sidebar; closing one restores the previous sidebar state. | `exxat-primary-nav-secondary-panel.mdc` |
47
47
  | **Site header** | The top bar on a primary route (org/product switcher + breadcrumbs + actions). Owned by `PrimaryPageTemplate`. | `apps/web/components/templates/primary-page-template.tsx` |
48
48
  | **Skill** | A `.cursor/skills/<name>/SKILL.md` (mirrored in `.claude/skills/`) workflow + checklist for a recurring agent task. Use a skill when the same checklist would be repeated across many sessions. | `apps/web/AGENTS.md` |
49
- | **`supportedViewTypes`** | The allowlist of `DataListViewType` values a hub implements. Passed to `HubTable.supportedViewTypes` so the Properties drawer never offers a view the hub can't render. | `packages/ui/src/components/data-views/hub-table.tsx` |
49
+ | **`supportedViewTypes`** | The allowlist of `DataListViewType` values a hub implements. Default **`FULL_HUB_SUPPORTED_VIEWS`** (seven views, same Add view as Library). Must match on **`ListPageTemplate`** + **`HubTable`**; every entry needs a renderer. | `packages/ui/src/lib/data-list-view-registry.ts`, `docs/hub-supported-views-pattern.md` |
50
+ | **`FULL_HUB_SUPPORTED_VIEWS`** | table · list · board · dashboard · folder · panel · tree-panel — canonical list-hub allowlist. | `data-list-view-registry.ts` |
50
51
  | **Trend polarity** | `MetricItem.trendPolarity` says whether "up" is good (`higher_is_better`, default), bad (`lower_is_better`), or value-neutral (`informational`). The arrow's tint follows the polarity, not the sign. | `exxat-kpi-trends.mdc` |
51
52
  | **`useTableState`** | The state hook that owns rows, filters, search, sort, pagination, group-by, and column visibility. Always one instance per hub. | `exxat-centralized-list-dataset.mdc` |
52
53
  | **View tab** | A tab on `ListPageTemplate` representing one view of the same dataset (table, list, board, dashboard, folder, panel, tree, …). Each tab carries a `viewType` and the `renderContent` callback receives it. | `exxat-list-page-connected-views.mdc` |
@@ -0,0 +1,53 @@
1
+ # Hub supported views pattern (Add view parity)
2
+
3
+ > **Agents:** `.cursor/rules/exxat-hub-supported-views.mdc` (binding). **Reference hub:** Library / All questions (`library-table.tsx`, `library-client.tsx`).
4
+
5
+ ## Problem this solves
6
+
7
+ `ListPageTemplate` filters **Add view** and Properties view tiles from `supportedViewTypes`. If Column types passes four views but Library passes seven, users see inconsistent menus. If a hub allows Board but has no `board-with-toolbar` renderer, users see **“does not implement Board view”**.
8
+
9
+ ## Canonical allowlist
10
+
11
+ Import from the registry (single source of truth):
12
+
13
+ ```ts
14
+ import { FULL_HUB_SUPPORTED_VIEWS } from "@/lib/data-list-view-registry"
15
+ // or
16
+ import { LIBRARY_SUPPORTED_VIEWS } from "@/lib/library-supported-views" // alias of FULL
17
+ ```
18
+
19
+ Seven views: **table**, **list**, **board**, **dashboard**, **folder**, **panel**, **tree-panel**.
20
+
21
+ `HubTable` and `ListPageTemplate` use this list when `supportedViewTypes` is omitted.
22
+
23
+ `PRIMARY_HUB_SUPPORTED_VIEWS` (four views) remains for hubs that intentionally omit folder/panel/tree — document that in `lib/<entity>-supported-views.ts`.
24
+
25
+ ## Wiring checklist
26
+
27
+ 1. **`ListPageTemplate`** — `supportedViewTypes={FULL_HUB_SUPPORTED_VIEWS}` (or entity alias).
28
+ 2. **`HubTable`** — same allowlist (or omit on both).
29
+ 3. **List** — `renderListRow` returning **`ListPageBoardCard`** `layout="row"` (copy from `library-table.tsx`).
30
+ 4. **Board** — `renderBoardCard` + `boardGroups` and/or `renderers["board-with-toolbar"]`.
31
+ 5. **Dashboard** — `renderers["dashboard-with-toolbar"]` with **`KeyMetrics`** on filtered rows.
32
+ 6. **Folder / panel / tree** — explicit `renderers` entries (Library reference) or **`LibraryTable`** for `LibraryItem` rows.
33
+
34
+ ## Special cases in this app
35
+
36
+ | Hub | Pattern |
37
+ |-----|---------|
38
+ | **Library / All questions** | `LibraryTable` + `LIBRARY_SUPPORTED_VIEWS` — reference |
39
+ | **Column types** | `LibraryTable` with `columnDefs` + `hubLabels` + `DEFAULT_LIBRARY_FOLDERS` — custom table, shared other views |
40
+ | **Tokens & themes** | `FULL_HUB_SUPPORTED_VIEWS` + `tokens-hub-auxiliary-views.tsx` |
41
+ | **New entity hub** | Start from `library-table.tsx` or token/columns references; never table-only unless approved |
42
+
43
+ ## Anti-patterns
44
+
45
+ - `supportedViewTypes={["table"]}` on a `ListPageTemplate` hub.
46
+ - `COLUMNS_SUPPORTED_VIEWS = PRIMARY_HUB_SUPPORTED_VIEWS` without board/folder/panel/tree renderers.
47
+ - Minimal `renderListRow` with only stem + `questionId` (not product list UI).
48
+
49
+ ## See also
50
+
51
+ - `packages/ui/src/lib/data-list-view-registry.ts`
52
+ - `apps/web/docs/data-views-pattern.md`
53
+ - `apps/web/lib/hub-connected-view-renderers.ts` — `defineHubViewRenderers` dev warnings
@@ -25,9 +25,9 @@ If you find yourself diverging from the reference page, ask **why** before shipp
25
25
  | Full hub: table + board + dashboard + list + paginated + conditional rules + dashboard customize | `apps/web/components/library-table.tsx` + `library-hub-client.tsx` | [`list-page-template`](./blueprints/list-page-template.md), [`data-table`](./blueprints/data-table.md), [`board-card`](./blueprints/board-card.md), [`key-metrics`](./blueprints/key-metrics.md) | [`exxat-data-tables`](../../../.cursor/rules/exxat-data-tables.mdc), [`exxat-list-page-connected-views`](../../../.cursor/rules/exxat-list-page-connected-views.mdc), [`exxat-centralized-list-dataset`](../../../.cursor/rules/exxat-centralized-list-dataset.mdc) | [`data-views-pattern`](./data-views-pattern.md) |
26
26
  | Hub with secondary panel scope (folder rail) | `apps/web/components/library-hub-client.tsx` + `library-secondary-nav.tsx` | [`list-page-template`](./blueprints/list-page-template.md) | [`exxat-primary-nav-secondary-panel`](../../../.cursor/rules/exxat-primary-nav-secondary-panel.mdc), [`exxat-library-hub-header`](../../../.cursor/rules/exxat-library-hub-header.mdc) | [`library-hub-header-pattern`](./library-hub-header-pattern.md) |
27
27
  | Hub with secondary panel scope (URL-driven category rail) — **smallest** secondary-panel reference + built-in pagination chrome | `apps/web/components/tokens-themes-client.tsx` + `tokens-secondary-nav.tsx` | [`list-page-template`](./blueprints/list-page-template.md) | [`exxat-primary-nav-secondary-panel`](../../../.cursor/rules/exxat-primary-nav-secondary-panel.mdc) | [`shell-surface-elevation-pattern`](./shell-surface-elevation-pattern.md) |
28
- | Single-view showcase hub (table only) — **18 SaaS cell patterns**, each rendered by an **importable named cell** from `@/components/data-views` (see "Cell primitives" table below). Categories: select, primary identity + ID + favorite, avatar + name + email, avatar group +N, type pill, difficulty signal, status chip, inline toggle, tag list, rating stars, progress bar, currency, numeric, attachment count, external link, relative time, absolute date, row actions overflow. | `apps/web/components/columns-showcase.tsx` + `columns-client.tsx` | [`list-page-template`](./blueprints/list-page-template.md), [`data-table`](./blueprints/data-table.md) | [`exxat-data-tables`](../../../.cursor/rules/exxat-data-tables.mdc) | — |
28
+ | Cell-pattern catalog — **18 SaaS cell patterns** via custom `columnDefs`; **seven views** via **`LibraryTable`** (same Add view as Library). | `apps/web/components/columns-showcase.tsx` + `columns-client.tsx` | [`list-page-template`](./blueprints/list-page-template.md), [`data-table`](./blueprints/data-table.md), [`hub-supported-views-pattern`](./hub-supported-views-pattern.md) | [`exxat-data-tables`](../../../.cursor/rules/exxat-data-tables.mdc), [`exxat-hub-supported-views`](../../../.cursor/rules/exxat-hub-supported-views.mdc) | — |
29
29
 
30
- > **First-time hub builder:** start with `columns-showcase.tsx` (single-view catalog, easiest) or `tokens-themes-client.tsx` (adds a secondary panel + URL-driven scope). Move to `library-table.tsx` only when you genuinely need a board / dashboard / conditional rules.
30
+ > **First-time hub builder:** copy **`library-table.tsx`** + **`library-client.tsx`** for seven-view wiring; use **`columns-showcase.tsx`** for custom columns on **`LibraryItem`**; use **`tokens-themes-client.tsx`** + **`tokens-hub-auxiliary-views.tsx`** for token rows. Read **`hub-supported-views-pattern.md`** before changing Add view.
31
31
 
32
32
  ---
33
33
 
@@ -0,0 +1,8 @@
1
+ /**
2
+ * App-wide default view allowlist for list-page hubs (Add view + Properties).
3
+ * Keep in sync with `library-table.tsx` / `ListPageTemplate` / `HubTable`.
4
+ */
5
+ export {
6
+ FULL_HUB_SUPPORTED_VIEWS,
7
+ PRIMARY_HUB_SUPPORTED_VIEWS,
8
+ } from "@exxatdesignux/ui/lib/data-list-view-registry"
@@ -1,12 +1,5 @@
1
- import type { DataListViewType } from "@/lib/data-list-view"
2
-
3
- /** Views implemented in `LibraryTable` — keep in sync with `ListPageConnectedViewBody` renderers. */
4
- export const LIBRARY_SUPPORTED_VIEWS = [
5
- "table",
6
- "list",
7
- "board",
8
- "dashboard",
9
- "folder",
10
- "panel",
11
- "tree-panel",
12
- ] as const satisfies readonly DataListViewType[]
1
+ export {
2
+ FULL_HUB_SUPPORTED_VIEWS,
3
+ FULL_HUB_SUPPORTED_VIEWS as LIBRARY_SUPPORTED_VIEWS,
4
+ PRIMARY_HUB_SUPPORTED_VIEWS,
5
+ } from "@exxatdesignux/ui/lib/data-list-view-registry"
@@ -11,7 +11,7 @@ export const motionHeaderEnter = {
11
11
  } as const
12
12
 
13
13
  /**
14
- * Sheet / Vaul drawer timing — implemented in `@exxatdesignux/ui` `Sheet` + `Drawer`
15
- * (`duration-300 ease-out`, shorter slide distance) so all panels animate consistently.
14
+ * Floating sheet panel timing — implemented in `@exxatdesignux/ui` `Sheet`
15
+ * (`duration-300 ease-out`) so Export, Properties, and invite panels animate consistently.
16
16
  */
17
17
  export const motionSheetMs = 300
@@ -9,6 +9,7 @@
9
9
  },
10
10
  "scripts": {
11
11
  "dev": "next dev --turbopack",
12
+ "dev:webpack": "next dev",
12
13
  "dev:3001": "next dev --turbopack -p 3001",
13
14
  "dev:3005": "next dev --turbopack -p 3005",
14
15
  "dev:daemon": "pm2 start ecosystem.config.cjs",
@@ -54,7 +55,6 @@
54
55
  "sonner": "^2.0.7",
55
56
  "tailwind-merge": "^3.5.0",
56
57
  "tw-animate-css": "^1.4.0",
57
- "vaul": "^1.1.2",
58
58
  "zod": "^4.3.6",
59
59
  "zustand": "^5.0.12"
60
60
  },
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "0.5.2",
2
+ "version": "0.5.4",
3
3
  "source": "packages/ui/src/globals.css",
4
- "generatedAt": "2026-05-22T05:01:54.358Z",
4
+ "generatedAt": "2026-05-22T11:42:41.710Z",
5
5
  "tokenCount": 197,
6
6
  "themeKeys": [
7
7
  "tailwind-bridge",
@@ -1,16 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React from 'react';
3
- import { Drawer as Drawer$1 } from 'vaul';
4
-
5
- declare function Drawer({ ...props }: React.ComponentProps<typeof Drawer$1.Root>): react_jsx_runtime.JSX.Element;
6
- declare function DrawerTrigger({ ...props }: React.ComponentProps<typeof Drawer$1.Trigger>): react_jsx_runtime.JSX.Element;
7
- declare function DrawerPortal({ ...props }: React.ComponentProps<typeof Drawer$1.Portal>): react_jsx_runtime.JSX.Element;
8
- declare function DrawerClose({ ...props }: React.ComponentProps<typeof Drawer$1.Close>): react_jsx_runtime.JSX.Element;
9
- declare function DrawerOverlay({ className, ...props }: React.ComponentProps<typeof Drawer$1.Overlay>): react_jsx_runtime.JSX.Element;
10
- declare function DrawerContent({ className, children, ...props }: React.ComponentProps<typeof Drawer$1.Content>): react_jsx_runtime.JSX.Element;
11
- declare function DrawerHeader({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
12
- declare function DrawerFooter({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
13
- declare function DrawerTitle({ className, ...props }: React.ComponentProps<typeof Drawer$1.Title>): react_jsx_runtime.JSX.Element;
14
- declare function DrawerDescription({ className, ...props }: React.ComponentProps<typeof Drawer$1.Description>): react_jsx_runtime.JSX.Element;
15
-
16
- export { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger };
@@ -1,125 +0,0 @@
1
- "use client";
2
- import { Drawer as Drawer$1 } from 'vaul';
3
- import { clsx } from 'clsx';
4
- import { twMerge } from 'tailwind-merge';
5
- import { jsx, jsxs } from 'react/jsx-runtime';
6
-
7
- function cn(...inputs) {
8
- return twMerge(clsx(inputs));
9
- }
10
- function Drawer({
11
- ...props
12
- }) {
13
- return /* @__PURE__ */ jsx(Drawer$1.Root, { "data-slot": "drawer", ...props });
14
- }
15
- function DrawerTrigger({
16
- ...props
17
- }) {
18
- return /* @__PURE__ */ jsx(Drawer$1.Trigger, { "data-slot": "drawer-trigger", ...props });
19
- }
20
- function DrawerPortal({
21
- ...props
22
- }) {
23
- return /* @__PURE__ */ jsx(Drawer$1.Portal, { "data-slot": "drawer-portal", ...props });
24
- }
25
- function DrawerClose({
26
- ...props
27
- }) {
28
- return /* @__PURE__ */ jsx(Drawer$1.Close, { "data-slot": "drawer-close", ...props });
29
- }
30
- function DrawerOverlay({
31
- className,
32
- ...props
33
- }) {
34
- return /* @__PURE__ */ jsx(
35
- Drawer$1.Overlay,
36
- {
37
- "data-slot": "drawer-overlay",
38
- className: cn(
39
- "fixed inset-0 z-50 bg-overlay duration-300 ease-out supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
40
- className
41
- ),
42
- ...props
43
- }
44
- );
45
- }
46
- function DrawerContent({
47
- className,
48
- children,
49
- ...props
50
- }) {
51
- return /* @__PURE__ */ jsxs(DrawerPortal, { "data-slot": "drawer-portal", children: [
52
- /* @__PURE__ */ jsx(DrawerOverlay, {}),
53
- /* @__PURE__ */ jsxs(
54
- Drawer$1.Content,
55
- {
56
- "data-slot": "drawer-content",
57
- className: cn(
58
- "group/drawer-content fixed z-50 flex h-auto flex-col bg-background text-sm duration-300 ease-out outline-none data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=bottom]:border-t data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:start-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-e-xl data-[vaul-drawer-direction=left]:border-e data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:end-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-s-xl data-[vaul-drawer-direction=right]:border-s data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=top]:border-b data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm",
59
- className
60
- ),
61
- ...props,
62
- children: [
63
- /* @__PURE__ */ jsx("div", { className: "mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-full bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block" }),
64
- children
65
- ]
66
- }
67
- )
68
- ] });
69
- }
70
- function DrawerHeader({ className, ...props }) {
71
- return /* @__PURE__ */ jsx(
72
- "div",
73
- {
74
- "data-slot": "drawer-header",
75
- className: cn(
76
- "flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-start",
77
- className
78
- ),
79
- ...props
80
- }
81
- );
82
- }
83
- function DrawerFooter({ className, ...props }) {
84
- return /* @__PURE__ */ jsx(
85
- "div",
86
- {
87
- "data-slot": "drawer-footer",
88
- className: cn("mt-auto flex flex-col gap-2 p-4", className),
89
- ...props
90
- }
91
- );
92
- }
93
- function DrawerTitle({
94
- className,
95
- ...props
96
- }) {
97
- return /* @__PURE__ */ jsx(
98
- Drawer$1.Title,
99
- {
100
- "data-slot": "drawer-title",
101
- className: cn(
102
- "font-heading text-base font-medium text-foreground",
103
- className
104
- ),
105
- ...props
106
- }
107
- );
108
- }
109
- function DrawerDescription({
110
- className,
111
- ...props
112
- }) {
113
- return /* @__PURE__ */ jsx(
114
- Drawer$1.Description,
115
- {
116
- "data-slot": "drawer-description",
117
- className: cn("text-sm text-muted-foreground", className),
118
- ...props
119
- }
120
- );
121
- }
122
-
123
- export { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger };
124
- //# sourceMappingURL=drawer.js.map
125
- //# sourceMappingURL=drawer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/drawer.tsx"],"names":["DrawerPrimitive"],"mappings":"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","file":"drawer.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Drawer as DrawerPrimitive } from \"vaul\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Drawer({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />\n}\n\nfunction DrawerTrigger({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />\n}\n\nfunction DrawerPortal({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />\n}\n\nfunction DrawerClose({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />\n}\n\nfunction DrawerOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n return (\n <DrawerPrimitive.Overlay\n data-slot=\"drawer-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-overlay duration-300 ease-out supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Content>) {\n return (\n <DrawerPortal data-slot=\"drawer-portal\">\n <DrawerOverlay />\n <DrawerPrimitive.Content\n data-slot=\"drawer-content\"\n className={cn(\n \"group/drawer-content fixed z-50 flex h-auto flex-col bg-background text-sm duration-300 ease-out outline-none data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=bottom]:border-t data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:start-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-e-xl data-[vaul-drawer-direction=left]:border-e data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:end-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-s-xl data-[vaul-drawer-direction=right]:border-s data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=top]:border-b data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm\",\n className\n )}\n {...props}\n >\n <div className=\"mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-full bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block\" />\n {children}\n </DrawerPrimitive.Content>\n </DrawerPortal>\n )\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-header\"\n className={cn(\n \"flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-start\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction DrawerTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n return (\n <DrawerPrimitive.Title\n data-slot=\"drawer-title\"\n className={cn(\n \"font-heading text-base font-medium text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n return (\n <DrawerPrimitive.Description\n data-slot=\"drawer-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Drawer,\n DrawerPortal,\n DrawerOverlay,\n DrawerTrigger,\n DrawerClose,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n}\n"]}
@@ -1,134 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { Drawer as DrawerPrimitive } from "vaul"
5
-
6
- import { cn } from "../../lib/utils"
7
-
8
- function Drawer({
9
- ...props
10
- }: React.ComponentProps<typeof DrawerPrimitive.Root>) {
11
- return <DrawerPrimitive.Root data-slot="drawer" {...props} />
12
- }
13
-
14
- function DrawerTrigger({
15
- ...props
16
- }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
17
- return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
18
- }
19
-
20
- function DrawerPortal({
21
- ...props
22
- }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
23
- return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />
24
- }
25
-
26
- function DrawerClose({
27
- ...props
28
- }: React.ComponentProps<typeof DrawerPrimitive.Close>) {
29
- return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />
30
- }
31
-
32
- function DrawerOverlay({
33
- className,
34
- ...props
35
- }: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
36
- return (
37
- <DrawerPrimitive.Overlay
38
- data-slot="drawer-overlay"
39
- className={cn(
40
- "fixed inset-0 z-50 bg-overlay duration-300 ease-out supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
41
- className
42
- )}
43
- {...props}
44
- />
45
- )
46
- }
47
-
48
- function DrawerContent({
49
- className,
50
- children,
51
- ...props
52
- }: React.ComponentProps<typeof DrawerPrimitive.Content>) {
53
- return (
54
- <DrawerPortal data-slot="drawer-portal">
55
- <DrawerOverlay />
56
- <DrawerPrimitive.Content
57
- data-slot="drawer-content"
58
- className={cn(
59
- "group/drawer-content fixed z-50 flex h-auto flex-col bg-background text-sm duration-300 ease-out outline-none data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=bottom]:border-t data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:start-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-e-xl data-[vaul-drawer-direction=left]:border-e data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:end-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-s-xl data-[vaul-drawer-direction=right]:border-s data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=top]:border-b data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm",
60
- className
61
- )}
62
- {...props}
63
- >
64
- <div className="mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-full bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
65
- {children}
66
- </DrawerPrimitive.Content>
67
- </DrawerPortal>
68
- )
69
- }
70
-
71
- function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
72
- return (
73
- <div
74
- data-slot="drawer-header"
75
- className={cn(
76
- "flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-start",
77
- className
78
- )}
79
- {...props}
80
- />
81
- )
82
- }
83
-
84
- function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
85
- return (
86
- <div
87
- data-slot="drawer-footer"
88
- className={cn("mt-auto flex flex-col gap-2 p-4", className)}
89
- {...props}
90
- />
91
- )
92
- }
93
-
94
- function DrawerTitle({
95
- className,
96
- ...props
97
- }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
98
- return (
99
- <DrawerPrimitive.Title
100
- data-slot="drawer-title"
101
- className={cn(
102
- "font-heading text-base font-medium text-foreground",
103
- className
104
- )}
105
- {...props}
106
- />
107
- )
108
- }
109
-
110
- function DrawerDescription({
111
- className,
112
- ...props
113
- }: React.ComponentProps<typeof DrawerPrimitive.Description>) {
114
- return (
115
- <DrawerPrimitive.Description
116
- data-slot="drawer-description"
117
- className={cn("text-sm text-muted-foreground", className)}
118
- {...props}
119
- />
120
- )
121
- }
122
-
123
- export {
124
- Drawer,
125
- DrawerPortal,
126
- DrawerOverlay,
127
- DrawerTrigger,
128
- DrawerClose,
129
- DrawerContent,
130
- DrawerHeader,
131
- DrawerFooter,
132
- DrawerTitle,
133
- DrawerDescription,
134
- }
@@ -1 +0,0 @@
1
- export * from "@exxatdesignux/ui/components/drawer"