@hexclave/dashboard-ui-components 1.0.53 → 1.0.55

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 (54) hide show
  1. package/dist/components/data-grid/data-grid-export-dialog.d.ts +1 -1
  2. package/dist/components/data-grid/data-grid-sizing.d.ts +1 -1
  3. package/dist/components/data-grid/data-grid-toolbar.d.ts +1 -1
  4. package/dist/components/data-grid/data-grid-toolbar.js +37 -29
  5. package/dist/components/data-grid/data-grid-toolbar.js.map +1 -1
  6. package/dist/components/data-grid/data-grid.d.ts +1 -1
  7. package/dist/components/data-grid/data-grid.js +96 -12
  8. package/dist/components/data-grid/data-grid.js.map +1 -1
  9. package/dist/components/data-grid/data-grid.test.js +101 -2
  10. package/dist/components/data-grid/data-grid.test.js.map +1 -1
  11. package/dist/components/data-grid/index.d.ts +8 -8
  12. package/dist/components/data-grid/state.d.ts +1 -1
  13. package/dist/components/data-grid/strings.d.ts +1 -1
  14. package/dist/components/data-grid/types.d.ts +1 -1
  15. package/dist/components/data-grid/use-data-source.d.ts +1 -1
  16. package/dist/components/data-grid/use-url-state.d.ts +1 -1
  17. package/dist/dashboard-ui-components.global.js +21283 -4277
  18. package/dist/dashboard-ui-components.global.js.map +4 -4
  19. package/dist/{data-grid-AJi1TNDa.d.ts → data-grid-DWHAjaNo.d.ts} +2 -2
  20. package/dist/data-grid-DWHAjaNo.d.ts.map +1 -0
  21. package/dist/{data-grid-sizing-S1ixcZKo.d.ts → data-grid-sizing-D9y1xwaq.d.ts} +2 -2
  22. package/dist/{data-grid-sizing-S1ixcZKo.d.ts.map → data-grid-sizing-D9y1xwaq.d.ts.map} +1 -1
  23. package/dist/{data-grid-toolbar-BGSNGDpT.d.ts → data-grid-toolbar-dgvnYEpC.d.ts} +10 -6
  24. package/dist/data-grid-toolbar-dgvnYEpC.d.ts.map +1 -0
  25. package/dist/esm/components/data-grid/data-grid-toolbar.d.ts +8 -4
  26. package/dist/esm/components/data-grid/data-grid-toolbar.d.ts.map +1 -1
  27. package/dist/esm/components/data-grid/data-grid-toolbar.js +38 -30
  28. package/dist/esm/components/data-grid/data-grid-toolbar.js.map +1 -1
  29. package/dist/esm/components/data-grid/data-grid.d.ts.map +1 -1
  30. package/dist/esm/components/data-grid/data-grid.js +96 -12
  31. package/dist/esm/components/data-grid/data-grid.js.map +1 -1
  32. package/dist/esm/components/data-grid/data-grid.test.js +102 -3
  33. package/dist/esm/components/data-grid/data-grid.test.js.map +1 -1
  34. package/dist/esm/components/data-grid/types.d.ts +7 -0
  35. package/dist/esm/components/data-grid/types.d.ts.map +1 -1
  36. package/dist/esm/package.json +12 -0
  37. package/dist/index.d.ts +8 -8
  38. package/dist/{state-6LW8ACh5.d.ts → state-D5wpAg_G.d.ts} +2 -2
  39. package/dist/{state-6LW8ACh5.d.ts.map → state-D5wpAg_G.d.ts.map} +1 -1
  40. package/dist/{strings-CACVtKlq.d.ts → strings-DsIJ_o4-.d.ts} +2 -2
  41. package/dist/{strings-CACVtKlq.d.ts.map → strings-DsIJ_o4-.d.ts.map} +1 -1
  42. package/dist/{types-1-eOd1JF.d.ts → types-D8o47V7M.d.ts} +8 -1
  43. package/dist/{types-1-eOd1JF.d.ts.map → types-D8o47V7M.d.ts.map} +1 -1
  44. package/dist/{use-data-source-BVFynerX.d.ts → use-data-source-CAZPhl8e.d.ts} +2 -2
  45. package/dist/{use-data-source-BVFynerX.d.ts.map → use-data-source-CAZPhl8e.d.ts.map} +1 -1
  46. package/dist/{use-url-state-B4_wnBjm.d.ts → use-url-state-97YdV81Q.d.ts} +2 -2
  47. package/dist/{use-url-state-B4_wnBjm.d.ts.map → use-url-state-97YdV81Q.d.ts.map} +1 -1
  48. package/package.json +3 -3
  49. package/src/components/data-grid/data-grid-toolbar.tsx +20 -6
  50. package/src/components/data-grid/data-grid.test.tsx +127 -1
  51. package/src/components/data-grid/data-grid.tsx +174 -37
  52. package/src/components/data-grid/types.ts +7 -0
  53. package/dist/data-grid-AJi1TNDa.d.ts.map +0 -1
  54. package/dist/data-grid-toolbar-BGSNGDpT.d.ts.map +0 -1
@@ -1,4 +1,4 @@
1
- import { h as DataGridExportOptions, i as DataGridColumnDef } from "../../types-1-eOd1JF.js";
1
+ import { h as DataGridExportOptions, i as DataGridColumnDef } from "../../types-D8o47V7M.js";
2
2
 
3
3
  //#region src/components/data-grid/data-grid-export-dialog.d.ts
4
4
  type DataGridExportDialogProps<TRow> = {
@@ -1,2 +1,2 @@
1
- import { a as getEffectiveMinWidth, i as getEffectiveMaxWidth, n as DEFAULT_MAX_COL_WIDTH, r as clampColumnWidth, t as DEFAULT_COL_WIDTH } from "../../data-grid-sizing-S1ixcZKo.js";
1
+ import { a as getEffectiveMinWidth, i as getEffectiveMaxWidth, n as DEFAULT_MAX_COL_WIDTH, r as clampColumnWidth, t as DEFAULT_COL_WIDTH } from "../../data-grid-sizing-D9y1xwaq.js";
2
2
  export { DEFAULT_COL_WIDTH, DEFAULT_MAX_COL_WIDTH, clampColumnWidth, getEffectiveMaxWidth, getEffectiveMinWidth };
@@ -1,2 +1,2 @@
1
- import { t as DataGridToolbar } from "../../data-grid-toolbar-BGSNGDpT.js";
1
+ import { t as DataGridToolbar } from "../../data-grid-toolbar-dgvnYEpC.js";
2
2
  export { DataGridToolbar };
@@ -151,7 +151,7 @@ function ColumnManager({ columns, visibility, onChange, strings, dateDisplay, on
151
151
  ]
152
152
  });
153
153
  }
154
- function DataGridToolbar({ ctx, extra, extraLeading, hideQuickSearch }) {
154
+ function DataGridToolbar({ ctx, extra, extraLeading, extraActions, hideQuickSearch }) {
155
155
  const { state, onChange, columns, strings, exportCsv } = ctx;
156
156
  const columnPopover = usePopover();
157
157
  const updateVisibility = (0, react.useCallback)((visibility) => {
@@ -177,8 +177,9 @@ function DataGridToolbar({ ctx, extra, extraLeading, hideQuickSearch }) {
177
177
  }));
178
178
  }, [onChange]);
179
179
  const hasDateColumns = (0, react.useMemo)(() => columns.some((c) => c.type === "date" || c.type === "dateTime"), [columns]);
180
+ const hasExtraActions = react.default.Children.toArray(extraActions).length > 0;
180
181
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
181
- className: "flex w-full min-w-0 flex-col gap-2 px-2.5 py-2.5 border-b border-foreground/[0.06] sm:flex-row sm:items-center sm:gap-2",
182
+ className: "flex w-full min-w-0 flex-col gap-2 px-2.5 py-2.5 pr-3 border-b border-foreground/[0.06] sm:flex-row sm:items-center sm:gap-2",
182
183
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
183
184
  className: "flex min-w-0 flex-1 flex-wrap items-center gap-2",
184
185
  children: [
@@ -191,33 +192,40 @@ function DataGridToolbar({ ctx, extra, extraLeading, hideQuickSearch }) {
191
192
  extra
192
193
  ]
193
194
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
194
- className: "flex shrink-0 items-center justify-end gap-2",
195
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
196
- className: "relative shrink-0",
197
- ref: columnPopover.ref,
198
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
199
- onClick: () => columnPopover.setOpen(!columnPopover.open),
200
- active: columnPopover.open,
201
- title: strings.columns,
202
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_phosphor_icons_react.Eye, { className: "h-3.5 w-3.5" })
203
- }), columnPopover.open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PopoverPanel, {
204
- popoverRef: columnPopover.ref,
205
- className: "right-0 left-auto",
206
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ColumnManager, {
207
- columns,
208
- visibility: state.columnVisibility,
209
- onChange: updateVisibility,
210
- strings,
211
- dateDisplay: state.dateDisplay,
212
- onDateDisplayChange: updateDateDisplay,
213
- hasDateColumns
214
- })
215
- })]
216
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
217
- onClick: exportCsv,
218
- title: strings.export,
219
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_phosphor_icons_react.DownloadSimple, { className: "h-3.5 w-3.5" })
220
- })]
195
+ className: "flex shrink-0 items-center justify-end gap-1.5",
196
+ children: [
197
+ hasExtraActions && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [extraActions, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
198
+ className: "mx-0.5 hidden h-4 w-px bg-foreground/[0.1] sm:block",
199
+ "aria-hidden": true
200
+ })] }),
201
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
202
+ className: "relative shrink-0",
203
+ ref: columnPopover.ref,
204
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
205
+ onClick: () => columnPopover.setOpen(!columnPopover.open),
206
+ active: columnPopover.open,
207
+ title: strings.columns,
208
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_phosphor_icons_react.Eye, { className: "h-3.5 w-3.5" })
209
+ }), columnPopover.open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PopoverPanel, {
210
+ popoverRef: columnPopover.ref,
211
+ className: "right-0 left-auto",
212
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ColumnManager, {
213
+ columns,
214
+ visibility: state.columnVisibility,
215
+ onChange: updateVisibility,
216
+ strings,
217
+ dateDisplay: state.dateDisplay,
218
+ onDateDisplayChange: updateDateDisplay,
219
+ hasDateColumns
220
+ })
221
+ })]
222
+ }),
223
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
224
+ onClick: exportCsv,
225
+ title: strings.export,
226
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_phosphor_icons_react.DownloadSimple, { className: "h-3.5 w-3.5" })
227
+ })
228
+ ]
221
229
  })]
222
230
  });
223
231
  }
@@ -1 +1 @@
1
- {"version":3,"file":"data-grid-toolbar.js","names":["MagnifyingGlass","X","Eye","EyeSlash","Check","DownloadSimple"],"sources":["../../../src/components/data-grid/data-grid-toolbar.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"@hexclave/ui\";\nimport {\n Check,\n DownloadSimple,\n Eye,\n EyeSlash,\n MagnifyingGlass,\n X,\n} from \"@phosphor-icons/react\";\nimport React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport type {\n DataGridColumnDef,\n DataGridDateDisplay,\n DataGridStrings,\n DataGridToolbarContext,\n} from \"./types\";\n\n// ─── Popover primitive ───────────────────────────────────────────────\n\nfunction usePopover() {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n React.useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpen(false);\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [open]);\n\n return { open, setOpen, ref };\n}\n\nfunction PopoverPanel({\n children,\n className,\n popoverRef,\n}: {\n children: React.ReactNode;\n className?: string;\n popoverRef: React.Ref<HTMLDivElement>;\n}) {\n return (\n <div\n ref={popoverRef}\n className={cn(\n \"absolute top-full left-0 mt-1 z-50\",\n \"bg-white text-popover-foreground rounded-xl shadow-lg dark:bg-popover\",\n \"ring-1 ring-black/[0.08] dark:ring-white/[0.1]\",\n \"backdrop-blur-xl\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n// ─── Quick search ────────────────────────────────────────────────────\n\nfunction QuickSearch({\n value,\n onChange,\n placeholder,\n}: {\n value: string;\n onChange: (value: string) => void;\n placeholder: string;\n}) {\n return (\n <div className=\"relative flex min-w-0 flex-1 items-center sm:flex-initial\">\n <MagnifyingGlass className=\"absolute left-2.5 h-3.5 w-3.5 text-muted-foreground/60 pointer-events-none\" />\n <input\n type=\"text\"\n className={cn(\n \"h-8 w-full sm:w-52 pl-8 pr-7 rounded-xl text-xs\",\n \"border border-black/[0.08] dark:border-white/[0.06]\",\n \"bg-white dark:bg-background shadow-sm ring-1 ring-black/[0.08] dark:ring-white/[0.06]\",\n \"placeholder:text-muted-foreground/50\",\n \"focus:outline-none focus:ring-1 focus:ring-foreground/[0.1]\",\n \"transition-all duration-150 hover:transition-none hover:ring-black/[0.12] dark:hover:ring-white/[0.1]\",\n )}\n placeholder={placeholder}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n />\n {value && (\n <button\n className=\"absolute right-2 text-muted-foreground/40 hover:text-muted-foreground\"\n onClick={() => onChange(\"\")}\n aria-label=\"Clear search\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n );\n}\n\n// ─── Toolbar button ──────────────────────────────────────────────────\n\nfunction ToolbarButton({\n children,\n onClick,\n active,\n title,\n className: extraClassName,\n}: {\n children: React.ReactNode;\n onClick?: () => void;\n active?: boolean;\n title?: string;\n className?: string;\n}) {\n return (\n <button\n className={cn(\n \"relative flex items-center justify-center rounded-lg text-xs font-medium\",\n \"h-7 w-7\",\n \"transition-colors duration-75\",\n active\n ? \"bg-foreground/[0.06] text-foreground\"\n : \"text-muted-foreground hover:text-foreground hover:bg-foreground/[0.04]\",\n extraClassName,\n )}\n onClick={onClick}\n title={title}\n >\n {children}\n </button>\n );\n}\n\n// ─── Column manager ──────────────────────────────────────────────────\n\nfunction ColumnManager<TRow>({\n columns,\n visibility,\n onChange,\n strings,\n dateDisplay,\n onDateDisplayChange,\n hasDateColumns,\n}: {\n columns: readonly DataGridColumnDef<TRow>[];\n visibility: Record<string, boolean>;\n onChange: (visibility: Record<string, boolean>) => void;\n strings: DataGridStrings;\n dateDisplay: DataGridDateDisplay;\n onDateDisplayChange: (mode: DataGridDateDisplay) => void;\n hasDateColumns: boolean;\n}) {\n const hideableColumns = useMemo(\n () => columns.filter((c) => c.hideable !== false),\n [columns],\n );\n\n const toggleColumn = (id: string) => {\n const current = visibility[id] !== false;\n onChange({ ...visibility, [id]: !current });\n };\n\n const showAll = () => {\n const next = { ...visibility };\n for (const col of hideableColumns) next[col.id] = true;\n onChange(next);\n };\n\n const hideAll = () => {\n const next = { ...visibility };\n for (const col of hideableColumns) next[col.id] = false;\n onChange(next);\n };\n\n return (\n <div className=\"p-2 min-w-[240px] max-w-[300px]\">\n <div className=\"max-h-[280px] overflow-y-auto space-y-0.5\">\n {hideableColumns.map((col) => {\n const visible = visibility[col.id] !== false;\n return (\n <button\n key={col.id}\n className={cn(\n \"flex items-center gap-2 w-full px-2.5 py-1.5 rounded-lg text-xs\",\n \"hover:bg-foreground/[0.06] transition-colors duration-75\",\n visible ? \"text-foreground\" : \"text-muted-foreground/50\",\n )}\n onClick={() => toggleColumn(col.id)}\n >\n {visible ? (\n <Eye className=\"h-3.5 w-3.5 flex-shrink-0 text-blue-500\" />\n ) : (\n <EyeSlash className=\"h-3.5 w-3.5 flex-shrink-0\" />\n )}\n <span className=\"truncate text-left\">\n {typeof col.header === \"string\" ? col.header : col.id}\n </span>\n {visible && <Check className=\"h-3 w-3 ml-auto flex-shrink-0 text-blue-500\" />}\n </button>\n );\n })}\n </div>\n <div className=\"flex items-center gap-2 mt-2 pt-2 border-t border-foreground/[0.06]\">\n <button className=\"text-[10px] text-muted-foreground hover:text-foreground font-medium uppercase tracking-wider transition-colors duration-75\" onClick={showAll}>\n {strings.showAll}\n </button>\n <span className=\"text-muted-foreground/20\">|</span>\n <button className=\"text-[10px] text-muted-foreground hover:text-foreground font-medium uppercase tracking-wider transition-colors duration-75\" onClick={hideAll}>\n {strings.hideAll}\n </button>\n </div>\n\n {/* Date format toggle — only rendered when at least one column\n uses `type: \"date\"` or `\"dateTime\"`. Toggling writes to\n `state.dateDisplay` and the grid re-renders every date cell. */}\n {hasDateColumns && (\n <div className=\"mt-2 pt-2 border-t border-foreground/[0.06]\">\n <div className=\"flex items-center justify-between gap-2 px-1\">\n <span className=\"text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">\n {strings.dateFormat}\n </span>\n <div className=\"inline-flex items-center gap-0.5 rounded-lg bg-zinc-100/90 p-0.5 ring-1 ring-black/[0.06] dark:bg-foreground/[0.04] dark:ring-white/[0.06]\">\n <button\n className={cn(\n \"px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-150 hover:transition-none\",\n dateDisplay === \"relative\"\n ? \"bg-white text-foreground shadow-sm ring-1 ring-black/[0.12] dark:bg-background dark:ring-white/[0.06]\"\n : \"text-muted-foreground hover:text-foreground hover:bg-white/50 dark:hover:bg-white/[0.06]\",\n )}\n onClick={() => onDateDisplayChange(\"relative\")}\n >\n {strings.dateFormatRelative}\n </button>\n <button\n className={cn(\n \"px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-150 hover:transition-none\",\n dateDisplay === \"absolute\"\n ? \"bg-white text-foreground shadow-sm ring-1 ring-black/[0.12] dark:bg-background dark:ring-white/[0.06]\"\n : \"text-muted-foreground hover:text-foreground hover:bg-white/50 dark:hover:bg-white/[0.06]\",\n )}\n onClick={() => onDateDisplayChange(\"absolute\")}\n >\n {strings.dateFormatAbsolute}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n// ─── Main toolbar ────────────────────────────────────────────────────\n\nexport function DataGridToolbar<TRow>({\n ctx,\n extra,\n extraLeading,\n hideQuickSearch,\n}: {\n ctx: DataGridToolbarContext<TRow>;\n /** Extra content rendered inside the toolbar row, to the left of the\n * built-in columns / export actions. Use this to add table-specific\n * affordances (refresh, custom toggles, row counts) without giving up\n * the default actions. */\n extra?: React.ReactNode;\n /** Extra content rendered at the START of the toolbar row — occupies\n * the same position as the built-in quick search (after it, if the\n * quick search is visible). Use this together with `hideQuickSearch`\n * to fully replace the quick search with a custom input, e.g. an\n * AI-powered search bar. */\n extraLeading?: React.ReactNode;\n /** Whether to hide the built-in quick-search input. When `true`,\n * callers are expected to provide their own search UI via\n * `extraLeading`. */\n hideQuickSearch?: boolean;\n}) {\n const { state, onChange, columns, strings, exportCsv } = ctx;\n\n const columnPopover = usePopover();\n\n const updateVisibility = useCallback(\n (visibility: Record<string, boolean>) => {\n onChange((s) => ({ ...s, columnVisibility: visibility }));\n },\n [onChange],\n );\n\n const updateDateDisplay = useCallback(\n (mode: DataGridDateDisplay) => {\n onChange((s) => ({ ...s, dateDisplay: mode }));\n },\n [onChange],\n );\n\n const updateQuickSearch = useCallback(\n (value: string) => {\n onChange((s) => ({\n ...s,\n quickSearch: value,\n // Reset to first page whenever the search text changes,\n // otherwise you can end up on a page index that no longer\n // exists in the filtered / refetched result set.\n pagination: { ...s.pagination, pageIndex: 0 },\n }));\n },\n [onChange],\n );\n\n const hasDateColumns = useMemo(\n () => columns.some((c) => c.type === \"date\" || c.type === \"dateTime\"),\n [columns],\n );\n\n return (\n <div className=\"flex w-full min-w-0 flex-col gap-2 px-2.5 py-2.5 border-b border-foreground/[0.06] sm:flex-row sm:items-center sm:gap-2\">\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-2\">\n {!hideQuickSearch && (\n <QuickSearch\n value={state.quickSearch}\n onChange={updateQuickSearch}\n placeholder={strings.searchPlaceholder}\n />\n )}\n {extraLeading}\n {extra}\n </div>\n <div className=\"flex shrink-0 items-center justify-end gap-2\">\n <div className=\"relative shrink-0\" ref={columnPopover.ref}>\n <ToolbarButton\n onClick={() => columnPopover.setOpen(!columnPopover.open)}\n active={columnPopover.open}\n title={strings.columns}\n >\n <Eye className=\"h-3.5 w-3.5\" />\n </ToolbarButton>\n {columnPopover.open && (\n <PopoverPanel popoverRef={columnPopover.ref} className=\"right-0 left-auto\">\n <ColumnManager\n columns={columns}\n visibility={state.columnVisibility}\n onChange={updateVisibility}\n strings={strings}\n dateDisplay={state.dateDisplay}\n onDateDisplayChange={updateDateDisplay}\n hasDateColumns={hasDateColumns}\n />\n </PopoverPanel>\n )}\n </div>\n\n <ToolbarButton onClick={exportCsv} title={strings.export}>\n <DownloadSimple className=\"h-3.5 w-3.5\" />\n </ToolbarButton>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"data-grid-toolbar.js","names":["MagnifyingGlass","X","Eye","EyeSlash","Check","React","DownloadSimple"],"sources":["../../../src/components/data-grid/data-grid-toolbar.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"@hexclave/ui\";\nimport {\n Check,\n DownloadSimple,\n Eye,\n EyeSlash,\n MagnifyingGlass,\n X,\n} from \"@phosphor-icons/react\";\nimport React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport type {\n DataGridColumnDef,\n DataGridDateDisplay,\n DataGridStrings,\n DataGridToolbarContext,\n} from \"./types\";\n\n// ─── Popover primitive ───────────────────────────────────────────────\n\nfunction usePopover() {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n React.useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpen(false);\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [open]);\n\n return { open, setOpen, ref };\n}\n\nfunction PopoverPanel({\n children,\n className,\n popoverRef,\n}: {\n children: React.ReactNode;\n className?: string;\n popoverRef: React.Ref<HTMLDivElement>;\n}) {\n return (\n <div\n ref={popoverRef}\n className={cn(\n \"absolute top-full left-0 mt-1 z-50\",\n \"bg-white text-popover-foreground rounded-xl shadow-lg dark:bg-popover\",\n \"ring-1 ring-black/[0.08] dark:ring-white/[0.1]\",\n \"backdrop-blur-xl\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n// ─── Quick search ────────────────────────────────────────────────────\n\nfunction QuickSearch({\n value,\n onChange,\n placeholder,\n}: {\n value: string;\n onChange: (value: string) => void;\n placeholder: string;\n}) {\n return (\n <div className=\"relative flex min-w-0 flex-1 items-center sm:flex-initial\">\n <MagnifyingGlass className=\"absolute left-2.5 h-3.5 w-3.5 text-muted-foreground/60 pointer-events-none\" />\n <input\n type=\"text\"\n className={cn(\n \"h-8 w-full sm:w-52 pl-8 pr-7 rounded-xl text-xs\",\n \"border border-black/[0.08] dark:border-white/[0.06]\",\n \"bg-white dark:bg-background shadow-sm ring-1 ring-black/[0.08] dark:ring-white/[0.06]\",\n \"placeholder:text-muted-foreground/50\",\n \"focus:outline-none focus:ring-1 focus:ring-foreground/[0.1]\",\n \"transition-all duration-150 hover:transition-none hover:ring-black/[0.12] dark:hover:ring-white/[0.1]\",\n )}\n placeholder={placeholder}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n />\n {value && (\n <button\n className=\"absolute right-2 text-muted-foreground/40 hover:text-muted-foreground\"\n onClick={() => onChange(\"\")}\n aria-label=\"Clear search\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n );\n}\n\n// ─── Toolbar button ──────────────────────────────────────────────────\n\nfunction ToolbarButton({\n children,\n onClick,\n active,\n title,\n className: extraClassName,\n}: {\n children: React.ReactNode;\n onClick?: () => void;\n active?: boolean;\n title?: string;\n className?: string;\n}) {\n return (\n <button\n className={cn(\n \"relative flex items-center justify-center rounded-lg text-xs font-medium\",\n \"h-7 w-7\",\n \"transition-colors duration-75\",\n active\n ? \"bg-foreground/[0.06] text-foreground\"\n : \"text-muted-foreground hover:text-foreground hover:bg-foreground/[0.04]\",\n extraClassName,\n )}\n onClick={onClick}\n title={title}\n >\n {children}\n </button>\n );\n}\n\n// ─── Column manager ──────────────────────────────────────────────────\n\nfunction ColumnManager<TRow>({\n columns,\n visibility,\n onChange,\n strings,\n dateDisplay,\n onDateDisplayChange,\n hasDateColumns,\n}: {\n columns: readonly DataGridColumnDef<TRow>[];\n visibility: Record<string, boolean>;\n onChange: (visibility: Record<string, boolean>) => void;\n strings: DataGridStrings;\n dateDisplay: DataGridDateDisplay;\n onDateDisplayChange: (mode: DataGridDateDisplay) => void;\n hasDateColumns: boolean;\n}) {\n const hideableColumns = useMemo(\n () => columns.filter((c) => c.hideable !== false),\n [columns],\n );\n\n const toggleColumn = (id: string) => {\n const current = visibility[id] !== false;\n onChange({ ...visibility, [id]: !current });\n };\n\n const showAll = () => {\n const next = { ...visibility };\n for (const col of hideableColumns) next[col.id] = true;\n onChange(next);\n };\n\n const hideAll = () => {\n const next = { ...visibility };\n for (const col of hideableColumns) next[col.id] = false;\n onChange(next);\n };\n\n return (\n <div className=\"p-2 min-w-[240px] max-w-[300px]\">\n <div className=\"max-h-[280px] overflow-y-auto space-y-0.5\">\n {hideableColumns.map((col) => {\n const visible = visibility[col.id] !== false;\n return (\n <button\n key={col.id}\n className={cn(\n \"flex items-center gap-2 w-full px-2.5 py-1.5 rounded-lg text-xs\",\n \"hover:bg-foreground/[0.06] transition-colors duration-75\",\n visible ? \"text-foreground\" : \"text-muted-foreground/50\",\n )}\n onClick={() => toggleColumn(col.id)}\n >\n {visible ? (\n <Eye className=\"h-3.5 w-3.5 flex-shrink-0 text-blue-500\" />\n ) : (\n <EyeSlash className=\"h-3.5 w-3.5 flex-shrink-0\" />\n )}\n <span className=\"truncate text-left\">\n {typeof col.header === \"string\" ? col.header : col.id}\n </span>\n {visible && <Check className=\"h-3 w-3 ml-auto flex-shrink-0 text-blue-500\" />}\n </button>\n );\n })}\n </div>\n <div className=\"flex items-center gap-2 mt-2 pt-2 border-t border-foreground/[0.06]\">\n <button className=\"text-[10px] text-muted-foreground hover:text-foreground font-medium uppercase tracking-wider transition-colors duration-75\" onClick={showAll}>\n {strings.showAll}\n </button>\n <span className=\"text-muted-foreground/20\">|</span>\n <button className=\"text-[10px] text-muted-foreground hover:text-foreground font-medium uppercase tracking-wider transition-colors duration-75\" onClick={hideAll}>\n {strings.hideAll}\n </button>\n </div>\n\n {/* Date format toggle — only rendered when at least one column\n uses `type: \"date\"` or `\"dateTime\"`. Toggling writes to\n `state.dateDisplay` and the grid re-renders every date cell. */}\n {hasDateColumns && (\n <div className=\"mt-2 pt-2 border-t border-foreground/[0.06]\">\n <div className=\"flex items-center justify-between gap-2 px-1\">\n <span className=\"text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">\n {strings.dateFormat}\n </span>\n <div className=\"inline-flex items-center gap-0.5 rounded-lg bg-zinc-100/90 p-0.5 ring-1 ring-black/[0.06] dark:bg-foreground/[0.04] dark:ring-white/[0.06]\">\n <button\n className={cn(\n \"px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-150 hover:transition-none\",\n dateDisplay === \"relative\"\n ? \"bg-white text-foreground shadow-sm ring-1 ring-black/[0.12] dark:bg-background dark:ring-white/[0.06]\"\n : \"text-muted-foreground hover:text-foreground hover:bg-white/50 dark:hover:bg-white/[0.06]\",\n )}\n onClick={() => onDateDisplayChange(\"relative\")}\n >\n {strings.dateFormatRelative}\n </button>\n <button\n className={cn(\n \"px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-150 hover:transition-none\",\n dateDisplay === \"absolute\"\n ? \"bg-white text-foreground shadow-sm ring-1 ring-black/[0.12] dark:bg-background dark:ring-white/[0.06]\"\n : \"text-muted-foreground hover:text-foreground hover:bg-white/50 dark:hover:bg-white/[0.06]\",\n )}\n onClick={() => onDateDisplayChange(\"absolute\")}\n >\n {strings.dateFormatAbsolute}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n// ─── Main toolbar ────────────────────────────────────────────────────\n\nexport function DataGridToolbar<TRow>({\n ctx,\n extra,\n extraLeading,\n extraActions,\n hideQuickSearch,\n}: {\n ctx: DataGridToolbarContext<TRow>;\n /** Extra content in the leading cluster, after search / `extraLeading`\n * (filters, status badges, row counts). Stays with the search side so\n * it doesn't compete with the trailing icon actions. */\n extra?: React.ReactNode;\n /** Extra content rendered at the START of the toolbar row — occupies\n * the same position as the built-in quick search (after it, if the\n * quick search is visible). Use this together with `hideQuickSearch`\n * to fully replace the quick search with a custom input, e.g. an\n * AI-powered search bar. */\n extraLeading?: React.ReactNode;\n /** Extra content in the trailing action cluster, immediately before\n * the built-in columns / export buttons (e.g. a labeled Refresh).\n * When present, a hairline divider separates it from those icons. */\n extraActions?: React.ReactNode;\n /** Whether to hide the built-in quick-search input. When `true`,\n * callers are expected to provide their own search UI via\n * `extraLeading`. */\n hideQuickSearch?: boolean;\n}) {\n const { state, onChange, columns, strings, exportCsv } = ctx;\n\n const columnPopover = usePopover();\n\n const updateVisibility = useCallback(\n (visibility: Record<string, boolean>) => {\n onChange((s) => ({ ...s, columnVisibility: visibility }));\n },\n [onChange],\n );\n\n const updateDateDisplay = useCallback(\n (mode: DataGridDateDisplay) => {\n onChange((s) => ({ ...s, dateDisplay: mode }));\n },\n [onChange],\n );\n\n const updateQuickSearch = useCallback(\n (value: string) => {\n onChange((s) => ({\n ...s,\n quickSearch: value,\n // Reset to first page whenever the search text changes,\n // otherwise you can end up on a page index that no longer\n // exists in the filtered / refetched result set.\n pagination: { ...s.pagination, pageIndex: 0 },\n }));\n },\n [onChange],\n );\n\n const hasDateColumns = useMemo(\n () => columns.some((c) => c.type === \"date\" || c.type === \"dateTime\"),\n [columns],\n );\n const hasExtraActions = React.Children.toArray(extraActions).length > 0;\n\n return (\n <div className=\"flex w-full min-w-0 flex-col gap-2 px-2.5 py-2.5 pr-3 border-b border-foreground/[0.06] sm:flex-row sm:items-center sm:gap-2\">\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-2\">\n {!hideQuickSearch && (\n <QuickSearch\n value={state.quickSearch}\n onChange={updateQuickSearch}\n placeholder={strings.searchPlaceholder}\n />\n )}\n {extraLeading}\n {extra}\n </div>\n <div className=\"flex shrink-0 items-center justify-end gap-1.5\">\n {hasExtraActions && (\n <>\n {extraActions}\n <div\n className=\"mx-0.5 hidden h-4 w-px bg-foreground/[0.1] sm:block\"\n aria-hidden\n />\n </>\n )}\n <div className=\"relative shrink-0\" ref={columnPopover.ref}>\n <ToolbarButton\n onClick={() => columnPopover.setOpen(!columnPopover.open)}\n active={columnPopover.open}\n title={strings.columns}\n >\n <Eye className=\"h-3.5 w-3.5\" />\n </ToolbarButton>\n {columnPopover.open && (\n <PopoverPanel popoverRef={columnPopover.ref} className=\"right-0 left-auto\">\n <ColumnManager\n columns={columns}\n visibility={state.columnVisibility}\n onChange={updateVisibility}\n strings={strings}\n dateDisplay={state.dateDisplay}\n onDateDisplayChange={updateDateDisplay}\n hasDateColumns={hasDateColumns}\n />\n </PopoverPanel>\n )}\n </div>\n\n <ToolbarButton onClick={exportCsv} title={strings.export}>\n <DownloadSimple className=\"h-3.5 w-3.5\" />\n </ToolbarButton>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { n as isDataGridInteractiveRowClickTarget, t as DataGrid } from "../../data-grid-AJi1TNDa.js";
1
+ import { n as isDataGridInteractiveRowClickTarget, t as DataGrid } from "../../data-grid-DWHAjaNo.js";
2
2
  export { DataGrid, isDataGridInteractiveRowClickTarget };
@@ -17,6 +17,7 @@ let __data_grid_export_dialog_js = require("./data-grid-export-dialog.js");
17
17
  let __data_grid_toolbar_js = require("./data-grid-toolbar.js");
18
18
  //#region src/components/data-grid/data-grid.tsx
19
19
  const DEFAULT_INFINITE_MAX_HEIGHT = "calc(100dvh - 16rem)";
20
+ const DATA_GRID_SCROLLBAR_CLASS_NAME = (0, _hexclave_ui.cn)("[&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar]:h-1.5", "[&::-webkit-scrollbar-track]:bg-transparent", "[&::-webkit-scrollbar-thumb]:bg-foreground/[0.08] [&::-webkit-scrollbar-thumb]:rounded-full", "[&::-webkit-scrollbar-thumb]:hover:bg-foreground/[0.15]");
20
21
  function getEventTargetElement(target) {
21
22
  if (target instanceof Element) return target;
22
23
  if (target instanceof Node) return target.parentElement;
@@ -250,6 +251,20 @@ function hashStringToInt(value) {
250
251
  for (let i = 0; i < value.length; i++) hash = (hash << 5) - hash + value.charCodeAt(i) | 0;
251
252
  return Math.abs(hash);
252
253
  }
254
+ /**
255
+ * Column flex fractions used when the grid is loading before any schema is
256
+ * known (e.g. QueryDataGrid discovers columns from the first result page).
257
+ * Without these, `SkeletonRow` would render zero cells and the body looks
258
+ * like an empty black void instead of a shimmer.
259
+ */
260
+ const SCHEMA_PENDING_COL_FRACTIONS = [
261
+ .18,
262
+ .16,
263
+ .34,
264
+ .2,
265
+ .12
266
+ ];
267
+ const SCHEMA_PENDING_SKELETON_ROWS = 10;
253
268
  function SkeletonRow({ columns, height, showCheckbox }) {
254
269
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
255
270
  className: "flex",
@@ -269,6 +284,46 @@ function SkeletonRow({ columns, height, showCheckbox }) {
269
284
  }, col.id))]
270
285
  });
271
286
  }
287
+ /** Sticky header shimmer when columns haven't been discovered yet. */
288
+ function SchemaPendingHeaderCells({ showCheckbox }) {
289
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [showCheckbox && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
290
+ className: "flex shrink-0 items-center justify-center border-r border-foreground/[0.04]",
291
+ style: { width: 44 }
292
+ }), SCHEMA_PENDING_COL_FRACTIONS.map((frac, colIdx) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
293
+ className: "flex items-center px-3 border-r border-black/[0.04] dark:border-white/[0.04] last:border-r-0",
294
+ style: { width: `${frac * 100}%` },
295
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___skeleton_js.DesignSkeleton, {
296
+ className: "h-3 rounded-md",
297
+ style: { width: `${45 + colIdx * 13 % 30}%` }
298
+ })
299
+ }, colIdx))] });
300
+ }
301
+ /** Full-width body shimmer when columns haven't been discovered yet. */
302
+ function SchemaPendingSkeleton({ rowHeight, showCheckbox }) {
303
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
304
+ className: "w-full",
305
+ "data-data-grid-schema-pending-skeleton": "",
306
+ role: "status",
307
+ "aria-label": "Loading",
308
+ children: Array.from({ length: SCHEMA_PENDING_SKELETON_ROWS }).map((_, rowIdx) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
309
+ className: "flex w-full border-b border-black/[0.04] dark:border-white/[0.04]",
310
+ style: { height: rowHeight },
311
+ role: "row",
312
+ children: [showCheckbox && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
313
+ className: "flex shrink-0 items-center justify-center border-r border-black/[0.04] dark:border-white/[0.04]",
314
+ style: { width: 44 },
315
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___skeleton_js.DesignSkeleton, { className: "h-4 w-4 rounded" })
316
+ }), SCHEMA_PENDING_COL_FRACTIONS.map((frac, colIdx) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
317
+ className: "flex items-center px-3 border-r border-black/[0.04] dark:border-white/[0.04] last:border-r-0",
318
+ style: { width: `${frac * 100}%` },
319
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___skeleton_js.DesignSkeleton, {
320
+ className: "h-3.5 rounded-md",
321
+ style: { width: `${50 + (rowIdx * 7 + colIdx * 19) % 40}%` }
322
+ })
323
+ }, colIdx))]
324
+ }, rowIdx))
325
+ });
326
+ }
272
327
  function SelectionCheckbox({ checked, indeterminate, onChange, ariaLabel, title }) {
273
328
  const Icon = indeterminate ? _phosphor_icons_react.MinusSquare : checked ? _phosphor_icons_react.CheckSquare : _phosphor_icons_react.Square;
274
329
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -433,7 +488,7 @@ function DefaultFooter({ ctx, pagination, onChange }) {
433
488
  * - `renderCell` must be a pure function — no React hooks inside.
434
489
  */
435
490
  function DataGrid(props) {
436
- const { columns: allColumns, rows, getRowId, totalRowCount, isLoading = false, isRefetching = false, hasMore = false, isLoadingMore = false, onLoadMore, state, onChange, paginationMode = "paginated", selectionMode = "none", resizable = true, rowHeight: rowHeightProp = 44, estimatedRowHeight: estimatedRowHeightProp, headerHeight = 44, overscan = 5, maxHeight, fillHeight = true, stickyTop, toolbar, toolbarExtra, emptyState, loadingState, footer, footerExtra, exportFilename = "export", exportOptions, strings: stringsOverride, className, onRowClick, onRowDoubleClick, onSelectionChange, onSortChange, onColumnResize, onColumnVisibilityChange } = props;
491
+ const { columns: allColumns, rows, getRowId, totalRowCount, isLoading = false, isRefetching = false, hasMore = false, isLoadingMore = false, onLoadMore, state, onChange, paginationMode = "paginated", selectionMode = "none", resizable = true, rowHeight: rowHeightProp = 44, estimatedRowHeight: estimatedRowHeightProp, headerHeight = 44, overscan = 5, maxHeight, fillHeight = true, stickyTop, horizontalScrollbarPosition = "bottom", toolbar, toolbarExtra, emptyState, loadingState, footer, footerExtra, exportFilename = "export", exportOptions, strings: stringsOverride, className, onRowClick, onRowDoubleClick, onSelectionChange, onSortChange, onColumnResize, onColumnVisibilityChange } = props;
437
492
  const isDynamicRowHeight = rowHeightProp === "auto";
438
493
  const fixedRowHeight = isDynamicRowHeight ? void 0 : rowHeightProp;
439
494
  const estimatedRowHeight = estimatedRowHeightProp ?? fixedRowHeight ?? 44;
@@ -718,11 +773,31 @@ function DataGrid(props) {
718
773
  observer.disconnect();
719
774
  };
720
775
  }, []);
721
- const handleBodyScroll = (0, react.useCallback)(() => {
776
+ const isSyncingHorizontalScrollRef = (0, react.useRef)(false);
777
+ const syncHorizontalScroll = (0, react.useCallback)((source) => {
722
778
  const body = scrollContainerRef.current;
723
779
  const header = headerScrollRef.current;
724
- if (body && header) header.scrollLeft = body.scrollLeft;
780
+ if (body == null || header == null || isSyncingHorizontalScrollRef.current) return;
781
+ const from = source === "header" ? header : body;
782
+ const to = source === "header" ? body : header;
783
+ if (to.scrollLeft === from.scrollLeft) return;
784
+ isSyncingHorizontalScrollRef.current = true;
785
+ to.scrollLeft = from.scrollLeft;
786
+ isSyncingHorizontalScrollRef.current = false;
725
787
  }, []);
788
+ const handleBodyScroll = (0, react.useCallback)(() => {
789
+ syncHorizontalScroll("body");
790
+ }, [syncHorizontalScroll]);
791
+ const handleHeaderScroll = (0, react.useCallback)(() => {
792
+ syncHorizontalScroll("header");
793
+ }, [syncHorizontalScroll]);
794
+ const horizontalScrollbarAtTop = horizontalScrollbarPosition === "top";
795
+ const handleBodyWheel = (0, react.useCallback)((event) => {
796
+ if (!horizontalScrollbarAtTop || event.deltaX === 0) return;
797
+ const header = headerScrollRef.current;
798
+ if (header == null) return;
799
+ header.scrollLeft += event.deltaX;
800
+ }, [horizontalScrollbarAtTop]);
726
801
  const toolbarCtx = (0, react.useMemo)(() => ({
727
802
  state,
728
803
  onChange,
@@ -801,15 +876,17 @@ function DataGrid(props) {
801
876
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-full w-1/3 bg-blue-500/60 rounded-full animate-pulse" })
802
877
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
803
878
  ref: headerScrollRef,
804
- className: "w-full min-w-0 shrink-0 overflow-hidden border-b border-foreground/[0.06]",
805
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
879
+ className: (0, _hexclave_ui.cn)("w-full min-w-0 shrink-0 border-b border-foreground/[0.06]", horizontalScrollbarAtTop ? (0, _hexclave_ui.cn)("overflow-x-auto overflow-y-hidden", DATA_GRID_SCROLLBAR_CLASS_NAME) : "overflow-hidden"),
880
+ onScroll: horizontalScrollbarAtTop ? handleHeaderScroll : void 0,
881
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
806
882
  className: "flex",
807
883
  style: {
808
884
  height: headerHeight,
809
- minWidth: totalContentWidth
885
+ minWidth: totalContentWidth || void 0,
886
+ width: visibleColumns.length === 0 ? "100%" : void 0
810
887
  },
811
888
  role: "row",
812
- children: [selectionMode !== "none" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
889
+ children: isLoading && visibleColumns.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SchemaPendingHeaderCells, { showCheckbox: selectionMode !== "none" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [selectionMode !== "none" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
813
890
  className: "flex items-center justify-center border-r border-foreground/[0.04]",
814
891
  style: { width: 44 },
815
892
  children: selectionMode === "multiple" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SelectionCheckbox, {
@@ -827,15 +904,16 @@ function DataGrid(props) {
827
904
  col,
828
905
  resizable
829
906
  }, col.id);
830
- })]
907
+ })] })
831
908
  })
832
909
  })]
833
910
  })]
834
911
  }),
835
912
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
836
913
  ref: scrollContainerRef,
837
- className: (0, _hexclave_ui.cn)("relative z-0 w-full min-w-0 overflow-auto bg-transparent", isBounded ? "min-h-0 flex-1" : "flex-none", "[&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar]:h-1.5", "[&::-webkit-scrollbar-track]:bg-transparent", "[&::-webkit-scrollbar-thumb]:bg-foreground/[0.08] [&::-webkit-scrollbar-thumb]:rounded-full", "[&::-webkit-scrollbar-thumb]:hover:bg-foreground/[0.15]"),
914
+ className: (0, _hexclave_ui.cn)("relative z-0 w-full min-w-0 bg-transparent", horizontalScrollbarAtTop ? "overflow-y-auto overflow-x-hidden" : "overflow-auto", isBounded ? "min-h-0 flex-1" : "flex-none", DATA_GRID_SCROLLBAR_CLASS_NAME),
838
915
  onScroll: handleBodyScroll,
916
+ onWheel: horizontalScrollbarAtTop ? handleBodyWheel : void 0,
839
917
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
840
918
  ref: rowsClipRef,
841
919
  "data-data-grid-rows-clip": "",
@@ -846,12 +924,18 @@ function DataGrid(props) {
846
924
  },
847
925
  children: [
848
926
  isLoading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
849
- style: { minWidth: totalContentWidth },
850
- children: loadingState ?? Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkeletonRow, {
927
+ style: {
928
+ minWidth: totalContentWidth || void 0,
929
+ width: visibleColumns.length === 0 ? "100%" : void 0
930
+ },
931
+ children: loadingState ?? (visibleColumns.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SchemaPendingSkeleton, {
932
+ rowHeight: estimatedRowHeight,
933
+ showCheckbox: selectionMode !== "none"
934
+ }) : Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkeletonRow, {
851
935
  columns: visibleColumns,
852
936
  height: estimatedRowHeight,
853
937
  showCheckbox: selectionMode !== "none"
854
- }, i))
938
+ }, i)))
855
939
  }),
856
940
  !isLoading && rows.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
857
941
  className: "flex items-center justify-center py-16 text-sm text-muted-foreground",