@exxatdesignux/ui 0.3.0 → 0.4.1

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 (214) hide show
  1. package/CHANGELOG.md +701 -6
  2. package/README.md +138 -0
  3. package/bin/init.mjs +134 -31
  4. package/consumer-extras/cursor-rules/exxat-board-cards.mdc +1 -1
  5. package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +2 -2
  6. package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +1 -1
  7. package/consumer-extras/cursor-rules/exxat-data-tables.mdc +2 -0
  8. package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +1 -1
  9. package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +3 -3
  10. package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +28 -0
  11. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +1 -1
  12. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +1 -1
  13. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +6 -6
  14. package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +1 -1
  15. package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +2 -2
  16. package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +1 -1
  17. package/consumer-extras/cursor-skills/exxat-collaboration-access/SKILL.md +3 -3
  18. package/consumer-extras/cursor-skills/exxat-dedicated-search-surfaces/SKILL.md +2 -2
  19. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +7 -7
  20. package/consumer-extras/cursor-skills/exxat-kpi-flat-band/SKILL.md +1 -1
  21. package/consumer-extras/cursor-skills/exxat-list-page-view-shells/SKILL.md +1 -1
  22. package/consumer-extras/cursor-skills/exxat-mono-ids/SKILL.md +4 -4
  23. package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +8 -8
  24. package/consumer-extras/cursor-skills/exxat-token-economy/SKILL.md +277 -0
  25. package/consumer-extras/handbook/HANDBOOK.md +2 -0
  26. package/consumer-extras/handbook/glossary.md +2 -1
  27. package/consumer-extras/handbook/reference-implementations.md +31 -4
  28. package/consumer-extras/patterns/collaboration-access-pattern.md +7 -7
  29. package/consumer-extras/patterns/data-views-pattern.md +18 -16
  30. package/consumer-extras/patterns/kpi-flat-band-pattern.md +2 -2
  31. package/dist/components/data-table/index.js +2 -2
  32. package/dist/components/data-table/index.js.map +1 -1
  33. package/dist/components/data-table/pagination.js +3 -3
  34. package/dist/components/data-table/pagination.js.map +1 -1
  35. package/dist/components/data-table/use-table-state.d.ts +1 -1
  36. package/dist/components/data-table/use-table-state.js.map +1 -1
  37. package/dist/components/data-views/data-row-list.js.map +1 -1
  38. package/dist/components/data-views/finder-panel-view.d.ts +1 -1
  39. package/dist/components/data-views/finder-panel-view.js.map +1 -1
  40. package/dist/components/data-views/hub-table.d.ts +9 -3
  41. package/dist/components/data-views/hub-table.js +262 -40
  42. package/dist/components/data-views/hub-table.js.map +1 -1
  43. package/dist/components/data-views/index.js +262 -40
  44. package/dist/components/data-views/index.js.map +1 -1
  45. package/dist/components/data-views/list-page-split-hub-tokens.d.ts +2 -2
  46. package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -1
  47. package/dist/components/data-views/list-page-tree-column-header.d.ts +1 -1
  48. package/dist/components/data-views/list-page-tree-column-header.js.map +1 -1
  49. package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -1
  50. package/dist/components/data-views/os-folder-glyph.d.ts +1 -1
  51. package/dist/components/data-views/os-folder-glyph.js.map +1 -1
  52. package/dist/components/ui/avatar.d.ts +1 -1
  53. package/dist/components/ui/key-metrics.js.map +1 -1
  54. package/dist/index.js +136 -39
  55. package/dist/index.js.map +1 -1
  56. package/package.json +3 -2
  57. package/src/components/data-table/index.tsx +2 -2
  58. package/src/components/data-table/pagination.tsx +5 -1
  59. package/src/components/data-table/use-table-state.ts +1 -1
  60. package/src/components/data-views/data-row-list.tsx +1 -1
  61. package/src/components/data-views/finder-panel-view.tsx +2 -2
  62. package/src/components/data-views/hub-table.tsx +149 -41
  63. package/src/components/data-views/list-page-split-hub-tokens.ts +2 -2
  64. package/src/components/data-views/list-page-tree-column-header.tsx +1 -1
  65. package/src/components/data-views/os-folder-glyph.tsx +1 -1
  66. package/src/components/ui/key-metrics.tsx +1 -1
  67. package/template/.claude/skills/exxat-ds-skill/SKILL.md +8 -7
  68. package/template/.cursor/rules/exxat-accessibility.mdc +1 -1
  69. package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
  70. package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +6 -6
  71. package/template/.cursor/rules/exxat-data-tables.mdc +3 -3
  72. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +5 -5
  73. package/template/.cursor/rules/exxat-mono-ids.mdc +1 -1
  74. package/template/.cursor/rules/exxat-page-vs-drawer.mdc +1 -1
  75. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
  76. package/template/AGENTS.md +43 -37
  77. package/template/app/(app)/columns/page.tsx +11 -0
  78. package/template/app/(app)/library/all/page.tsx +11 -0
  79. package/template/app/(app)/library/find/page.tsx +12 -0
  80. package/template/app/(app)/{question-bank → library}/layout.tsx +16 -16
  81. package/template/app/(app)/library/list/page.tsx +12 -0
  82. package/template/app/(app)/{question-bank → library}/new/page.tsx +10 -10
  83. package/template/app/(app)/library/page.tsx +11 -0
  84. package/template/app/(app)/tokens-themes/page.tsx +11 -0
  85. package/template/components/ask-leo-composer.tsx +2 -2
  86. package/template/components/columns-client.tsx +158 -0
  87. package/template/components/columns-showcase.tsx +541 -0
  88. package/template/components/data-views/index.ts +32 -6
  89. package/template/components/data-views/{question-bank-folder-tree-branch.tsx → library-folder-tree-branch.tsx} +19 -19
  90. package/template/components/data-views/table-cells.tsx +673 -0
  91. package/template/components/folder-details-shell.tsx +11 -11
  92. package/template/components/hub-tree-panel-view.tsx +24 -24
  93. package/template/components/{question-bank-board-view.tsx → library-board-view.tsx} +44 -44
  94. package/template/components/{question-bank-client.tsx → library-client.tsx} +82 -82
  95. package/template/components/{question-bank-dashboard-charts.tsx → library-dashboard-charts.tsx} +14 -14
  96. package/template/components/{question-bank-favorite-button.tsx → library-favorite-button.tsx} +7 -7
  97. package/template/components/{question-bank-hub-client.tsx → library-hub-client.tsx} +43 -43
  98. package/template/components/{question-bank-new-folder-sheet.tsx → library-new-folder-sheet.tsx} +14 -14
  99. package/template/components/{question-bank-os-folder-view.tsx → library-os-folder-view.tsx} +31 -31
  100. package/template/components/{question-bank-page-header.tsx → library-page-header.tsx} +6 -6
  101. package/template/components/library-panel-activator.tsx +8 -0
  102. package/template/components/{question-bank-secondary-nav.tsx → library-secondary-nav.tsx} +60 -60
  103. package/template/components/{question-bank-table.tsx → library-table.tsx} +97 -97
  104. package/template/components/list-hub-status-badge.tsx +2 -2
  105. package/template/components/{new-question-composer.tsx → new-library-item-form.tsx} +37 -37
  106. package/template/components/sidebar/app-sidebar.tsx +61 -5
  107. package/template/components/sidebar/secondary-panel.tsx +109 -56
  108. package/template/components/sidebar/sidebar-auto-collapse.tsx +2 -2
  109. package/template/components/sidebar/sidebar-auto-open.tsx +2 -1
  110. package/template/components/table-properties/types.ts +1 -1
  111. package/template/components/templates/discovery-hub-template.tsx +1 -1
  112. package/template/components/templates/new-focus-template.tsx +2 -2
  113. package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
  114. package/template/components/tokens-secondary-nav.tsx +192 -0
  115. package/template/components/tokens-themes-client.tsx +476 -0
  116. package/template/components/tokens-themes-section.tsx +386 -0
  117. package/template/docs/HANDBOOK.md +187 -0
  118. package/template/docs/blueprints/README.md +1 -1
  119. package/template/docs/blueprints/board-card.md +1 -1
  120. package/template/docs/blueprints/data-table.md +2 -2
  121. package/template/docs/blueprints/list-page-template.md +3 -3
  122. package/template/docs/blueprints/page-header.md +4 -4
  123. package/template/docs/collaboration-access-pattern.md +7 -7
  124. package/template/docs/component-selection-guide.md +1 -1
  125. package/template/docs/data-views-pattern.md +18 -16
  126. package/template/docs/glossary.md +58 -0
  127. package/template/docs/kpi-flat-band-pattern.md +3 -3
  128. package/template/docs/kpi-trend-pattern.md +18 -3
  129. package/template/docs/large-dataset-strategy.md +155 -0
  130. package/template/docs/library-hub-header-pattern.md +25 -0
  131. package/template/docs/migrations/_template.md +1 -1
  132. package/template/docs/reference-implementations.md +151 -0
  133. package/template/docs/token-taxonomy.md +1 -1
  134. package/template/docs/voice-and-tone.md +262 -0
  135. package/template/eslint.config.mjs +9 -39
  136. package/template/hooks/use-secondary-panel-hub-nav.ts +10 -10
  137. package/template/lib/ask-leo-route-context.ts +6 -18
  138. package/template/lib/coach-mark-registry.ts +0 -16
  139. package/template/lib/command-menu-config.ts +5 -12
  140. package/template/lib/command-menu-search-data.ts +8 -39
  141. package/template/lib/{question-bank-authoring.ts → library-authoring.ts} +89 -88
  142. package/template/lib/library-dedicated-search.ts +19 -0
  143. package/template/lib/library-hub-search.ts +90 -0
  144. package/template/lib/library-nav.ts +477 -0
  145. package/template/lib/library-recent-searches.ts +22 -0
  146. package/template/lib/{placements-supported-views.ts → library-supported-views.ts} +2 -2
  147. package/template/lib/list-status-badges.ts +16 -104
  148. package/template/lib/mock/dashboard.ts +1 -1
  149. package/template/lib/mock/{question-bank-folders.ts → library-folders.ts} +30 -30
  150. package/template/lib/mock/library-header-collaborators.ts +54 -0
  151. package/template/lib/mock/{question-bank-inspector.ts → library-inspector.ts} +29 -29
  152. package/template/lib/mock/{question-bank-kpi.ts → library-kpi.ts} +20 -20
  153. package/template/lib/mock/library.ts +249 -0
  154. package/template/lib/mock/navigation.tsx +32 -26
  155. package/template/lib/table-state-lifecycle.ts +1 -1
  156. package/template/next.config.mjs +7 -4
  157. package/template/package.json +0 -1
  158. package/tokens/hooks-index.json +2874 -0
  159. package/consumer-extras/cursor-rules/exxat-question-bank-hub-header.mdc +0 -28
  160. package/template/app/(app)/examples/page.tsx +0 -41
  161. package/template/app/(app)/question-bank/find/page.tsx +0 -12
  162. package/template/app/(app)/question-bank/library/page.tsx +0 -11
  163. package/template/app/(app)/question-bank/list/page.tsx +0 -12
  164. package/template/app/(app)/question-bank/page.tsx +0 -11
  165. package/template/components/compliance-board-view.tsx +0 -142
  166. package/template/components/compliance-client.tsx +0 -92
  167. package/template/components/compliance-page-header.tsx +0 -89
  168. package/template/components/compliance-table.tsx +0 -468
  169. package/template/components/data-view-dashboard-charts-compliance.tsx +0 -963
  170. package/template/components/data-view-dashboard-charts-team.tsx +0 -971
  171. package/template/components/data-view-dashboard-charts.tsx +0 -1503
  172. package/template/components/new-placement-back-btn.tsx +0 -28
  173. package/template/components/new-placement-form.tsx +0 -942
  174. package/template/components/placement-board-card.tsx +0 -250
  175. package/template/components/placement-detail.tsx +0 -438
  176. package/template/components/placements-board-view.tsx +0 -397
  177. package/template/components/placements-client.tsx +0 -220
  178. package/template/components/placements-list-view.tsx +0 -124
  179. package/template/components/placements-page-header.tsx +0 -166
  180. package/template/components/placements-table-cells.test.tsx +0 -22
  181. package/template/components/placements-table-cells.tsx +0 -173
  182. package/template/components/placements-table-columns.tsx +0 -210
  183. package/template/components/placements-table.tsx +0 -934
  184. package/template/components/question-bank-panel-activator.tsx +0 -8
  185. package/template/components/rotations-empty-state.tsx +0 -50
  186. package/template/components/rotations-panel-activator.tsx +0 -8
  187. package/template/components/sites-board-view.tsx +0 -67
  188. package/template/components/sites-client.tsx +0 -154
  189. package/template/components/sites-table.tsx +0 -249
  190. package/template/components/team-board-view.tsx +0 -122
  191. package/template/components/team-client.tsx +0 -100
  192. package/template/components/team-page-header.tsx +0 -92
  193. package/template/components/team-table.tsx +0 -553
  194. package/template/docs/question-bank-hub-header-pattern.md +0 -25
  195. package/template/lib/compliance-supported-views.ts +0 -10
  196. package/template/lib/data-view-dashboard-placements-layout.ts +0 -215
  197. package/template/lib/mock/compliance-kpi.ts +0 -61
  198. package/template/lib/mock/compliance.ts +0 -146
  199. package/template/lib/mock/placements-kpi.ts +0 -134
  200. package/template/lib/mock/placements.ts +0 -176
  201. package/template/lib/mock/question-bank-header-collaborators.ts +0 -54
  202. package/template/lib/mock/question-bank.ts +0 -249
  203. package/template/lib/mock/sites-directory.ts +0 -16
  204. package/template/lib/mock/sites-kpi.ts +0 -25
  205. package/template/lib/mock/team-kpi.ts +0 -60
  206. package/template/lib/mock/team.ts +0 -118
  207. package/template/lib/placement-board-card-layout.ts +0 -79
  208. package/template/lib/question-bank-dedicated-search.ts +0 -19
  209. package/template/lib/question-bank-hub-search.ts +0 -90
  210. package/template/lib/question-bank-nav.ts +0 -477
  211. package/template/lib/question-bank-recent-searches.ts +0 -22
  212. package/template/lib/question-bank-supported-views.ts +0 -12
  213. package/template/lib/sites-supported-views.ts +0 -10
  214. package/template/lib/team-supported-views.ts +0 -10
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import * as React10 from 'react';
3
- import { useTheme } from 'next-themes';
4
- import { createPortal } from 'react-dom';
5
3
  import { clsx } from 'clsx';
6
4
  import { twMerge } from 'tailwind-merge';
5
+ import { useTheme } from 'next-themes';
6
+ import { createPortal } from 'react-dom';
7
7
  import { cva } from 'class-variance-authority';
8
8
  import { Slot, Label as Label$1, Checkbox as Checkbox$1, RadioGroup as RadioGroup$1, Popover as Popover$1, DropdownMenu as DropdownMenu$1, Tooltip as Tooltip$1, Dialog, Select as Select$1 } from 'radix-ui';
9
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -2605,8 +2605,8 @@ function DataTableInner({
2605
2605
  setHeaderScrollLeft(e.currentTarget.scrollLeft);
2606
2606
  },
2607
2607
  className: cn(
2608
- "mx-4 lg:mx-6 overflow-x-auto border border-border",
2609
- hasFooter ? "rounded-t-lg" : "rounded-lg"
2608
+ "mx-4 lg:mx-6 overflow-x-auto border-t border-x border-border",
2609
+ hasFooter ? "rounded-t-lg" : "border-b rounded-lg"
2610
2610
  ),
2611
2611
  children: /* @__PURE__ */ jsxs(
2612
2612
  "table",
@@ -3105,6 +3105,131 @@ function DataTable(props) {
3105
3105
  }
3106
3106
  return /* @__PURE__ */ jsx(DataTableWithInternalState, { ...props });
3107
3107
  }
3108
+ function PaginationBar({
3109
+ page,
3110
+ pageSize,
3111
+ total,
3112
+ pageSizeOptions,
3113
+ onPageChange,
3114
+ onPageSizeChange
3115
+ }) {
3116
+ const totalPages = Math.max(1, Math.ceil(total / pageSize));
3117
+ const from = Math.min((page - 1) * pageSize + 1, total);
3118
+ const to = Math.min(page * pageSize, total);
3119
+ function handleKeyDown(e) {
3120
+ if (e.key === "ArrowLeft" && page > 1) {
3121
+ e.preventDefault();
3122
+ onPageChange(page - 1);
3123
+ } else if (e.key === "ArrowRight" && page < totalPages) {
3124
+ e.preventDefault();
3125
+ onPageChange(page + 1);
3126
+ }
3127
+ }
3128
+ return /* @__PURE__ */ jsxs(
3129
+ "div",
3130
+ {
3131
+ className: "flex items-center justify-between px-4 py-2.5 border-t border-border bg-background text-sm select-none",
3132
+ onKeyDown: handleKeyDown,
3133
+ children: [
3134
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
3135
+ /* @__PURE__ */ jsx("span", { children: "Rows per page" }),
3136
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
3137
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
3138
+ "button",
3139
+ {
3140
+ type: "button",
3141
+ "aria-label": "Rows per page",
3142
+ className: "inline-flex items-center gap-1 px-2 py-1 rounded border border-input bg-background hover:bg-interactive-hover text-foreground text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3143
+ children: [
3144
+ pageSize,
3145
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-down text-xs", "aria-hidden": "true" })
3146
+ ]
3147
+ }
3148
+ ) }),
3149
+ /* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", className: "w-20", children: pageSizeOptions.map((n) => /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: () => onPageSizeChange(n), children: n }, n)) })
3150
+ ] })
3151
+ ] }),
3152
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
3153
+ /* @__PURE__ */ jsx(
3154
+ "span",
3155
+ {
3156
+ role: "status",
3157
+ "aria-live": "polite",
3158
+ className: "text-muted-foreground tabular-nums",
3159
+ children: total === 0 ? "0 results" : `${from}\u2013${to} of ${total}`
3160
+ }
3161
+ ),
3162
+ /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
3163
+ /* @__PURE__ */ jsx(Tip, { label: "First page", side: "top", children: /* @__PURE__ */ jsx(
3164
+ "button",
3165
+ {
3166
+ type: "button",
3167
+ "aria-label": "First page",
3168
+ disabled: page === 1,
3169
+ onClick: () => onPageChange(1),
3170
+ className: "inline-flex items-center justify-center size-7 rounded hover:bg-interactive-hover disabled:opacity-40 disabled:pointer-events-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3171
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevrons-left text-xs", "aria-hidden": "true" })
3172
+ }
3173
+ ) }),
3174
+ /* @__PURE__ */ jsx(Tip, { label: "Previous page", side: "top", children: /* @__PURE__ */ jsx(
3175
+ "button",
3176
+ {
3177
+ type: "button",
3178
+ "aria-label": "Previous page",
3179
+ disabled: page === 1,
3180
+ onClick: () => onPageChange(page - 1),
3181
+ className: "inline-flex items-center justify-center size-7 rounded hover:bg-interactive-hover disabled:opacity-40 disabled:pointer-events-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3182
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-left text-xs", "aria-hidden": "true" })
3183
+ }
3184
+ ) }),
3185
+ /* @__PURE__ */ jsxs("span", { className: "px-2 text-muted-foreground tabular-nums", children: [
3186
+ page,
3187
+ " / ",
3188
+ totalPages
3189
+ ] }),
3190
+ /* @__PURE__ */ jsx(Tip, { label: "Next page", side: "top", children: /* @__PURE__ */ jsx(
3191
+ "button",
3192
+ {
3193
+ type: "button",
3194
+ "aria-label": "Next page",
3195
+ disabled: page >= totalPages,
3196
+ onClick: () => onPageChange(page + 1),
3197
+ className: "inline-flex items-center justify-center size-7 rounded hover:bg-interactive-hover disabled:opacity-40 disabled:pointer-events-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3198
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-right text-xs", "aria-hidden": "true" })
3199
+ }
3200
+ ) }),
3201
+ /* @__PURE__ */ jsx(Tip, { label: "Last page", side: "top", children: /* @__PURE__ */ jsx(
3202
+ "button",
3203
+ {
3204
+ type: "button",
3205
+ "aria-label": "Last page",
3206
+ disabled: page >= totalPages,
3207
+ onClick: () => onPageChange(totalPages),
3208
+ className: "inline-flex items-center justify-center size-7 rounded hover:bg-interactive-hover disabled:opacity-40 disabled:pointer-events-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3209
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevrons-right text-xs", "aria-hidden": "true" })
3210
+ }
3211
+ ) })
3212
+ ] }) })
3213
+ ] })
3214
+ ]
3215
+ }
3216
+ );
3217
+ }
3218
+ function CountSyncer({
3219
+ count,
3220
+ onSync,
3221
+ onReset
3222
+ }) {
3223
+ const prevCount = React10.useRef(count);
3224
+ React10.useLayoutEffect(() => {
3225
+ if (prevCount.current !== count) {
3226
+ prevCount.current = count;
3227
+ onSync(count);
3228
+ onReset();
3229
+ }
3230
+ }, [count, onSync, onReset]);
3231
+ return null;
3232
+ }
3108
3233
 
3109
3234
  // src/lib/data-list-view.ts
3110
3235
  var DATA_LIST_VIEW_TILES = [
@@ -5367,6 +5492,8 @@ function HubTable({
5367
5492
  handleRef,
5368
5493
  tableRenderer,
5369
5494
  paginationOverride,
5495
+ paginationPageSizeOptions = [10, 25, 50, 100],
5496
+ paginationInitialPageSize = 10,
5370
5497
  syncedSearchFromUrl,
5371
5498
  renderListRow,
5372
5499
  listAriaLabel,
@@ -5412,13 +5539,23 @@ function HubTable({
5412
5539
  },
5413
5540
  []
5414
5541
  );
5542
+ const [internalPage, setInternalPage] = React10.useState(1);
5543
+ const [internalPageSize, setInternalPageSize] = React10.useState(paginationInitialPageSize);
5544
+ const chromeOwnedPagination = pagination === true && paginationOverride === void 0;
5545
+ const effectivePaginationOverride = paginationOverride ?? (chromeOwnedPagination ? { page: internalPage, pageSize: internalPageSize } : void 0);
5415
5546
  const tableState = useTableState(
5416
5547
  rows,
5417
5548
  columns,
5418
5549
  defaultSort,
5419
- paginationOverride,
5550
+ effectivePaginationOverride,
5420
5551
  syncedSearchFromUrl
5421
5552
  );
5553
+ const handlePageChange = React10.useCallback((p) => setInternalPage(p), []);
5554
+ const handlePageSizeChange = React10.useCallback((n) => {
5555
+ setInternalPageSize(n);
5556
+ setInternalPage(1);
5557
+ }, []);
5558
+ const resetPage = React10.useCallback(() => setInternalPage(1), []);
5422
5559
  const { setSheetOpen: openPropertiesSheet } = tableState;
5423
5560
  React10.useImperativeHandle(
5424
5561
  handleRef ?? null,
@@ -5474,27 +5611,70 @@ function HubTable({
5474
5611
  drawerToolbarProps
5475
5612
  ]
5476
5613
  );
5477
- const defaultTableRenderer = (args2) => /* @__PURE__ */ jsx("div", { className: "pb-6", children: /* @__PURE__ */ jsx(
5478
- DataTable,
5479
- {
5480
- data: rows,
5481
- columns,
5482
- getRowId,
5483
- getRowSelectionLabel,
5484
- selectable,
5485
- searchable: displayOptions.showToolbarSearch,
5486
- showColumnHeaders: displayOptions.showColumnLabels,
5487
- groupable,
5488
- defaultSort,
5489
- emptyState: emptyState ?? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No records match your filters." }),
5490
- conditionalRules,
5491
- state: args2.state,
5492
- renderFilterOptionValue,
5493
- toolbarSlot: (s) => /* @__PURE__ */ jsx(TablePropertiesDrawerButton, { ...drawerToolbarProps, state: s }),
5494
- bulkActionsSlot,
5495
- onRowClick
5496
- }
5497
- ) });
5614
+ const defaultTableRenderer = (args2) => {
5615
+ const filteredCount = args2.state.rows.length;
5616
+ const totalPages = Math.max(1, Math.ceil(filteredCount / Math.max(1, internalPageSize)));
5617
+ const safePage = Math.min(internalPage, totalPages);
5618
+ return /* @__PURE__ */ jsxs("div", { className: "pb-6", children: [
5619
+ chromeOwnedPagination ? /* @__PURE__ */ jsx(
5620
+ CountSyncer,
5621
+ {
5622
+ count: filteredCount,
5623
+ onSync: (n) => {
5624
+ const next = Math.max(1, Math.ceil(n / Math.max(1, internalPageSize)));
5625
+ if (safePage > next) setInternalPage(next);
5626
+ },
5627
+ onReset: resetPage
5628
+ }
5629
+ ) : null,
5630
+ /* @__PURE__ */ jsx(
5631
+ DataTable,
5632
+ {
5633
+ data: rows,
5634
+ columns,
5635
+ getRowId,
5636
+ getRowSelectionLabel,
5637
+ selectable,
5638
+ searchable: displayOptions.showToolbarSearch,
5639
+ showColumnHeaders: displayOptions.showColumnLabels,
5640
+ groupable,
5641
+ defaultSort,
5642
+ emptyState: emptyState ?? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No records match your filters." }),
5643
+ conditionalRules,
5644
+ state: args2.state,
5645
+ renderFilterOptionValue,
5646
+ toolbarSlot: (s) => /* @__PURE__ */ jsx(TablePropertiesDrawerButton, { ...drawerToolbarProps, state: s }),
5647
+ bulkActionsSlot,
5648
+ onRowClick,
5649
+ hasFooter: chromeOwnedPagination
5650
+ }
5651
+ ),
5652
+ chromeOwnedPagination ? /* @__PURE__ */ jsx(
5653
+ "div",
5654
+ {
5655
+ className: cn(
5656
+ "mx-4 lg:mx-6 border-x border-b border-border rounded-b-lg overflow-hidden bg-background",
5657
+ // z-40 sits above pinned cells (z-20), group headers (z-25), and column headers
5658
+ // (z-30 / z-40) so the sticky footer paints over any table content that scrolls
5659
+ // behind it. Pinned-left cells ship with their own `bg-dt-row-bg`, which
5660
+ // otherwise wins because of z-20 > z-10.
5661
+ "sticky bottom-0 z-40"
5662
+ ),
5663
+ children: /* @__PURE__ */ jsx(
5664
+ PaginationBar,
5665
+ {
5666
+ page: safePage,
5667
+ pageSize: internalPageSize,
5668
+ total: filteredCount,
5669
+ pageSizeOptions: paginationPageSizeOptions,
5670
+ onPageChange: handlePageChange,
5671
+ onPageSizeChange: handlePageSizeChange
5672
+ }
5673
+ )
5674
+ }
5675
+ ) : null
5676
+ ] });
5677
+ };
5498
5678
  const args = {
5499
5679
  state: tableState,
5500
5680
  toolbar,
@@ -5518,20 +5698,62 @@ function HubTable({
5518
5698
  "data-table": () => (tableRenderer ?? defaultTableRenderer)(args)
5519
5699
  };
5520
5700
  if (renderers["list-with-toolbar"] == null && renderListRow != null) {
5521
- composed["list-with-toolbar"] = () => args.toolbarShell(
5522
- /* @__PURE__ */ jsx(
5523
- DataRowList,
5524
- {
5525
- rows: args.state.rows,
5526
- getRowId: (row) => getRowId(row),
5527
- ariaLabel: listAriaLabel ?? hubLabel,
5528
- emptyState: listEmptyState ?? "No records match your filters.",
5529
- ...listVirtualizeThreshold !== void 0 ? { virtualizeThreshold: listVirtualizeThreshold } : {},
5530
- ...listEstimatedRowHeight !== void 0 ? { estimatedRowHeight: listEstimatedRowHeight } : {},
5531
- renderRow: renderListRow
5532
- }
5533
- )
5534
- );
5701
+ composed["list-with-toolbar"] = () => {
5702
+ const fullRows = args.state.rows;
5703
+ const pagedRows = chromeOwnedPagination ? args.state.pagedRows : fullRows;
5704
+ const filteredCount = fullRows.length;
5705
+ const totalPages = Math.max(1, Math.ceil(filteredCount / Math.max(1, internalPageSize)));
5706
+ const safePage = Math.min(internalPage, totalPages);
5707
+ return args.toolbarShell(
5708
+ /* @__PURE__ */ jsxs(Fragment, { children: [
5709
+ chromeOwnedPagination ? /* @__PURE__ */ jsx(
5710
+ CountSyncer,
5711
+ {
5712
+ count: filteredCount,
5713
+ onSync: (n) => {
5714
+ const next = Math.max(1, Math.ceil(n / Math.max(1, internalPageSize)));
5715
+ if (safePage > next) setInternalPage(next);
5716
+ },
5717
+ onReset: resetPage
5718
+ }
5719
+ ) : null,
5720
+ /* @__PURE__ */ jsx(
5721
+ DataRowList,
5722
+ {
5723
+ rows: pagedRows,
5724
+ getRowId: (row) => getRowId(row),
5725
+ ariaLabel: listAriaLabel ?? hubLabel,
5726
+ emptyState: listEmptyState ?? "No records match your filters.",
5727
+ ...listVirtualizeThreshold !== void 0 ? { virtualizeThreshold: listVirtualizeThreshold } : {},
5728
+ ...listEstimatedRowHeight !== void 0 ? { estimatedRowHeight: listEstimatedRowHeight } : {},
5729
+ renderRow: renderListRow
5730
+ }
5731
+ ),
5732
+ chromeOwnedPagination ? /* @__PURE__ */ jsx(
5733
+ "div",
5734
+ {
5735
+ className: cn(
5736
+ "mx-4 lg:mx-6 border-x border-b border-border rounded-b-lg overflow-hidden bg-background",
5737
+ // Match the table-view footer — above pinned cells (z-20) and column
5738
+ // headers (z-30 / z-40) so the sticky chrome paints over scrolling rows.
5739
+ "sticky bottom-0 z-40"
5740
+ ),
5741
+ children: /* @__PURE__ */ jsx(
5742
+ PaginationBar,
5743
+ {
5744
+ page: safePage,
5745
+ pageSize: internalPageSize,
5746
+ total: filteredCount,
5747
+ pageSizeOptions: paginationPageSizeOptions,
5748
+ onPageChange: handlePageChange,
5749
+ onPageSizeChange: handlePageSizeChange
5750
+ }
5751
+ )
5752
+ }
5753
+ ) : null
5754
+ ] })
5755
+ );
5756
+ };
5535
5757
  }
5536
5758
  if (renderers["board-with-toolbar"] == null && renderBoardCard != null && boardGroups != null) {
5537
5759
  composed["board-with-toolbar"] = () => args.toolbarShell(