@camunda/design-system 0.58.0 → 0.60.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 (210) hide show
  1. package/dist/carbon-compat/accordion-skeleton.d.ts +8 -2
  2. package/dist/carbon-compat/accordion-skeleton.d.ts.map +1 -1
  3. package/dist/carbon-compat/accordion-skeleton.js +4 -2
  4. package/dist/carbon-compat/accordion-skeleton.js.map +1 -1
  5. package/dist/carbon-compat/c3-data-table.d.ts +7 -1
  6. package/dist/carbon-compat/c3-data-table.d.ts.map +1 -1
  7. package/dist/carbon-compat/c3-data-table.js +8 -6
  8. package/dist/carbon-compat/c3-data-table.js.map +1 -1
  9. package/dist/carbon-compat/code-snippet.d.ts +2 -2
  10. package/dist/carbon-compat/code-snippet.d.ts.map +1 -1
  11. package/dist/carbon-compat/code-snippet.js +8 -6
  12. package/dist/carbon-compat/code-snippet.js.map +1 -1
  13. package/dist/carbon-compat/error-boundary.d.ts +2 -1
  14. package/dist/carbon-compat/error-boundary.d.ts.map +1 -1
  15. package/dist/carbon-compat/error-boundary.js +11 -1
  16. package/dist/carbon-compat/error-boundary.js.map +1 -1
  17. package/dist/carbon-compat/filterable-multi-select.d.ts.map +1 -1
  18. package/dist/carbon-compat/filterable-multi-select.js +6 -1
  19. package/dist/carbon-compat/filterable-multi-select.js.map +1 -1
  20. package/dist/carbon-compat/modal.d.ts.map +1 -1
  21. package/dist/carbon-compat/modal.js +5 -1
  22. package/dist/carbon-compat/modal.js.map +1 -1
  23. package/dist/carbon-compat/multi-select.d.ts.map +1 -1
  24. package/dist/carbon-compat/multi-select.js +5 -1
  25. package/dist/carbon-compat/multi-select.js.map +1 -1
  26. package/dist/carbon-compat/search.d.ts +4 -1
  27. package/dist/carbon-compat/search.d.ts.map +1 -1
  28. package/dist/carbon-compat/search.js +4 -2
  29. package/dist/carbon-compat/search.js.map +1 -1
  30. package/dist/carbon-compat/table-batch-actions.d.ts +5 -1
  31. package/dist/carbon-compat/table-batch-actions.d.ts.map +1 -1
  32. package/dist/carbon-compat/table-batch-actions.js +8 -3
  33. package/dist/carbon-compat/table-batch-actions.js.map +1 -1
  34. package/dist/carbon-compat/table-expand.d.ts +5 -1
  35. package/dist/carbon-compat/table-expand.d.ts.map +1 -1
  36. package/dist/carbon-compat/table-expand.js +6 -2
  37. package/dist/carbon-compat/table-expand.js.map +1 -1
  38. package/dist/carbon-compat/table-select.d.ts +9 -2
  39. package/dist/carbon-compat/table-select.d.ts.map +1 -1
  40. package/dist/carbon-compat/table-select.js +5 -2
  41. package/dist/carbon-compat/table-select.js.map +1 -1
  42. package/dist/carbon-compat/table-toolbar.d.ts +1 -0
  43. package/dist/carbon-compat/table-toolbar.d.ts.map +1 -1
  44. package/dist/carbon-compat/table-toolbar.js +5 -2
  45. package/dist/carbon-compat/table-toolbar.js.map +1 -1
  46. package/dist/src/components/ui/alert-dialog.d.ts +11 -1
  47. package/dist/src/components/ui/alert-dialog.d.ts.map +1 -1
  48. package/dist/src/components/ui/alert-dialog.js +5 -4
  49. package/dist/src/components/ui/alert-dialog.js.map +1 -1
  50. package/dist/src/components/ui/alert.d.ts +3 -1
  51. package/dist/src/components/ui/alert.d.ts.map +1 -1
  52. package/dist/src/components/ui/alert.js +6 -2
  53. package/dist/src/components/ui/alert.js.map +1 -1
  54. package/dist/src/components/ui/app-header.d.ts +1 -0
  55. package/dist/src/components/ui/app-header.d.ts.map +1 -1
  56. package/dist/src/components/ui/app-header.js +4 -2
  57. package/dist/src/components/ui/app-header.js.map +1 -1
  58. package/dist/src/components/ui/app-sidebar.d.ts +49 -2
  59. package/dist/src/components/ui/app-sidebar.d.ts.map +1 -1
  60. package/dist/src/components/ui/app-sidebar.js +74 -22
  61. package/dist/src/components/ui/app-sidebar.js.map +1 -1
  62. package/dist/src/components/ui/breadcrumb.d.ts +7 -1
  63. package/dist/src/components/ui/breadcrumb.d.ts.map +1 -1
  64. package/dist/src/components/ui/breadcrumb.js +6 -3
  65. package/dist/src/components/ui/breadcrumb.js.map +1 -1
  66. package/dist/src/components/ui/c4-provider.d.ts +10 -0
  67. package/dist/src/components/ui/c4-provider.d.ts.map +1 -1
  68. package/dist/src/components/ui/c4-provider.js +11 -2
  69. package/dist/src/components/ui/c4-provider.js.map +1 -1
  70. package/dist/src/components/ui/card.d.ts +3 -1
  71. package/dist/src/components/ui/card.d.ts.map +1 -1
  72. package/dist/src/components/ui/card.js +18 -2
  73. package/dist/src/components/ui/card.js.map +1 -1
  74. package/dist/src/components/ui/chart.d.ts +1 -0
  75. package/dist/src/components/ui/chart.d.ts.map +1 -1
  76. package/dist/src/components/ui/chart.js +4 -2
  77. package/dist/src/components/ui/chart.js.map +1 -1
  78. package/dist/src/components/ui/code-block.d.ts +5 -0
  79. package/dist/src/components/ui/code-block.d.ts.map +1 -1
  80. package/dist/src/components/ui/code-block.js +15 -20
  81. package/dist/src/components/ui/code-block.js.map +1 -1
  82. package/dist/src/components/ui/combobox.d.ts +2 -0
  83. package/dist/src/components/ui/combobox.d.ts.map +1 -1
  84. package/dist/src/components/ui/combobox.js +55 -18
  85. package/dist/src/components/ui/combobox.js.map +1 -1
  86. package/dist/src/components/ui/data-table.d.ts +63 -6
  87. package/dist/src/components/ui/data-table.d.ts.map +1 -1
  88. package/dist/src/components/ui/data-table.js +38 -23
  89. package/dist/src/components/ui/data-table.js.map +1 -1
  90. package/dist/src/components/ui/date-picker.d.ts +1 -0
  91. package/dist/src/components/ui/date-picker.d.ts.map +1 -1
  92. package/dist/src/components/ui/date-picker.js +6 -2
  93. package/dist/src/components/ui/date-picker.js.map +1 -1
  94. package/dist/src/components/ui/date-range-picker.d.ts +3 -0
  95. package/dist/src/components/ui/date-range-picker.d.ts.map +1 -1
  96. package/dist/src/components/ui/date-range-picker.js +26 -5
  97. package/dist/src/components/ui/date-range-picker.js.map +1 -1
  98. package/dist/src/components/ui/dialog.d.ts +23 -3
  99. package/dist/src/components/ui/dialog.d.ts.map +1 -1
  100. package/dist/src/components/ui/dialog.js +15 -9
  101. package/dist/src/components/ui/dialog.js.map +1 -1
  102. package/dist/src/components/ui/file-uploader.d.ts +4 -4
  103. package/dist/src/components/ui/file-uploader.d.ts.map +1 -1
  104. package/dist/src/components/ui/file-uploader.js +38 -9
  105. package/dist/src/components/ui/file-uploader.js.map +1 -1
  106. package/dist/src/components/ui/form-error-summary.d.ts +13 -0
  107. package/dist/src/components/ui/form-error-summary.d.ts.map +1 -0
  108. package/dist/src/components/ui/form-error-summary.js +53 -0
  109. package/dist/src/components/ui/form-error-summary.js.map +1 -0
  110. package/dist/src/components/ui/inline-edit.d.ts +1 -1
  111. package/dist/src/components/ui/inline-edit.d.ts.map +1 -1
  112. package/dist/src/components/ui/inline-edit.js +17 -2
  113. package/dist/src/components/ui/inline-edit.js.map +1 -1
  114. package/dist/src/components/ui/meter.d.ts +1 -0
  115. package/dist/src/components/ui/meter.d.ts.map +1 -1
  116. package/dist/src/components/ui/meter.js +7 -3
  117. package/dist/src/components/ui/meter.js.map +1 -1
  118. package/dist/src/components/ui/multi-select.d.ts +16 -0
  119. package/dist/src/components/ui/multi-select.d.ts.map +1 -1
  120. package/dist/src/components/ui/multi-select.js +86 -23
  121. package/dist/src/components/ui/multi-select.js.map +1 -1
  122. package/dist/src/components/ui/multi-step-dialog.d.ts +35 -1
  123. package/dist/src/components/ui/multi-step-dialog.d.ts.map +1 -1
  124. package/dist/src/components/ui/multi-step-dialog.js +47 -8
  125. package/dist/src/components/ui/multi-step-dialog.js.map +1 -1
  126. package/dist/src/components/ui/nav-breadcrumb.d.ts +29 -12
  127. package/dist/src/components/ui/nav-breadcrumb.d.ts.map +1 -1
  128. package/dist/src/components/ui/nav-breadcrumb.js +69 -24
  129. package/dist/src/components/ui/nav-breadcrumb.js.map +1 -1
  130. package/dist/src/components/ui/notifications.d.ts +52 -5
  131. package/dist/src/components/ui/notifications.d.ts.map +1 -1
  132. package/dist/src/components/ui/notifications.js +25 -10
  133. package/dist/src/components/ui/notifications.js.map +1 -1
  134. package/dist/src/components/ui/overflow-strip.d.ts +18 -0
  135. package/dist/src/components/ui/overflow-strip.d.ts.map +1 -0
  136. package/dist/src/components/ui/overflow-strip.js +103 -0
  137. package/dist/src/components/ui/overflow-strip.js.map +1 -0
  138. package/dist/src/components/ui/scorecard.d.ts +1 -0
  139. package/dist/src/components/ui/scorecard.d.ts.map +1 -1
  140. package/dist/src/components/ui/scorecard.js +28 -4
  141. package/dist/src/components/ui/scorecard.js.map +1 -1
  142. package/dist/src/components/ui/search-input.d.ts +1 -1
  143. package/dist/src/components/ui/search-input.d.ts.map +1 -1
  144. package/dist/src/components/ui/search-input.js +4 -2
  145. package/dist/src/components/ui/search-input.js.map +1 -1
  146. package/dist/src/components/ui/select.d.ts +2 -2
  147. package/dist/src/components/ui/select.d.ts.map +1 -1
  148. package/dist/src/components/ui/select.js +123 -6
  149. package/dist/src/components/ui/select.js.map +1 -1
  150. package/dist/src/components/ui/sheet.d.ts +5 -2
  151. package/dist/src/components/ui/sheet.d.ts.map +1 -1
  152. package/dist/src/components/ui/sheet.js +4 -2
  153. package/dist/src/components/ui/sheet.js.map +1 -1
  154. package/dist/src/components/ui/sidebar-provider.d.ts.map +1 -1
  155. package/dist/src/components/ui/sidebar-provider.js +5 -1
  156. package/dist/src/components/ui/sidebar-provider.js.map +1 -1
  157. package/dist/src/components/ui/split-button.d.ts +1 -0
  158. package/dist/src/components/ui/split-button.d.ts.map +1 -1
  159. package/dist/src/components/ui/split-button.js +4 -2
  160. package/dist/src/components/ui/split-button.js.map +1 -1
  161. package/dist/src/components/ui/tabs.d.ts +2 -1
  162. package/dist/src/components/ui/tabs.d.ts.map +1 -1
  163. package/dist/src/components/ui/tabs.js +16 -4
  164. package/dist/src/components/ui/tabs.js.map +1 -1
  165. package/dist/src/components/ui/toast.d.ts +10 -4
  166. package/dist/src/components/ui/toast.d.ts.map +1 -1
  167. package/dist/src/components/ui/toast.js +213 -25
  168. package/dist/src/components/ui/toast.js.map +1 -1
  169. package/dist/src/components/ui/toggle-group.d.ts +7 -1
  170. package/dist/src/components/ui/toggle-group.d.ts.map +1 -1
  171. package/dist/src/components/ui/toggle-group.js +23 -4
  172. package/dist/src/components/ui/toggle-group.js.map +1 -1
  173. package/dist/src/components/ui/tree-view.d.ts +10 -2
  174. package/dist/src/components/ui/tree-view.d.ts.map +1 -1
  175. package/dist/src/components/ui/tree-view.js +67 -46
  176. package/dist/src/components/ui/tree-view.js.map +1 -1
  177. package/dist/src/components/ui/user-menu.d.ts +12 -1
  178. package/dist/src/components/ui/user-menu.d.ts.map +1 -1
  179. package/dist/src/components/ui/user-menu.js +5 -3
  180. package/dist/src/components/ui/user-menu.js.map +1 -1
  181. package/dist/src/hooks/use-is-truncated.d.ts +9 -5
  182. package/dist/src/hooks/use-is-truncated.d.ts.map +1 -1
  183. package/dist/src/hooks/use-is-truncated.js +20 -7
  184. package/dist/src/hooks/use-is-truncated.js.map +1 -1
  185. package/dist/src/index.d.ts +3 -0
  186. package/dist/src/index.d.ts.map +1 -1
  187. package/dist/src/index.js +3 -0
  188. package/dist/src/index.js.map +1 -1
  189. package/dist/src/lib/focus-visible-on-close.d.ts +28 -0
  190. package/dist/src/lib/focus-visible-on-close.d.ts.map +1 -1
  191. package/dist/src/lib/focus-visible-on-close.js +54 -1
  192. package/dist/src/lib/focus-visible-on-close.js.map +1 -1
  193. package/dist/src/lib/i18n/context.d.ts +48 -0
  194. package/dist/src/lib/i18n/context.d.ts.map +1 -0
  195. package/dist/src/lib/i18n/context.js +157 -0
  196. package/dist/src/lib/i18n/context.js.map +1 -0
  197. package/dist/src/lib/i18n/dictionary.d.ts +151 -0
  198. package/dist/src/lib/i18n/dictionary.d.ts.map +1 -0
  199. package/dist/src/lib/i18n/dictionary.js +134 -0
  200. package/dist/src/lib/i18n/dictionary.js.map +1 -0
  201. package/dist/src/lib/merge-refs.d.ts +8 -0
  202. package/dist/src/lib/merge-refs.d.ts.map +1 -0
  203. package/dist/src/lib/merge-refs.js +15 -0
  204. package/dist/src/lib/merge-refs.js.map +1 -0
  205. package/dist/src/lib/with-ref.d.ts +3 -1
  206. package/dist/src/lib/with-ref.d.ts.map +1 -1
  207. package/dist/src/lib/with-ref.js +0 -10
  208. package/dist/src/lib/with-ref.js.map +1 -1
  209. package/dist/styles.css +65 -6
  210. package/package.json +4 -2
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @internal
3
+ * Shared horizontal-overflow affordance for `TabsList` and `ToggleGroup`.
4
+ * Not part of the public API — never exported from `src/index.ts`.
5
+ */
6
+ import * as React from "react";
7
+ export type OverflowStripDirection = "before" | "after";
8
+ export declare function useOverflowStrip<T extends HTMLElement>(): {
9
+ ref: React.RefObject<T | null>;
10
+ hasMoreBefore: boolean;
11
+ hasMoreAfter: boolean;
12
+ scrollByStep: (direction: OverflowStripDirection) => void;
13
+ };
14
+ export declare function OverflowStripArrow({ direction, onScroll, }: {
15
+ direction: OverflowStripDirection;
16
+ onScroll: () => void;
17
+ }): React.JSX.Element;
18
+ //# sourceMappingURL=overflow-strip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overflow-strip.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/overflow-strip.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAExD,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,WAAW;;;;8BAsDtC,sBAAsB;EAsBrC;AAED,wBAAgB,kBAAkB,CAAC,EACjC,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,EAAE,sBAAsB,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,qBAqCA"}
@@ -0,0 +1,103 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * @internal
4
+ * Shared horizontal-overflow affordance for `TabsList` and `ToggleGroup`.
5
+ * Not part of the public API — never exported from `src/index.ts`.
6
+ */
7
+ import * as React from "react";
8
+ import { ChevronLeft, ChevronRight } from "../../icons/lucide.js";
9
+ import { useC4Dictionary } from "../../lib/i18n/context.js";
10
+ import { Button } from "./button.js";
11
+ const SCROLL_EDGE_EPSILON_PX = 1;
12
+ const SCROLL_STEP_RATIO = 0.8;
13
+ export function useOverflowStrip() {
14
+ const ref = React.useRef(null);
15
+ const [hasMoreBefore, setHasMoreBefore] = React.useState(false);
16
+ const [hasMoreAfter, setHasMoreAfter] = React.useState(false);
17
+ const recompute = React.useCallback(() => {
18
+ const node = ref.current;
19
+ if (node == null)
20
+ return;
21
+ // Vertical Tabs/ToggleGroup never scroll horizontally and never get
22
+ // arrows — Radix stamps `data-orientation` on this same list/root
23
+ // element, so no extra prop has to be threaded through to read it here.
24
+ if (node.dataset.orientation === "vertical") {
25
+ setHasMoreBefore(false);
26
+ setHasMoreAfter(false);
27
+ return;
28
+ }
29
+ setHasMoreBefore(node.scrollLeft > SCROLL_EDGE_EPSILON_PX);
30
+ setHasMoreAfter(node.scrollLeft <
31
+ node.scrollWidth - node.clientWidth - SCROLL_EDGE_EPSILON_PX);
32
+ }, []);
33
+ // No dependency list on purpose: items added to a strip that is already
34
+ // clamped change its `scrollWidth` but not its box, so neither the
35
+ // ResizeObserver below nor a scroll event would notice them.
36
+ React.useLayoutEffect(recompute);
37
+ React.useLayoutEffect(() => {
38
+ const node = ref.current;
39
+ if (node == null)
40
+ return;
41
+ node.addEventListener("scroll", recompute, { passive: true });
42
+ // A web font that lands after mount widens the labels of a strip whose
43
+ // own box is already clamped — no resize, no scroll, only a new
44
+ // `scrollWidth`. jsdom has no `document.fonts`.
45
+ document.fonts?.ready.then(recompute);
46
+ // jsdom (unit tests, and the non-browser half of the Storybook toolchain)
47
+ // has no ResizeObserver — skip live width tracking there instead of
48
+ // throwing on mount.
49
+ let resizeObserver;
50
+ if (typeof ResizeObserver !== "undefined") {
51
+ resizeObserver = new ResizeObserver(recompute);
52
+ resizeObserver.observe(node);
53
+ }
54
+ return () => {
55
+ node.removeEventListener("scroll", recompute);
56
+ resizeObserver?.disconnect();
57
+ };
58
+ }, [recompute]);
59
+ const scrollByStep = React.useCallback((direction) => {
60
+ const node = ref.current;
61
+ if (node == null)
62
+ return;
63
+ const delta = node.clientWidth *
64
+ SCROLL_STEP_RATIO *
65
+ (direction === "before" ? -1 : 1);
66
+ // No explicit `behavior` option: the list itself carries
67
+ // `motion-safe:scroll-smooth`, and `scrollBy`'s default ("auto") defers
68
+ // to that CSS property, unlike assigning `scrollLeft` directly, which is
69
+ // always instant regardless of `scroll-behavior`.
70
+ if (typeof node.scrollBy === "function") {
71
+ node.scrollBy({ left: delta });
72
+ }
73
+ else {
74
+ // jsdom has no `scrollBy` implementation.
75
+ node.scrollLeft += delta;
76
+ }
77
+ }, []);
78
+ return { ref, hasMoreBefore, hasMoreAfter, scrollByStep };
79
+ }
80
+ export function OverflowStripArrow({ direction, onScroll, }) {
81
+ const { t } = useC4Dictionary();
82
+ const Icon = direction === "before" ? ChevronLeft : ChevronRight;
83
+ // Two literal `t()` call sites rather than one call with a computed key —
84
+ // dictionary-usage.test.mjs's static audit only recognizes a key that
85
+ // appears as `t("literal.key")` verbatim, not one assembled at runtime.
86
+ const label = direction === "before"
87
+ ? t("overflowStrip.previous")
88
+ : t("overflowStrip.next");
89
+ return (_jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", "data-slot": "overflow-strip-arrow", "data-direction": direction,
90
+ // Pointer/touch affordance only: keyboard users already move between
91
+ // items with the arrow keys, and the browser scrolls the newly
92
+ // focused item into view on its own — so this button is never part of
93
+ // the keyboard path, and `aria-hidden` keeps it out of the tablist/
94
+ // group's accessible child count. The `aria-label` still follows the
95
+ // usual icon-only-element rule, since assistive tech attached
96
+ // directly to the DOM node (rather than walking the a11y tree) can
97
+ // still surface it.
98
+ tabIndex: -1, "aria-hidden": "true", "aria-label": label,
99
+ // `tabIndex={-1}` still takes focus on click; keeping it on the active
100
+ // item means the arrow keys keep working right after a click.
101
+ onPointerDown: (event) => event.preventDefault(), onClick: onScroll, className: "shrink-0", children: _jsx(Icon, { "aria-hidden": "true" }) }));
102
+ }
103
+ //# sourceMappingURL=overflow-strip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overflow-strip.js","sourceRoot":"","sources":["../../../../src/components/ui/overflow-strip.tsx"],"names":[],"mappings":"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"}
@@ -18,6 +18,7 @@ interface ScorecardProps {
18
18
  size?: "default" | "sm";
19
19
  loading?: boolean;
20
20
  empty?: boolean;
21
+ /** Content shown in place of `value` when `empty` is set. Sourced from the i18n dictionary at key `"scorecard.empty"` when omitted. */
21
22
  emptyMessage?: string;
22
23
  className?: string;
23
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scorecard.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/scorecard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;IACnC,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC5C;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,cAAc;IACtB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkFD,iBAAS,SAAS,CAAC,EACjB,KAAK,EACL,OAAO,EACP,KAAK,EACL,KAAK,EACL,SAAS,EACT,MAAa,EACb,IAAgB,EAChB,OAAe,EACf,KAAa,EACb,YAAwB,EACxB,SAAS,GACV,EAAE,cAAc,qBAwDhB;AAED,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,sBAAsB,EAAE,CAAC"}
1
+ {"version":3,"file":"scorecard.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/scorecard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAY/B,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;IACnC,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC5C;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,cAAc;IACtB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uIAAuI;IACvI,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyHD,iBAAS,SAAS,CAAC,EACjB,KAAK,EACL,OAAO,EACP,KAAK,EACL,KAAK,EACL,SAAS,EACT,MAAa,EACb,IAAgB,EAChB,OAAe,EACf,KAAa,EACb,YAAY,EACZ,SAAS,GACV,EAAE,cAAc,qBA6DhB;AAED,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,sBAAsB,EAAE,CAAC"}
@@ -2,11 +2,23 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
2
2
  import * as React from "react";
3
3
  import { ArrowDownRight, ArrowUpRight } from "../../icons/lucide.js";
4
4
  import { cn } from "../../lib/utils.js";
5
+ import { useC4Dictionary } from "../../lib/i18n/context.js";
6
+ import { useIsTruncated } from "../../hooks/use-is-truncated.js";
5
7
  import { Badge } from "./badge.js";
6
8
  import { Card, CardHeader, CardTitle } from "./card.js";
7
9
  import { Skeleton } from "./skeleton.js";
8
10
  import { Sparkline } from "./sparkline.js";
11
+ import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
9
12
  function ScorecardBody({ label, tooltip, value, delta, sparkline, size, loading, empty, emptyMessage, asCard, }) {
13
+ // Hook must run unconditionally, above the `loading` early return below, or
14
+ // the loading→loaded transition changes this component's hook count. During
15
+ // loading the value span isn't rendered, so `ref.current` is null and
16
+ // `measure()` is a no-op (same situation multi-select's placeholder hook is
17
+ // in while chips are showing instead).
18
+ const { ref: valueRef, isTruncated: valueTruncated, measure: measureValue, } = useIsTruncated();
19
+ React.useLayoutEffect(() => {
20
+ measureValue();
21
+ });
10
22
  if (loading) {
11
23
  return (_jsxs(_Fragment, { children: [_jsx(Skeleton, { className: "h-4 w-24" }), _jsx(Skeleton, { className: cn("h-7 w-20", size === "sm" && "h-6 w-16") })] }));
12
24
  }
@@ -21,12 +33,22 @@ function ScorecardBody({ label, tooltip, value, delta, sparkline, size, loading,
21
33
  const sparklineElement = sparkline ? (_jsx(Sparkline, { data: sparkline.data, dataKey: sparkline.dataKey, loading: false, activeDot: false, className: asCard
22
34
  ? "w-auto -mx-4 -mb-4 group-data-[size=sm]/card:-mx-3 group-data-[size=sm]/card:-mb-3"
23
35
  : undefined })) : null;
24
- return (_jsxs(_Fragment, { children: [_jsx(CardTitle, { tooltip: tooltip, className: "text-sm font-normal", children: label }), _jsx("div", { className: "flex min-w-0 items-center", children: _jsxs("span", { className: "inline-flex min-w-0 max-w-full items-center gap-2", children: [_jsx("span", { className: cn("min-w-0 truncate text-2xl font-semibold text-neutral-foreground-strong", size === "sm" && "text-xl"), children: empty ? emptyMessage : value }), !empty && delta && (_jsxs(Badge, { variant: delta.variant, className: "shrink-0", children: [_jsx(DeltaIcon, { "data-icon": "inline-start", "aria-hidden": "true" }), _jsx("span", { className: "sr-only", children: delta.direction === "increase"
36
+ const valueContent = empty ? emptyMessage : value;
37
+ // No focusable ancestor wraps this KPI value — plain static text, per the
38
+ // "Truncated Text" decision tree in docs/specs/shadcn/patterns.md.
39
+ // `tabIndex={0}` goes directly on the value span. `ring-inset`: this span
40
+ // lives inside `<Card>`'s own `overflow-hidden` (when `asCard`), same clip
41
+ // risk nav-breadcrumb.tsx's label button ring documents.
42
+ const valueSpan = (_jsx("span", { ref: valueRef, tabIndex: 0, onPointerEnter: measureValue, onFocus: measureValue, className: cn("min-w-0 truncate rounded-sm text-2xl font-semibold text-neutral-foreground-strong outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset", size === "sm" && "text-xl"), children: valueContent }));
43
+ const valueElement = valueTruncated ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: valueSpan }), _jsx(TooltipContent, { children: valueContent })] })) : (valueSpan);
44
+ return (_jsxs(_Fragment, { children: [_jsx(CardTitle, { tooltip: tooltip, className: "text-sm font-normal", children: label }), _jsx("div", { className: "flex min-w-0 items-center", children: _jsxs("span", { className: "inline-flex min-w-0 max-w-full items-center gap-2", children: [valueElement, !empty && delta && (_jsxs(Badge, { variant: delta.variant, className: "shrink-0", children: [_jsx(DeltaIcon, { "data-icon": "inline-start", "aria-hidden": "true" }), _jsx("span", { className: "sr-only", children: delta.direction === "increase"
25
45
  ? "Increased by "
26
46
  : "Decreased by " }), delta.value] }))] }) }), !empty && sparklineElement] }));
27
47
  }
28
- function Scorecard({ label, tooltip, value, delta, sparkline, asCard = true, size = "default", loading = false, empty = false, emptyMessage = "No data", className, }) {
29
- const content = (_jsx(ScorecardBody, { label: label, tooltip: tooltip, value: value, delta: delta, sparkline: sparkline, size: size, loading: loading, empty: empty, emptyMessage: emptyMessage, asCard: asCard }));
48
+ function Scorecard({ label, tooltip, value, delta, sparkline, asCard = true, size = "default", loading = false, empty = false, emptyMessage, className, }) {
49
+ const { t } = useC4Dictionary();
50
+ const resolvedEmptyMessage = emptyMessage ?? t("scorecard.empty");
51
+ const content = (_jsx(ScorecardBody, { label: label, tooltip: tooltip, value: value, delta: delta, sparkline: sparkline, size: size, loading: loading, empty: empty, emptyMessage: resolvedEmptyMessage, asCard: asCard }));
30
52
  // Loading removes the title from the accessible tree (it becomes a
31
53
  // Skeleton), so `aria-busy` alone would leave the busy region unnamed.
32
54
  // `aria-label` alone isn't enough either: the root is a plain `<div>`
@@ -34,7 +56,9 @@ function Scorecard({ label, tooltip, value, delta, sparkline, asCard = true, siz
34
56
  // — axe flags it as `aria-prohibited-attr`. `role="status"` (same fix
35
57
  // `tree-view.tsx`'s own loading state already uses) both permits the name
36
58
  // and gets the busy→loaded transition announced as a polite live region.
37
- const loadingLabel = typeof label === "string" ? `Loading ${label}` : "Loading";
59
+ const loadingLabel = typeof label === "string"
60
+ ? t("scorecard.loading", { label })
61
+ : t("scorecard.loadingFallback");
38
62
  if (asCard) {
39
63
  return (_jsx(Card, { size: size, "aria-busy": loading || undefined, role: loading ? "status" : undefined, "aria-live": loading ? "polite" : undefined, "aria-label": loading ? loadingLabel : undefined, className: cn("text-neutral-foreground-subtle", className), children: _jsx(CardHeader, { children: content }) }));
40
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scorecard.js","sourceRoot":"","sources":["../../../../src/components/ui/scorecard.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scorecard.js","sourceRoot":"","sources":["../../../../src/components/ui/scorecard.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AA4BpE,SAAS,aAAa,CAAC,EACrB,KAAK,EACL,OAAO,EACP,KAAK,EACL,KAAK,EACL,SAAS,EACT,IAAI,EACJ,OAAO,EACP,KAAK,EACL,YAAY,EACZ,MAAM,GAIqE;IAC3E,4EAA4E;IAC5E,4EAA4E;IAC5E,sEAAsE;IACtE,4EAA4E;IAC5E,uCAAuC;IACvC,MAAM,EACJ,GAAG,EAAE,QAAQ,EACb,WAAW,EAAE,cAAc,EAC3B,OAAO,EAAE,YAAY,GACtB,GAAG,cAAc,EAAmB,CAAC;IAEtC,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE;QACzB,YAAY,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CACL,8BACE,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,IAAI,UAAU,CAAC,GAAI,IACnE,CACJ,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GACb,KAAK,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC;IAClE,qEAAqE;IACrE,sEAAsE;IACtE,0EAA0E;IAC1E,sEAAsE;IACtE,yEAAyE;IACzE,sEAAsE;IACtE,kEAAkE;IAClE,MAAM,gBAAgB,GAAG,SAAS,CAAC,CAAC,CAAC,CACnC,KAAC,SAAS,IACR,IAAI,EAAE,SAAS,CAAC,IAAI,EACpB,OAAO,EAAE,SAAS,CAAC,OAAO,EAC1B,OAAO,EAAE,KAAK,EACd,SAAS,EAAE,KAAK,EAChB,SAAS,EACP,MAAM;YACJ,CAAC,CAAC,oFAAoF;YACtF,CAAC,CAAC,SAAS,GAEf,CACH,CAAC,CAAC,CAAC,IAAI,CAAC;IAET,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;IAElD,0EAA0E;IAC1E,mEAAmE;IACnE,0EAA0E;IAC1E,2EAA2E;IAC3E,yDAAyD;IACzD,MAAM,SAAS,GAAG,CAChB,eACE,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,CAAC,EACX,cAAc,EAAE,YAAY,EAC5B,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,EAAE,CACX,sKAAsK,EACtK,IAAI,KAAK,IAAI,IAAI,SAAS,CAC3B,YAEA,YAAY,GACR,CACR,CAAC;IAEF,MAAM,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC,CACpC,MAAC,OAAO,eACN,KAAC,cAAc,IAAC,OAAO,kBAAE,SAAS,GAAkB,EACpD,KAAC,cAAc,cAAE,YAAY,GAAkB,IACvC,CACX,CAAC,CAAC,CAAC,CACF,SAAS,CACV,CAAC;IAEF,OAAO,CACL,8BACE,KAAC,SAAS,IAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAC,qBAAqB,YACzD,KAAK,GACI,EACZ,cAAK,SAAS,EAAC,2BAA2B,YACxC,gBAAM,SAAS,EAAC,mDAAmD,aAChE,YAAY,EACZ,CAAC,KAAK,IAAI,KAAK,IAAI,CAClB,MAAC,KAAK,IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAC,UAAU,aACjD,KAAC,SAAS,iBAAW,cAAc,iBAAa,MAAM,GAAG,EACzD,eAAM,SAAS,EAAC,SAAS,YACtB,KAAK,CAAC,SAAS,KAAK,UAAU;wCAC7B,CAAC,CAAC,eAAe;wCACjB,CAAC,CAAC,eAAe,GACd,EACN,KAAK,CAAC,KAAK,IACN,CACT,IACI,GACH,EACL,CAAC,KAAK,IAAI,gBAAgB,IAC1B,CACJ,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,EACjB,KAAK,EACL,OAAO,EACP,KAAK,EACL,KAAK,EACL,SAAS,EACT,MAAM,GAAG,IAAI,EACb,IAAI,GAAG,SAAS,EAChB,OAAO,GAAG,KAAK,EACf,KAAK,GAAG,KAAK,EACb,YAAY,EACZ,SAAS,GACM;IACf,MAAM,EAAE,CAAC,EAAE,GAAG,eAAe,EAAE,CAAC;IAChC,MAAM,oBAAoB,GAAG,YAAY,IAAI,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAElE,MAAM,OAAO,GAAG,CACd,KAAC,aAAa,IACZ,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,oBAAoB,EAClC,MAAM,EAAE,MAAM,GACd,CACH,CAAC;IAEF,mEAAmE;IACnE,uEAAuE;IACvE,sEAAsE;IACtE,0EAA0E;IAC1E,sEAAsE;IACtE,0EAA0E;IAC1E,yEAAyE;IACzE,MAAM,YAAY,GAChB,OAAO,KAAK,KAAK,QAAQ;QACvB,CAAC,CAAC,CAAC,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,CAAC;QACnC,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC;IAErC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CACL,KAAC,IAAI,IACH,IAAI,EAAE,IAAI,eACC,OAAO,IAAI,SAAS,EAC/B,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,eACzB,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,gBAC7B,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAC9C,SAAS,EAAE,EAAE,CAAC,gCAAgC,EAAE,SAAS,CAAC,YAE1D,KAAC,UAAU,cAAE,OAAO,GAAc,GAC7B,CACR,CAAC;IACJ,CAAC;IAED,OAAO,CACL,2BACY,WAAW,eACV,OAAO,IAAI,SAAS,EAC/B,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,eACzB,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,gBAC7B,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAC9C,SAAS,EAAE,EAAE,CACX,qEAAqE,EACrE,SAAS,CACV,YAEA,OAAO,GACJ,CACP,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  type SearchInputProps = Omit<React.ComponentProps<"input">, "type"> & {
3
3
  /** Called after the clear path resets the value and fires the synthesized `onChange("")`. */
4
4
  onClear?: () => void;
5
- /** Accessible name for the clear button. Only name assistive tech announces — native cancel button is suppressed. */
5
+ /** Accessible name for the clear button. Only name assistive tech announces — native cancel button is suppressed. Sourced from the i18n dictionary at key `"searchInput.clear"` when omitted. */
6
6
  clearLabel?: string;
7
7
  };
8
8
  declare const SearchInput: React.ForwardRefExoticComponent<Omit<SearchInputProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
@@ -1 +1 @@
1
- {"version":3,"file":"search-input.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/search-input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,KAAK,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,GAAG;IACpE,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qHAAqH;IACrH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAuGF,QAAA,MAAM,WAAW,wGAEhB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"search-input.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/search-input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,KAAK,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,GAAG;IACpE,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iMAAiM;IACjM,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAwGF,QAAA,MAAM,WAAW,wGAEhB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,CAAC"}
@@ -2,9 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import { SearchIcon, XIcon } from "../../icons/lucide.js";
4
4
  import { cn } from "../../lib/utils.js";
5
+ import { useC4Dictionary } from "../../lib/i18n/context.js";
5
6
  import { withRef } from "../../lib/with-ref.js";
6
7
  import { Input } from "./input.js";
7
- function SearchInputImpl({ ref, value, defaultValue, disabled, onChange, onClear, onKeyDown, clearLabel = "Clear search", className, ...props }) {
8
+ function SearchInputImpl({ ref, value, defaultValue, disabled, onChange, onClear, onKeyDown, clearLabel, className, ...props }) {
9
+ const { t } = useC4Dictionary();
8
10
  const inputRef = React.useRef(null);
9
11
  const [internalValue, setInternalValue] = React.useState(defaultValue !== undefined ? String(defaultValue) : "");
10
12
  const isControlled = value !== undefined;
@@ -50,7 +52,7 @@ function SearchInputImpl({ ref, value, defaultValue, disabled, onChange, onClear
50
52
  // `className` sizes/positions the whole search affordance (wrapper), not the
51
53
  // bare input — the clear button is absolutely positioned against this wrapper,
52
54
  // so routing width here keeps the button pinned to the field's real edge.
53
- _jsxs("div", { "data-slot": "search-input", className: cn("relative", className), children: [_jsx(SearchIcon, { "aria-hidden": "true", className: "pointer-events-none absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-neutral-foreground-subtle" }), _jsx(Input, { ...props, ref: setRefs, type: "search", role: "searchbox", value: currentValue, disabled: disabled, onChange: handleChange, onKeyDown: handleKeyDown, className: cn("pl-8 [&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none", showClear && "pr-9") }), showClear && (_jsx("button", { type: "button", "aria-label": clearLabel, onClick: handleClear, className: "absolute right-2 top-1/2 inline-flex size-7 -translate-y-1/2 items-center justify-center rounded-sm text-neutral-foreground-subtle hover:text-neutral-foreground-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(XIcon, { "aria-hidden": "true", className: "h-4 w-4" }) }))] }));
55
+ _jsxs("div", { "data-slot": "search-input", className: cn("relative", className), children: [_jsx(SearchIcon, { "aria-hidden": "true", className: "pointer-events-none absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-neutral-foreground-subtle" }), _jsx(Input, { ...props, ref: setRefs, type: "search", role: "searchbox", value: currentValue, disabled: disabled, onChange: handleChange, onKeyDown: handleKeyDown, className: cn("pl-8 [&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none", showClear && "pr-9") }), showClear && (_jsx("button", { type: "button", "aria-label": clearLabel ?? t("searchInput.clear"), onClick: handleClear, className: "absolute right-2 top-1/2 inline-flex size-7 -translate-y-1/2 items-center justify-center rounded-sm text-neutral-foreground-subtle hover:text-neutral-foreground-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(XIcon, { "aria-hidden": "true", className: "h-4 w-4" }) }))] }));
54
56
  }
55
57
  const SearchInput = withRef(SearchInputImpl);
56
58
  export { SearchInput };
@@ -1 +1 @@
1
- {"version":3,"file":"search-input.js","sourceRoot":"","sources":["../../../../src/components/ui/search-input.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-input.js","sourceRoot":"","sources":["../../../../src/components/ui/search-input.tsx"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import { Select as SelectPrimitive } from "radix-ui";
3
3
  declare function Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>): React.JSX.Element;
4
4
  declare function SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>): React.JSX.Element;
5
- declare function SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>): React.JSX.Element;
5
+ declare function SelectValue({ children, ...props }: React.ComponentProps<typeof SelectPrimitive.Value>): React.JSX.Element;
6
6
  type SelectTriggerProps = React.ComponentProps<typeof SelectPrimitive.Trigger> & {
7
7
  size?: "sm" | "default";
8
8
  /** Rendered below the trigger when `aria-invalid` is set. Also wires `aria-errormessage`/`aria-describedby`. */
@@ -10,7 +10,7 @@ type SelectTriggerProps = React.ComponentProps<typeof SelectPrimitive.Trigger> &
10
10
  /** Rendered below the trigger when not invalid. Wires `aria-describedby`. */
11
11
  helperText?: React.ReactNode;
12
12
  };
13
- declare function SelectTrigger({ className, size, children, id, invalidText, helperText, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, "aria-errormessage": ariaErrorMessage, ...props }: SelectTriggerProps): React.JSX.Element;
13
+ declare function SelectTrigger({ className, size, children, id, invalidText, helperText, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, "aria-errormessage": ariaErrorMessage, ref, onPointerEnter, onFocus, ...props }: SelectTriggerProps): React.JSX.Element;
14
14
  declare function SelectContent({ className, children, position, onCloseAutoFocus, restoreFocusRef, ...props }: React.ComponentProps<typeof SelectPrimitive.Content> & {
15
15
  /**
16
16
  * Element to refocus when the select closes, instead of the default
@@ -1 +1 @@
1
- {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAUrD,iBAAS,MAAM,CAAC,EACd,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,qBAEnD;AAED,iBAAS,WAAW,CAAC,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,qBAEpD;AAED,iBAAS,WAAW,CAAC,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,qBAEpD;AAED,KAAK,kBAAkB,GAAG,KAAK,CAAC,cAAc,CAC5C,OAAO,eAAe,CAAC,OAAO,CAC/B,GAAG;IACF,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACxB,gHAAgH;IAChH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B,CAAC;AAEF,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,IAAgB,EAChB,QAAQ,EACR,EAAE,EACF,WAAW,EACX,UAAU,EACV,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,mBAAmB,EAAE,gBAAgB,EACrC,GAAG,KAAK,EACT,EAAE,kBAAkB,qBAwDpB;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,QAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,GAAG;IACxD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CACvD,qBAwCA;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,qBAWpD;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,qBAkBnD;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,SAAS,CAAC,qBAQxD;AAED,iBAAS,oBAAoB,CAAC,EAC5B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,cAAc,CAAC,qBAa7D;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,gBAAgB,CAAC,qBAa/D;AAED,OAAO,EACL,MAAM,EACN,aAAa,EACb,WAAW,EACX,UAAU,EACV,WAAW,EACX,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,WAAW,GACZ,CAAC;AACF,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AA6BrD,iBAAS,MAAM,CAAC,EACd,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,qBAEnD;AAED,iBAAS,WAAW,CAAC,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,qBAEpD;AAED,iBAAS,WAAW,CAAC,EACnB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,qBAsCpD;AAED,KAAK,kBAAkB,GAAG,KAAK,CAAC,cAAc,CAC5C,OAAO,eAAe,CAAC,OAAO,CAC/B,GAAG;IACF,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACxB,gHAAgH;IAChH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B,CAAC;AAEF,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,IAAgB,EAChB,QAAQ,EACR,EAAE,EACF,WAAW,EACX,UAAU,EACV,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,mBAAmB,EAAE,gBAAgB,EACrC,GAAG,EACH,cAAc,EACd,OAAO,EACP,GAAG,KAAK,EACT,EAAE,kBAAkB,qBAsJpB;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,QAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,GAAG;IACxD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CACvD,qBAwCA;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,qBAWpD;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,qBAkBnD;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,SAAS,CAAC,qBAQxD;AAED,iBAAS,oBAAoB,CAAC,EAC5B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,cAAc,CAAC,qBAa7D;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,gBAAgB,CAAC,qBAa/D;AAED,OAAO,EACL,MAAM,EACN,aAAa,EACb,WAAW,EACX,UAAU,EACV,WAAW,EACX,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,WAAW,GACZ,CAAC;AACF,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
@@ -4,18 +4,59 @@ import * as React from "react";
4
4
  import { Select as SelectPrimitive } from "radix-ui";
5
5
  import { cn } from "../../lib/utils.js";
6
6
  import { composeCloseAutoFocus, useDialogFocusReturn, } from "../../lib/focus-visible-on-close.js";
7
+ import { useIsTruncated } from "../../hooks/use-is-truncated.js";
7
8
  import { C4Provider } from "./c4-provider.js";
8
9
  import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "../../icons/lucide.js";
10
+ import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
11
+ // No existing ref-merge utility in this package (single-consumer need so
12
+ // far, same reasoning as `code-block.tsx`'s own copy): the forwarded `ref`
13
+ // (an external consumer's, if passed via `...props` — SelectTrigger doesn't
14
+ // destructure it today) and the internal ref this file needs to read the
15
+ // rendered `[data-slot="select-value"]` node both have to land on the same
16
+ // `SelectPrimitive.Trigger` DOM node.
17
+ function mergeRefs(a, b) {
18
+ return (node) => {
19
+ if (typeof a === "function")
20
+ a(node);
21
+ else if (a)
22
+ a.current = node;
23
+ b.current = node;
24
+ };
25
+ }
9
26
  function Select({ ...props }) {
10
27
  return _jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
11
28
  }
12
29
  function SelectGroup({ ...props }) {
13
30
  return _jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props });
14
31
  }
15
- function SelectValue({ ...props }) {
16
- return _jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
32
+ function SelectValue({ children, ...props }) {
33
+ // Radix's `Select.Value` destructures `className`/`style` out of props and
34
+ // never forwards them to the rendered node (see
35
+ // `@radix-ui/react-select`'s own `SelectValue` implementation) — so styling
36
+ // this node's own display/truncation can't be done via a `className` prop
37
+ // on it directly, no matter how it's computed here. `data-*` attributes
38
+ // aren't stripped, though: they land in Radix's own `...valueProps` spread
39
+ // and reach the DOM, so `SelectTrigger`'s className reaches this node via
40
+ // a `[data-slot=select-value]` DESCENDANT selector (not the `*:` direct-
41
+ // child variant the previous, broken attempt used — this node isn't
42
+ // always a direct child of the trigger; see the icon+value composition in
43
+ // `filter-bar.stories.tsx`, which nests `SelectValue` inside a consumer
44
+ // span). `data-has-children` distinguishes the two layouts that selector
45
+ // needs to produce: plain `truncate` when Radix auto-renders the selected
46
+ // item's text (no `children` passed here — the common case, and the only
47
+ // one any consumer in this repo actually uses), or `flex` when a consumer
48
+ // passes its own `children` instead of relying on that auto-text.
49
+ //
50
+ // Radix's own `hasChildren` (`children !== void 0`) gates whether it
51
+ // auto-renders the selected item's text at all: passing this component
52
+ // *any* non-undefined `children` — even conditionally, even `null` — would
53
+ // suppress that auto-text for every consumer that doesn't. So this only
54
+ // ever wraps `children` when the consumer actually supplied some; it never
55
+ // passes an empty wrapper through in the common case.
56
+ const hasChildren = children !== undefined;
57
+ return (_jsx(SelectPrimitive.Value, { "data-slot": "select-value", "data-has-children": hasChildren ? "" : undefined, ...props, children: hasChildren ? (_jsx("span", { "data-slot": "select-value-text", className: "min-w-0 truncate", children: children })) : undefined }));
17
58
  }
18
- function SelectTrigger({ className, size = "default", children, id, invalidText, helperText, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, "aria-errormessage": ariaErrorMessage, ...props }) {
59
+ function SelectTrigger({ className, size = "default", children, id, invalidText, helperText, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, "aria-errormessage": ariaErrorMessage, ref, onPointerEnter, onFocus, ...props }) {
19
60
  const generatedId = React.useId();
20
61
  const resolvedId = id ?? generatedId;
21
62
  const isInvalid = ariaInvalid === true || ariaInvalid === "true";
@@ -26,13 +67,89 @@ function SelectTrigger({ className, size = "default", children, id, invalidText,
26
67
  const errorMessageId = ariaErrorMessage ?? errorId;
27
68
  const describedBy = [errorId, helperId, ariaDescribedBy].filter(Boolean).join(" ") || undefined;
28
69
  const hasMessage = showInvalidText || showHelperText;
29
- const triggerEl = (_jsxs(SelectPrimitive.Trigger, { id: resolvedId, "data-slot": "select-trigger", "data-size": size, "aria-invalid": ariaInvalid, "aria-errormessage": errorMessageId, "aria-describedby": describedBy, className: cn("flex w-fit min-w-0 items-center justify-between gap-2 rounded-lg border border-input bg-input-background px-3 py-2 text-sm whitespace-nowrap transition-all duration-200 outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/20 dark:focus-visible:ring-ring/40 data-[focus-visible-restore]:border-ring data-[focus-visible-restore]:ring-3 data-[focus-visible-restore]:ring-ring/20 dark:data-[focus-visible-restore]:ring-ring/40 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-danger-foreground-subtle aria-invalid:ring-3 aria-invalid:ring-danger-foreground-subtle/20 data-placeholder:text-neutral-foreground-subtle data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:hover:bg-neutral-background-medium dark:aria-invalid:ring-danger-foreground-subtle/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDownIcon, { className: "pointer-events-none size-4 opacity-50" }) })] }));
70
+ // `SelectValue`'s content is opaque to `SelectTrigger` — it's rendered as
71
+ // `children`, an arbitrary consumer-authored subtree — so unlike the other
72
+ // 3 truncation-reveal sites there is no JSX ref to attach directly to the
73
+ // node the truncation utility clips (`data-slot="select-value"`, or its
74
+ // inner `data-slot="select-value-text"` span when `SelectValue` was given
75
+ // `children` — see the `[data-slot=select-value]` descendant selectors in
76
+ // this trigger's className below). `triggerRef` reads the rendered DOM
77
+ // instead: an ADDITIONAL internal ref alongside any consumer `ref` (merged
78
+ // via `mergeRefs`, not a replacement — `props` may still carry a consumer
79
+ // ref since it's not destructured above).
80
+ const triggerRef = React.useRef(null);
81
+ const mergedRef = React.useMemo(() => mergeRefs(ref, triggerRef), [ref, triggerRef]);
82
+ const { ref: valueRef, isTruncated, measure } = useIsTruncated();
83
+ const [tooltipText, setTooltipText] = React.useState("");
84
+ // Every commit, not just on a `children` change: which node currently
85
+ // carries `data-slot="select-value"`, and the room the trigger has, can
86
+ // both change with no reference-identity change on `children` to key on
87
+ // (e.g. picking a different option re-renders `SelectValue` under the same
88
+ // trigger). See "Truncated Text" in `docs/specs/shadcn/patterns.md`. No
89
+ // deps array is intentional (same reasoning `nav-breadcrumb.tsx` documents
90
+ // for its own equivalent effect) — the lint rule flags the direct
91
+ // `setTooltipText` call as a possible infinite-update chain, but `useState`
92
+ // bails out via `Object.is` when the computed text is unchanged, same as
93
+ // `measure()`'s own `setIsTruncated` call one layer down (which the rule
94
+ // can't see into, and so doesn't flag).
95
+ // eslint-disable-next-line react-hooks/exhaustive-deps
96
+ React.useLayoutEffect(() => {
97
+ // Prefer the inner `select-value-text` span — present only when
98
+ // `SelectValue` was given `children` — over the outer `select-value`
99
+ // node itself: that outer node is `flex` in that case (to lay out
100
+ // `children` alongside other content), and measuring `scrollWidth` /
101
+ // `clientWidth` on a flex container doesn't reflect text clipping the
102
+ // way it does on the actual `truncate`d node. See `select.tsx`'s
103
+ // `SelectValue` for why the split exists at all.
104
+ const valueEl = triggerRef.current?.querySelector('[data-slot="select-value-text"]') ??
105
+ triggerRef.current?.querySelector('[data-slot="select-value"]');
106
+ valueRef.current = valueEl ?? null;
107
+ measure();
108
+ setTooltipText(valueEl?.textContent ?? "");
109
+ });
110
+ const triggerEl = (_jsxs(SelectPrimitive.Trigger, { ref: mergedRef, id: resolvedId, "data-slot": "select-trigger", "data-size": size, "aria-invalid": ariaInvalid, "aria-errormessage": errorMessageId, "aria-describedby": describedBy,
111
+ // Composed rather than clobbered: `props` may still carry a consumer
112
+ // handler (only `ref` is destructured above, not these two), and
113
+ // `{...props}` spreads AFTER this element's own attributes — the
114
+ // opposite order from `combobox.tsx`, so the risk here is a consumer
115
+ // handler silently winning over `measure()`, not the other way round.
116
+ onPointerEnter: (e) => {
117
+ onPointerEnter?.(e);
118
+ measure();
119
+ }, onFocus: (e) => {
120
+ onFocus?.(e);
121
+ measure();
122
+ }, className: cn("flex w-fit min-w-0 items-center justify-between gap-2 rounded-lg border border-input bg-input-background px-3 py-2 text-sm whitespace-nowrap transition-all duration-200 outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/20 dark:focus-visible:ring-ring/40 data-[focus-visible-restore]:border-ring data-[focus-visible-restore]:ring-3 data-[focus-visible-restore]:ring-ring/20 dark:data-[focus-visible-restore]:ring-ring/40 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-danger-foreground-subtle aria-invalid:ring-3 aria-invalid:ring-danger-foreground-subtle/20 data-placeholder:text-neutral-foreground-subtle data-[size=default]:h-9 data-[size=sm]:h-8 [&_[data-slot=select-value]]:min-w-0 [&_[data-slot=select-value]:not([data-has-children])]:truncate [&_[data-slot=select-value][data-has-children]]:flex [&_[data-slot=select-value][data-has-children]]:items-center [&_[data-slot=select-value][data-has-children]]:gap-1.5 dark:hover:bg-neutral-background-medium dark:aria-invalid:ring-danger-foreground-subtle/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDownIcon, { className: "pointer-events-none size-4 opacity-50" }) })] }));
123
+ // DEVIATES from the other 3 truncation-reveal sites (and from
124
+ // `nav-breadcrumb.tsx`'s reference pattern), and empirically so — not by
125
+ // assumption: `Tooltip`/`TooltipTrigger` are mounted UNCONDITIONALLY here
126
+ // (only `TooltipContent` is conditional on `isTruncated`), instead of
127
+ // conditionally mounting the whole `Tooltip` subtree. Conditionally
128
+ // mounting the whole subtree was tried first and measurably broken —
129
+ // toggling `isTruncated` changes the JSX shape at `SelectPrimitive.Trigger`'s
130
+ // own tree position (bare element vs. wrapped in `Tooltip`), which makes
131
+ // React unmount and remount it, and with it Radix Select's own internal
132
+ // `SelectValue` registration. The remounted value node measures 0×0 on the
133
+ // commit right after the remount (confirmed with a throwaway console probe:
134
+ // `onPointerEnter`'s `measure()` read the correct 260×110 and set
135
+ // `isTruncated` true; the very next commit's layout effect then read the
136
+ // SAME query on the freshly-remounted node as 0×0 and flipped it back to
137
+ // false), so the tooltip opened and immediately closed on every hover
138
+ // instead of staying open — a real correctness bug, not a style
139
+ // preference. `SelectPrimitive.Trigger` needs a permanently stable tree
140
+ // position for its internal state to survive a truncation toggle; the
141
+ // other 3 sites don't have that constraint; the accepted cost versus
142
+ // `nav-breadcrumb.tsx`'s document (an unconditional `Tooltip` still runs
143
+ // Radix's open-request handling and touches `TooltipProvider`'s
144
+ // delay-skip state on every hover of a SHORT value too) is real but minor
145
+ // next to a tooltip that cannot stay open.
146
+ const wrappedTriggerEl = (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: triggerEl }), isTruncated ? _jsx(TooltipContent, { children: tooltipText }) : null] }));
30
147
  if (!hasMessage) {
31
- return triggerEl;
148
+ return wrappedTriggerEl;
32
149
  }
33
150
  // `w-fit` here would make a `width: 100%` trigger circular against its own
34
151
  // shrink-to-fit parent, silently dropping a `w-full` className override.
35
- return (_jsxs("div", { className: "flex w-full flex-col gap-1.5", children: [triggerEl, showInvalidText ? (_jsx("span", { id: errorId, className: "text-xs text-danger-foreground-subtle", children: invalidText })) : null, showHelperText ? (_jsx("span", { id: helperId, className: "text-xs text-neutral-foreground-subtle", children: helperText })) : null] }));
152
+ return (_jsxs("div", { className: "flex w-full flex-col gap-1.5", children: [wrappedTriggerEl, showInvalidText ? (_jsx("span", { id: errorId, className: "text-xs text-danger-foreground-subtle", children: invalidText })) : null, showHelperText ? (_jsx("span", { id: helperId, className: "text-xs text-neutral-foreground-subtle", children: helperText })) : null] }));
36
153
  }
37
154
  function SelectContent({ className, children, position = "popper", onCloseAutoFocus, restoreFocusRef, ...props }) {
38
155
  const dialogFocusReturn = useDialogFocusReturn(restoreFocusRef);
@@ -1 +1 @@
1
- {"version":3,"file":"select.js","sourceRoot":"","sources":["../../../../src/components/ui/select.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../../../../src/components/ui/select.tsx"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ declare function SheetOverlay({ className, ...props }: React.ComponentProps<type
9
9
  declare const sheetVariants: (props?: ({
10
10
  side?: "bottom" | "left" | "right" | "top" | null | undefined;
11
11
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
12
- declare function SheetContent({ className, children, side, showCloseButton, onOpenAutoFocus, onCloseAutoFocus, restoreFocusRef, ...props }: React.ComponentProps<typeof SheetPrimitive.Content> & VariantProps<typeof sheetVariants> & {
12
+ type SheetContentProps = React.ComponentProps<typeof SheetPrimitive.Content> & VariantProps<typeof sheetVariants> & {
13
13
  showCloseButton?: boolean;
14
14
  /**
15
15
  * Element to refocus when the sheet closes, instead of the auto-captured
@@ -18,7 +18,10 @@ declare function SheetContent({ className, children, side, showCloseButton, onOp
18
18
  * still-mounted element, typically the menu's own trigger.
19
19
  */
20
20
  restoreFocusRef?: React.RefObject<HTMLElement | null>;
21
- }): React.JSX.Element;
21
+ /** Accessible name for the close button. Sourced from the i18n dictionary, overridable via this prop. */
22
+ closeLabel?: string;
23
+ };
24
+ declare function SheetContent({ className, children, side, showCloseButton, onOpenAutoFocus, onCloseAutoFocus, restoreFocusRef, closeLabel, ...props }: SheetContentProps): React.JSX.Element;
22
25
  declare function SheetHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
23
26
  declare function SheetFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
24
27
  declare function SheetTitle({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Title>): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/sheet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAalE,iBAAS,KAAK,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,IAAI,CAAC,qBAE5E;AAED,iBAAS,YAAY,CAAC,EACpB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,qBAErD;AAED,iBAAS,UAAU,CAAC,EAClB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,KAAK,CAAC,qBAEnD;AAED,iBAAS,WAAW,CAAC,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,MAAM,CAAC,qBAEpD;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,qBAcrD;AAED,QAAA,MAAM,aAAa;;8EAelB,CAAC;AAEF,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,QAAQ,EACR,IAAa,EACb,eAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,GACpD,YAAY,CAAC,OAAO,aAAa,CAAC,GAAG;IACnC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CACvD,qBA0CF;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQxE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQxE;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,KAAK,CAAC,qBAUnD;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,WAAW,CAAC,qBAQzD;AAED,OAAO,EACL,KAAK,EACL,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,EACX,aAAa,EACb,UAAU,EACV,YAAY,GACb,CAAC"}
1
+ {"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/sheet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAclE,iBAAS,KAAK,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,IAAI,CAAC,qBAE5E;AAED,iBAAS,YAAY,CAAC,EACpB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,qBAErD;AAED,iBAAS,UAAU,CAAC,EAClB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,KAAK,CAAC,qBAEnD;AAED,iBAAS,WAAW,CAAC,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,MAAM,CAAC,qBAEpD;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,qBAcrD;AAED,QAAA,MAAM,aAAa;;8EAelB,CAAC;AAEF,KAAK,iBAAiB,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,GAC1E,YAAY,CAAC,OAAO,aAAa,CAAC,GAAG;IACnC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACtD,yGAAyG;IACzG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEJ,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,QAAQ,EACR,IAAa,EACb,eAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,GAAG,KAAK,EACT,EAAE,iBAAiB,qBA6CnB;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQxE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQxE;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,KAAK,CAAC,qBAUnD;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,WAAW,CAAC,qBAQzD;AAED,OAAO,EACL,KAAK,EACL,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,EACX,aAAa,EACb,UAAU,EACV,YAAY,GACb,CAAC"}
@@ -5,6 +5,7 @@ import { Dialog as SheetPrimitive } from "radix-ui";
5
5
  import { cva } from "class-variance-authority";
6
6
  import { XIcon } from "../../icons/lucide.js";
7
7
  import { cn } from "../../lib/utils.js";
8
+ import { useC4Dictionary } from "../../lib/i18n/context.js";
8
9
  import { composeCloseAutoFocus, composeOpenAutoFocus, useDialogFocusReturn, } from "../../lib/focus-visible-on-close.js";
9
10
  import { C4Provider } from "./c4-provider.js";
10
11
  import { Button } from "../ui/button.js";
@@ -39,8 +40,9 @@ const sheetVariants = cva("fixed z-50 flex flex-col bg-popover text-sm text-popo
39
40
  },
40
41
  defaultVariants: { side: "left" },
41
42
  });
42
- function SheetContent({ className, children, side = "left", showCloseButton = true, onOpenAutoFocus, onCloseAutoFocus, restoreFocusRef, ...props }) {
43
+ function SheetContent({ className, children, side = "left", showCloseButton = true, onOpenAutoFocus, onCloseAutoFocus, restoreFocusRef, closeLabel, ...props }) {
43
44
  const dialogFocusReturn = useDialogFocusReturn(restoreFocusRef);
45
+ const { t } = useC4Dictionary();
44
46
  return (_jsx(SheetPortal, { children: _jsxs(C4Provider, { children: [_jsx(SheetOverlay, {}), _jsxs(SheetPrimitive.Content, { "data-slot": "sheet-content", "data-side": side,
45
47
  // #26413 — restore focus to the real launcher on close, even for
46
48
  // controlled-`open` usage with no `SheetTrigger` (see
@@ -48,7 +50,7 @@ function SheetContent({ className, children, side = "left", showCloseButton = tr
48
50
  onOpenAutoFocus: composeOpenAutoFocus(onOpenAutoFocus, dialogFocusReturn.onOpenAutoFocus),
49
51
  // #259 — make the trigger's restored focus ring visible on a mouse
50
52
  // close (see focus-visible-on-close).
51
- onCloseAutoFocus: composeCloseAutoFocus(onCloseAutoFocus, dialogFocusReturn.onCloseAutoFocus), className: cn(sheetVariants({ side }), className), ...props, children: [children, showCloseButton && (_jsx(SheetPrimitive.Close, { "data-slot": "sheet-close", asChild: true, children: _jsxs(Button, { variant: "ghost", className: "absolute top-2 right-2", size: "icon-sm", children: [_jsx(XIcon, {}), _jsx("span", { className: "sr-only", children: "Close" })] }) }))] })] }) }));
53
+ onCloseAutoFocus: composeCloseAutoFocus(onCloseAutoFocus, dialogFocusReturn.onCloseAutoFocus), className: cn(sheetVariants({ side }), className), ...props, children: [children, showCloseButton && (_jsx(SheetPrimitive.Close, { "data-slot": "sheet-close", asChild: true, children: _jsxs(Button, { variant: "ghost", className: "absolute top-2 right-2", size: "icon-sm", children: [_jsx(XIcon, {}), _jsx("span", { className: "sr-only", children: closeLabel ?? t("sheet.close") })] }) }))] })] }) }));
52
54
  }
53
55
  function SheetHeader({ className, ...props }) {
54
56
  return (_jsx("div", { "data-slot": "sheet-header", className: cn("flex flex-col gap-1.5 p-4", className), ...props }));