gridsmith-ui 0.26.0 → 0.27.0

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 (102) hide show
  1. package/CHANGELOG.md +969 -0
  2. package/README.md +21 -5
  3. package/dist/charts.d.ts +2 -2
  4. package/dist/charts.js +58 -43
  5. package/dist/charts.js.map +1 -1
  6. package/dist/chat.js +4 -3
  7. package/dist/chat.js.map +1 -1
  8. package/dist/{chunk-CYN5O567.js → chunk-2CKSSWYG.js} +9 -5
  9. package/dist/chunk-2CKSSWYG.js.map +1 -0
  10. package/dist/chunk-3BRQRKDO.js +1 -0
  11. package/dist/chunk-3BRQRKDO.js.map +1 -1
  12. package/dist/{chunk-RWKCAKN3.js → chunk-5TUVX4B2.js} +6 -5
  13. package/dist/chunk-5TUVX4B2.js.map +1 -0
  14. package/dist/{chunk-X2HEV7FB.js → chunk-64TXZ4L7.js} +23 -33
  15. package/dist/chunk-64TXZ4L7.js.map +1 -0
  16. package/dist/chunk-7Q46JXSK.js +1 -0
  17. package/dist/chunk-7Q46JXSK.js.map +1 -1
  18. package/dist/chunk-CRQ6KCRD.js +1 -0
  19. package/dist/chunk-CRQ6KCRD.js.map +1 -1
  20. package/dist/{chunk-ZYVXV4WC.js → chunk-EKBWWA6P.js} +53 -6
  21. package/dist/chunk-EKBWWA6P.js.map +1 -0
  22. package/dist/chunk-HP7WUZPK.js +1 -0
  23. package/dist/chunk-HP7WUZPK.js.map +1 -1
  24. package/dist/{chunk-MYIJNVTK.js → chunk-IXR4UEF4.js} +5 -4
  25. package/dist/chunk-IXR4UEF4.js.map +1 -0
  26. package/dist/chunk-M2QRNBDQ.js +1 -0
  27. package/dist/chunk-M2QRNBDQ.js.map +1 -1
  28. package/dist/chunk-MD2EFMES.js +1 -0
  29. package/dist/chunk-MD2EFMES.js.map +1 -1
  30. package/dist/chunk-NRHIYS5W.js +1 -0
  31. package/dist/chunk-NRHIYS5W.js.map +1 -1
  32. package/dist/chunk-OTCEJN64.js +1 -0
  33. package/dist/chunk-OTCEJN64.js.map +1 -1
  34. package/dist/chunk-OYNUU346.js +78 -0
  35. package/dist/chunk-OYNUU346.js.map +1 -0
  36. package/dist/{chunk-EX64MN2U.js → chunk-PO65I3MQ.js} +4 -3
  37. package/dist/chunk-PO65I3MQ.js.map +1 -0
  38. package/dist/chunk-QM4SJKWV.js +1 -0
  39. package/dist/chunk-QM4SJKWV.js.map +1 -1
  40. package/dist/{chunk-KWLNEH53.js → chunk-R5NFCEZ3.js} +10 -7
  41. package/dist/chunk-R5NFCEZ3.js.map +1 -0
  42. package/dist/chunk-SFY2KMHG.js +1 -0
  43. package/dist/chunk-SFY2KMHG.js.map +1 -1
  44. package/dist/{chunk-HXVXJUGV.js → chunk-TJEV7YAY.js} +38 -10
  45. package/dist/chunk-TJEV7YAY.js.map +1 -0
  46. package/dist/chunk-WH2FUFAC.js +1 -0
  47. package/dist/chunk-WH2FUFAC.js.map +1 -1
  48. package/dist/chunk-XVB55M3N.js +1 -0
  49. package/dist/chunk-XVB55M3N.js.map +1 -1
  50. package/dist/chunk-ZI3OQDET.js +1 -0
  51. package/dist/chunk-ZI3OQDET.js.map +1 -1
  52. package/dist/data-grid.d.ts +1 -1
  53. package/dist/data-grid.js +5 -3
  54. package/dist/data-grid.js.map +1 -1
  55. package/dist/editor-mentions.js +2 -1
  56. package/dist/editor-mentions.js.map +1 -1
  57. package/dist/editor.js +3 -2
  58. package/dist/editor.js.map +1 -1
  59. package/dist/{feather-VFWLAILO.js → feather-FNBQ74RR.js} +10 -17
  60. package/dist/feather-FNBQ74RR.js.map +1 -0
  61. package/dist/{heroicons-H3Z7DFCF.js → heroicons-DODCSYWD.js} +9 -8
  62. package/dist/heroicons-DODCSYWD.js.map +1 -0
  63. package/dist/icons.d.ts +31 -4
  64. package/dist/icons.js +2 -1
  65. package/dist/icons.js.map +1 -1
  66. package/dist/index.d.ts +418 -65
  67. package/dist/index.js +1893 -838
  68. package/dist/index.js.map +1 -1
  69. package/dist/kanban.js +3 -2
  70. package/dist/kanban.js.map +1 -1
  71. package/dist/{lucide-MR32KM4G.js → lucide-ZWE3EPGP.js} +9 -8
  72. package/dist/lucide-ZWE3EPGP.js.map +1 -0
  73. package/dist/{phosphor-ABQQL5N5.js → phosphor-DIHPA4AJ.js} +9 -8
  74. package/dist/phosphor-DIHPA4AJ.js.map +1 -0
  75. package/dist/resizable.js +7 -5
  76. package/dist/resizable.js.map +1 -1
  77. package/dist/roots.css +25 -7
  78. package/dist/{tabler-ANUSY4D2.js → tabler-D3VYTSGI.js} +9 -8
  79. package/dist/tabler-D3VYTSGI.js.map +1 -0
  80. package/dist/tokens.css +11 -8
  81. package/dist/{use-pagination-BnKOnBdz.d.ts → use-pagination-BxcRlNQG.d.ts} +6 -0
  82. package/dist/utils.d.ts +275 -1
  83. package/dist/utils.js +875 -1
  84. package/dist/utils.js.map +1 -1
  85. package/dist/virtualized.d.ts +1 -1
  86. package/dist/virtualized.js +5 -3
  87. package/dist/virtualized.js.map +1 -1
  88. package/dist-static/tokens.css +11 -8
  89. package/package.json +5 -3
  90. package/dist/chunk-CYN5O567.js.map +0 -1
  91. package/dist/chunk-EX64MN2U.js.map +0 -1
  92. package/dist/chunk-HXVXJUGV.js.map +0 -1
  93. package/dist/chunk-KWLNEH53.js.map +0 -1
  94. package/dist/chunk-MYIJNVTK.js.map +0 -1
  95. package/dist/chunk-RWKCAKN3.js.map +0 -1
  96. package/dist/chunk-X2HEV7FB.js.map +0 -1
  97. package/dist/chunk-ZYVXV4WC.js.map +0 -1
  98. package/dist/feather-VFWLAILO.js.map +0 -1
  99. package/dist/heroicons-H3Z7DFCF.js.map +0 -1
  100. package/dist/lucide-MR32KM4G.js.map +0 -1
  101. package/dist/phosphor-ABQQL5N5.js.map +0 -1
  102. package/dist/tabler-ANUSY4D2.js.map +0 -1
package/README.md CHANGED
@@ -10,6 +10,8 @@ gridsmith-ui needs React 19. On a React 18 project, upgrade `react`, `react-dom`
10
10
  npm install gridsmith-ui
11
11
  ```
12
12
 
13
+ **Upgrading:** each release in `CHANGELOG.md` (in this package, `node_modules/gridsmith-ui/CHANGELOG.md`) ends with an upgrade note for agents: what an app on the previous version changes. A 0.x minor release can break code written for the one before, so `^0.26.0` never reaches 0.27.0 by itself.
14
+
13
15
  ### Charts (optional)
14
16
 
15
17
  ```bash
@@ -38,19 +40,28 @@ npm install react-resizable-panels # gridsmith-ui/
38
40
 
39
41
  ### Icon packs
40
42
 
41
- The `Icon` component uses `lucide-react` by default, and every other pack falls back to it for a missing name, so always install it. Other packs are loaded on demand — install only what you need:
43
+ The `Icon` component uses `lucide-react` by default, and every other pack falls back to it for a missing name, so always install it. For another pack, install it and register it once, at the top of your app's shell (in Next.js the shell is a client file; never the root layout, a server component) and before any `preloadPack`: the library names no pack but Lucide, so your bundler (Next.js's included) only meets the pack you installed. A pack you draw without registering it draws Lucide's icons, and in development the console names the line to add.
42
44
 
43
45
  ```bash
44
46
  # Default and fallback (required)
45
47
  npm install lucide-react
46
48
 
47
- # Alternative packs
49
+ # Alternative packs: install the one your theme uses
48
50
  npm install @phosphor-icons/react # phosphor
49
51
  npm install @heroicons/react # heroicons
50
52
  npm install @tabler/icons-react # tabler
51
53
  npm install react-icons # feather (via react-icons)
52
54
  ```
53
55
 
56
+ ```tsx
57
+ import { registerIconPack } from "gridsmith-ui/icons";
58
+
59
+ registerIconPack("feather", () => import("react-icons/fi"));
60
+ // phosphor: () => import("@phosphor-icons/react")
61
+ // heroicons: () => import("@heroicons/react/24/outline")
62
+ // tabler: () => import("@tabler/icons-react")
63
+ ```
64
+
54
65
  ## Setup
55
66
 
56
67
  Import the design tokens and Tailwind bindings in your CSS entry point:
@@ -68,7 +79,7 @@ Import the design tokens and Tailwind bindings in your CSS entry point:
68
79
  - **tailwind.css** — maps `--ds-*` tokens to Tailwind utilities (`p-ds-4`, `text-2xs`, `opacity-disabled`)
69
80
  - **@source** — tells Tailwind to scan the compiled components; without it they render unstyled. It must come after every `@import`.
70
81
 
71
- For the fastest icon rendering on cold loads, call `preloadPack` in your entry point before `createRoot`:
82
+ For the fastest icon rendering on cold loads, call `preloadPack` in your entry point before `createRoot` (in Next.js, at the top of the shell), another pack's after its registration:
72
83
 
73
84
  ```tsx
74
85
  import { preloadPack } from "gridsmith-ui/icons";
@@ -77,6 +88,8 @@ preloadPack("lucide");
77
88
 
78
89
  ## Entry Points
79
90
 
91
+ Every entry but `gridsmith-ui/utils` is client code, each file opening with `"use client"`. In Next.js (15 or later), a server component (a page with no `'use client'` of its own) renders the components with plain data: text, numbers, dates, elements. A function (`onClick`, `onChange`, a column's `render`) needs a client component of yours, and so does calling the library's hooks; a server page hands the library's constants and contexts on as they are, without reading them, and renders a compound part by its own name (`TabsList` for `Tabs.List`, `CollapsibleTrigger` for `Collapsible.Trigger`). On the server (a page, a route handler, a server action), call the helpers from `gridsmith-ui/utils`, passing them `requestLocale(LANG, acceptLanguage)` so their words read as the components' do; a Date is read there in the server's time zone, so hand `RelativeTime` and the Calendar the data for what the visitor reads in their own. Vite and Remix ignore the marker.
92
+
80
93
  | Import path | What it provides |
81
94
  |---|---|
82
95
  | `gridsmith-ui` | Every component outside the entry points below (actions, forms, data display, navigation, overlays, feedback, layout) |
@@ -88,8 +101,8 @@ preloadPack("lucide");
88
101
  | `gridsmith-ui/data-grid` | `DataGrid` (requires `@tanstack/react-table`) |
89
102
  | `gridsmith-ui/virtualized` | `VirtualizedList` (requires `@tanstack/react-virtual`) |
90
103
  | `gridsmith-ui/resizable` | `ResizablePanelGroup`, `ResizablePanel`, `ResizableHandle`, `SplitView` (requires `react-resizable-panels`) |
91
- | `gridsmith-ui/icons` | `Icon`, `IconProvider`, `preloadPack` — 5 icon packs with two-phase loading |
92
- | `gridsmith-ui/utils` | `cn()` — className merge utility (clsx + tailwind-merge) |
104
+ | `gridsmith-ui/icons` | `Icon`, `IconProvider`, `preloadPack`, `registerIconPack` — 5 icon packs with two-phase loading |
105
+ | `gridsmith-ui/utils` | `cn()` — className merge utility (clsx + tailwind-merge) — 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 |
93
106
  | `gridsmith-ui/roots.css` | CSS custom property engine |
94
107
  | `gridsmith-ui/tokens.css` | Default preset token values |
95
108
  | `gridsmith-ui/tailwind.css` | Tailwind v4 `@theme` bindings for `--ds-*` tokens |
@@ -100,6 +113,7 @@ preloadPack("lucide");
100
113
  import { Button, Card, Input, Table } from "gridsmith-ui";
101
114
  import { BarChart, LineChart } from "gridsmith-ui/charts";
102
115
  import { RichTextEditor } from "gridsmith-ui/editor";
116
+ import { useMentions } from "gridsmith-ui/editor-mentions";
103
117
  import { MarkdownContent } from "gridsmith-ui/chat";
104
118
  import { KanbanBoard } from "gridsmith-ui/kanban";
105
119
  import { DataGrid } from "gridsmith-ui/data-grid";
@@ -136,6 +150,8 @@ Wrap your app in `<IconProvider>` to select a pack:
136
150
  - **Import errors after installing a package while `vite` is running** — restart with `npm run dev -- --force` (or delete `node_modules/.vite`); Vite's dependency cache otherwise serves the pre-install module graph.
137
151
  - **Components render unstyled** — add `@source "../node_modules/gridsmith-ui/dist/*.js"` to your CSS entry point *after* every `@import`. Tailwind v4 needs it to scan the compiled components, and rejects an `@import` that follows it.
138
152
  - **`IconProvider` is not exported** — upgrade to a current `gridsmith-ui`; the provider ships from the `gridsmith-ui/icons` entry point.
153
+ - **"Attempted to call … from the server" in Next.js** — a server component called one of the library's functions or hooks: take the helper from `gridsmith-ui/utils`, or mark the file `'use client'`. "Functions cannot be passed directly to Client Components" — it handed a component a function: move that element into a client component of yours.
154
+ - **A component test in jsdom fails on `ResizeObserver`** — jsdom has none: stub it in the test setup (`globalThis.ResizeObserver = class { observe() {} unobserve() {} disconnect() {} }`), as the components measure their width.
139
155
 
140
156
  ## Peer Dependencies
141
157
 
package/dist/charts.d.ts CHANGED
@@ -18,7 +18,7 @@ type CategoryKind = "names" | "scale";
18
18
  * anchored pattern to be "scale"; an all-empty set is "scale". LineChart and AreaChart are always "scale"; BarChart and
19
19
  * CompositeChart guess with this, and their `categoryKind` prop overrides the guess.
20
20
  */
21
- declare function categoryKind(labels: ReadonlyArray<unknown>): CategoryKind;
21
+ declare function categoryKind(labels: ReadonlyArray<unknown>, locale?: string): CategoryKind;
22
22
 
23
23
  type XAxisInterval = number | "preserveStart" | "preserveEnd" | "preserveStartEnd" | "equidistantPreserveStart";
24
24
 
@@ -399,4 +399,4 @@ declare function ChartContainer({ height, title, loading, emptyState, variant, c
399
399
 
400
400
  declare function useChartColors(count: number, soft?: boolean): string[];
401
401
 
402
- export { AreaChart, type AreaChartProps, type AreaDef, BarChart, type BarChartProps, type BarDef, ChartContainer, CompositeChart, type CompositeChartProps, FunnelChart, type FunnelChartProps, LineChart, type LineChartProps, type LineDef, PieChart, type PieChartProps, RadarChart, type RadarChartProps, type RadarDataKey, RadialBarChart, type RadialBarChartProps, SankeyChart, type SankeyChartProps, ScatterChart, type ScatterChartProps, type ScatterSeries, Sparkline, type SparklineProps, TreemapChart, type TreemapChartProps, type TreemapNode, type ValueFormat, categoryKind, useChartColors };
402
+ export { AreaChart, type AreaChartProps, type AreaDef, BarChart, type BarChartProps, type BarDef, type CategoryKind, ChartContainer, CompositeChart, type CompositeChartProps, FunnelChart, type FunnelChartProps, LineChart, type LineChartProps, type LineDef, PieChart, type PieChartProps, RadarChart, type RadarChartProps, type RadarDataKey, RadialBarChart, type RadialBarChartProps, SankeyChart, type SankeyChartProps, ScatterChart, type ScatterChartProps, type ScatterSeries, Sparkline, type SparklineProps, TreemapChart, type TreemapChartProps, type TreemapNode, type ValueFormat, categoryKind, useChartColors };
package/dist/charts.js CHANGED
@@ -1,4 +1,6 @@
1
- import { formatLocale, TITLE_TEXT, Skeleton } from './chunk-X2HEV7FB.js';
1
+ "use client";
2
+ import { useFormatLocale, useHydrated, TITLE_TEXT, Skeleton } from './chunk-64TXZ4L7.js';
3
+ import { formatLocale, elementType } from './chunk-OYNUU346.js';
2
4
  import { mergeRefs } from './chunk-7Q46JXSK.js';
3
5
  import { cn, GLASS_SURFACE } from './chunk-M2QRNBDQ.js';
4
6
  import { createContext, forwardRef, useContext, useRef, useState, useMemo, useLayoutEffect, useEffect, useId, useSyncExternalStore, Children, isValidElement } from 'react';
@@ -194,8 +196,12 @@ function intlNames(locale, kind) {
194
196
  }
195
197
  return out;
196
198
  }
197
- function locales() {
199
+ function locales(given) {
198
200
  const out = /* @__PURE__ */ new Set(["en"]);
201
+ if (given !== void 0) {
202
+ out.add(given);
203
+ return [...out];
204
+ }
199
205
  try {
200
206
  out.add(new Intl.DateTimeFormat().resolvedOptions().locale);
201
207
  } catch {
@@ -205,8 +211,8 @@ function locales() {
205
211
  return [...out];
206
212
  }
207
213
  var cached = null;
208
- function patterns() {
209
- const tags = locales();
214
+ function patterns(given) {
215
+ const tags = locales(given);
210
216
  const key = tags.join("|");
211
217
  if (cached?.key === key) return cached;
212
218
  const months = new Set(ENGLISH_MONTHS);
@@ -258,8 +264,8 @@ function patterns() {
258
264
  cached = { key, list };
259
265
  return cached;
260
266
  }
261
- function categoryKind(labels) {
262
- const { list } = patterns();
267
+ function categoryKind(labels, locale) {
268
+ const { list } = patterns(locale);
263
269
  for (const raw of labels) {
264
270
  if (raw == null) continue;
265
271
  if (typeof raw === "number") {
@@ -407,7 +413,7 @@ function isLibraryChart(children) {
407
413
  if (kids.length !== 1) return false;
408
414
  const only = kids[0];
409
415
  if (!isValidElement(only)) return false;
410
- const type = only.type;
416
+ const type = elementType(only.type);
411
417
  return !!type && typeof type !== "string" && type[CHART_MARK] === true;
412
418
  }
413
419
  var ChartContainerContext = createContext(null);
@@ -534,7 +540,7 @@ function exact(format, maxDigits = MAX_FRACTION) {
534
540
  }
535
541
  return format(maxDigits);
536
542
  }
537
- var unitFormat = (unit, value) => (digits) => new Intl.NumberFormat(formatLocale(), { style: "unit", unit, unitDisplay: "short", maximumFractionDigits: digits }).format(value);
543
+ var unitFormat = (unit, value, locale) => (digits) => new Intl.NumberFormat(locale, { style: "unit", unit, unitDisplay: "short", maximumFractionDigits: digits }).format(value);
538
544
  var unitsOf = (format) => format === "bytes" ? BYTE_UNITS : TIME_UNITS;
539
545
  function unitReached(units, value) {
540
546
  return units.find(([, size]) => Math.abs(value) >= size) ?? units[units.length - 1];
@@ -552,26 +558,26 @@ function valueAxisTicks(values) {
552
558
  if (lo === hi) return [lo];
553
559
  return getNiceTickValues([lo, hi], TICK_COUNT, true).map(Number);
554
560
  }
555
- function axisTickFormatter(values, format = "number") {
561
+ function axisTickFormatter(values, format, locale) {
556
562
  if (typeof format === "function") return format;
557
- if (format === "percent") return (value) => exact((d) => new Intl.NumberFormat(formatLocale(), { style: "percent", maximumFractionDigits: d }).format(value / 100));
563
+ if (format === "percent") return (value) => exact((d) => new Intl.NumberFormat(locale, { style: "percent", maximumFractionDigits: d }).format(value / 100));
558
564
  if (format === "milliseconds" || format === "bytes") {
559
565
  const [unit, size] = axisUnit(unitsOf(format), valueAxisTicks(values));
560
- return (value) => exact(unitFormat(unit, value / size));
566
+ return (value) => exact(unitFormat(unit, value / size, locale));
561
567
  }
562
- const compact = (value) => exact((d) => new Intl.NumberFormat(formatLocale(), { notation: "compact", maximumFractionDigits: d }).format(value));
563
- const plain = (value) => exact((d) => new Intl.NumberFormat(formatLocale(), { maximumFractionDigits: d }).format(value));
568
+ const compact = (value) => exact((d) => new Intl.NumberFormat(locale, { notation: "compact", maximumFractionDigits: d }).format(value));
569
+ const plain = (value) => exact((d) => new Intl.NumberFormat(locale, { maximumFractionDigits: d }).format(value));
564
570
  const largest = Math.max(0, ...values.filter(Number.isFinite).map(Math.abs));
565
571
  return largest >= COMPACT_FROM ? compact : plain;
566
572
  }
567
573
  var COMPACT_FROM = 1e4;
568
- function fullValueFormatter(format = "number") {
574
+ function fullValueFormatter(format, locale) {
569
575
  if (typeof format === "function") return format;
570
- if (format === "number") return (value) => value.toLocaleString(formatLocale());
571
- if (format === "percent") return (value) => exact((d) => new Intl.NumberFormat(formatLocale(), { style: "percent", maximumFractionDigits: d }).format(value / 100), 4);
576
+ if (format === void 0 || format === "number") return (value) => value.toLocaleString(locale);
577
+ if (format === "percent") return (value) => exact((d) => new Intl.NumberFormat(locale, { style: "percent", maximumFractionDigits: d }).format(value / 100), 4);
572
578
  return (value) => {
573
579
  const [unit, size] = unitReached(unitsOf(format), value);
574
- return exact(unitFormat(unit, value / size), 4);
580
+ return exact(unitFormat(unit, value / size, locale), 4);
575
581
  };
576
582
  }
577
583
  function axisExtent(data, series) {
@@ -595,10 +601,10 @@ function seriesValues(data, keys, stacked = false) {
595
601
  }
596
602
  var hasLabel = (label) => label != null && label !== "" && typeof label !== "number";
597
603
  var entryName = (entry, label) => !hasLabel(label) && typeof entry.payload?.name === "string" && entry.payload.name || entry.name;
598
- var entryValue = (entry, format) => typeof entry.value === "number" ? format ? format(entry.value, entry.dataKey) : entry.value.toLocaleString(formatLocale()) : entry.value;
599
- function tooltipAnnouncement(label, payload, format) {
604
+ var entryValue = (entry, format, locale) => typeof entry.value === "number" ? format ? format(entry.value, entry.dataKey) : entry.value.toLocaleString(locale) : entry.value;
605
+ function tooltipAnnouncement(label, payload, format, locale = formatLocale()) {
600
606
  if (!payload?.length) return "";
601
- const values = payload.map((entry) => `${entryName(entry, label)} ${entryValue(entry, format)}`).join(", ");
607
+ const values = payload.map((entry) => `${entryName(entry, label)} ${entryValue(entry, format, locale)}`).join(", ");
602
608
  return hasLabel(label) ? `${String(label)}: ${values}` : values;
603
609
  }
604
610
  function ChartTooltipContent({ active, payload, label }) {
@@ -607,6 +613,7 @@ function ChartTooltipContent({ active, payload, label }) {
607
613
  const textPrimary = useResolvedToken("--ds-text-primary");
608
614
  const textSecondary = useResolvedToken("--ds-text-secondary");
609
615
  const { live, formatValue } = useContext(ChartFrameContext);
616
+ const locale = useFormatLocale();
610
617
  const on = !!active && !!payload?.length;
611
618
  const showLabel = hasLabel(label);
612
619
  const box = on ? /* @__PURE__ */ jsxs(
@@ -634,7 +641,7 @@ function ChartTooltipContent({ active, payload, label }) {
634
641
  entryName(entry, label),
635
642
  ":"
636
643
  ] }),
637
- /* @__PURE__ */ jsx("span", { className: "tabular-nums", style: { color: textPrimary }, children: entryValue(entry, formatValue) })
644
+ /* @__PURE__ */ jsx("span", { className: "tabular-nums", style: { color: textPrimary }, children: entryValue(entry, formatValue, locale) })
638
645
  ] }, i);
639
646
  })
640
647
  ]
@@ -643,7 +650,7 @@ function ChartTooltipContent({ active, payload, label }) {
643
650
  if (live) {
644
651
  return /* @__PURE__ */ jsxs(Fragment, { children: [
645
652
  box,
646
- createPortal(on ? tooltipAnnouncement(label, payload, formatValue) : "", live)
653
+ createPortal(on ? tooltipAnnouncement(label, payload, formatValue, locale) : "", live)
647
654
  ] });
648
655
  }
649
656
  return /* @__PURE__ */ jsx("div", { role: "status", "aria-live": "polite", children: box });
@@ -888,12 +895,14 @@ var BarChart = markChart(forwardRef(function BarChart2({
888
895
  }, ref) {
889
896
  const wrapperRef = useRef(null);
890
897
  const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? "")), [data, xAxisKey]);
891
- const kind = categoryKind2 ?? categoryKind((data ?? []).map((d) => d[xAxisKey]));
898
+ const locale = useFormatLocale();
899
+ const hydrated = useHydrated();
900
+ const kind = categoryKind2 ?? categoryKind((data ?? []).map((d) => d[xAxisKey]), hydrated ? void 0 : locale);
892
901
  const names = kind === "names";
893
902
  const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);
894
903
  const values = useMemo(() => valueExtent(data ?? [], bars, stacked), [data, bars, stacked]);
895
- const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat), [values, valueFormat]);
896
- const fullFormat = useMemo(() => fullValueFormatter(valueFormat), [valueFormat]);
904
+ const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);
905
+ const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);
897
906
  const axisWidth = useMemo(
898
907
  () => measured.measure ? valueAxisWidth(values, measured.measure, tickFormat) : 0,
899
908
  [measured.measure, values, tickFormat]
@@ -1028,8 +1037,9 @@ var LineChart = markChart(forwardRef(function LineChart2({
1028
1037
  }, ref) {
1029
1038
  const wrapperRef = useRef(null);
1030
1039
  const values = useMemo(() => seriesValues(data ?? [], lines.map((s) => s.dataKey), false), [data, lines]);
1031
- const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat), [values, valueFormat]);
1032
- const fullFormat = useMemo(() => fullValueFormatter(valueFormat), [valueFormat]);
1040
+ const locale = useFormatLocale();
1041
+ const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);
1042
+ const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);
1033
1043
  const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, "scale");
1034
1044
  const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);
1035
1045
  const colors = useChartColors(lines.length, false);
@@ -1113,8 +1123,9 @@ var AreaChart = markChart(forwardRef(function AreaChart2({
1113
1123
  }, ref) {
1114
1124
  const wrapperRef = useRef(null);
1115
1125
  const values = useMemo(() => seriesValues(data ?? [], areas.map((s) => s.dataKey), stacked), [data, areas, stacked]);
1116
- const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat), [values, valueFormat]);
1117
- const fullFormat = useMemo(() => fullValueFormatter(valueFormat), [valueFormat]);
1126
+ const locale = useFormatLocale();
1127
+ const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);
1128
+ const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);
1118
1129
  const xTicks = useCategoryTicks(data, xAxisKey, wrapperRef, xAxisInterval, "scale");
1119
1130
  const measured = useAxisMeasure(wrapperRef, !!yAxisLabel && (data?.length ?? 0) > 0);
1120
1131
  const instanceId = useId();
@@ -1244,7 +1255,9 @@ var CompositeChart = markChart(forwardRef(function CompositeChart2({
1244
1255
  }, ref) {
1245
1256
  const wrapperRef = useRef(null);
1246
1257
  const labels = useMemo(() => (data ?? []).map((d) => String(d[xAxisKey] ?? "")), [data, xAxisKey]);
1247
- const kind = categoryKind2 ?? categoryKind((data ?? []).map((d) => d[xAxisKey]));
1258
+ const locale = useFormatLocale();
1259
+ const hydrated = useHydrated();
1260
+ const kind = categoryKind2 ?? categoryKind((data ?? []).map((d) => d[xAxisKey]), hydrated ? void 0 : locale);
1248
1261
  const names = kind === "names";
1249
1262
  const measured = useAxisMeasure(wrapperRef, (data?.length ?? 0) > 0);
1250
1263
  const [values, lineValues] = useMemo(() => {
@@ -1255,14 +1268,14 @@ var CompositeChart = markChart(forwardRef(function CompositeChart2({
1255
1268
  const lineValues2 = (data ?? []).flatMap((row) => lines.map((l) => Number(row[l.dataKey])));
1256
1269
  return [values2, lineValues2];
1257
1270
  }, [data, bars, lines, stacked, dualAxis]);
1258
- const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat), [values, valueFormat]);
1259
- const lineTickFormat = useMemo(() => axisTickFormatter(lineValues, lineValueFormat), [lineValues, lineValueFormat]);
1271
+ const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);
1272
+ const lineTickFormat = useMemo(() => axisTickFormatter(lineValues, lineValueFormat, locale), [lineValues, lineValueFormat, locale]);
1260
1273
  const fullFormat = useMemo(() => {
1261
- const bar = fullValueFormatter(valueFormat);
1262
- const line = fullValueFormatter(dualAxis ? lineValueFormat : valueFormat);
1274
+ const bar = fullValueFormatter(valueFormat, locale);
1275
+ const line = fullValueFormatter(dualAxis ? lineValueFormat : valueFormat, locale);
1263
1276
  const lineKeys = new Set(lines.map((l) => l.dataKey));
1264
1277
  return (value, dataKey) => dataKey && lineKeys.has(dataKey) ? line(value) : bar(value);
1265
- }, [valueFormat, lineValueFormat, dualAxis, lines]);
1278
+ }, [valueFormat, lineValueFormat, dualAxis, lines, locale]);
1266
1279
  const axisWidth = useMemo(() => {
1267
1280
  if (!measured.measure) return 0;
1268
1281
  return valueAxisWidth(values, measured.measure, tickFormat) + (dualAxis ? valueAxisWidth(lineValues, measured.measure, lineTickFormat) : 0);
@@ -1411,16 +1424,17 @@ var ScatterChart = markChart(forwardRef(function ScatterChart2({
1411
1424
  className
1412
1425
  }, ref) {
1413
1426
  const wrapperRef = useRef(null);
1427
+ const locale = useFormatLocale();
1414
1428
  const [xTickFormat, yTickFormat, fullFormat] = useMemo(() => {
1415
1429
  const points = (data ?? []).flatMap((s) => s.points);
1416
- const x = fullValueFormatter(xValueFormat);
1417
- const y = fullValueFormatter(valueFormat);
1430
+ const x = fullValueFormatter(xValueFormat, locale);
1431
+ const y = fullValueFormatter(valueFormat, locale);
1418
1432
  return [
1419
- axisTickFormatter(points.map((p) => p.x), xValueFormat),
1420
- axisTickFormatter(points.map((p) => p.y), valueFormat),
1421
- (value, dataKey) => dataKey === "x" ? x(value) : dataKey === "y" ? y(value) : value.toLocaleString(formatLocale())
1433
+ axisTickFormatter(points.map((p) => p.x), xValueFormat, locale),
1434
+ axisTickFormatter(points.map((p) => p.y), valueFormat, locale),
1435
+ (value, dataKey) => dataKey === "x" ? x(value) : dataKey === "y" ? y(value) : value.toLocaleString(locale)
1422
1436
  ];
1423
- }, [data, valueFormat, xValueFormat]);
1437
+ }, [data, valueFormat, xValueFormat, locale]);
1424
1438
  const measured = useAxisMeasure(wrapperRef, !!yLabel && (data?.length ?? 0) > 0);
1425
1439
  const colors = useChartColors(data.length, false);
1426
1440
  const gridStroke = useGridStroke();
@@ -1511,8 +1525,9 @@ var RadarChart = markChart(forwardRef(function RadarChart2({
1511
1525
  const isAnimated = useChartAnimation(animated);
1512
1526
  const legendVisible = showLegend ?? dataKeys.length >= 2;
1513
1527
  const values = useMemo(() => seriesValues(data ?? [], dataKeys.map((dk) => dk.key)), [data, dataKeys]);
1514
- const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat), [values, valueFormat]);
1515
- const fullFormat = useMemo(() => fullValueFormatter(valueFormat), [valueFormat]);
1528
+ const locale = useFormatLocale();
1529
+ const tickFormat = useMemo(() => axisTickFormatter(values, valueFormat, locale), [values, valueFormat, locale]);
1530
+ const fullFormat = useMemo(() => fullValueFormatter(valueFormat, locale), [valueFormat, locale]);
1516
1531
  if (!data?.length) return null;
1517
1532
  return /* @__PURE__ */ jsx(ChartWrapper, { ref, height, size: { model: "square" }, chart: "radar", className, "aria-label": ariaLabel, formatValue: fullFormat, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(RadarChart$1, { data, cx: "50%", cy: "50%", outerRadius: "75%", accessibilityLayer: true, children: [
1518
1533
  /* @__PURE__ */ jsx(PolarGrid, { stroke: "var(--ds-border-subtle)" }),