@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,8 +1,8 @@
1
1
  import * as React10 from 'react';
2
- import { useTheme } from 'next-themes';
3
- import { createPortal } from 'react-dom';
4
2
  import { clsx } from 'clsx';
5
3
  import { twMerge } from 'tailwind-merge';
4
+ import { useTheme } from 'next-themes';
5
+ import { createPortal } from 'react-dom';
6
6
  import { cva } from 'class-variance-authority';
7
7
  import { Slot, Label as Label$1, Checkbox as Checkbox$1, RadioGroup as RadioGroup$1, Popover as Popover$1, Collapsible, DropdownMenu as DropdownMenu$1, Tooltip as Tooltip$1, Avatar as Avatar$1, Dialog, Select as Select$1 } from 'radix-ui';
8
8
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -2606,8 +2606,8 @@ function DataTableInner({
2606
2606
  setHeaderScrollLeft(e.currentTarget.scrollLeft);
2607
2607
  },
2608
2608
  className: cn(
2609
- "mx-4 lg:mx-6 overflow-x-auto border border-border",
2610
- hasFooter ? "rounded-t-lg" : "rounded-lg"
2609
+ "mx-4 lg:mx-6 overflow-x-auto border-t border-x border-border",
2610
+ hasFooter ? "rounded-t-lg" : "border-b rounded-lg"
2611
2611
  ),
2612
2612
  children: /* @__PURE__ */ jsxs(
2613
2613
  "table",
@@ -3106,6 +3106,131 @@ function DataTable(props) {
3106
3106
  }
3107
3107
  return /* @__PURE__ */ jsx(DataTableWithInternalState, { ...props });
3108
3108
  }
3109
+ function PaginationBar({
3110
+ page,
3111
+ pageSize,
3112
+ total,
3113
+ pageSizeOptions,
3114
+ onPageChange,
3115
+ onPageSizeChange
3116
+ }) {
3117
+ const totalPages = Math.max(1, Math.ceil(total / pageSize));
3118
+ const from = Math.min((page - 1) * pageSize + 1, total);
3119
+ const to = Math.min(page * pageSize, total);
3120
+ function handleKeyDown(e) {
3121
+ if (e.key === "ArrowLeft" && page > 1) {
3122
+ e.preventDefault();
3123
+ onPageChange(page - 1);
3124
+ } else if (e.key === "ArrowRight" && page < totalPages) {
3125
+ e.preventDefault();
3126
+ onPageChange(page + 1);
3127
+ }
3128
+ }
3129
+ return /* @__PURE__ */ jsxs(
3130
+ "div",
3131
+ {
3132
+ className: "flex items-center justify-between px-4 py-2.5 border-t border-border bg-background text-sm select-none",
3133
+ onKeyDown: handleKeyDown,
3134
+ children: [
3135
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
3136
+ /* @__PURE__ */ jsx("span", { children: "Rows per page" }),
3137
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
3138
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
3139
+ "button",
3140
+ {
3141
+ type: "button",
3142
+ "aria-label": "Rows per page",
3143
+ 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",
3144
+ children: [
3145
+ pageSize,
3146
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-down text-xs", "aria-hidden": "true" })
3147
+ ]
3148
+ }
3149
+ ) }),
3150
+ /* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", className: "w-20", children: pageSizeOptions.map((n) => /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: () => onPageSizeChange(n), children: n }, n)) })
3151
+ ] })
3152
+ ] }),
3153
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
3154
+ /* @__PURE__ */ jsx(
3155
+ "span",
3156
+ {
3157
+ role: "status",
3158
+ "aria-live": "polite",
3159
+ className: "text-muted-foreground tabular-nums",
3160
+ children: total === 0 ? "0 results" : `${from}\u2013${to} of ${total}`
3161
+ }
3162
+ ),
3163
+ /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
3164
+ /* @__PURE__ */ jsx(Tip, { label: "First page", side: "top", children: /* @__PURE__ */ jsx(
3165
+ "button",
3166
+ {
3167
+ type: "button",
3168
+ "aria-label": "First page",
3169
+ disabled: page === 1,
3170
+ onClick: () => onPageChange(1),
3171
+ 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",
3172
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevrons-left text-xs", "aria-hidden": "true" })
3173
+ }
3174
+ ) }),
3175
+ /* @__PURE__ */ jsx(Tip, { label: "Previous page", side: "top", children: /* @__PURE__ */ jsx(
3176
+ "button",
3177
+ {
3178
+ type: "button",
3179
+ "aria-label": "Previous page",
3180
+ disabled: page === 1,
3181
+ onClick: () => onPageChange(page - 1),
3182
+ 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",
3183
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-left text-xs", "aria-hidden": "true" })
3184
+ }
3185
+ ) }),
3186
+ /* @__PURE__ */ jsxs("span", { className: "px-2 text-muted-foreground tabular-nums", children: [
3187
+ page,
3188
+ " / ",
3189
+ totalPages
3190
+ ] }),
3191
+ /* @__PURE__ */ jsx(Tip, { label: "Next page", side: "top", children: /* @__PURE__ */ jsx(
3192
+ "button",
3193
+ {
3194
+ type: "button",
3195
+ "aria-label": "Next page",
3196
+ disabled: page >= totalPages,
3197
+ onClick: () => onPageChange(page + 1),
3198
+ 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",
3199
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-right text-xs", "aria-hidden": "true" })
3200
+ }
3201
+ ) }),
3202
+ /* @__PURE__ */ jsx(Tip, { label: "Last page", side: "top", children: /* @__PURE__ */ jsx(
3203
+ "button",
3204
+ {
3205
+ type: "button",
3206
+ "aria-label": "Last page",
3207
+ disabled: page >= totalPages,
3208
+ onClick: () => onPageChange(totalPages),
3209
+ 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",
3210
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevrons-right text-xs", "aria-hidden": "true" })
3211
+ }
3212
+ ) })
3213
+ ] }) })
3214
+ ] })
3215
+ ]
3216
+ }
3217
+ );
3218
+ }
3219
+ function CountSyncer({
3220
+ count,
3221
+ onSync,
3222
+ onReset
3223
+ }) {
3224
+ const prevCount = React10.useRef(count);
3225
+ React10.useLayoutEffect(() => {
3226
+ if (prevCount.current !== count) {
3227
+ prevCount.current = count;
3228
+ onSync(count);
3229
+ onReset();
3230
+ }
3231
+ }, [count, onSync, onReset]);
3232
+ return null;
3233
+ }
3109
3234
 
3110
3235
  // src/lib/data-list-view.ts
3111
3236
  var DATA_LIST_VIEW_TILES = [
@@ -5423,6 +5548,8 @@ function HubTable({
5423
5548
  handleRef,
5424
5549
  tableRenderer,
5425
5550
  paginationOverride,
5551
+ paginationPageSizeOptions = [10, 25, 50, 100],
5552
+ paginationInitialPageSize = 10,
5426
5553
  syncedSearchFromUrl,
5427
5554
  renderListRow,
5428
5555
  listAriaLabel,
@@ -5468,13 +5595,23 @@ function HubTable({
5468
5595
  },
5469
5596
  []
5470
5597
  );
5598
+ const [internalPage, setInternalPage] = React10.useState(1);
5599
+ const [internalPageSize, setInternalPageSize] = React10.useState(paginationInitialPageSize);
5600
+ const chromeOwnedPagination = pagination === true && paginationOverride === void 0;
5601
+ const effectivePaginationOverride = paginationOverride ?? (chromeOwnedPagination ? { page: internalPage, pageSize: internalPageSize } : void 0);
5471
5602
  const tableState = useTableState(
5472
5603
  rows,
5473
5604
  columns,
5474
5605
  defaultSort,
5475
- paginationOverride,
5606
+ effectivePaginationOverride,
5476
5607
  syncedSearchFromUrl
5477
5608
  );
5609
+ const handlePageChange = React10.useCallback((p) => setInternalPage(p), []);
5610
+ const handlePageSizeChange = React10.useCallback((n) => {
5611
+ setInternalPageSize(n);
5612
+ setInternalPage(1);
5613
+ }, []);
5614
+ const resetPage = React10.useCallback(() => setInternalPage(1), []);
5478
5615
  const { setSheetOpen: openPropertiesSheet } = tableState;
5479
5616
  React10.useImperativeHandle(
5480
5617
  handleRef ?? null,
@@ -5530,27 +5667,70 @@ function HubTable({
5530
5667
  drawerToolbarProps
5531
5668
  ]
5532
5669
  );
5533
- const defaultTableRenderer = (args2) => /* @__PURE__ */ jsx("div", { className: "pb-6", children: /* @__PURE__ */ jsx(
5534
- DataTable,
5535
- {
5536
- data: rows,
5537
- columns,
5538
- getRowId,
5539
- getRowSelectionLabel,
5540
- selectable,
5541
- searchable: displayOptions.showToolbarSearch,
5542
- showColumnHeaders: displayOptions.showColumnLabels,
5543
- groupable,
5544
- defaultSort,
5545
- emptyState: emptyState ?? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No records match your filters." }),
5546
- conditionalRules,
5547
- state: args2.state,
5548
- renderFilterOptionValue,
5549
- toolbarSlot: (s) => /* @__PURE__ */ jsx(TablePropertiesDrawerButton, { ...drawerToolbarProps, state: s }),
5550
- bulkActionsSlot,
5551
- onRowClick
5552
- }
5553
- ) });
5670
+ const defaultTableRenderer = (args2) => {
5671
+ const filteredCount = args2.state.rows.length;
5672
+ const totalPages = Math.max(1, Math.ceil(filteredCount / Math.max(1, internalPageSize)));
5673
+ const safePage = Math.min(internalPage, totalPages);
5674
+ return /* @__PURE__ */ jsxs("div", { className: "pb-6", children: [
5675
+ chromeOwnedPagination ? /* @__PURE__ */ jsx(
5676
+ CountSyncer,
5677
+ {
5678
+ count: filteredCount,
5679
+ onSync: (n) => {
5680
+ const next = Math.max(1, Math.ceil(n / Math.max(1, internalPageSize)));
5681
+ if (safePage > next) setInternalPage(next);
5682
+ },
5683
+ onReset: resetPage
5684
+ }
5685
+ ) : null,
5686
+ /* @__PURE__ */ jsx(
5687
+ DataTable,
5688
+ {
5689
+ data: rows,
5690
+ columns,
5691
+ getRowId,
5692
+ getRowSelectionLabel,
5693
+ selectable,
5694
+ searchable: displayOptions.showToolbarSearch,
5695
+ showColumnHeaders: displayOptions.showColumnLabels,
5696
+ groupable,
5697
+ defaultSort,
5698
+ emptyState: emptyState ?? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No records match your filters." }),
5699
+ conditionalRules,
5700
+ state: args2.state,
5701
+ renderFilterOptionValue,
5702
+ toolbarSlot: (s) => /* @__PURE__ */ jsx(TablePropertiesDrawerButton, { ...drawerToolbarProps, state: s }),
5703
+ bulkActionsSlot,
5704
+ onRowClick,
5705
+ hasFooter: chromeOwnedPagination
5706
+ }
5707
+ ),
5708
+ chromeOwnedPagination ? /* @__PURE__ */ jsx(
5709
+ "div",
5710
+ {
5711
+ className: cn(
5712
+ "mx-4 lg:mx-6 border-x border-b border-border rounded-b-lg overflow-hidden bg-background",
5713
+ // z-40 sits above pinned cells (z-20), group headers (z-25), and column headers
5714
+ // (z-30 / z-40) so the sticky footer paints over any table content that scrolls
5715
+ // behind it. Pinned-left cells ship with their own `bg-dt-row-bg`, which
5716
+ // otherwise wins because of z-20 > z-10.
5717
+ "sticky bottom-0 z-40"
5718
+ ),
5719
+ children: /* @__PURE__ */ jsx(
5720
+ PaginationBar,
5721
+ {
5722
+ page: safePage,
5723
+ pageSize: internalPageSize,
5724
+ total: filteredCount,
5725
+ pageSizeOptions: paginationPageSizeOptions,
5726
+ onPageChange: handlePageChange,
5727
+ onPageSizeChange: handlePageSizeChange
5728
+ }
5729
+ )
5730
+ }
5731
+ ) : null
5732
+ ] });
5733
+ };
5554
5734
  const args = {
5555
5735
  state: tableState,
5556
5736
  toolbar,
@@ -5574,20 +5754,62 @@ function HubTable({
5574
5754
  "data-table": () => (tableRenderer ?? defaultTableRenderer)(args)
5575
5755
  };
5576
5756
  if (renderers["list-with-toolbar"] == null && renderListRow != null) {
5577
- composed["list-with-toolbar"] = () => args.toolbarShell(
5578
- /* @__PURE__ */ jsx(
5579
- DataRowList,
5580
- {
5581
- rows: args.state.rows,
5582
- getRowId: (row) => getRowId(row),
5583
- ariaLabel: listAriaLabel ?? hubLabel,
5584
- emptyState: listEmptyState ?? "No records match your filters.",
5585
- ...listVirtualizeThreshold !== void 0 ? { virtualizeThreshold: listVirtualizeThreshold } : {},
5586
- ...listEstimatedRowHeight !== void 0 ? { estimatedRowHeight: listEstimatedRowHeight } : {},
5587
- renderRow: renderListRow
5588
- }
5589
- )
5590
- );
5757
+ composed["list-with-toolbar"] = () => {
5758
+ const fullRows = args.state.rows;
5759
+ const pagedRows = chromeOwnedPagination ? args.state.pagedRows : fullRows;
5760
+ const filteredCount = fullRows.length;
5761
+ const totalPages = Math.max(1, Math.ceil(filteredCount / Math.max(1, internalPageSize)));
5762
+ const safePage = Math.min(internalPage, totalPages);
5763
+ return args.toolbarShell(
5764
+ /* @__PURE__ */ jsxs(Fragment, { children: [
5765
+ chromeOwnedPagination ? /* @__PURE__ */ jsx(
5766
+ CountSyncer,
5767
+ {
5768
+ count: filteredCount,
5769
+ onSync: (n) => {
5770
+ const next = Math.max(1, Math.ceil(n / Math.max(1, internalPageSize)));
5771
+ if (safePage > next) setInternalPage(next);
5772
+ },
5773
+ onReset: resetPage
5774
+ }
5775
+ ) : null,
5776
+ /* @__PURE__ */ jsx(
5777
+ DataRowList,
5778
+ {
5779
+ rows: pagedRows,
5780
+ getRowId: (row) => getRowId(row),
5781
+ ariaLabel: listAriaLabel ?? hubLabel,
5782
+ emptyState: listEmptyState ?? "No records match your filters.",
5783
+ ...listVirtualizeThreshold !== void 0 ? { virtualizeThreshold: listVirtualizeThreshold } : {},
5784
+ ...listEstimatedRowHeight !== void 0 ? { estimatedRowHeight: listEstimatedRowHeight } : {},
5785
+ renderRow: renderListRow
5786
+ }
5787
+ ),
5788
+ chromeOwnedPagination ? /* @__PURE__ */ jsx(
5789
+ "div",
5790
+ {
5791
+ className: cn(
5792
+ "mx-4 lg:mx-6 border-x border-b border-border rounded-b-lg overflow-hidden bg-background",
5793
+ // Match the table-view footer — above pinned cells (z-20) and column
5794
+ // headers (z-30 / z-40) so the sticky chrome paints over scrolling rows.
5795
+ "sticky bottom-0 z-40"
5796
+ ),
5797
+ children: /* @__PURE__ */ jsx(
5798
+ PaginationBar,
5799
+ {
5800
+ page: safePage,
5801
+ pageSize: internalPageSize,
5802
+ total: filteredCount,
5803
+ pageSizeOptions: paginationPageSizeOptions,
5804
+ onPageChange: handlePageChange,
5805
+ onPageSizeChange: handlePageSizeChange
5806
+ }
5807
+ )
5808
+ }
5809
+ ) : null
5810
+ ] })
5811
+ );
5812
+ };
5591
5813
  }
5592
5814
  if (renderers["board-with-toolbar"] == null && renderBoardCard != null && boardGroups != null) {
5593
5815
  composed["board-with-toolbar"] = () => args.toolbarShell(