@12-apps/ui 6.13.1 → 6.13.2

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 (74) hide show
  1. package/dist/_internal/components/data-display/Carousel/Carousel.js +2 -2
  2. package/dist/_internal/components/data-display/Chart/Chart.js +3 -3
  3. package/dist/_internal/components/data-display/Chart/SpecChart.js +6 -6
  4. package/dist/_internal/components/data-display/Chart/chart-renderers.js +2 -2
  5. package/dist/_internal/components/data-display/Chart/chart-spec.js +2 -2
  6. package/dist/_internal/components/data-display/DataGrid/DataGrid.js +1 -1
  7. package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +13 -12
  8. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +18 -17
  9. package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +3 -3
  10. package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +1 -1
  11. package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +9 -9
  12. package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +5 -5
  13. package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +3 -3
  14. package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +4 -4
  15. package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +2 -2
  16. package/dist/_internal/components/data-display/DataViews/data-views-selection.js +1 -1
  17. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +2 -2
  18. package/dist/_internal/components/data-display/DataViews/data-views-writers.js +9 -0
  19. package/dist/_internal/components/data-display/DataViews/data-views-writers.js.map +1 -0
  20. package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +3 -2
  21. package/dist/_internal/components/data-display/index.js +14 -14
  22. package/dist/_internal/components/index.js +14 -14
  23. package/dist/charts.js +11 -11
  24. package/dist/{chunk-BV5XTGKB.js → chunk-2UCJJACD.js} +7 -9
  25. package/dist/chunk-2UCJJACD.js.map +1 -0
  26. package/dist/{chunk-IN642YHK.js → chunk-4VNUOSTQ.js} +2 -2
  27. package/dist/{chunk-XPS7FWZS.js → chunk-4ZEU22L2.js} +4 -4
  28. package/dist/{chunk-NC2AATCC.js → chunk-6PFBYCBU.js} +2 -2
  29. package/dist/{chunk-CXA6UNFF.js → chunk-AP3PVR3T.js} +5 -5
  30. package/dist/{chunk-XULTDO56.js → chunk-BVGR7OYA.js} +4 -4
  31. package/dist/{chunk-JKLWHENB.js → chunk-HNDUCGM3.js} +3 -3
  32. package/dist/{chunk-NPEKJXVV.js → chunk-HRJ27X5B.js} +4 -4
  33. package/dist/chunk-LLZWB32X.js +36 -0
  34. package/dist/chunk-LLZWB32X.js.map +1 -0
  35. package/dist/{chunk-ZHPKFV7Y.js → chunk-N6JGYVRY.js} +2 -2
  36. package/dist/{chunk-JPDKRGYI.js → chunk-PDGAFQ6Z.js} +3 -3
  37. package/dist/{chunk-T4BFDZGU.js → chunk-Q4ITS2EP.js} +6 -6
  38. package/dist/{chunk-GOWBYHYW.js → chunk-R6SBP5M5.js} +4 -4
  39. package/dist/{chunk-DEOC5OI7.js → chunk-RRYQG5Y6.js} +3 -3
  40. package/dist/{chunk-WLCVOQCJ.js → chunk-RUO4D4N6.js} +3 -3
  41. package/dist/chunk-U5FOJBLG.js +19 -0
  42. package/dist/chunk-U5FOJBLG.js.map +1 -0
  43. package/dist/{chunk-BZTFPSWT.js → chunk-XEE7PLDR.js} +4 -4
  44. package/dist/data-display/CardKit.js +3 -3
  45. package/dist/data-display/Carousel.js +2 -2
  46. package/dist/data-display/Chart.js +11 -11
  47. package/dist/data-display/DataGrid.js +1 -1
  48. package/dist/data-display/DataViews.js +19 -18
  49. package/dist/types/components/data-display/DataViews/data-views-selection.d.ts +31 -2
  50. package/dist/types/components/data-display/DataViews/data-views-selection.d.ts.map +1 -1
  51. package/dist/types/components/data-display/DataViews/data-views-writers.d.ts +20 -0
  52. package/dist/types/components/data-display/DataViews/data-views-writers.d.ts.map +1 -0
  53. package/dist/types/components/data-display/DataViews/use-data-views-state.d.ts.map +1 -1
  54. package/package.json +1 -1
  55. package/src/components/data-display/DataViews/data-views-selection.ts +61 -6
  56. package/src/components/data-display/DataViews/data-views-writers.ts +45 -0
  57. package/src/components/data-display/DataViews/use-data-views-state.ts +4 -11
  58. package/dist/chunk-BV5XTGKB.js.map +0 -1
  59. package/dist/chunk-WTOTWP6A.js +0 -27
  60. package/dist/chunk-WTOTWP6A.js.map +0 -1
  61. /package/dist/{chunk-IN642YHK.js.map → chunk-4VNUOSTQ.js.map} +0 -0
  62. /package/dist/{chunk-XPS7FWZS.js.map → chunk-4ZEU22L2.js.map} +0 -0
  63. /package/dist/{chunk-NC2AATCC.js.map → chunk-6PFBYCBU.js.map} +0 -0
  64. /package/dist/{chunk-CXA6UNFF.js.map → chunk-AP3PVR3T.js.map} +0 -0
  65. /package/dist/{chunk-XULTDO56.js.map → chunk-BVGR7OYA.js.map} +0 -0
  66. /package/dist/{chunk-JKLWHENB.js.map → chunk-HNDUCGM3.js.map} +0 -0
  67. /package/dist/{chunk-NPEKJXVV.js.map → chunk-HRJ27X5B.js.map} +0 -0
  68. /package/dist/{chunk-ZHPKFV7Y.js.map → chunk-N6JGYVRY.js.map} +0 -0
  69. /package/dist/{chunk-JPDKRGYI.js.map → chunk-PDGAFQ6Z.js.map} +0 -0
  70. /package/dist/{chunk-T4BFDZGU.js.map → chunk-Q4ITS2EP.js.map} +0 -0
  71. /package/dist/{chunk-GOWBYHYW.js.map → chunk-R6SBP5M5.js.map} +0 -0
  72. /package/dist/{chunk-DEOC5OI7.js.map → chunk-RRYQG5Y6.js.map} +0 -0
  73. /package/dist/{chunk-WLCVOQCJ.js.map → chunk-RUO4D4N6.js.map} +0 -0
  74. /package/dist/{chunk-BZTFPSWT.js.map → chunk-XEE7PLDR.js.map} +0 -0
@@ -11,11 +11,14 @@ import {
11
11
  } from "./chunk-IMLIIW77.js";
12
12
  import {
13
13
  useSelection
14
- } from "./chunk-WTOTWP6A.js";
14
+ } from "./chunk-LLZWB32X.js";
15
15
  import {
16
16
  resolveScope,
17
17
  useScopeConfigChecks
18
18
  } from "./chunk-LYKV3C7B.js";
19
+ import {
20
+ useStateWriters
21
+ } from "./chunk-U5FOJBLG.js";
19
22
  import {
20
23
  computeActiveFilterCount,
21
24
  defaultSortFields
@@ -38,10 +41,6 @@ function useMatchedRows(server, rows, columns, fields, rangeFields, state) {
38
41
  [server, rows, columns, fields, rangeFields, state.search, state.pills, state.ranges]
39
42
  );
40
43
  }
41
- function nextVisibleColumns(current, id, visible) {
42
- const without = current.filter((colId) => colId !== id);
43
- return visible ? [...without, id] : without;
44
- }
45
44
  function useStateSyncEffects(appliedState, syncState, state, onStateChange, setState) {
46
45
  const firstApplied = useRef(true);
47
46
  useEffect(() => {
@@ -132,7 +131,7 @@ function useDataViewsState({
132
131
  );
133
132
  const [filterOpen, setFilterOpen] = useState(false);
134
133
  useStateSyncEffects(appliedState, syncState, state, onStateChange, setState);
135
- const patch = (next) => setState((prev) => ({ ...prev, ...typeof next === "function" ? next(prev) : next }));
134
+ const { patch, toggleColumn } = useStateWriters(setState);
136
135
  const matched = useMatchedRows(server, rows, columns, fields, rangeFields, state);
137
136
  const scope = resolveScope(scopes, state.scope);
138
137
  const { changePage } = useServerQuery(server, state, scope);
@@ -142,8 +141,7 @@ function useDataViewsState({
142
141
  onRowClick,
143
142
  state.order
144
143
  );
145
- const toggleColumn = (id, visible) => setState((prev) => ({ ...prev, visibleColumns: nextVisibleColumns(prev.visibleColumns, id, visible) }));
146
- const selection = useSelection(matched, getRowId);
144
+ const selection = useSelection(matched, getRowId, { rememberOffPage: Boolean(server) });
147
145
  const resolvedSortFields = sortFields ?? defaultSortFields(columns);
148
146
  return {
149
147
  state,
@@ -174,4 +172,4 @@ function useDataViewsState({
174
172
  export {
175
173
  useDataViewsState
176
174
  };
177
- //# sourceMappingURL=chunk-BV5XTGKB.js.map
175
+ //# sourceMappingURL=chunk-2UCJJACD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/DataViews/use-data-views-state.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { type GridColumn } from \"../DataGrid\";\nimport { type SortFieldDefinition } from \"../../layout/ContentToolbar\";\n\nimport { filterRows } from \"./data-views-filter\";\nimport {\n useColumnsWithActions,\n useRenderedColumns,\n type HideableColumn,\n} from \"./data-views-columns\";\nimport { computeActiveFilterCount, defaultSortFields } from \"./data-views-grid-helpers\";\nimport { resolveScope, useScopeConfigChecks, type ScopeConfig } from \"./data-views-scopes\";\nimport { serverDerived, useServerQuery } from \"./data-views-server-query\";\nimport { useSelection } from \"./data-views-selection\";\nimport { useStateWriters } from \"./data-views-writers\";\nimport {\n emptyViewState,\n type DataViewColumn,\n type DataViewServer,\n type DataViewState,\n type DataViewStatePatch,\n type DataViewSyncState,\n type FilterFieldConfig,\n type RangeFieldConfig,\n type DataViewQuery,\n type RangeValue,\n type RowAction,\n} from \"./data-views-types\";\n\nexport type { HideableColumn };\n\n/** Inputs the hook needs to own the view state + derived data. */\ninterface UseDataViewsStateArgs<T extends Record<string, unknown>> {\n rows: T[];\n columns: DataViewColumn<T>[];\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n getRowId: (row: T) => string | number;\n onRowClick?: (row: T) => void;\n appliedState?: DataViewState;\n /**\n * URL-driven controls (search/pills/ranges/sort) that re-apply on reference\n * change while preserving column visibility — see {@link DataViewSyncState}.\n */\n syncState?: DataViewSyncState;\n onStateChange?: (state: DataViewState) => void;\n testIdPrefix: string;\n sortFields?: SortFieldDefinition[];\n rowActions?: RowAction<T>[];\n rowActionsLeading?: (row: T) => React.ReactNode;\n /** Bespoke per-row menu rendered in the actions column instead of the auto kebab. */\n renderRowMenu?: (row: T) => React.ReactNode;\n /**\n * When present, the table is BACKEND-driven: `rows` is already the current\n * page (no in-browser filter/sort/paginate), and query changes re-fetch via\n * `server.onQueryChange`. Omit for the legacy client-side behaviour.\n */\n server?: DataViewServer;\n /**\n * The page-level partition rendered as tabs under the toolbar. Requires server\n * mode: a scope is applied at the BACKEND, never in the browser.\n */\n scopes?: ScopeConfig[];\n /**\n * The row field the scopes partition by, when the host knows it — used only to\n * reject the pill/scope clash at setup. See `assertNoScopePillOverlap`.\n */\n scopeFieldId?: string;\n}\n\n/** Everything the DataViewsGrid render needs; keeps the component itself thin. */\nexport interface DataViewsController<T extends Record<string, unknown>> {\n state: DataViewState;\n ranges: Record<string, RangeValue>;\n /**\n * Merge a partial into the view state.\n *\n * The UPDATER form is the one to reach for when the patch is derived from\n * state you are also changing — successive calls within one tick each see the\n * previous call's result, where the object form would have every caller build\n * its patch from the same render-scoped snapshot and the last write would win.\n */\n patch: (next: DataViewStatePatch) => void;\n matched: T[];\n gridColumns: GridColumn<T>[];\n /** Columns eligible for the show/hide menu (hideable, with a text header). */\n hideableColumns: HideableColumn[];\n /** Every column id in reading order — what the Colunas tab reorders. */\n columnOrder: string[];\n /** Toggle one column's visibility in the current view state. */\n toggleColumn: (id: string, visible: boolean) => void;\n selectedIds: Set<string | number>;\n setSelectedIds: (ids: Set<string | number>) => void;\n /**\n * Add/remove ONE id from the selection. The card and board bodies both need\n * it, so it lives here rather than being written out twice at the call sites —\n * one selection model, one toggle, identical in every layout.\n */\n toggleId: (id: string | number) => void;\n selectedRows: T[];\n clearSelection: () => void;\n selectAll: () => void;\n filterOpen: boolean;\n setFilterOpen: (open: boolean) => void;\n resolvedSortFields: SortFieldDefinition[];\n activeSortField: string;\n activeSortOrder: \"asc\" | \"desc\";\n activeFilterCount: number;\n /** True when the table is backend-driven (server mode). */\n serverMode: boolean;\n /** Server-mode pagination: 1-based current page (1 when client mode). */\n serverPage: number;\n /** Server-mode pagination: total pages (1 when client mode). */\n serverPageCount: number;\n /** Server-mode: total matched rows across all pages (drives the counter). */\n serverTotalCount: number;\n /** Server-mode: request a specific 1-based page (re-fetches via onQueryChange). */\n changePage: (page: number) => void;\n /**\n * The active scope id, RESOLVED against the declared scopes (see\n * `resolveScope`). `undefined` when the table declares none — which is what\n * keeps `scope` out of the emitted query for every table that never opted in.\n */\n scope: string | undefined;\n /** Select a scope: re-fetches from page 1 and drops the selection. */\n setScope: (id: string) => void;\n /**\n * The query the grid is currently showing. Read by Export, which hands it\n * back to the host UNPAGINATED — so an export follows the filters rather\n * than the 25 rows that happen to be loaded.\n */\n currentQuery: DataViewQuery;\n /**\n * Server-supplied per-scope totals, passed through verbatim, or `undefined`\n * when the server omits them. NEVER falls back to counting `matched`: a count\n * off the loaded page is wrong under pagination, which is the bug scopes fix.\n */\n scopeCounts?: Record<string, number>;\n}\n\n/**\n * The rows to render: in server mode `rows` is already the current page (the\n * backend filtered/sorted/paginated), so it passes through untouched; otherwise\n * the client search/pill/range filter narrows it.\n */\nfunction useMatchedRows<T extends Record<string, unknown>>(\n server: DataViewServer | undefined,\n rows: T[],\n columns: DataViewColumn<T>[],\n fields: FilterFieldConfig<T>[],\n rangeFields: RangeFieldConfig<T>[],\n state: DataViewState,\n): T[] {\n return useMemo(\n () =>\n server\n ? rows\n : filterRows(\n rows,\n columns,\n fields,\n { search: state.search, pills: state.pills, ranges: state.ranges },\n rangeFields,\n ),\n [server, rows, columns, fields, rangeFields, state.search, state.pills, state.ranges],\n );\n}\n\n/**\n * Reconcile external state changes and surface every change to the caller:\n * - `appliedState` (a saved view) fully REPLACES the state — it is columns-\n * authoritative, so applying a view restores its filters, sort AND columns.\n * - `syncState` (URL-driven controls) MERGES over the current state, leaving\n * `visibleColumns` untouched — so browser back/forward or a same-route\n * deep-link re-applies search/pills/sort without wiping a user's hidden columns.\n * Each channel only fires when its own reference changes (after the first run).\n */\nfunction useStateSyncEffects(\n appliedState: DataViewState | undefined,\n syncState: DataViewSyncState | undefined,\n state: DataViewState,\n onStateChange: ((state: DataViewState) => void) | undefined,\n setState: React.Dispatch<React.SetStateAction<DataViewState>>,\n): void {\n const firstApplied = useRef(true);\n useEffect(() => {\n if (firstApplied.current) {\n firstApplied.current = false;\n return;\n }\n if (appliedState) setState(appliedState);\n // `setState` is a stable useState setter (passed in), included to satisfy\n // exhaustive-deps; the effect still only re-applies when `appliedState` changes.\n }, [appliedState, setState]);\n const firstSync = useRef(true);\n useEffect(() => {\n if (firstSync.current) {\n firstSync.current = false;\n return;\n }\n // Merge — keep the current `visibleColumns` (never URL-carried); only the\n // URL-driven controls change.\n if (syncState) setState((prev) => ({ ...prev, ...syncState }));\n }, [syncState, setState]);\n useEffect(() => {\n onStateChange?.(state);\n }, [state, onStateChange]);\n}\n\n/**\n * The seed view state: a saved view (`appliedState`) or a pristine all-columns\n * one, with the URL-driven controls (`syncState`) merged over it so a deep-linked\n * filter or scope is reflected on the FIRST render. Column visibility is never\n * URL-carried, so the merge cannot wipe it.\n */\nfunction seedState(\n appliedState: DataViewState | undefined,\n syncState: DataViewSyncState | undefined,\n allColumnIds: string[],\n): DataViewState {\n const seed = appliedState ?? emptyViewState(allColumnIds);\n return syncState ? { ...seed, ...syncState } : seed;\n}\n\n/**\n * Selecting a scope: record it, then DROP the selection.\n *\n * A scope change renders a different result set. A selection that survived it\n * would let a bulk action run against rows the user can no longer see — the\n * same reason changing any other part of the query clears it.\n */\nfunction makeSetScope(\n patch: (next: DataViewStatePatch) => void,\n clearSelection: () => void,\n): (id: string) => void {\n return (id) => {\n patch({ scope: id });\n clearSelection();\n };\n}\n\n/**\n * The declared column ids in the stored reading order — the same tolerance\n * `applyOrder` uses, so the Colunas tab lists exactly what the grid renders.\n */\nfunction orderedColumnIds(allColumnIds: string[], order: string[] | undefined): string[] {\n if (!order || order.length === 0) return allColumnIds;\n const declared = new Set(allColumnIds);\n const kept = order.filter((id) => declared.has(id));\n const seen = new Set(kept);\n return [...kept, ...allColumnIds.filter((id) => !seen.has(id))];\n}\n\n/**\n * The query the grid is currently SHOWING — the same shape `onQueryChange`\n * emits, kept as a value so a host control (Exportar) can re-run it against the\n * backend rather than reading the loaded rows.\n */\nfunction liveQuery(\n state: DataViewState,\n scope: string | undefined,\n server: DataViewServer | undefined,\n matchedCount: number,\n): DataViewQuery {\n return {\n search: state.search,\n pills: state.pills,\n ranges: state.ranges ?? {},\n sortBy: state.sortBy,\n // Absent, not undefined, when the table declares no scopes.\n ...(scope !== undefined ? { scope } : {}),\n page: server?.page ?? 1,\n // Client mode has one page, and it is everything that matched.\n pageSize: server?.pageSize ?? matchedCount,\n };\n}\n\n/** The toolbar's active sort, read off the state's FIRST sort entry. */\nfunction activeSortOf(\n state: DataViewState,\n resolvedSortFields: SortFieldDefinition[],\n): { activeSortField: string; activeSortOrder: \"asc\" | \"desc\" } {\n const active = state.sortBy?.[0];\n return {\n activeSortField: active?.id ?? resolvedSortFields[0]?.value ?? \"\",\n activeSortOrder: active?.dir === \"desc\" ? \"desc\" : \"asc\",\n };\n}\n\n/**\n * Owns the DataViews view state (search/pills/ranges/sort/visibleColumns),\n * multi-select, the filter-panel toggle, and every derived value (filtered rows,\n * grid columns, active sort/filter counts). Extracted from the component so the\n * render stays within the size/complexity budget.\n */\nexport function useDataViewsState<T extends Record<string, unknown>>({\n rows,\n columns,\n fields,\n rangeFields,\n getRowId,\n onRowClick,\n appliedState,\n syncState,\n onStateChange,\n testIdPrefix,\n sortFields,\n rowActions,\n rowActionsLeading,\n renderRowMenu,\n server,\n scopes = [],\n scopeFieldId,\n}: UseDataViewsStateArgs<T>): DataViewsController<T> {\n useScopeConfigChecks(scopes, fields.map((field) => field.id), scopeFieldId, server !== undefined);\n const { columnsWithActions, allColumnIds } = useColumnsWithActions(columns, {\n rowActions,\n rowActionsLeading,\n renderRowMenu,\n testIdPrefix,\n getRowId,\n });\n // Seed once — see {@link seedState}.\n const [state, setState] = useState<DataViewState>(() =>\n seedState(appliedState, syncState, allColumnIds),\n );\n const [filterOpen, setFilterOpen] = useState(false);\n\n useStateSyncEffects(appliedState, syncState, state, onStateChange, setState);\n\n const { patch, toggleColumn } = useStateWriters(setState);\n const matched = useMatchedRows(server, rows, columns, fields, rangeFields, state);\n // Resolved at READ time, every render: a stale deep link or a saved view naming\n // a scope that has since been removed falls back to the first declared scope\n // instead of putting an id the backend rejects on the wire.\n const scope = resolveScope(scopes, state.scope);\n // Server mode: re-fetch on query change (page resets to 1) + drive pagination.\n const { changePage } = useServerQuery(server, state, scope);\n const { gridColumns, hideableColumns } = useRenderedColumns(\n columnsWithActions,\n state.visibleColumns,\n onRowClick,\n state.order,\n );\n // Server mode is where `matched` is a PAGE — see `useSelection` (FUT-942).\n const selection = useSelection(matched, getRowId, { rememberOffPage: Boolean(server) });\n const resolvedSortFields = sortFields ?? defaultSortFields(columns);\n\n return {\n state,\n ranges: state.ranges ?? {},\n patch,\n matched,\n gridColumns,\n hideableColumns,\n columnOrder: orderedColumnIds(allColumnIds, state.order),\n toggleColumn,\n ...selection,\n filterOpen,\n setFilterOpen,\n resolvedSortFields,\n ...activeSortOf(state, resolvedSortFields),\n activeFilterCount: computeActiveFilterCount(state, fields, rangeFields),\n ...serverDerived(server, matched.length),\n changePage,\n scope,\n setScope: makeSetScope(patch, selection.clearSelection),\n currentQuery: liveQuery(state, scope, server, matched.length),\n // Verbatim, or absent. See DataViewServer.scopeCounts for why there is no\n // client-side fallback.\n scopeCounts: server?.scopeCounts,\n };\n}\n"],"mappings":"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","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-ECIGNYSI.js";
4
4
  import {
5
5
  PanelRangeField
6
- } from "./chunk-BZTFPSWT.js";
6
+ } from "./chunk-XEE7PLDR.js";
7
7
  import {
8
8
  useDataViewsCopy
9
9
  } from "./chunk-KHG57NAE.js";
@@ -154,4 +154,4 @@ export {
154
154
  GridFilterPanel,
155
155
  FilterDialog
156
156
  };
157
- //# sourceMappingURL=chunk-IN642YHK.js.map
157
+ //# sourceMappingURL=chunk-4VNUOSTQ.js.map
@@ -1,9 +1,9 @@
1
- import {
2
- SaveViewModal
3
- } from "./chunk-U7SO3N42.js";
4
1
  import {
5
2
  ManageViewsDialog
6
3
  } from "./chunk-UHXNEXOC.js";
4
+ import {
5
+ SaveViewModal
6
+ } from "./chunk-U7SO3N42.js";
7
7
  import {
8
8
  useDataViewsCopy
9
9
  } from "./chunk-KHG57NAE.js";
@@ -121,4 +121,4 @@ export {
121
121
  ViewsMenuSlot,
122
122
  ViewDialogs
123
123
  };
124
- //# sourceMappingURL=chunk-XPS7FWZS.js.map
124
+ //# sourceMappingURL=chunk-4ZEU22L2.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RangeBounds
3
- } from "./chunk-BZTFPSWT.js";
3
+ } from "./chunk-XEE7PLDR.js";
4
4
  import {
5
5
  isRangeSet
6
6
  } from "./chunk-GCZJH4XL.js";
@@ -188,4 +188,4 @@ export {
188
188
  fieldClearing,
189
189
  MoreGroup
190
190
  };
191
- //# sourceMappingURL=chunk-NC2AATCC.js.map
191
+ //# sourceMappingURL=chunk-6PFBYCBU.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  renderChartByType
3
- } from "./chunk-XULTDO56.js";
3
+ } from "./chunk-BVGR7OYA.js";
4
+ import {
5
+ ChartContainer
6
+ } from "./chunk-M5T3COS2.js";
4
7
  import {
5
8
  getSizeStyles,
6
9
  getVariantStyles
7
10
  } from "./chunk-AVU6KU27.js";
8
- import {
9
- ChartContainer
10
- } from "./chunk-M5T3COS2.js";
11
11
  import {
12
12
  muiColor
13
13
  } from "./chunk-I6PZVHIT.js";
@@ -104,4 +104,4 @@ var Chart = (props) => {
104
104
  export {
105
105
  Chart
106
106
  };
107
- //# sourceMappingURL=chunk-CXA6UNFF.js.map
107
+ //# sourceMappingURL=chunk-AP3PVR3T.js.map
@@ -1,10 +1,10 @@
1
- import {
2
- buildChartContext
3
- } from "./chunk-XSKVBGCZ.js";
4
1
  import {
5
2
  ChartLegendContent,
6
3
  ChartTooltipContent
7
4
  } from "./chunk-M5T3COS2.js";
5
+ import {
6
+ buildChartContext
7
+ } from "./chunk-XSKVBGCZ.js";
8
8
 
9
9
  // src/components/data-display/Chart/chart-renderers.tsx
10
10
  import {
@@ -312,4 +312,4 @@ function renderChartByType(props, theme) {
312
312
  export {
313
313
  renderChartByType
314
314
  };
315
- //# sourceMappingURL=chunk-XULTDO56.js.map
315
+ //# sourceMappingURL=chunk-BVGR7OYA.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  GridShell
3
- } from "./chunk-T4BFDZGU.js";
3
+ } from "./chunk-Q4ITS2EP.js";
4
4
  import {
5
5
  useDataViewsState
6
- } from "./chunk-BV5XTGKB.js";
6
+ } from "./chunk-2UCJJACD.js";
7
7
 
8
8
  // src/components/data-display/DataViews/DataViewsGrid.tsx
9
9
  import { useEffect, useRef } from "react";
@@ -27,4 +27,4 @@ function DataViewsGrid(props) {
27
27
  export {
28
28
  DataViewsGrid
29
29
  };
30
- //# sourceMappingURL=chunk-JKLWHENB.js.map
30
+ //# sourceMappingURL=chunk-HNDUCGM3.js.map
@@ -1,3 +1,6 @@
1
+ import {
2
+ useCarouselNavigation
3
+ } from "./chunk-RUIV5TVA.js";
1
4
  import {
2
5
  CarouselChrome
3
6
  } from "./chunk-5QXSPLWU.js";
@@ -7,9 +10,6 @@ import {
7
10
  import {
8
11
  CarouselTrack
9
12
  } from "./chunk-WIXUMFU7.js";
10
- import {
11
- useCarouselNavigation
12
- } from "./chunk-RUIV5TVA.js";
13
13
  import {
14
14
  withDefaults
15
15
  } from "./chunk-HPK33ACY.js";
@@ -152,4 +152,4 @@ var Carousel = (props) => {
152
152
  export {
153
153
  Carousel
154
154
  };
155
- //# sourceMappingURL=chunk-NPEKJXVV.js.map
155
+ //# sourceMappingURL=chunk-HRJ27X5B.js.map
@@ -0,0 +1,36 @@
1
+ // src/components/data-display/DataViews/data-views-selection.ts
2
+ import { useMemo, useRef, useState } from "react";
3
+ function useSelection(matched, getRowId, options = {}) {
4
+ const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
5
+ const remembered = useRef(/* @__PURE__ */ new Map());
6
+ const selectedRows = useMemo(() => {
7
+ const onPage = matched.filter((row) => selectedIds.has(getRowId(row)));
8
+ if (!options.rememberOffPage) return onPage;
9
+ const cache = remembered.current;
10
+ for (const row of onPage) cache.set(getRowId(row), row);
11
+ for (const id of cache.keys()) if (!selectedIds.has(id)) cache.delete(id);
12
+ const onPageIds = new Set(onPage.map(getRowId));
13
+ const offPage = [...cache.entries()].flatMap(
14
+ ([id, row]) => onPageIds.has(id) ? [] : [row]
15
+ );
16
+ return [...onPage, ...offPage];
17
+ }, [matched, selectedIds, getRowId, options.rememberOffPage]);
18
+ return {
19
+ selectedIds,
20
+ setSelectedIds,
21
+ toggleId: (id) => setSelectedIds((prev) => {
22
+ const next = new Set(prev);
23
+ if (next.has(id)) next.delete(id);
24
+ else next.add(id);
25
+ return next;
26
+ }),
27
+ selectedRows,
28
+ clearSelection: () => setSelectedIds(/* @__PURE__ */ new Set()),
29
+ selectAll: () => setSelectedIds(new Set(matched.map((row) => getRowId(row))))
30
+ };
31
+ }
32
+
33
+ export {
34
+ useSelection
35
+ };
36
+ //# sourceMappingURL=chunk-LLZWB32X.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/DataViews/data-views-selection.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useRef, useState } from \"react\";\n\n/** The multi-select model, identical in every layout (table, cards, board). */\ninterface DataViewsSelection<T> {\n selectedIds: Set<string | number>;\n setSelectedIds: (ids: Set<string | number>) => void;\n /** Add/remove ONE id — what a card's or board card's checkbox calls. */\n toggleId: (id: string | number) => void;\n /** The selected rows, INCLUDING ones the current page no longer renders. */\n selectedRows: T[];\n clearSelection: () => void;\n selectAll: () => void;\n}\n\n/**\n * Owns the DataViews selection. ONE set of ids across every layout, so switching\n * from the board to the table (or to the cards) keeps exactly the same rows\n * selected and offers exactly the same bulk actions.\n *\n * Extracted from {@link useDataViewsState} for that hook's size budget, and\n * because `toggleId` needs a functional update: two cards toggled in the same\n * tick would otherwise both read the pre-render set and the second would drop\n * the first's change.\n *\n * ## A selection has to survive PAGING\n *\n * `selectedIds` always did — nothing clears it when the page changes — but\n * `selectedRows` was `matched.filter(...)`, and in SERVER mode `matched` is one\n * page. So ticking three rows, paging, and ticking two more left the checkboxes\n * claiming five and the bulk action receiving two, silently, with the other\n * three still ticked on a page nobody was looking at.\n *\n * That is the worst shape a bug can have here: the UI and the write disagree,\n * neither says so, and the rows that did not move are exactly the ones out of\n * sight. So a row is REMEMBERED for as long as its id is selected, and\n * `selectedRows` answers from that memory for anything the current page does\n * not hold.\n *\n * **Server mode only** ({@link SelectionOptions.rememberOffPage}), and the\n * distinction is not a hedge. In client mode `matched` is the whole filtered\n * result, so nothing is ever off-page and there is nothing to remember — while\n * narrowing the selection as the FILTER narrows is the behaviour a client-mode\n * grid should keep. Remembering there would mean a bulk action reaching rows\n * the operator has just filtered away.\n */\nexport interface SelectionOptions {\n /**\n * Keep rows the current page no longer renders.\n *\n * True in server mode, where `matched` is a page rather than the result.\n */\n rememberOffPage?: boolean;\n}\n\nexport function useSelection<T>(\n matched: T[],\n getRowId: (row: T) => string | number,\n options: SelectionOptions = {},\n): DataViewsSelection<T> {\n const [selectedIds, setSelectedIds] = useState<Set<string | number>>(new Set());\n // Rows seen while selected, so a selection outlives the page that made it.\n // A ref rather than state: it is a CACHE derived from what has been rendered,\n // and holding it in state would re-render on every page load to store rows\n // nothing is waiting for.\n const remembered = useRef(new Map<string | number, T>());\n\n const selectedRows = useMemo(() => {\n const onPage = matched.filter((row) => selectedIds.has(getRowId(row)));\n if (!options.rememberOffPage) return onPage;\n\n const cache = remembered.current;\n // Refresh from what is on screen NOW: a row edited elsewhere and re-fetched\n // must not be acted on through a stale snapshot from three pages ago.\n for (const row of onPage) cache.set(getRowId(row), row);\n // …and forget anything no longer selected, so the map cannot outgrow the\n // selection it exists to describe.\n for (const id of cache.keys()) if (!selectedIds.has(id)) cache.delete(id);\n\n // On-page rows first, in the page's own order — unchanged from before this\n // — then the remembered tail. Appending rather than interleaving keeps the\n // familiar case byte-identical and makes the addition exactly the addition.\n const onPageIds = new Set(onPage.map(getRowId));\n const offPage = [...cache.entries()].flatMap(([id, row]) =>\n onPageIds.has(id) ? [] : [row],\n );\n return [...onPage, ...offPage];\n }, [matched, selectedIds, getRowId, options.rememberOffPage]);\n\n return {\n selectedIds,\n setSelectedIds,\n toggleId: (id) =>\n setSelectedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n }),\n selectedRows,\n clearSelection: () => setSelectedIds(new Set()),\n selectAll: () => setSelectedIds(new Set(matched.map((row) => getRowId(row)))),\n };\n}\n"],"mappings":";AAEA,SAAS,SAAS,QAAQ,gBAAgB;AAsDnC,SAAS,aACd,SACA,UACA,UAA4B,CAAC,GACN;AACvB,QAAM,CAAC,aAAa,cAAc,IAAI,SAA+B,oBAAI,IAAI,CAAC;AAK9E,QAAM,aAAa,OAAO,oBAAI,IAAwB,CAAC;AAEvD,QAAM,eAAe,QAAQ,MAAM;AACjC,UAAM,SAAS,QAAQ,OAAO,CAAC,QAAQ,YAAY,IAAI,SAAS,GAAG,CAAC,CAAC;AACrE,QAAI,CAAC,QAAQ,gBAAiB,QAAO;AAErC,UAAM,QAAQ,WAAW;AAGzB,eAAW,OAAO,OAAQ,OAAM,IAAI,SAAS,GAAG,GAAG,GAAG;AAGtD,eAAW,MAAM,MAAM,KAAK,EAAG,KAAI,CAAC,YAAY,IAAI,EAAE,EAAG,OAAM,OAAO,EAAE;AAKxE,UAAM,YAAY,IAAI,IAAI,OAAO,IAAI,QAAQ,CAAC;AAC9C,UAAM,UAAU,CAAC,GAAG,MAAM,QAAQ,CAAC,EAAE;AAAA,MAAQ,CAAC,CAAC,IAAI,GAAG,MACpD,UAAU,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG;AAAA,IAC/B;AACA,WAAO,CAAC,GAAG,QAAQ,GAAG,OAAO;AAAA,EAC/B,GAAG,CAAC,SAAS,aAAa,UAAU,QAAQ,eAAe,CAAC;AAE5D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,CAAC,OACT,eAAe,CAAC,SAAS;AACvB,YAAM,OAAO,IAAI,IAAI,IAAI;AACzB,UAAI,KAAK,IAAI,EAAE,EAAG,MAAK,OAAO,EAAE;AAAA,UAC3B,MAAK,IAAI,EAAE;AAChB,aAAO;AAAA,IACT,CAAC;AAAA,IACH;AAAA,IACA,gBAAgB,MAAM,eAAe,oBAAI,IAAI,CAAC;AAAA,IAC9C,WAAW,MAAM,eAAe,IAAI,IAAI,QAAQ,IAAI,CAAC,QAAQ,SAAS,GAAG,CAAC,CAAC,CAAC;AAAA,EAC9E;AACF;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MoreGroup,
3
3
  fieldClearing
4
- } from "./chunk-NC2AATCC.js";
4
+ } from "./chunk-6PFBYCBU.js";
5
5
  import {
6
6
  useDataViewsCopy
7
7
  } from "./chunk-KHG57NAE.js";
@@ -180,4 +180,4 @@ function MoreFilters({
180
180
  export {
181
181
  MoreFilters
182
182
  };
183
- //# sourceMappingURL=chunk-ZHPKFV7Y.js.map
183
+ //# sourceMappingURL=chunk-N6JGYVRY.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  Chart
3
- } from "./chunk-CXA6UNFF.js";
3
+ } from "./chunk-AP3PVR3T.js";
4
4
  import {
5
5
  CHART_SEMANTIC_COLORS,
6
6
  specToChartProps
7
- } from "./chunk-GOWBYHYW.js";
7
+ } from "./chunk-R6SBP5M5.js";
8
8
  import {
9
9
  accentFor
10
10
  } from "./chunk-I6PZVHIT.js";
@@ -46,4 +46,4 @@ var SpecChart = ({
46
46
  export {
47
47
  SpecChart
48
48
  };
49
- //# sourceMappingURL=chunk-JPDKRGYI.js.map
49
+ //# sourceMappingURL=chunk-PDGAFQ6Z.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  FilterDialog,
3
3
  GridFilterPanel
4
- } from "./chunk-IN642YHK.js";
4
+ } from "./chunk-4VNUOSTQ.js";
5
5
  import {
6
6
  DataViewsEmpty
7
7
  } from "./chunk-S7CAXRRP.js";
8
8
  import {
9
9
  InlineFilterControls
10
- } from "./chunk-WLCVOQCJ.js";
10
+ } from "./chunk-RUO4D4N6.js";
11
11
  import {
12
12
  GridMain
13
13
  } from "./chunk-QQE2PVLO.js";
@@ -18,12 +18,12 @@ import {
18
18
  toOverflowFields,
19
19
  useFilterOverflow
20
20
  } from "./chunk-TQ6FPOPD.js";
21
- import {
22
- ScopeTabsSlot
23
- } from "./chunk-OGGHD64H.js";
24
21
  import {
25
22
  ShellToolbar
26
23
  } from "./chunk-AWTERXCW.js";
24
+ import {
25
+ ScopeTabsSlot
26
+ } from "./chunk-OGGHD64H.js";
27
27
  import {
28
28
  DataViewsLayoutProvider,
29
29
  useDataViewsLayout
@@ -261,4 +261,4 @@ function GridShell(props) {
261
261
  export {
262
262
  GridShell
263
263
  };
264
- //# sourceMappingURL=chunk-T4BFDZGU.js.map
264
+ //# sourceMappingURL=chunk-Q4ITS2EP.js.map
@@ -1,10 +1,10 @@
1
- import {
2
- chartValueFormatter
3
- } from "./chunk-QVWNK4JO.js";
4
1
  import {
5
2
  getChartSpecRenderer,
6
3
  getRegisteredChartSpecTypes
7
4
  } from "./chunk-WKUA6P3W.js";
5
+ import {
6
+ chartValueFormatter
7
+ } from "./chunk-QVWNK4JO.js";
8
8
 
9
9
  // src/components/data-display/Chart/chart-spec.ts
10
10
  var CHART_SEMANTIC_COLORS = [
@@ -149,4 +149,4 @@ export {
149
149
  parseChartSpec,
150
150
  specToChartProps
151
151
  };
152
- //# sourceMappingURL=chunk-GOWBYHYW.js.map
152
+ //# sourceMappingURL=chunk-R6SBP5M5.js.map
@@ -3,14 +3,14 @@ import {
3
3
  } from "./chunk-LS42VJAI.js";
4
4
  import {
5
5
  DataViewsGrid
6
- } from "./chunk-JKLWHENB.js";
6
+ } from "./chunk-HNDUCGM3.js";
7
7
  import {
8
8
  viewStateKey
9
9
  } from "./chunk-ZOLAYP2D.js";
10
10
  import {
11
11
  ViewDialogs,
12
12
  ViewMutationErrorAlert
13
- } from "./chunk-XPS7FWZS.js";
13
+ } from "./chunk-4ZEU22L2.js";
14
14
  import {
15
15
  useSavedViewsController
16
16
  } from "./chunk-HR7YTBR7.js";
@@ -178,4 +178,4 @@ function renderViewDialogs(ctl, fields, columns, views, testIdPrefix, onSaved) {
178
178
  export {
179
179
  DataViewsTableBase
180
180
  };
181
- //# sourceMappingURL=chunk-DEOC5OI7.js.map
181
+ //# sourceMappingURL=chunk-RRYQG5Y6.js.map
@@ -7,10 +7,10 @@ import {
7
7
  } from "./chunk-ECIGNYSI.js";
8
8
  import {
9
9
  MoreFilters
10
- } from "./chunk-ZHPKFV7Y.js";
10
+ } from "./chunk-N6JGYVRY.js";
11
11
  import {
12
12
  RangePill
13
- } from "./chunk-BZTFPSWT.js";
13
+ } from "./chunk-XEE7PLDR.js";
14
14
  import {
15
15
  CollapsedSearch,
16
16
  InlineKeyword
@@ -220,4 +220,4 @@ function FilterSlots({
220
220
  export {
221
221
  InlineFilterControls
222
222
  };
223
- //# sourceMappingURL=chunk-WLCVOQCJ.js.map
223
+ //# sourceMappingURL=chunk-RUO4D4N6.js.map
@@ -0,0 +1,19 @@
1
+ // src/components/data-display/DataViews/data-views-writers.ts
2
+ function nextVisibleColumns(current, id, visible) {
3
+ const without = current.filter((colId) => colId !== id);
4
+ return visible ? [...without, id] : without;
5
+ }
6
+ function useStateWriters(setState) {
7
+ return {
8
+ patch: (next) => setState((prev) => ({ ...prev, ...typeof next === "function" ? next(prev) : next })),
9
+ toggleColumn: (id, visible) => setState((prev) => ({
10
+ ...prev,
11
+ visibleColumns: nextVisibleColumns(prev.visibleColumns, id, visible)
12
+ }))
13
+ };
14
+ }
15
+
16
+ export {
17
+ useStateWriters
18
+ };
19
+ //# sourceMappingURL=chunk-U5FOJBLG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/data-display/DataViews/data-views-writers.ts"],"sourcesContent":["\"use client\";\n\nimport { type Dispatch, type SetStateAction } from \"react\";\n\nimport { type DataViewState, type DataViewStatePatch } from \"./data-views-types\";\n\n/**\n * Add or remove one column id from the visible-columns list.\n *\n * Moved here with its only caller. A visible column is APPENDED rather than\n * restored to its original index, which is what makes re-showing a column put\n * it last — the behaviour the Exibir panel has always had.\n */\nfunction nextVisibleColumns(current: string[], id: string, visible: boolean): string[] {\n const without = current.filter((colId) => colId !== id);\n return visible ? [...without, id] : without;\n}\n\n/**\n * The two ways a DataViews state is WRITTEN, spelled once.\n *\n * Both are `setState` with a shape — a whole-state patch, and the one column\n * toggle that has to merge into a list rather than replace a field. They sat\n * inline in `useDataViewsState`, which is permanently at the size gate's\n * ceiling; here they sit next to each other, where the fact that\n * `toggleColumn` is just a `patch` with a merge rule is visible.\n *\n * Extracted for the same reason `useSelection` was: that hook is a COMPOSITION\n * of the pieces below it, and every piece that can be named on its own leaves\n * it reading as what it assembles rather than as how each part works.\n */\nexport function useStateWriters(setState: Dispatch<SetStateAction<DataViewState>>): {\n patch: (next: DataViewStatePatch) => void;\n toggleColumn: (id: string, visible: boolean) => void;\n} {\n return {\n patch: (next) =>\n setState((prev) => ({ ...prev, ...(typeof next === \"function\" ? next(prev) : next) })),\n toggleColumn: (id, visible) =>\n setState((prev) => ({\n ...prev,\n visibleColumns: nextVisibleColumns(prev.visibleColumns, id, visible),\n })),\n };\n}\n"],"mappings":";AAaA,SAAS,mBAAmB,SAAmB,IAAY,SAA4B;AACrF,QAAM,UAAU,QAAQ,OAAO,CAAC,UAAU,UAAU,EAAE;AACtD,SAAO,UAAU,CAAC,GAAG,SAAS,EAAE,IAAI;AACtC;AAeO,SAAS,gBAAgB,UAG9B;AACA,SAAO;AAAA,IACL,OAAO,CAAC,SACN,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,GAAI,OAAO,SAAS,aAAa,KAAK,IAAI,IAAI,KAAM,EAAE;AAAA,IACvF,cAAc,CAAC,IAAI,YACjB,SAAS,CAAC,UAAU;AAAA,MAClB,GAAG;AAAA,MACH,gBAAgB,mBAAmB,KAAK,gBAAgB,IAAI,OAAO;AAAA,IACrE,EAAE;AAAA,EACN;AACF;","names":[]}
@@ -1,12 +1,12 @@
1
+ import {
2
+ NumberBoundInput
3
+ } from "./chunk-FV36LFPX.js";
1
4
  import {
2
5
  RangePresets
3
6
  } from "./chunk-F4RR4666.js";
4
7
  import {
5
8
  presetsFor
6
9
  } from "./chunk-CBOB5AV6.js";
7
- import {
8
- NumberBoundInput
9
- } from "./chunk-FV36LFPX.js";
10
10
  import {
11
11
  isRangeInverted,
12
12
  isRangeSet,
@@ -279,4 +279,4 @@ export {
279
279
  RangePill,
280
280
  PanelRangeField
281
281
  };
282
- //# sourceMappingURL=chunk-BZTFPSWT.js.map
282
+ //# sourceMappingURL=chunk-XEE7PLDR.js.map
@@ -1,3 +1,6 @@
1
+ import {
2
+ CardKebab
3
+ } from "../chunk-ONZPM6FP.js";
1
4
  import {
2
5
  useRowConfirm
3
6
  } from "../chunk-SJIBPRPB.js";
@@ -18,9 +21,6 @@ import {
18
21
  CardActionsProvider,
19
22
  useCardActions
20
23
  } from "../chunk-77GA5YHQ.js";
21
- import {
22
- CardKebab
23
- } from "../chunk-ONZPM6FP.js";
24
24
  import "../chunk-WVML3ENZ.js";
25
25
  import "../chunk-IDHZHOZW.js";
26
26
  import "../chunk-XCBQXSTR.js";
@@ -1,7 +1,8 @@
1
1
  import "../chunk-62FET2BM.js";
2
2
  import {
3
3
  Carousel
4
- } from "../chunk-NPEKJXVV.js";
4
+ } from "../chunk-HRJ27X5B.js";
5
+ import "../chunk-RUIV5TVA.js";
5
6
  import "../chunk-5QXSPLWU.js";
6
7
  import "../chunk-Z56IO7OV.js";
7
8
  import "../chunk-WIXUMFU7.js";
@@ -10,7 +11,6 @@ import {
10
11
  CarouselIndicators,
11
12
  CarouselThumbnails
12
13
  } from "../chunk-2XGM5PDA.js";
13
- import "../chunk-RUIV5TVA.js";
14
14
  import "../chunk-HPK33ACY.js";
15
15
  import "../chunk-I6PZVHIT.js";
16
16
  import "../chunk-7CA6GVBO.js";
@@ -1,14 +1,11 @@
1
1
  import "../chunk-5KLSLD72.js";
2
2
  import {
3
3
  SpecChart
4
- } from "../chunk-JPDKRGYI.js";
4
+ } from "../chunk-PDGAFQ6Z.js";
5
5
  import {
6
6
  Chart
7
- } from "../chunk-CXA6UNFF.js";
8
- import "../chunk-XULTDO56.js";
9
- import "../chunk-XSKVBGCZ.js";
10
- import "../chunk-AVU6KU27.js";
11
- import "../chunk-4V532JF6.js";
7
+ } from "../chunk-AP3PVR3T.js";
8
+ import "../chunk-BVGR7OYA.js";
12
9
  import {
13
10
  ChartContainer,
14
11
  ChartLegend,
@@ -16,21 +13,24 @@ import {
16
13
  ChartTooltip,
17
14
  ChartTooltipContent
18
15
  } from "../chunk-M5T3COS2.js";
16
+ import "../chunk-XSKVBGCZ.js";
17
+ import "../chunk-AVU6KU27.js";
18
+ import "../chunk-4V532JF6.js";
19
19
  import {
20
20
  CHART_SEMANTIC_COLORS,
21
21
  ChartSpecError,
22
22
  parseChartSpec,
23
23
  specToChartProps
24
- } from "../chunk-GOWBYHYW.js";
25
- import {
26
- chartValueFormatter,
27
- formatChartValue
28
- } from "../chunk-QVWNK4JO.js";
24
+ } from "../chunk-R6SBP5M5.js";
29
25
  import {
30
26
  getChartSpecRenderer,
31
27
  getRegisteredChartSpecTypes,
32
28
  registerChartSpecRenderer
33
29
  } from "../chunk-WKUA6P3W.js";
30
+ import {
31
+ chartValueFormatter,
32
+ formatChartValue
33
+ } from "../chunk-QVWNK4JO.js";
34
34
  import "../chunk-I6PZVHIT.js";
35
35
  import "../chunk-7CA6GVBO.js";
36
36
  import "../chunk-PZ5AY32C.js";
@@ -5,8 +5,8 @@ import {
5
5
  import "../chunk-DLJGBJZW.js";
6
6
  import "../chunk-KZLLTOB2.js";
7
7
  import "../chunk-E5LWJDI3.js";
8
- import "../chunk-5E3XZAED.js";
9
8
  import "../chunk-G3E66C6J.js";
9
+ import "../chunk-5E3XZAED.js";
10
10
  import "../chunk-PZ5AY32C.js";
11
11
  export {
12
12
  DataGrid