gridsmith-ui 0.32.0 → 0.33.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 (70) hide show
  1. package/CHANGELOG.md +64 -1
  2. package/README.md +4 -2
  3. package/dist/charts.d.ts +10 -1
  4. package/dist/charts.js +115 -50
  5. package/dist/charts.js.map +1 -1
  6. package/dist/chat.js +6 -6
  7. package/dist/{chunk-WSKPESAX.js → chunk-4FX6UCSS.js} +5 -5
  8. package/dist/{chunk-WSKPESAX.js.map → chunk-4FX6UCSS.js.map} +1 -1
  9. package/dist/{chunk-DO6DLTFK.js → chunk-4TQVFRKK.js} +6 -6
  10. package/dist/{chunk-DO6DLTFK.js.map → chunk-4TQVFRKK.js.map} +1 -1
  11. package/dist/{chunk-HCEHTJ5E.js → chunk-77X7AHFB.js} +3 -3
  12. package/dist/{chunk-HCEHTJ5E.js.map → chunk-77X7AHFB.js.map} +1 -1
  13. package/dist/{chunk-SIEU4H3H.js → chunk-BL2C35BN.js} +43 -33
  14. package/dist/chunk-BL2C35BN.js.map +1 -0
  15. package/dist/chunk-GIA4BMGI.js +18 -0
  16. package/dist/chunk-GIA4BMGI.js.map +1 -0
  17. package/dist/{chunk-2724SJO2.js → chunk-HDFTENVW.js} +7 -3
  18. package/dist/chunk-HDFTENVW.js.map +1 -0
  19. package/dist/{chunk-OVHM55JF.js → chunk-MPXE2XOP.js} +41 -6
  20. package/dist/chunk-MPXE2XOP.js.map +1 -0
  21. package/dist/{chunk-XBVZIN26.js → chunk-MW5CJOJN.js} +10 -8
  22. package/dist/chunk-MW5CJOJN.js.map +1 -0
  23. package/dist/{chunk-QY2RA2HO.js → chunk-N6QLEZFH.js} +5 -5
  24. package/dist/{chunk-QY2RA2HO.js.map → chunk-N6QLEZFH.js.map} +1 -1
  25. package/dist/{chunk-TMPPBXX3.js → chunk-NFVJEICH.js} +3 -3
  26. package/dist/{chunk-TMPPBXX3.js.map → chunk-NFVJEICH.js.map} +1 -1
  27. package/dist/{chunk-JHZ22HQP.js → chunk-NJG6JQGC.js} +61 -222
  28. package/dist/chunk-NJG6JQGC.js.map +1 -0
  29. package/dist/chunk-P3NUUIL6.js +9 -0
  30. package/dist/chunk-P3NUUIL6.js.map +1 -0
  31. package/dist/{chunk-NGZJK57C.js → chunk-PT4HYHI3.js} +10 -9
  32. package/dist/chunk-PT4HYHI3.js.map +1 -0
  33. package/dist/chunk-R7FG4ZQ5.js +16 -0
  34. package/dist/chunk-R7FG4ZQ5.js.map +1 -0
  35. package/dist/chunk-T33JK3ZE.js +81 -0
  36. package/dist/chunk-T33JK3ZE.js.map +1 -0
  37. package/dist/chunk-UI4BSRCQ.js +213 -0
  38. package/dist/chunk-UI4BSRCQ.js.map +1 -0
  39. package/dist/{chunk-HUVZQOU4.js → chunk-XJGFZ5CP.js} +5 -5
  40. package/dist/{chunk-HUVZQOU4.js.map → chunk-XJGFZ5CP.js.map} +1 -1
  41. package/dist/{chunk-R2IAK3J3.js → chunk-ZTS6HJAU.js} +3 -3
  42. package/dist/{chunk-R2IAK3J3.js.map → chunk-ZTS6HJAU.js.map} +1 -1
  43. package/dist/dashboard.d.ts +207 -0
  44. package/dist/dashboard.js +1210 -0
  45. package/dist/dashboard.js.map +1 -0
  46. package/dist/data-grid.js +10 -9
  47. package/dist/data-grid.js.map +1 -1
  48. package/dist/editor-mentions.js +2 -2
  49. package/dist/editor.js +2 -2
  50. package/dist/index.d.ts +64 -8
  51. package/dist/index.js +245 -147
  52. package/dist/index.js.map +1 -1
  53. package/dist/kanban.js +8 -8
  54. package/dist/resizable.js +9 -8
  55. package/dist/resizable.js.map +1 -1
  56. package/dist/utils.d.ts +51 -1
  57. package/dist/utils.js +55 -4
  58. package/dist/utils.js.map +1 -1
  59. package/dist/virtualized.js +8 -8
  60. package/package.json +6 -1
  61. package/dist/chunk-2724SJO2.js.map +0 -1
  62. package/dist/chunk-H732QL56.js +0 -71
  63. package/dist/chunk-H732QL56.js.map +0 -1
  64. package/dist/chunk-JHZ22HQP.js.map +0 -1
  65. package/dist/chunk-LJYSVZMI.js +0 -25
  66. package/dist/chunk-LJYSVZMI.js.map +0 -1
  67. package/dist/chunk-NGZJK57C.js.map +0 -1
  68. package/dist/chunk-OVHM55JF.js.map +0 -1
  69. package/dist/chunk-SIEU4H3H.js.map +0 -1
  70. package/dist/chunk-XBVZIN26.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,6 +1,69 @@
1
1
  # gridsmith-ui changelog
2
2
 
3
- ## 0.32.0 — 19 October 2026
3
+ ## 0.33.1 — 23 October 2026
4
+
5
+ What the owner's review of the Map page found in the library (Sprint 32's follow-up): a number field that went 0.1, 0.2, 0.30000000000000004 and took any number of decimals typed, a slider that snapped to the same noise, and a selectable list in a card whose rows didn't line up with the card's title. Its fresh-eyes review added two in Tabs: two on a page could mix up their tabs, and a panel was a Tab stop even when it started with something to reach.
6
+
7
+ **Added.**
8
+ - **NumberInput's `decimals`:** the places the field takes and always shows ("12.50"), never fewer than its step's, `min`'s or `max`'s own. Money with whole-unit buttons is `decimals={2}` with `step={1}`.
9
+
10
+ **Fixed.**
11
+ - **A NumberInput keeps the places its value needs.** A step adds and rounds to the step's places (or `min`'s or `max`'s, if they have more), so 0.1 stepped twice is 0.3, shown "0.3", and a held button counts 0.1 at a time. With `allowDecimals` on a whole step a value keeps every digit it has, and a step adds in its own places (0.14 stepped by 1 is 1.14, and 1234567890123 stays exact), as DataGrid's number editor needs. A step's places are read with any exponent (`1e-7` is seven), and a value never shows with one (0.0000001). A negative zero shows as "0", and a missing value as an empty field. A page value with more places than the field shows rounded, and `aria-valuenow` gives that number.
12
+ - **Stepping an empty NumberInput** starts from `min`, or from 0 with no `min`.
13
+ - **A focused NumberInput follows its value when the page changes it** (a map's handle dragged while the field has focus), an empty one too, while its text still shows the value it had: a number half typed stays.
14
+ - **A NumberInput in a Field is described by the Field's hint and error:** it puts the Field's `aria-describedby` and `aria-required` on its input, so a screen reader hears the hint (a field's unit) with the field.
15
+ - **SliderRange snaps to the step's places,** from the pointer and the keys: ArrowRight three times on a 0.1 step is 0.3.
16
+ - **A selectable StackedList in a Card lines up with the Card's title:** its rows' text starts where the header's does, in every preset, and the selection's rail sits in the inset.
17
+ - **Two Tabs on a page keep their tabs apart.** Each Tabs' tabs and panels have ids of their own, so two with a tab of the same id (two "Overview" tabs) no longer share one: the arrow keys move within their own tabs, and each panel is named by its own tab.
18
+ - **A tab panel is a Tab stop of its own only when it needs one** (the Authoring Practices' tab panel): when it holds nothing to reach, or starts with words a Tab would pass by. One that starts with a control, or with a list or a scrolling region that is a stop, takes none, so Tab goes straight there: one press, not two.
19
+
20
+ **Changed.**
21
+ - **Typing in a NumberInput stops at its places:** a decimal past them isn't taken, as a letter isn't. A step of 0.5 now refuses "0.25"; `decimals={2}` (or a step of 0.01) takes it.
22
+ - **Leaving a NumberInput changes nothing:** what's typed is reported as it's typed, held to the limits, so leaving the field calls no `onChange` and leaves the form unmarked; an empty field left at "-" stays empty, where it took the minimum. A page value outside `min` or `max` is still clamped as the field's own change, as since 0.21.0.
23
+
24
+ ### Upgrade note for agents (0.33.0 → 0.33.1)
25
+
26
+ `^0.33.0` takes 0.33.1. What to check:
27
+ - **A field with a fractional step that takes finer values** than its step: a step of 0.5 now refuses "0.25". Give it `decimals` with the places it takes.
28
+ - **Money fields:** `decimals={2}` with `step={1}` (pence typed, shown "12.50"). One that passed `allowDecimals` for pence can keep it, or take `decimals={2}` to stop at two places.
29
+ - **Tests that left a NumberInput to commit a value:** leaving it with nothing typed no longer calls `onChange`; type in it or step it instead.
30
+ - **A screenshot test of a selectable list in a Card** changes by a few pixels, the rows' inset.
31
+ - **A test that found a tab or a tab panel by its id** (`ds-tab-…`, `ds-tabpanel-…`): the ids now carry each Tabs' own part. Find it by its role and name.
32
+ - **A keyboard test that tabbed into a panel starting with a control:** Tab now goes straight to the control.
33
+
34
+ ## 0.33.0 — 22 October 2026
35
+
36
+ A dashboard its people arrange (Sprint 32): a new entry, `gridsmith-ui/dashboard`, whose widgets are dragged, sized and added from a widget library, with a keyboard way and a plain-click way for every drag; a chart in a widget fills it; a chart's frame takes its own actions; and a hook that gives the theme's colours to anything that can't read CSS variables, such as a map.
37
+
38
+ **Added.**
39
+ - **`gridsmith-ui/dashboard`:** `DashboardGrid` (widgets in a reading order on 12 columns, arranged in an edit mode the page enters on purpose: a move handle, a ⋯ menu with Set up, Move and Size, and a resize grip beside each widget, never inside it; the keyboard moves and resizes on the grid's own state; every move and size has a menu way; a polite live region says each one by the widget's name), `DashboardItem` (one widget, around one titled frame), `DashboardPalette` (the widget library: each kind one row, a button named "Add" and its name, that a click, Enter or Space adds at the end and a pointer drags onto the grid; a drag cancelled by Escape adds nothing, and Escape then closes nothing around it; a row is drawn unavailable while the grid isn't editing; a line above the list says what a row does, "Select or drag to add", or "Select a widget to add it" where the rows don't drag, and `hint` gives other words or `false` none), `DashboardEditor` (the drag a palette and a grid share) and `useDraftHistory` (a draft held whole until Save, with undo and redo, Ctrl+Z and ⌘Z outside text fields). On the optional peers `@dnd-kit/core` and `@dnd-kit/utilities` alone. A widget is at least three columns wide and two rows tall; below 40rem of its own width the grid stacks in the same order, and dragging and resizing are off there.
40
+ - **The layout's helpers in `gridsmith-ui/utils`** (safe on a server): `normaliseLayout`, `moveItem`, `resizeItem`, `addItem`, `removeItem`, and the `DashboardLayout` types.
41
+ - **ChartContainer's `actions`:** the page's own slot in the chart's header, beside the Chart / Table switch, for a link to the report behind the chart. Drawn with a `title`.
42
+ - **`useThemeColors(ref, names)`:** the theme's colours as hex (`#rrggbbaa` when see-through), read where an element sits and again when a `data-mode` changes, for anything that takes colours rather than CSS (a map's style, a canvas).
43
+ - **An AsidePanel a page draws docks beside the content column,** where AppShell's aside slot is, and stays in the page's tree (a dashboard editor's widget library inside its DashboardEditor).
44
+
45
+ **Changed.**
46
+ - **A page header's actions wrap when they don't fit:** in every variant, actions that don't fit beside a title of about eight characters (or all of a shorter title) go under it and wrap among themselves, so nothing runs off a phone's screen (a date range and a button ran off a 430 px phone). The eight characters are the title's own: a back button, an avatar or the collapsed bar's last crumb beside it adds its width, and a badge goes under the title before the title would be cut shorter. Where they fit, the header draws as before.
47
+ - **An icon Button follows the size around it:** `size="icon"` draws at the small size where the controls around it are small (a minimal or collapsed page header, a filters row, a pane's heading, a TableToolbar) and at the large size where they're large, as a Button with no size does, so a header's ⋯ menu matches the buttons beside it. `icon-xs`, `icon-sm` and `icon-lg` keep their own size.
48
+ - **A Button with `aria-disabled` looks and acts unavailable:** it draws as a disabled one (a busy one keeps its spinner's look) and ignores its press, while it stays a Tab stop and keeps focus, which `disabled` doesn't.
49
+ - **One AsidePanel is open at a time in a shell,** whatever its side or form: opening one closes any other through its own `onClose`, so the one opened last wins (opening a page's own panel collapses an open assistant, its conversation kept; opening the assistant again closes the page's panel).
50
+ - **A chart's header wraps when its title would be squeezed:** under about 240 px of frame, the Chart / Table switch (and the page's actions) go to the line below the title, at its end. A header whose title fits draws as before.
51
+ - **A StatsCard's value steps down in size to fit its card** (from the 2xl size to xl, then lg, never smaller), and in a card under about 13rem it sits under the icon tile, across the card, so a long figure never runs into the tile.
52
+ - **A Sparkline is a picture:** it's no longer an unnamed Tab stop; with no `aria-label` it's hidden from screen readers (the stat beside it says what it shows), and with one it's an image of that name. Its hover values are for a pointer only.
53
+ - **In a dashboard's widget only** (nothing changes elsewhere): a chart fills the widget, except a sideways bar chart or a funnel, which keeps a row per name and scrolls, and no chart goes below the small chart height; a titled Table keeps its table form and scrolls sideways; a note, a table or a stat taller than its widget scrolls in its frame, a Tab stop only while it scrolls.
54
+
55
+ ### Upgrade note for agents (0.32.0 → 0.33.0)
56
+
57
+ `^0.32.0` doesn't take 0.33.0: install it with `npm install gridsmith-ui@^0.33.0`. A dashboard its people arrange also needs `npm install @dnd-kit/core @dnd-kit/utilities` (an app with a KanbanBoard has them). What to check:
58
+ - **Side panels.** Only one AsidePanel is open at a time: a page that opens its own panel while the assistant is open sees the assistant close (through its `onClose`, so the Launcher comes back). A page's own AsidePanel is drawn in the page now (it docks beside the content column); keep the app-wide assistant's in AppShell's `aside` slot.
59
+ - **Stats and charts.** A narrow StatsCard draws its value smaller, and under the icon in a very narrow card; a chart's switch goes under a squeezed title. Nothing to change; check a screenshot test that pinned either.
60
+ - **Sparklines** are no longer Tab stops: a test that tabbed to one, or read its hover values by keyboard, changes.
61
+ - **Page headers.** Actions too wide to sit beside the title now go under it and wrap, mostly on a phone; a short title keeps them beside it wherever both fit, and a badge goes under a squeezed title. Nothing to change, but a screenshot test of a narrow header with several actions changes.
62
+ - **Small icon buttons.** `size="icon"` in a small row (a minimal or collapsed page header, a TableToolbar's actions, a filters row, a pane's heading) now draws small, as the buttons beside it do; one that passed `icon-sm` there to match can keep it. A screenshot test of such a row changes.
63
+ - **`aria-disabled` Buttons** now look unavailable and ignore their press: a page's own `aria-disabled:` classes and its check in `onClick` can go. A page that ran something on a press while `aria-disabled` (to say why it's unavailable) says why beside the Button or in its tooltip instead.
64
+ - **A fixed dashboard** stays as it is; `get_component_api('DashboardGrid')` gives the composition for one its people arrange.
65
+
66
+ ## 0.32.0 — 20 October 2026
4
67
 
5
68
  What the owner's look review of 19 October found (Sprint 25.33): charts with no textures and no worked-out sentence on show, a bulk-action bar that floats, tables that pin only while they scroll, chips as wide as their words, panes that pad what they hold, and the rail's selected item in the accent.
6
69
 
package/README.md CHANGED
@@ -35,6 +35,7 @@ npm install @tiptap/react @tiptap/pm @tiptap/starter-kit lowlight \
35
35
  npm install @tiptap/extension-mention@<v> @tiptap/suggestion@<v> # gridsmith-ui/editor-mentions: <v> is your @tiptap/core version (npm ls @tiptap/core)
36
36
  npm install react-markdown remark-gfm # gridsmith-ui/chat
37
37
  npm install @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities # gridsmith-ui/kanban
38
+ npm install @dnd-kit/core @dnd-kit/utilities # gridsmith-ui/dashboard
38
39
  npm install @tanstack/react-table # gridsmith-ui/data-grid
39
40
  npm install @tanstack/react-virtual # gridsmith-ui/virtualized
40
41
  npm install react-resizable-panels # gridsmith-ui/resizable
@@ -102,11 +103,12 @@ Every entry but `gridsmith-ui/utils` is client code, each file opening with `"us
102
103
  | `gridsmith-ui/editor-mentions` | `useMentions`, @mentions for `RichTextEditor` (requires `@tiptap/extension-mention` and `@tiptap/suggestion` at your other tiptap packages' version) |
103
104
  | `gridsmith-ui/chat` | `MarkdownContent` for chat replies; pass it to `ChatMessageList`'s `renderContent` (requires `react-markdown` + `remark-gfm`) |
104
105
  | `gridsmith-ui/kanban` | `KanbanBoard` (requires `@dnd-kit/*`) |
106
+ | `gridsmith-ui/dashboard` | `DashboardGrid`, `DashboardItem`, `DashboardPalette`, `DashboardEditor` and `useDraftHistory`: a dashboard its people arrange (requires `@dnd-kit/core` and `@dnd-kit/utilities`) |
105
107
  | `gridsmith-ui/data-grid` | `DataGrid` (requires `@tanstack/react-table`) |
106
108
  | `gridsmith-ui/virtualized` | `VirtualizedList` (requires `@tanstack/react-virtual`) |
107
109
  | `gridsmith-ui/resizable` | `ResizablePanelGroup`, `ResizablePanel`, `ResizableHandle`, `SplitView` (requires `react-resizable-panels`) |
108
110
  | `gridsmith-ui/icons` | `Icon`, `IconProvider`, `preloadPack`, `registerIconPack` — 5 icon packs with two-phase loading |
109
- | `gridsmith-ui/utils` | `cn()` — className merge utility (clsx + tailwind-merge) — the shared focus styles (`FOCUS_RING` and its kin) for an element of your own that takes focus, and the helpers server code calls: the repeat rules, calendar days and date ranges, time zones, a chart's label kind, and `requestLocale()` for a request's locale. Nothing in it needs React or a browser |
111
+ | `gridsmith-ui/utils` | `cn()` — className merge utility (clsx + tailwind-merge) — the shared focus styles (`FOCUS_RING` and its kin) for an element of your own that takes focus, and the helpers server code calls: the repeat rules, calendar days and date ranges, time zones, a chart's label kind, a dashboard's layout (`moveItem`, `resizeItem`, `addItem`, `removeItem`, `normaliseLayout`), and `requestLocale()` for a request's locale. Nothing in it needs React or a browser |
110
112
  | `gridsmith-ui/roots.css` | CSS custom property engine |
111
113
  | `gridsmith-ui/tokens.css` | Default preset token values |
112
114
  | `gridsmith-ui/tailwind.css` | Tailwind v4 `@theme` bindings for `--ds-*` tokens |
@@ -166,7 +168,7 @@ Wrap your app in `<IconProvider>` to select a pack:
166
168
  | `recharts` | Optional (required for `gridsmith-ui/charts`) |
167
169
  | `@tiptap/*`, `lowlight` | Optional (required for `gridsmith-ui/editor`). The mention packages for `gridsmith-ui/editor-mentions` aren't declared: install them at your `@tiptap/core` version, as tiptap's packages must all be one version |
168
170
  | `react-markdown`, `remark-gfm` | Optional (required for `gridsmith-ui/chat`) |
169
- | `@dnd-kit/*` | Optional (required for `gridsmith-ui/kanban`) |
171
+ | `@dnd-kit/*` | Optional (required for `gridsmith-ui/kanban`; `@dnd-kit/core` and `@dnd-kit/utilities` alone for `gridsmith-ui/dashboard`) |
170
172
  | `@tanstack/react-table` | Optional (required for `gridsmith-ui/data-grid`) |
171
173
  | `@tanstack/react-virtual` | Optional (required for `gridsmith-ui/virtualized`) |
172
174
  | `react-resizable-panels` | Optional (required for `gridsmith-ui/resizable`) |
package/dist/charts.d.ts CHANGED
@@ -563,6 +563,9 @@ interface ChartContainerProps {
563
563
  * sideways bars and funnels, two wide to one high for charts over dates or numbers, square for round charts — and in
564
564
  * a row its frame matches the tallest block while the chart grows only to its bound.
565
565
  * A preset (sm, md, lg) or a number of px sets this chart's height instead, and beats the chart's own.
566
+ * In a widget on a dashboard its people arrange (DashboardGrid), the widget's height decides: the chart fills the
567
+ * widget the person sized, a sideways bar chart or a funnel keeping a row per name and scrolling, and no chart going
568
+ * below the small height. Nothing is passed for it.
566
569
  */
567
570
  height?: "auto" | "sm" | "md" | "lg" | number;
568
571
  /**
@@ -572,6 +575,12 @@ interface ChartContainerProps {
572
575
  * card-title style, never cut; the chart's graphic is named by it.
573
576
  */
574
577
  title?: string;
578
+ /**
579
+ * The page's own actions for the chart, in its header: a link to the report behind it ("Open report"), as a Table's
580
+ * or a CardHeader's actions. They sit before the chart's Chart / Table switch, which keeps the header's end, so a
581
+ * row of charts shows its switches in one place. Needs `title`: the actions belong to the header the title heads.
582
+ */
583
+ actions?: ReactNode;
575
584
  loading?: boolean;
576
585
  emptyState?: ReactNode;
577
586
  /** "default" is a card surface. "ghost" drops surface, border, shadow and padding for charts embedded in another container. */
@@ -579,7 +588,7 @@ interface ChartContainerProps {
579
588
  children: ReactNode;
580
589
  className?: string;
581
590
  }
582
- declare function ChartContainer({ height, title, loading, emptyState, variant, children, className, }: ChartContainerProps): react_jsx_runtime.JSX.Element;
591
+ declare function ChartContainer({ height, title, actions: pageActions, loading, emptyState, variant, children, className, }: ChartContainerProps): react_jsx_runtime.JSX.Element;
583
592
 
584
593
  /**
585
594
  * The theme's chart series colours, `count` of them in series order (repeating past the palette's length), read from the
package/dist/charts.js CHANGED
@@ -1,16 +1,18 @@
1
1
  "use client";
2
- import { SegmentedControl, TITLE_TEXT, Skeleton } from './chunk-OVHM55JF.js';
3
- import { useKeyboardScroll } from './chunk-H732QL56.js';
4
- import { useFormatLocale, useHydrated } from './chunk-LJYSVZMI.js';
5
- import './chunk-DO6DLTFK.js';
2
+ import { SegmentedControl, CELL_FRAME, TITLE_TEXT, TITLE_FLOOR, CELL_ROOM_INNER, CELL_HIDE_CHART_ACTIONS, Skeleton } from './chunk-MPXE2XOP.js';
3
+ import { useFormatLocale } from './chunk-R7FG4ZQ5.js';
4
+ import './chunk-4TQVFRKK.js';
6
5
  import { formatLocale } from './chunk-7QLXYRPD.js';
6
+ import './chunk-ZTS6HJAU.js';
7
+ import { DashboardCellContext } from './chunk-P3NUUIL6.js';
8
+ import { useHydrated } from './chunk-GIA4BMGI.js';
7
9
  import { FormChangeCtx } from './chunk-72SDAX54.js';
8
- import { elementType } from './chunk-XBVZIN26.js';
10
+ import { elementType } from './chunk-MW5CJOJN.js';
9
11
  import './chunk-7RKC5C7G.js';
10
- import './chunk-R2IAK3J3.js';
11
- import { mergeRefs } from './chunk-HCEHTJ5E.js';
12
+ import { useKeyboardScroll } from './chunk-T33JK3ZE.js';
13
+ import { mergeRefs } from './chunk-77X7AHFB.js';
12
14
  import { warnOnce } from './chunk-53F7GVBQ.js';
13
- import { cn, FOCUS_INSET, GLASS_SURFACE } from './chunk-2724SJO2.js';
15
+ import { cn, FOCUS_INSET, GLASS_SURFACE } from './chunk-HDFTENVW.js';
14
16
  import { createContext, forwardRef, useContext, useRef, useState, useId, useMemo, useLayoutEffect, useEffect, useCallback, useSyncExternalStore, Children, isValidElement } from 'react';
15
17
  import { ResponsiveContainer, BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, Bar, LineChart as LineChart$1, Line, AreaChart as AreaChart$1, Area, PieChart as PieChart$1, Pie, Cell, ComposedChart, ScatterChart as ScatterChart$1, ZAxis, Scatter, Symbols, RadarChart as RadarChart$1, PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar, RadialBarChart as RadialBarChart$1, RadialBar, FunnelChart as FunnelChart$1, Funnel, LabelList, Treemap, Sankey, Text, Legend, ReferenceArea, ReferenceLine, getNiceTickValues, Rectangle, usePlotArea, ZIndexLayer, DefaultZIndexes } from 'recharts';
16
18
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -979,35 +981,45 @@ function forecastElements(categories, from, label, look) {
979
981
  }
980
982
  return elements;
981
983
  }
982
- function ChartTable({ table, name, labelledBy }) {
984
+ function ChartTable({ table, name, labelledBy, cell = false }) {
983
985
  const [frame, setFrame] = useState(null);
984
986
  useKeyboardScroll(frame, name, true, false, "both");
985
- return /* @__PURE__ */ jsxs("div", { "data-chart-table": "", className: "flex min-h-0 flex-1 flex-col gap-ds-2", children: [
986
- /* @__PURE__ */ jsx(
987
- "div",
988
- {
989
- ref: setFrame,
990
- className: cn(
991
- "min-h-0 max-h-[var(--ds-chart-height-lg)] overflow-auto rounded-[var(--ds-radius-md)]",
992
- "border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
993
- FOCUS_INSET
987
+ return /* @__PURE__ */ jsxs(
988
+ "div",
989
+ {
990
+ "data-chart-table": "",
991
+ className: cell ? "flex flex-[1_1_0px] flex-col gap-ds-2" : "flex min-h-0 flex-1 flex-col gap-ds-2",
992
+ style: cell ? { minHeight: "var(--ds-chart-height-sm)" } : void 0,
993
+ children: [
994
+ /* @__PURE__ */ jsx(
995
+ "div",
996
+ {
997
+ ref: setFrame,
998
+ className: cn(
999
+ "min-h-0",
1000
+ !cell && "max-h-[var(--ds-chart-height-lg)]",
1001
+ "overflow-auto rounded-[var(--ds-radius-md)]",
1002
+ "border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
1003
+ FOCUS_INSET
1004
+ ),
1005
+ children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-sm", "aria-labelledby": labelledBy, "aria-label": labelledBy ? void 0 : name, children: [
1006
+ /* @__PURE__ */ jsx("thead", { className: "bg-[var(--ds-bg-muted)]", children: /* @__PURE__ */ jsx("tr", { children: table.columns.map((column, i) => /* @__PURE__ */ jsx(
1007
+ "th",
1008
+ {
1009
+ scope: "col",
1010
+ className: cn("px-ds-3 py-ds-2 text-xs font-semibold text-[var(--ds-text-secondary)] whitespace-nowrap", table.numeric[i] ? "text-right" : "text-left"),
1011
+ children: column
1012
+ },
1013
+ i
1014
+ )) }) }),
1015
+ /* @__PURE__ */ jsx("tbody", { children: table.rows.map((row, r) => /* @__PURE__ */ jsx("tr", { className: "border-t-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]", children: row.map((cell2, i) => i === (table.rowHeader ?? 0) ? /* @__PURE__ */ jsx("th", { scope: "row", className: "px-ds-3 py-ds-2 text-left font-normal text-[var(--ds-text-primary)]", children: cell2 }, i) : /* @__PURE__ */ jsx("td", { className: cn("px-ds-3 py-ds-2 text-[var(--ds-text-primary)]", table.numeric[i] && "text-right tabular-nums whitespace-nowrap"), children: cell2 }, i)) }, r)) })
1016
+ ] })
1017
+ }
994
1018
  ),
995
- children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-sm", "aria-labelledby": labelledBy, "aria-label": labelledBy ? void 0 : name, children: [
996
- /* @__PURE__ */ jsx("thead", { className: "bg-[var(--ds-bg-muted)]", children: /* @__PURE__ */ jsx("tr", { children: table.columns.map((column, i) => /* @__PURE__ */ jsx(
997
- "th",
998
- {
999
- scope: "col",
1000
- className: cn("px-ds-3 py-ds-2 text-xs font-semibold text-[var(--ds-text-secondary)] whitespace-nowrap", table.numeric[i] ? "text-right" : "text-left"),
1001
- children: column
1002
- },
1003
- i
1004
- )) }) }),
1005
- /* @__PURE__ */ jsx("tbody", { children: table.rows.map((row, r) => /* @__PURE__ */ jsx("tr", { className: "border-t-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]", children: row.map((cell, i) => i === (table.rowHeader ?? 0) ? /* @__PURE__ */ jsx("th", { scope: "row", className: "px-ds-3 py-ds-2 text-left font-normal text-[var(--ds-text-primary)]", children: cell }, i) : /* @__PURE__ */ jsx("td", { className: cn("px-ds-3 py-ds-2 text-[var(--ds-text-primary)]", table.numeric[i] && "text-right tabular-nums whitespace-nowrap"), children: cell }, i)) }, r)) })
1006
- ] })
1007
- }
1008
- ),
1009
- table.notes.length > 0 && /* @__PURE__ */ jsx("ul", { "data-chart-notes": "", className: "text-xs text-[var(--ds-text-secondary)]", children: table.notes.map((note, i) => /* @__PURE__ */ jsx("li", { children: note }, i)) })
1010
- ] });
1019
+ table.notes.length > 0 && /* @__PURE__ */ jsx("ul", { "data-chart-notes": "", className: "text-xs text-[var(--ds-text-secondary)]", children: table.notes.map((note, i) => /* @__PURE__ */ jsx("li", { children: note }, i)) })
1020
+ ]
1021
+ }
1022
+ );
1011
1023
  }
1012
1024
  var CHART_HEIGHTS = {
1013
1025
  sm: "var(--ds-chart-height-sm)",
@@ -1033,6 +1045,9 @@ function plotBoxStyle(size, fixed) {
1033
1045
  }
1034
1046
  return { height: fixed ?? `clamp(${SM}, 50cqi, ${LG})`, maxHeight: `max(${fixed ?? LG}, 100cqi)`, flex: "1 0 auto" };
1035
1047
  }
1048
+ function cellPlotStyle(size) {
1049
+ return size.model === "rows" ? plotBoxStyle(size, void 0) : { flex: "1 1 0px", minHeight: SM };
1050
+ }
1036
1051
  var CHART_MARK = /* @__PURE__ */ Symbol.for("gridsmith.Chart");
1037
1052
  function markChart(component) {
1038
1053
  Object.assign(component, { [CHART_MARK]: true });
@@ -1065,6 +1080,8 @@ function remapRowKeys(e) {
1065
1080
  const event = new View.KeyboardEvent("keydown", { key: next ? "ArrowLeft" : "ArrowRight", bubbles: true, cancelable: true });
1066
1081
  REMAPPED.add(event);
1067
1082
  target.dispatchEvent(event);
1083
+ const plot = e.currentTarget;
1084
+ View.requestAnimationFrame(() => plot.querySelector(".recharts-tooltip-cursor")?.scrollIntoView?.({ block: "nearest", inline: "nearest" }));
1068
1085
  }
1069
1086
  var ChartWrapper = forwardRef(function ChartWrapper2({
1070
1087
  height = "auto",
@@ -1104,9 +1121,10 @@ var ChartWrapper = forwardRef(function ChartWrapper2({
1104
1121
  observer.observe(plot);
1105
1122
  return () => observer.disconnect();
1106
1123
  }, [plotEl]);
1107
- const fill = container?.fillArea === true;
1124
+ const cell = container?.cell === true;
1125
+ const fill = !cell && container?.fillArea === true;
1108
1126
  const fixed = container?.height ?? fixedChartHeight(height);
1109
- const plotStyle = fill ? { flex: "1 1 0%", minHeight: 0 } : plotBoxStyle(size, fixed);
1127
+ const plotStyle = cell ? cellPlotStyle(size) : fill ? { flex: "1 1 0%", minHeight: 0 } : plotBoxStyle(size, fixed);
1110
1128
  const subtitle = description?.trim() || void 0;
1111
1129
  const summary = access?.description;
1112
1130
  const describers = [subtitle && subtitleId, summary && summaryId].filter(Boolean).join(" ");
@@ -1131,6 +1149,26 @@ var ChartWrapper = forwardRef(function ChartWrapper2({
1131
1149
  }, [categoryAxis, plotEl]);
1132
1150
  const register = container?.register;
1133
1151
  useLayoutEffect(() => register?.(), [register]);
1152
+ const drawing = container?.drawing;
1153
+ useLayoutEffect(() => {
1154
+ if (!drawing || !plotEl || typeof MutationObserver === "undefined") return;
1155
+ let counted;
1156
+ const read = () => {
1157
+ const surface = !!plotEl.querySelector('svg[tabindex="0"]');
1158
+ if (surface && !counted) counted = drawing();
1159
+ else if (!surface && counted) {
1160
+ counted();
1161
+ counted = void 0;
1162
+ }
1163
+ };
1164
+ read();
1165
+ const observer = new MutationObserver(read);
1166
+ observer.observe(plotEl, { childList: true, subtree: true, attributes: true, attributeFilter: ["tabindex"] });
1167
+ return () => {
1168
+ observer.disconnect();
1169
+ counted?.();
1170
+ };
1171
+ }, [drawing, plotEl]);
1134
1172
  const switcher = access ? /* @__PURE__ */ jsx(FormChangeCtx, { value: null, children: /* @__PURE__ */ jsx(
1135
1173
  SegmentedControl,
1136
1174
  {
@@ -1153,7 +1191,7 @@ var ChartWrapper = forwardRef(function ChartWrapper2({
1153
1191
  "data-gs-chart": chart,
1154
1192
  "data-category-kind": categoryKind2,
1155
1193
  "data-categories": categories,
1156
- className: cn("relative flex w-full flex-col", fill && "h-full", className),
1194
+ className: cn("relative flex w-full flex-col", fill && "h-full", cell && "min-h-full", className),
1157
1195
  style: { containerType: "inline-size", minInlineSize: "min(100%, 16rem)", ...fill ? {} : { flex: "1 0 auto" } },
1158
1196
  children: [
1159
1197
  (headText || switcher && !actions) && /* @__PURE__ */ jsxs("div", { "data-chart-head": "", className: "mb-ds-3 flex items-start justify-between gap-ds-3", children: [
@@ -1179,7 +1217,7 @@ var ChartWrapper = forwardRef(function ChartWrapper2({
1179
1217
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0", style: drawn2 ? { minWidth: drawn2.width, minHeight: drawn2.height } : void 0, children: /* @__PURE__ */ jsx(ChartFrameContext.Provider, { value: frame, children: /* @__PURE__ */ jsx(PlotNames, { children }) }) })
1180
1218
  ]
1181
1219
  }
1182
- ) : /* @__PURE__ */ jsx(ChartTable, { table: access.table, name: `${ariaLabel || container?.title || "The chart"}: values`, labelledBy: ariaLabel ? void 0 : container?.titleId }),
1220
+ ) : /* @__PURE__ */ jsx(ChartTable, { table: access.table, name: `${ariaLabel || container?.title || "The chart"}: values`, labelledBy: ariaLabel ? void 0 : container?.titleId, cell }),
1183
1221
  /* @__PURE__ */ jsx("div", { ref: setLegend, "data-chart-legend": "" }),
1184
1222
  /* @__PURE__ */ jsx("div", { ref: setLive, role: "status", "aria-live": "polite", className: "sr-only" }),
1185
1223
  /* @__PURE__ */ jsx(
@@ -2722,7 +2760,7 @@ var TreemapChart = markChart(forwardRef(function TreemapChart2({
2722
2760
  children: showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}) })
2723
2761
  }
2724
2762
  ) }),
2725
- /* @__PURE__ */ jsx("span", { ref: probe2, "aria-hidden": true, className: LABEL_TEXT, style: { position: "absolute", visibility: "hidden", pointerEvents: "none" }, children: "M" })
2763
+ /* @__PURE__ */ jsx("span", { ref: probe2, "aria-hidden": true, className: LABEL_TEXT, style: { position: "absolute", top: 0, left: 0, visibility: "hidden", pointerEvents: "none" }, children: "M" })
2726
2764
  ] });
2727
2765
  }));
2728
2766
  function oneWayFlows(links) {
@@ -2893,10 +2931,11 @@ var Sparkline = forwardRef(function Sparkline2({
2893
2931
  const chartColor = useResolvedToken(tokenName);
2894
2932
  const softColor = useResolvedToken(softTokenName);
2895
2933
  const chartData = data.map((value, i) => ({ value, index: i }));
2934
+ const picture = ariaLabel ? { role: "img", "aria-label": ariaLabel } : { "aria-hidden": true };
2896
2935
  const containerStyle = insideContainer ? { width: "100%", height: "100%" } : { width: typeof width === "number" ? `${width}px` : width, height: `${height}px` };
2897
2936
  if (!data?.length) return null;
2898
2937
  if (variant === "bar") {
2899
- return /* @__PURE__ */ jsx("div", { ref, style: containerStyle, className, ...ariaLabel ? { role: "img", "aria-label": ariaLabel } : {}, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(BarChart$1, { data: chartData, margin: { top: 0, right: 0, bottom: 0, left: 0 }, children: [
2938
+ return /* @__PURE__ */ jsx("div", { ref, style: containerStyle, className, ...picture, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(BarChart$1, { data: chartData, margin: { top: 0, right: 0, bottom: 0, left: 0 }, accessibilityLayer: false, children: [
2900
2939
  /* @__PURE__ */ jsx(XAxis, { dataKey: "index", hide: true }),
2901
2940
  /* @__PURE__ */ jsx(YAxis, { hide: true }),
2902
2941
  showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}), cursor: false }),
@@ -2913,7 +2952,7 @@ var Sparkline = forwardRef(function Sparkline2({
2913
2952
  }
2914
2953
  if (variant === "area") {
2915
2954
  const gradientId = `sparkline-gradient-${instanceId}-${color}`;
2916
- return /* @__PURE__ */ jsx("div", { ref, style: containerStyle, className, ...ariaLabel ? { role: "img", "aria-label": ariaLabel } : {}, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(AreaChart$1, { data: chartData, margin: { top: 2, right: 2, bottom: 2, left: 2 }, children: [
2955
+ return /* @__PURE__ */ jsx("div", { ref, style: containerStyle, className, ...picture, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(AreaChart$1, { data: chartData, margin: { top: 2, right: 2, bottom: 2, left: 2 }, accessibilityLayer: false, children: [
2917
2956
  /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
2918
2957
  /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: softColor, stopOpacity: 1 }),
2919
2958
  /* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: softColor, stopOpacity: 0.1 })
@@ -2936,7 +2975,7 @@ var Sparkline = forwardRef(function Sparkline2({
2936
2975
  )
2937
2976
  ] }) }) });
2938
2977
  }
2939
- return /* @__PURE__ */ jsx("div", { ref, style: containerStyle, className, ...ariaLabel ? { role: "img", "aria-label": ariaLabel } : {}, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(LineChart$1, { data: chartData, margin: { top: 2, right: 2, bottom: 2, left: 2 }, children: [
2978
+ return /* @__PURE__ */ jsx("div", { ref, style: containerStyle, className, ...picture, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(LineChart$1, { data: chartData, margin: { top: 2, right: 2, bottom: 2, left: 2 }, accessibilityLayer: false, children: [
2940
2979
  /* @__PURE__ */ jsx(XAxis, { dataKey: "index", hide: true }),
2941
2980
  /* @__PURE__ */ jsx(YAxis, { hide: true, domain: ["dataMin - 1", "dataMax + 1"] }),
2942
2981
  showTooltip && /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartTooltipContent, {}), cursor: false }),
@@ -2954,10 +2993,12 @@ var Sparkline = forwardRef(function Sparkline2({
2954
2993
  )
2955
2994
  ] }) }) });
2956
2995
  });
2996
+ var CELL_BODY = "min-h-0 overflow-y-auto -m-[4px] p-[4px] scroll-p-[4px]";
2957
2997
  var CHART_TITLE_CLASSES = TITLE_TEXT;
2958
2998
  function ChartContainer({
2959
2999
  height = "auto",
2960
3000
  title,
3001
+ actions: pageActions,
2961
3002
  loading = false,
2962
3003
  emptyState,
2963
3004
  variant = "default",
@@ -2965,9 +3006,27 @@ function ChartContainer({
2965
3006
  className
2966
3007
  }) {
2967
3008
  const titleId = useId();
3009
+ const hint = useContext(DashboardCellContext) !== null;
3010
+ const rootRef = useRef(null);
3011
+ const [nested, setNested] = useState(false);
3012
+ useLayoutEffect(() => {
3013
+ if (hint) setNested(!rootRef.current?.matches(CELL_FRAME));
3014
+ }, [hint]);
3015
+ const cell = hint && !nested;
2968
3016
  const fixed = fixedChartHeight(height);
2969
3017
  const sizesItself = !loading && !!children && isLibraryChart(children);
2970
3018
  const area = fixed ?? CHART_HEIGHTS.md;
3019
+ const [bodyEl, setBodyEl] = useState(null);
3020
+ const [drawings, setDrawings] = useState(0);
3021
+ const drawing = useCallback(() => {
3022
+ setDrawings((n) => n + 1);
3023
+ return () => setDrawings((n) => n - 1);
3024
+ }, []);
3025
+ useKeyboardScroll(bodyEl, title || "Chart", cell && drawings === 0);
3026
+ const strayActions = !title && !!pageActions;
3027
+ useEffect(() => {
3028
+ if (strayActions) warnOnce("ChartContainer", "actions are drawn in the chart's header, beside its title, and this chart has no title: give it a title (what the chart is), or the actions don't show.");
3029
+ }, [strayActions]);
2971
3030
  const [actions, setActions] = useState(null);
2972
3031
  const [charts, setCharts] = useState(0);
2973
3032
  const register = useCallback(() => {
@@ -2975,8 +3034,8 @@ function ChartContainer({
2975
3034
  return () => setCharts((n) => n - 1);
2976
3035
  }, []);
2977
3036
  const context = useMemo(
2978
- () => ({ height: fixed, titleId: title ? titleId : void 0, title: title || void 0, fillArea: !sizesItself, actions, charts, register }),
2979
- [fixed, title, titleId, sizesItself, actions, charts, register]
3037
+ () => ({ height: fixed, titleId: title ? titleId : void 0, title: title || void 0, fillArea: !sizesItself, cell, actions, charts, register, drawing: cell ? drawing : void 0 }),
3038
+ [fixed, title, titleId, sizesItself, cell, actions, charts, register, drawing]
2980
3039
  );
2981
3040
  let body = null;
2982
3041
  if (loading) {
@@ -2985,16 +3044,17 @@ function ChartContainer({
2985
3044
  /* @__PURE__ */ jsx(Skeleton, { variant: "text", lines: 1, className: "w-full" })
2986
3045
  ] });
2987
3046
  } else if (children) {
2988
- body = /* @__PURE__ */ jsx(ChartContainerContext.Provider, { value: context, children: sizesItself ? children : (
3047
+ body = /* @__PURE__ */ jsx(ChartContainerContext.Provider, { value: context, children: /* @__PURE__ */ jsx(DashboardCellContext, { value: null, children: sizesItself || cell ? children : (
2989
3048
  // the area is absolute, so a child that fills 100% has a definite height to fill
2990
3049
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx("div", { className: "h-full w-full", children }) })
2991
- ) });
3050
+ ) }) });
2992
3051
  } else if (emptyState) {
2993
3052
  body = /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center", children: emptyState });
2994
3053
  }
2995
3054
  return /* @__PURE__ */ jsxs(
2996
3055
  "div",
2997
3056
  {
3057
+ ref: rootRef,
2998
3058
  "data-card": "",
2999
3059
  "data-gs": "chart",
3000
3060
  className: cn(
@@ -3008,16 +3068,21 @@ function ChartContainer({
3008
3068
  className
3009
3069
  ),
3010
3070
  children: [
3011
- title && /* @__PURE__ */ jsxs("div", { "data-chart-header": "", className: "mb-ds-4 flex items-start justify-between gap-ds-3", children: [
3012
- /* @__PURE__ */ jsx("h3", { id: titleId, className: cn(CHART_TITLE_CLASSES, "min-w-0 flex-1"), children: title }),
3071
+ title && // Sprint 32 (F2): CardHeader's rule for the title's room. Its basis is its floor (TITLE_FLOOR) and it takes what's
3072
+ // left, so the page's actions and the switch's slot, items of their own, wrap under it, at the end, only when the
3073
+ // title would go under its floor; a title that fits draws as before, and a word wider than the frame breaks there
3074
+ /* @__PURE__ */ jsxs("div", { "data-chart-header": "", className: cn("mb-ds-4 flex flex-wrap items-start justify-end gap-x-ds-3 gap-y-ds-2", CELL_ROOM_INNER, CELL_HIDE_CHART_ACTIONS), children: [
3075
+ /* @__PURE__ */ jsx("h3", { id: titleId, className: cn(CHART_TITLE_CLASSES, "min-w-0 grow me-auto", TITLE_FLOOR), children: title }),
3076
+ pageActions ? /* @__PURE__ */ jsx("div", { "data-chart-page-actions": "", className: "flex shrink-0 items-center gap-ds-2", children: pageActions }) : null,
3013
3077
  /* @__PURE__ */ jsx("div", { ref: setActions, "data-chart-actions": "", className: "shrink-0 empty:hidden" })
3014
3078
  ] }),
3015
3079
  /* @__PURE__ */ jsx(
3016
3080
  "div",
3017
3081
  {
3082
+ ref: setBodyEl,
3018
3083
  "data-chart-body": "",
3019
- className: "relative flex min-w-0 flex-col",
3020
- style: { flex: "1 1 0%", minHeight: sizesItself ? void 0 : area },
3084
+ className: cn("relative flex min-w-0 flex-col", cell && [CELL_BODY, FOCUS_INSET]),
3085
+ style: { flex: "1 1 0%", minHeight: sizesItself || cell ? void 0 : area },
3021
3086
  children: body
3022
3087
  }
3023
3088
  )