@reopt-ai/opt-ui 1.9.0 → 1.11.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 (64) hide show
  1. package/COMPONENT_CATALOG.md +177 -66
  2. package/README.md +21 -5
  3. package/dist/core/index.cjs +106 -104
  4. package/dist/core/index.d.cts +3 -3
  5. package/dist/core/index.d.ts +3 -3
  6. package/dist/core/index.js +3 -3
  7. package/dist/docs/02-components/01-core.md +92 -41
  8. package/dist/docs/02-components/02-visuals.md +1 -1
  9. package/dist/docs/02-components/03-shells.md +96 -26
  10. package/dist/docs/02-components/04-surfaces.md +1 -1
  11. package/dist/docs/02-components/index.md +5 -5
  12. package/dist/{field-sidebar-B5vk3luQ.d.cts → field-sidebar-B5SQC35J.d.cts} +226 -3
  13. package/dist/field-sidebar-B5SQC35J.d.cts.map +1 -0
  14. package/dist/{field-sidebar-B7QkWvMG.js → field-sidebar-BXl5RJ3q.js} +599 -43
  15. package/dist/field-sidebar-BXl5RJ3q.js.map +1 -0
  16. package/dist/{field-sidebar-Dk9gJGA_.d.ts → field-sidebar-CBeWE8xX.d.ts} +226 -3
  17. package/dist/field-sidebar-CBeWE8xX.d.ts.map +1 -0
  18. package/dist/{field-sidebar-mFHemxBz.cjs → field-sidebar-DAuN4jPV.cjs} +883 -309
  19. package/dist/id-registry.cjs +46 -6
  20. package/dist/id-registry.d.cts.map +1 -1
  21. package/dist/id-registry.d.ts.map +1 -1
  22. package/dist/id-registry.js +46 -6
  23. package/dist/id-registry.js.map +1 -1
  24. package/dist/id-registry.json +97 -12
  25. package/dist/index.cjs +593 -587
  26. package/dist/index.d.cts +10 -6
  27. package/dist/index.d.cts.map +1 -1
  28. package/dist/index.d.ts +10 -6
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +20 -19
  31. package/dist/index.js.map +1 -1
  32. package/dist/{key-pad-menu-D8OS_VCT.d.cts → key-pad-menu-BxTy_u0Q.d.cts} +152 -51
  33. package/dist/key-pad-menu-BxTy_u0Q.d.cts.map +1 -0
  34. package/dist/{key-pad-menu-DoGskWbp.cjs → key-pad-menu-Cg6rZBie.cjs} +670 -923
  35. package/dist/{key-pad-menu-EEb6Ho5h.d.ts → key-pad-menu-u5GTJl9B.d.ts} +152 -51
  36. package/dist/key-pad-menu-u5GTJl9B.d.ts.map +1 -0
  37. package/dist/{key-pad-menu-BFd79JoS.js → key-pad-menu-wXkWn1I1.js} +500 -699
  38. package/dist/key-pad-menu-wXkWn1I1.js.map +1 -0
  39. package/dist/meta.cjs +486 -9
  40. package/dist/meta.d.cts.map +1 -1
  41. package/dist/meta.d.ts.map +1 -1
  42. package/dist/meta.js +486 -9
  43. package/dist/meta.js.map +1 -1
  44. package/dist/shells/index.cjs +4 -1
  45. package/dist/shells/index.d.cts +2 -2
  46. package/dist/shells/index.d.ts +2 -2
  47. package/dist/shells/index.js +2 -2
  48. package/dist/{highlight-CGcrYGMC.cjs → text-truncate-BZdL1k5Z.cjs} +608 -83
  49. package/dist/{highlight-C2sfnJN8.js → text-truncate-C17HHCR-.js} +534 -87
  50. package/dist/text-truncate-C17HHCR-.js.map +1 -0
  51. package/dist/{field-token-CSOrU5gl.d.ts → text-truncate-DW78lg4S.d.cts} +63 -4
  52. package/dist/text-truncate-DW78lg4S.d.cts.map +1 -0
  53. package/dist/{field-token-CSOrU5gl.d.cts → text-truncate-DW78lg4S.d.ts} +63 -4
  54. package/dist/text-truncate-DW78lg4S.d.ts.map +1 -0
  55. package/package.json +2 -2
  56. package/dist/field-sidebar-B5vk3luQ.d.cts.map +0 -1
  57. package/dist/field-sidebar-B7QkWvMG.js.map +0 -1
  58. package/dist/field-sidebar-Dk9gJGA_.d.ts.map +0 -1
  59. package/dist/field-token-CSOrU5gl.d.cts.map +0 -1
  60. package/dist/field-token-CSOrU5gl.d.ts.map +0 -1
  61. package/dist/highlight-C2sfnJN8.js.map +0 -1
  62. package/dist/key-pad-menu-BFd79JoS.js.map +0 -1
  63. package/dist/key-pad-menu-D8OS_VCT.d.cts.map +0 -1
  64. package/dist/key-pad-menu-EEb6Ho5h.d.ts.map +0 -1
@@ -1,15 +1,15 @@
1
1
  "use client";
2
- const require_highlight = require("./highlight-CGcrYGMC.cjs");
2
+ const require_text_truncate = require("./text-truncate-BZdL1k5Z.cjs");
3
3
  let react_jsx_runtime = require("react/jsx-runtime");
4
4
  let react = require("react");
5
- react = require_highlight.__toESM(react, 1);
5
+ react = require_text_truncate.__toESM(react, 1);
6
6
  let _reopt_ai_opt_ui_primitives = require("@reopt-ai/opt-ui-primitives");
7
7
  let lucide_react = require("lucide-react");
8
8
  let react_resizable_panels = require("react-resizable-panels");
9
9
  let ogl = require("ogl");
10
10
  let _reopt_ai_opt_palette = require("@reopt-ai/opt-palette");
11
11
  //#region src/core/text.tsx
12
- const _excluded$17 = [
12
+ const _excluded$15 = [
13
13
  "as",
14
14
  "variant",
15
15
  "tone",
@@ -25,10 +25,10 @@ const toneStyles$1 = {
25
25
  };
26
26
  /** Semantic body text whose visual role is controlled by foundation tokens. */
27
27
  function Text(_ref) {
28
- let { as, variant = "body", tone = "primary", truncate = false, className, children } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$17);
28
+ let { as, variant = "body", tone = "primary", truncate = false, className, children } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$15);
29
29
  const Component = as !== null && as !== void 0 ? as : "span";
30
- const elementProps = require_highlight._objectSpread2(require_highlight._objectSpread2({}, props), {}, {
31
- className: require_highlight.cn(`opt-type-${variant}`, toneStyles$1[tone], truncate && "truncate", className),
30
+ const elementProps = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, props), {}, {
31
+ className: require_text_truncate.cn(`opt-type-${variant}`, toneStyles$1[tone], truncate && "truncate", className),
32
32
  "data-opt-component": "text",
33
33
  "data-opt-part": "root",
34
34
  "data-opt-id": "NFKP2",
@@ -40,7 +40,7 @@ function Text(_ref) {
40
40
  }
41
41
  //#endregion
42
42
  //#region src/core/heading.tsx
43
- const _excluded$16 = [
43
+ const _excluded$14 = [
44
44
  "level",
45
45
  "variant",
46
46
  "className",
@@ -48,7 +48,7 @@ const _excluded$16 = [
48
48
  ];
49
49
  /** Semantic heading with independently selectable visual hierarchy. */
50
50
  function Heading(_ref) {
51
- let { level = 2, variant = `heading-${level}`, className, children } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$16);
51
+ let { level = 2, variant = `heading-${level}`, className, children } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$14);
52
52
  const Component = {
53
53
  1: "h1",
54
54
  2: "h2",
@@ -57,7 +57,7 @@ function Heading(_ref) {
57
57
  5: "h5",
58
58
  6: "h6"
59
59
  }[level];
60
- return (0, react.createElement)(Component, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn(`opt-type-${variant}`, "text-text-primary", className) }, props), {}, {
60
+ return (0, react.createElement)(Component, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn(`opt-type-${variant}`, "text-text-primary", className) }, props), {}, {
61
61
  "data-opt-component": "heading",
62
62
  "data-opt-part": "root",
63
63
  "data-opt-id": "NF0BT",
@@ -74,7 +74,7 @@ function Heading(_ref) {
74
74
  */
75
75
  function Separator$1({ orientation = "horizontal", decorative = false, children, className }) {
76
76
  if (orientation === "horizontal" && children != null) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
77
- className: require_highlight.cn("gap-element flex items-center", className),
77
+ className: require_text_truncate.cn("gap-element flex items-center", className),
78
78
  "data-opt-id": "7PWJS",
79
79
  "data-opt-slug": "separator.Separator",
80
80
  children: [
@@ -97,7 +97,7 @@ function Separator$1({ orientation = "horizontal", decorative = false, children,
97
97
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.Separator, {
98
98
  orientation,
99
99
  decorative,
100
- className: require_highlight.cn("bg-border shrink-0", orientation === "horizontal" ? "h-px w-full" : "h-full w-px self-stretch", className),
100
+ className: require_text_truncate.cn("bg-border shrink-0", orientation === "horizontal" ? "h-px w-full" : "h-full w-px self-stretch", className),
101
101
  "data-opt-id": "7PWJS",
102
102
  "data-opt-slug": "separator.Separator"
103
103
  });
@@ -122,7 +122,7 @@ function OtpField({ length = 6, value: controlledValue, defaultValue = "", onCha
122
122
  const labelId = label ? `${fieldId}-label` : void 0;
123
123
  const groupLabelledBy = ariaLabel ? void 0 : labelId;
124
124
  const groupAriaLabel = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : groupLabelledBy ? void 0 : "One-time code";
125
- const [value, setRawValue] = require_highlight.useControlledState(defaultValue, controlledValue, onChange);
125
+ const [value, setRawValue] = require_text_truncate.useControlledState(defaultValue, controlledValue, onChange);
126
126
  const completedRef = react.useRef(false);
127
127
  const setValue = react.useCallback((next) => {
128
128
  const clipped = next.slice(0, length);
@@ -215,20 +215,20 @@ function OtpField({ length = 6, value: controlledValue, defaultValue = "", onCha
215
215
  focusCell
216
216
  ]);
217
217
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
218
- className: require_highlight.cn("flex flex-col gap-1.5", className),
218
+ className: require_text_truncate.cn("flex flex-col gap-1.5", className),
219
219
  "data-opt-id": "0083Q",
220
220
  "data-opt-slug": "otp-field.OtpField",
221
221
  children: [
222
222
  label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
223
223
  className: "text-sm font-medium text-text-primary",
224
224
  id: labelId,
225
- children: [label, required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.RequiredMark, {})]
225
+ children: [label, required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.RequiredMark, {})]
226
226
  }),
227
227
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
228
228
  role: "group",
229
229
  "aria-label": groupAriaLabel,
230
230
  "aria-labelledby": groupLabelledBy,
231
- "aria-describedby": require_highlight.getDescribedBy(fieldId, error, hint),
231
+ "aria-describedby": require_text_truncate.getDescribedBy(fieldId, error, hint),
232
232
  className: "gap-element flex items-center",
233
233
  children: cells.map((cell, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
234
234
  ref: (node) => {
@@ -247,7 +247,7 @@ function OtpField({ length = 6, value: controlledValue, defaultValue = "", onCha
247
247
  onKeyDown: handleKeyDown(i),
248
248
  onPaste: handlePaste(i),
249
249
  onFocus: (e) => e.target.select(),
250
- className: require_highlight.cn(require_highlight.OPT_INPUT, "h-12 w-10 text-center text-lg font-medium", hasError && "border-danger focus-visible:outline-danger")
250
+ className: require_text_truncate.cn(require_text_truncate.OPT_INPUT, "h-12 w-10 text-center text-lg font-medium", hasError && "border-danger focus-visible:outline-danger")
251
251
  }, i))
252
252
  }),
253
253
  name && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
@@ -256,7 +256,7 @@ function OtpField({ length = 6, value: controlledValue, defaultValue = "", onCha
256
256
  value,
257
257
  disabled
258
258
  }),
259
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.FieldMessages, {
259
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FieldMessages, {
260
260
  id: fieldId,
261
261
  error,
262
262
  hint
@@ -267,25 +267,25 @@ function OtpField({ length = 6, value: controlledValue, defaultValue = "", onCha
267
267
  OtpField.displayName = "OtpField";
268
268
  //#endregion
269
269
  //#region src/core/toggle.tsx
270
- const _excluded$15 = [
270
+ const _excluded$13 = [
271
271
  "size",
272
272
  "className",
273
273
  "children"
274
274
  ];
275
- const _excluded2$8 = [
275
+ const _excluded2$7 = [
276
276
  "className",
277
277
  "children",
278
278
  "orientation"
279
279
  ];
280
- const sizeStyles$8 = {
280
+ const sizeStyles$7 = {
281
281
  sm: "h-8 min-w-8 px-2 text-xs gap-1.5",
282
282
  md: "h-10 min-w-10 px-3 text-sm gap-2"
283
283
  };
284
- const toggleBase = require_highlight.cn("inline-flex cursor-pointer items-center justify-center rounded-md border border-border bg-surface font-medium text-text-secondary", "hover:bg-bg-subtle hover:text-text-primary", "data-[pressed]:border-accent data-[pressed]:bg-accent-subtle data-[pressed]:text-accent", "disabled:pointer-events-none disabled:opacity-40", require_highlight.OPT_FOCUS_VISIBLE);
284
+ const toggleBase = require_text_truncate.cn("inline-flex cursor-pointer items-center justify-center rounded-md border border-border bg-surface font-medium text-text-secondary", "hover:bg-bg-subtle hover:text-text-primary", "data-[pressed]:border-accent data-[pressed]:bg-accent-subtle data-[pressed]:text-accent", "disabled:pointer-events-none disabled:opacity-40", require_text_truncate.OPT_FOCUS_VISIBLE);
285
285
  /** A two-state (pressed) button. Use standalone or inside `ToggleGroup`. */
286
286
  function Toggle(_ref) {
287
- let { size = "md", className, children } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$15);
288
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.Toggle, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn(toggleBase, sizeStyles$8[size], className) }, props), {}, {
287
+ let { size = "md", className, children } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$13);
288
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.Toggle, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn(toggleBase, sizeStyles$7[size], className) }, props), {}, {
289
289
  "data-opt-id": "GFCMY",
290
290
  "data-opt-slug": "toggle.Toggle",
291
291
  children
@@ -294,11 +294,11 @@ function Toggle(_ref) {
294
294
  Toggle.displayName = "Toggle";
295
295
  /** A set of related toggles with shared selection and keyboard navigation. */
296
296
  function ToggleGroup(_ref2) {
297
- let { className, children, orientation = "horizontal" } = _ref2, props = require_highlight._objectWithoutProperties(_ref2, _excluded2$8);
298
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.ToggleGroup, require_highlight._objectSpread2(require_highlight._objectSpread2({
297
+ let { className, children, orientation = "horizontal" } = _ref2, props = require_text_truncate._objectWithoutProperties(_ref2, _excluded2$7);
298
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.ToggleGroup, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
299
299
  orientation,
300
300
  "aria-orientation": orientation,
301
- className: require_highlight.cn("inline-flex gap-1", orientation === "vertical" ? "flex-col" : "flex-row", className)
301
+ className: require_text_truncate.cn("inline-flex gap-1", orientation === "vertical" ? "flex-col" : "flex-row", className)
302
302
  }, props), {}, {
303
303
  "data-opt-id": "47J37",
304
304
  "data-opt-slug": "toggle.ToggleGroup",
@@ -308,27 +308,27 @@ function ToggleGroup(_ref2) {
308
308
  ToggleGroup.displayName = "ToggleGroup";
309
309
  //#endregion
310
310
  //#region src/core/accordion.tsx
311
- const _excluded$14 = ["className"];
312
- const _excluded2$7 = ["className"];
313
- const _excluded3$4 = ["className", "children"];
314
- const _excluded4$3 = ["className", "children"];
315
- const triggerClass = `group/acc-trigger flex w-full cursor-pointer items-center justify-between gap-2 py-4 text-left text-sm font-medium text-text-primary transition-colors hover:text-text-secondary ${require_highlight.OPT_FOCUS} disabled:cursor-not-allowed disabled:opacity-50`;
316
- const contentClass = `overflow-hidden text-sm text-text-secondary ${require_highlight.OPT_ANIMATE_ENTER_EXIT}`;
311
+ const _excluded$12 = ["className"];
312
+ const _excluded2$6 = ["className"];
313
+ const _excluded3$3 = ["className", "children"];
314
+ const _excluded4$2 = ["className", "children"];
315
+ const triggerClass = `group/acc-trigger flex w-full cursor-pointer items-center justify-between gap-2 py-4 text-left text-sm font-medium text-text-primary transition-colors hover:text-text-secondary ${require_text_truncate.OPT_FOCUS} disabled:cursor-not-allowed disabled:opacity-50`;
316
+ const contentClass = `overflow-hidden text-sm text-text-secondary ${require_text_truncate.OPT_ANIMATE_ENTER_EXIT}`;
317
317
  /** A vertically stacked set of expandable panels (single or multiple open). */
318
318
  function AccordionRoot(_ref) {
319
- let { className } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$14);
319
+ let { className } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$12);
320
320
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
321
- className: require_highlight.cn("border-border border-y", className),
321
+ className: require_text_truncate.cn("border-border border-y", className),
322
322
  "data-opt-id": "CSBA9",
323
323
  "data-opt-slug": "accordion.AccordionRoot",
324
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.AccordionRoot, require_highlight._objectSpread2({}, props))
324
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.AccordionRoot, require_text_truncate._objectSpread2({}, props))
325
325
  });
326
326
  }
327
327
  AccordionRoot.displayName = "AccordionRoot";
328
328
  /** A single accordion entry, identified by its `value`. */
329
329
  function AccordionItem(_ref2) {
330
- let { className } = _ref2, props = require_highlight._objectWithoutProperties(_ref2, _excluded2$7);
331
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.AccordionItem, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("border-border border-b last:border-b-0", className) }, props), {}, {
330
+ let { className } = _ref2, props = require_text_truncate._objectWithoutProperties(_ref2, _excluded2$6);
331
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.AccordionItem, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn("border-border border-b last:border-b-0", className) }, props), {}, {
332
332
  "data-opt-id": "JTY9M",
333
333
  "data-opt-slug": "accordion.AccordionItem"
334
334
  }));
@@ -336,8 +336,8 @@ function AccordionItem(_ref2) {
336
336
  AccordionItem.displayName = "AccordionItem";
337
337
  /** The clickable header that expands/collapses its panel. */
338
338
  function AccordionTrigger(_ref3) {
339
- let { className, children } = _ref3, props = require_highlight._objectWithoutProperties(_ref3, _excluded3$4);
340
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_reopt_ai_opt_ui_primitives.AccordionTrigger, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn(triggerClass, className) }, props), {}, {
339
+ let { className, children } = _ref3, props = require_text_truncate._objectWithoutProperties(_ref3, _excluded3$3);
340
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_reopt_ai_opt_ui_primitives.AccordionTrigger, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn(triggerClass, className) }, props), {}, {
341
341
  "data-opt-id": "CWJZZ",
342
342
  "data-opt-slug": "accordion.AccordionTrigger",
343
343
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -352,8 +352,8 @@ function AccordionTrigger(_ref3) {
352
352
  AccordionTrigger.displayName = "AccordionTrigger";
353
353
  /** The collapsible panel body associated with a trigger. */
354
354
  function AccordionContent(_ref4) {
355
- let { className, children } = _ref4, props = require_highlight._objectWithoutProperties(_ref4, _excluded4$3);
356
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.AccordionContent, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn(contentClass, className) }, props), {}, {
355
+ let { className, children } = _ref4, props = require_text_truncate._objectWithoutProperties(_ref4, _excluded4$2);
356
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.AccordionContent, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn(contentClass, className) }, props), {}, {
357
357
  "data-opt-id": "J98AG",
358
358
  "data-opt-slug": "accordion.AccordionContent",
359
359
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -372,19 +372,19 @@ function interpolate(template, values) {
372
372
  function Breadcrumb({ items, separator = "/", className, onNavigate, "aria-label": ariaLabel = "Breadcrumb" }) {
373
373
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
374
374
  "aria-label": ariaLabel,
375
- className: require_highlight.cn("flex items-center gap-1 px-1.5 text-sm", className),
375
+ className: require_text_truncate.cn("flex items-center gap-1 px-1.5 text-sm", className),
376
376
  "data-opt-id": "3FR0Y",
377
377
  "data-opt-slug": "breadcrumb.Breadcrumb",
378
378
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ol", {
379
379
  className: "flex items-center gap-1",
380
380
  children: items.map((item, index) => {
381
381
  const isLast = index === items.length - 1;
382
- const linkClassName = require_highlight.cn(`flex items-center gap-1.5 rounded-sm ${require_highlight.OPT_FOCUS} transition-colors`, item.disabled ? `${require_highlight.OPT_TEXT_TERTIARY} cursor-not-allowed` : `${require_highlight.OPT_TEXT_SECONDARY} hover:text-text-primary cursor-pointer`);
382
+ const linkClassName = require_text_truncate.cn(`flex items-center gap-1.5 rounded-sm ${require_text_truncate.OPT_FOCUS} transition-colors`, item.disabled ? `${require_text_truncate.OPT_TEXT_TERTIARY} cursor-not-allowed` : `${require_text_truncate.OPT_TEXT_SECONDARY} hover:text-text-primary cursor-pointer`);
383
383
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
384
384
  className: "flex items-center gap-1",
385
385
  children: isLast ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
386
386
  "aria-current": "page",
387
- className: `flex items-center gap-1.5 font-medium ${require_highlight.OPT_TEXT_PRIMARY}`,
387
+ className: `flex items-center gap-1.5 font-medium ${require_text_truncate.OPT_TEXT_PRIMARY}`,
388
388
  children: [item.icon, item.label]
389
389
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [item.href ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
390
390
  href: item.disabled ? void 0 : item.href,
@@ -395,13 +395,13 @@ function Breadcrumb({ items, separator = "/", className, onNavigate, "aria-label
395
395
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
396
396
  type: "button",
397
397
  disabled: item.disabled,
398
- "aria-label": interpolate(require_highlight.koBreadcrumbLabels.navAriaLabel, { label: item.label }),
398
+ "aria-label": interpolate(require_text_truncate.koBreadcrumbLabels.navAriaLabel, { label: item.label }),
399
399
  className: linkClassName,
400
400
  onClick: () => !item.disabled && (onNavigate === null || onNavigate === void 0 ? void 0 : onNavigate(item)),
401
401
  children: [item.icon, item.label]
402
402
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
403
403
  "aria-hidden": "true",
404
- className: require_highlight.OPT_TEXT_TERTIARY,
404
+ className: require_text_truncate.OPT_TEXT_TERTIARY,
405
405
  children: separator
406
406
  })] })
407
407
  }, item.id);
@@ -410,8 +410,352 @@ function Breadcrumb({ items, separator = "/", className, onNavigate, "aria-label
410
410
  });
411
411
  }
412
412
  //#endregion
413
+ //#region src/core/description-list.tsx
414
+ const defaultLabels$3 = {
415
+ copy: (term) => `Copy ${term}`,
416
+ copied: "Copied",
417
+ empty: "—"
418
+ };
419
+ const columnsClass = {
420
+ 1: "grid-cols-1",
421
+ 2: "grid-cols-1 sm:grid-cols-2",
422
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
423
+ 4: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4"
424
+ };
425
+ function CopyButton({ value, label, copiedLabel }) {
426
+ const [copied, setCopied] = (0, react.useState)(false);
427
+ const handleCopy = (0, react.useCallback)(() => {
428
+ var _navigator$clipboard;
429
+ (_navigator$clipboard = navigator.clipboard) === null || _navigator$clipboard === void 0 || _navigator$clipboard.writeText(value).then(() => {
430
+ setCopied(true);
431
+ window.setTimeout(() => setCopied(false), 1500);
432
+ });
433
+ }, [value]);
434
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
435
+ type: "button",
436
+ onClick: handleCopy,
437
+ "aria-label": copied ? copiedLabel : label,
438
+ className: require_text_truncate.cn(require_text_truncate.OPT_FOCUS_VISIBLE, require_text_truncate.OPT_TEXT_TERTIARY, "hover:text-text-primary shrink-0 rounded p-0.5 transition-colors"),
439
+ children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, {
440
+ className: "size-3.5",
441
+ "aria-hidden": "true"
442
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Copy, {
443
+ className: "size-3.5",
444
+ "aria-hidden": "true"
445
+ })
446
+ });
447
+ }
448
+ /**
449
+ * DescriptionList — the labelled facts about one thing.
450
+ *
451
+ * Detail views collect a dozen short fields that each mean nothing without
452
+ * their label, and hand-rolling them as a `<div>` grid loses the term/value
453
+ * association that assistive tech needs. This keeps the pairs in a real `<dl>`
454
+ * while still laying them out as boxed cells.
455
+ *
456
+ * @example
457
+ * ```tsx
458
+ * <DescriptionList
459
+ * layout="grid"
460
+ * columns={2}
461
+ * items={[
462
+ * { id: "id", term: "Session ID", description: session.id, copyValue: session.id },
463
+ * { id: "entry", term: "Entry path", description: session.entryPath },
464
+ * ]}
465
+ * />
466
+ * ```
467
+ */
468
+ function DescriptionList({ items, layout = "grid", columns = 2, compressed = false, labels: customLabels, className }) {
469
+ const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$3), customLabels);
470
+ if (layout === "inline") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dl", {
471
+ className: require_text_truncate.cn("flex flex-wrap items-baseline gap-x-6 gap-y-2", className),
472
+ "data-opt-id": "1NPD2",
473
+ "data-opt-slug": "description-list.DescriptionList",
474
+ children: items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
475
+ className: "flex items-baseline gap-2",
476
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", {
477
+ className: require_text_truncate.cn(require_text_truncate.OPT_TEXT_TERTIARY, "text-xs"),
478
+ title: item.hint,
479
+ children: item.term
480
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", {
481
+ className: require_text_truncate.cn(require_text_truncate.OPT_TEXT_PRIMARY, "text-sm font-medium"),
482
+ children: item.description || labels.empty
483
+ })]
484
+ }, item.id))
485
+ });
486
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dl", {
487
+ className: require_text_truncate.cn("grid", compressed ? "gap-element" : "gap-group", columnsClass[columns], className),
488
+ "data-opt-id": "1NPD2",
489
+ "data-opt-slug": "description-list.DescriptionList",
490
+ children: items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
491
+ className: require_text_truncate.cn("flex min-w-0 flex-col gap-1", layout === "grid" && [
492
+ "border border-border",
493
+ "bg-bg-subtle rounded-lg",
494
+ compressed ? "px-2.5 py-1.5" : "px-3 py-2"
495
+ ]),
496
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", {
497
+ className: require_text_truncate.cn(require_text_truncate.OPT_TEXT_TERTIARY, "text-xs"),
498
+ title: item.hint,
499
+ children: item.term
500
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dd", {
501
+ className: require_text_truncate.cn(require_text_truncate.OPT_TEXT_PRIMARY, "flex min-w-0 items-center gap-1.5 text-sm"),
502
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
503
+ className: require_text_truncate.cn("min-w-0", item.wrap ? "break-all" : "truncate", !item.description && "text-text-secondary"),
504
+ children: item.description || labels.empty
505
+ }), item.copyValue && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyButton, {
506
+ value: item.copyValue,
507
+ label: labels.copy(typeof item.term === "string" ? item.term : item.id),
508
+ copiedLabel: labels.copied
509
+ })]
510
+ })]
511
+ }, item.id))
512
+ });
513
+ }
514
+ DescriptionList.displayName = "DescriptionList";
515
+ //#endregion
516
+ //#region src/core/avatar.tsx
517
+ const _excluded$11 = [
518
+ "src",
519
+ "srcSet",
520
+ "sizes",
521
+ "crossOrigin",
522
+ "referrerPolicy",
523
+ "alt",
524
+ "name",
525
+ "size",
526
+ "fallback",
527
+ "status",
528
+ "className",
529
+ "onLoadingStatusChange"
530
+ ];
531
+ const _excluded2$5 = [
532
+ "max",
533
+ "size",
534
+ "children",
535
+ "className"
536
+ ];
537
+ const useIsoLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
538
+ /**
539
+ * Tracks an image's loading status by preloading it off-DOM, so the avatar can
540
+ * show its fallback until the image is actually decoded (no broken-image flash)
541
+ * and recover from late `error`/`load` events. Supports responsive `srcSet`/`sizes`.
542
+ */
543
+ function useImageLoadingStatus(src, { srcSet, sizes, crossOrigin, referrerPolicy }) {
544
+ const [status, setStatus] = (0, react.useState)("idle");
545
+ useIsoLayoutEffect(() => {
546
+ if (!src && !srcSet) {
547
+ setStatus("error");
548
+ return;
549
+ }
550
+ let isMounted = true;
551
+ const image = new window.Image();
552
+ const update = (next) => () => {
553
+ if (isMounted) setStatus(next);
554
+ };
555
+ setStatus("loading");
556
+ image.onload = update("loaded");
557
+ image.onerror = update("error");
558
+ if (referrerPolicy) image.referrerPolicy = referrerPolicy;
559
+ image.crossOrigin = crossOrigin !== null && crossOrigin !== void 0 ? crossOrigin : null;
560
+ if (sizes) image.sizes = sizes;
561
+ if (srcSet) image.srcset = srcSet;
562
+ if (src) image.src = src;
563
+ if (image.complete) setStatus(image.naturalWidth > 0 ? "loaded" : "error");
564
+ return () => {
565
+ isMounted = false;
566
+ };
567
+ }, [
568
+ src,
569
+ srcSet,
570
+ sizes,
571
+ crossOrigin,
572
+ referrerPolicy
573
+ ]);
574
+ return status;
575
+ }
576
+ const sizeStyles$6 = {
577
+ xs: "h-6 w-6 text-[10px]",
578
+ sm: "h-8 w-8 text-xs",
579
+ md: "h-10 w-10 text-sm",
580
+ lg: "h-12 w-12 text-base",
581
+ xl: "h-16 w-16 text-lg"
582
+ };
583
+ const statusStyles = {
584
+ online: "bg-success",
585
+ offline: "bg-bg-muted",
586
+ busy: "bg-danger",
587
+ away: "bg-warning"
588
+ };
589
+ const statusSizeStyles = {
590
+ xs: "h-1.5 w-1.5 border",
591
+ sm: "h-2 w-2 border",
592
+ md: "h-2.5 w-2.5 border-2",
593
+ lg: "h-3 w-3 border-2",
594
+ xl: "h-4 w-4 border-2"
595
+ };
596
+ function getInitials(name) {
597
+ const parts = name.trim().split(/\s+/);
598
+ if (parts.length === 1) return parts[0].charAt(0).toUpperCase();
599
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();
600
+ }
601
+ const bgColors = [
602
+ "bg-blue-500",
603
+ "bg-emerald-500",
604
+ "bg-amber-500",
605
+ "bg-rose-500",
606
+ "bg-purple-500",
607
+ "bg-cyan-500",
608
+ "bg-orange-500",
609
+ "bg-indigo-500"
610
+ ];
611
+ function getColorFromName(name) {
612
+ let hash = 0;
613
+ for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
614
+ return bgColors[Math.abs(hash) % bgColors.length];
615
+ }
616
+ /** Renders the avatar component. */
617
+ function Avatar(_ref) {
618
+ var _ref2, _ref3;
619
+ let { src, srcSet, sizes, crossOrigin, referrerPolicy, alt, name, size = "md", fallback, status, className, onLoadingStatusChange } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$11);
620
+ const loadingStatus = useImageLoadingStatus(src, {
621
+ srcSet,
622
+ sizes,
623
+ crossOrigin,
624
+ referrerPolicy
625
+ });
626
+ (0, react.useEffect)(() => {
627
+ onLoadingStatusChange === null || onLoadingStatusChange === void 0 || onLoadingStatusChange(loadingStatus);
628
+ }, [loadingStatus, onLoadingStatusChange]);
629
+ const showImage = (Boolean(src) || Boolean(srcSet)) && loadingStatus === "loaded";
630
+ const initials = name ? getInitials(name) : null;
631
+ const bgColor = name ? getColorFromName(name) : "bg-bg-subtle";
632
+ const avatarLabel = status ? `${(_ref2 = name !== null && name !== void 0 ? name : alt) !== null && _ref2 !== void 0 ? _ref2 : "Avatar"} (${status})` : (_ref3 = name !== null && name !== void 0 ? name : alt) !== null && _ref3 !== void 0 ? _ref3 : "Avatar";
633
+ let avatarContent;
634
+ if (showImage) {
635
+ var _ref4;
636
+ avatarContent = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
637
+ src,
638
+ srcSet,
639
+ sizes,
640
+ crossOrigin,
641
+ referrerPolicy,
642
+ alt: (_ref4 = alt !== null && alt !== void 0 ? alt : name) !== null && _ref4 !== void 0 ? _ref4 : "Avatar",
643
+ className: "h-full w-full object-cover"
644
+ });
645
+ } else if (fallback) avatarContent = fallback;
646
+ else if (initials) avatarContent = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
647
+ className: "font-medium text-white",
648
+ children: initials
649
+ });
650
+ else avatarContent = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
651
+ className: "text-text-tertiary h-3/5 w-3/5",
652
+ fill: "currentColor",
653
+ viewBox: "0 0 24 24",
654
+ "aria-hidden": "true",
655
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" })
656
+ });
657
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
658
+ role: "img",
659
+ "aria-label": avatarLabel,
660
+ className: require_text_truncate.cn("relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full", sizeStyles$6[size], !showImage && bgColor, className)
661
+ }, props), {}, {
662
+ "data-opt-id": "SCMM0",
663
+ "data-opt-slug": "avatar.Avatar",
664
+ children: [avatarContent, status && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
665
+ className: require_text_truncate.cn("border-surface absolute right-0 bottom-0 rounded-full", statusStyles[status], statusSizeStyles[size]),
666
+ "aria-hidden": "true"
667
+ })]
668
+ }));
669
+ }
670
+ /** Renders the avatar group component. */
671
+ function AvatarGroup(_ref5) {
672
+ let { max = 4, size = "md", children, className } = _ref5, props = require_text_truncate._objectWithoutProperties(_ref5, _excluded2$5);
673
+ const avatars = Array.isArray(children) ? children : [children];
674
+ const visibleAvatars = avatars.slice(0, max);
675
+ const remainingCount = avatars.length - max;
676
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn("flex", className) }, props), {}, {
677
+ "data-opt-id": "MVB53",
678
+ "data-opt-slug": "avatar.AvatarGroup",
679
+ children: [visibleAvatars.map((child, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
680
+ className: "ring-surface relative -ml-2 inline-block rounded-full ring-2 first:ml-0",
681
+ children: child
682
+ }, index)), remainingCount > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
683
+ className: require_text_truncate.cn("bg-bg-subtle text-text-secondary ring-surface relative inline-flex items-center justify-center rounded-full font-medium ring-2", sizeStyles$6[size]),
684
+ children: ["+", remainingCount]
685
+ })]
686
+ }));
687
+ }
688
+ //#endregion
689
+ //#region src/core/identity.tsx
690
+ const defaultLabels$2 = {
691
+ identified: "Identified",
692
+ anonymous: "Anonymous"
693
+ };
694
+ /** Picks the display name, degrading through the identifiers we do have. */
695
+ function resolveDisplay(name, secondary, id) {
696
+ const trimmedName = name === null || name === void 0 ? void 0 : name.trim();
697
+ const trimmedSecondary = secondary === null || secondary === void 0 ? void 0 : secondary.trim();
698
+ if (trimmedName) return {
699
+ primary: trimmedName,
700
+ sub: trimmedSecondary || null
701
+ };
702
+ if (trimmedSecondary) return {
703
+ primary: trimmedSecondary,
704
+ sub: null
705
+ };
706
+ return {
707
+ primary: id !== null && id !== void 0 ? id : "—",
708
+ sub: null
709
+ };
710
+ }
711
+ /**
712
+ * Identity — one person (or one anonymous device) as a table cell.
713
+ *
714
+ * Every analytics surface renders the same fallback chain — name, then email,
715
+ * then an opaque id — and every hand-rolled copy of it drifts. Centralising it
716
+ * also centralises the anonymity marker, which is the part readers most often
717
+ * lose track of when a table mixes profiles and devices.
718
+ */
719
+ function Identity({ name, secondary, id, avatarSrc, state, badge, size = "md", hideAvatar = false, labels: customLabels, className }) {
720
+ const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$2), customLabels);
721
+ const { primary, sub } = resolveDisplay(name, secondary, id);
722
+ const anonymous = state === "anonymous";
723
+ const badgeContent = badge !== null && badge !== void 0 ? badge : state ? anonymous ? labels.anonymous : labels.identified : null;
724
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
725
+ className: require_text_truncate.cn("flex min-w-0 items-center gap-2", className),
726
+ title: id,
727
+ "data-opt-id": "BRGG2",
728
+ "data-opt-slug": "identity.Identity",
729
+ children: [!hideAvatar && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Avatar, {
730
+ src: avatarSrc !== null && avatarSrc !== void 0 ? avatarSrc : void 0,
731
+ name: anonymous ? void 0 : primary,
732
+ size: size === "sm" ? "xs" : "sm",
733
+ alt: "",
734
+ className: "shrink-0"
735
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
736
+ className: "flex min-w-0 flex-col",
737
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
738
+ className: "flex min-w-0 items-center gap-1.5",
739
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
740
+ className: require_text_truncate.cn("truncate text-sm font-medium", anonymous && !name ? require_text_truncate.OPT_TEXT_SECONDARY : require_text_truncate.OPT_TEXT_PRIMARY),
741
+ children: primary
742
+ }), badgeContent && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.Badge, {
743
+ size: "sm",
744
+ variant: anonymous ? "default" : "info",
745
+ className: "shrink-0",
746
+ children: badgeContent
747
+ })]
748
+ }), sub && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
749
+ className: require_text_truncate.cn("text-text-tertiary", "truncate text-xs"),
750
+ children: sub
751
+ })]
752
+ })]
753
+ });
754
+ }
755
+ Identity.displayName = "Identity";
756
+ //#endregion
413
757
  //#region src/core/card.tsx
414
- const _excluded$13 = [
758
+ const _excluded$10 = [
415
759
  "variant",
416
760
  "padding",
417
761
  "shadow",
@@ -425,17 +769,17 @@ const _excluded$13 = [
425
769
  "role",
426
770
  "tabIndex"
427
771
  ];
428
- const _excluded2$6 = [
772
+ const _excluded2$4 = [
429
773
  "gap",
430
774
  "className",
431
775
  "children"
432
776
  ];
433
- const _excluded3$3 = [
777
+ const _excluded3$2 = [
434
778
  "as",
435
779
  "className",
436
780
  "children"
437
781
  ];
438
- const _excluded4$2 = ["className", "children"];
782
+ const _excluded4$1 = ["className", "children"];
439
783
  const _excluded5 = [
440
784
  "spacing",
441
785
  "className",
@@ -448,7 +792,7 @@ const _excluded6 = [
448
792
  ];
449
793
  /** Renders the card component. */
450
794
  function Card(_ref) {
451
- let { variant = "default", padding = "md", shadow = true, selectable = false, selected = false, onSelectedChange, className, children, onClick, onKeyDown, role, tabIndex } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$13);
795
+ let { variant = "default", padding = "md", shadow = true, selectable = false, selected = false, onSelectedChange, className, children, onClick, onKeyDown, role, tabIndex } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$10);
452
796
  const isInteractive = selectable || !!onClick;
453
797
  const handleClick = selectable ? (e) => {
454
798
  onSelectedChange === null || onSelectedChange === void 0 || onSelectedChange(!selected);
@@ -467,7 +811,7 @@ function Card(_ref) {
467
811
  }
468
812
  onKeyDown === null || onKeyDown === void 0 || onKeyDown(e);
469
813
  } : onKeyDown;
470
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_highlight._objectSpread2(require_highlight._objectSpread2(require_highlight._objectSpread2({}, props), {}, { className: require_highlight.cn("rounded-xl", variant === "default" && require_highlight.cn(`border border-border bg-surface`, shadow && "shadow-sm"), variant === "outline" && "border-border border-2 bg-transparent", variant === "ghost" && "bg-bg-subtle", padding === "none" && "p-0", padding === "sm" && "p-3", padding === "md" && "p-5", padding === "lg" && "p-8", selectable && "cursor-pointer transition-colors", selectable && selected && "ring-accent border-accent ring-2 ring-offset-1", selectable && !selected && "hover:border-accent/50", className) }, isInteractive ? {
814
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, props), {}, { className: require_text_truncate.cn("rounded-xl", variant === "default" && require_text_truncate.cn(`border border-border bg-surface`, shadow && "shadow-sm"), variant === "outline" && "border-border border-2 bg-transparent", variant === "ghost" && "bg-bg-subtle", padding === "none" && "p-0", padding === "sm" && "p-3", padding === "md" && "p-5", padding === "lg" && "p-8", selectable && "cursor-pointer transition-colors", selectable && selected && "ring-accent border-accent ring-2 ring-offset-1", selectable && !selected && "hover:border-accent/50", className) }, isInteractive ? {
471
815
  role: selectable ? "option" : "button",
472
816
  tabIndex: 0,
473
817
  "aria-selected": selectable ? selected : void 0,
@@ -491,8 +835,8 @@ const headerGapClasses = {
491
835
  };
492
836
  /** Renders the card header component. */
493
837
  function CardHeader(_ref2) {
494
- let { gap = "sm", className, children } = _ref2, props = require_highlight._objectWithoutProperties(_ref2, _excluded2$6);
495
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("flex flex-col", headerGapClasses[gap], className) }, props), {}, {
838
+ let { gap = "sm", className, children } = _ref2, props = require_text_truncate._objectWithoutProperties(_ref2, _excluded2$4);
839
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn("flex flex-col", headerGapClasses[gap], className) }, props), {}, {
496
840
  "data-opt-id": "JST3J",
497
841
  "data-opt-slug": "card.CardHeader",
498
842
  children
@@ -500,8 +844,8 @@ function CardHeader(_ref2) {
500
844
  }
501
845
  /** Renders the card title component. */
502
846
  function CardTitle(_ref3) {
503
- let { as: Tag = "h3", className, children } = _ref3, props = require_highlight._objectWithoutProperties(_ref3, _excluded3$3);
504
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tag, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn(`text-lg font-semibold ${require_highlight.OPT_TEXT_PRIMARY}`, className) }, props), {}, {
847
+ let { as: Tag = "h3", className, children } = _ref3, props = require_text_truncate._objectWithoutProperties(_ref3, _excluded3$2);
848
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tag, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn(`text-lg font-semibold ${require_text_truncate.OPT_TEXT_PRIMARY}`, className) }, props), {}, {
505
849
  "data-opt-id": "V15TX",
506
850
  "data-opt-slug": "card.CardTitle",
507
851
  children
@@ -509,8 +853,8 @@ function CardTitle(_ref3) {
509
853
  }
510
854
  /** Renders the card description component. */
511
855
  function CardDescription(_ref4) {
512
- let { className, children } = _ref4, props = require_highlight._objectWithoutProperties(_ref4, _excluded4$2);
513
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn(`text-sm ${require_highlight.OPT_TEXT_SECONDARY}`, className) }, props), {}, {
856
+ let { className, children } = _ref4, props = require_text_truncate._objectWithoutProperties(_ref4, _excluded4$1);
857
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn(`text-sm ${require_text_truncate.OPT_TEXT_SECONDARY}`, className) }, props), {}, {
514
858
  "data-opt-id": "YB1RN",
515
859
  "data-opt-slug": "card.CardDescription",
516
860
  children
@@ -524,8 +868,8 @@ const contentSpacingClasses = {
524
868
  };
525
869
  /** Renders the card content component. */
526
870
  function CardContent(_ref5) {
527
- let { spacing = "md", className, children } = _ref5, props = require_highlight._objectWithoutProperties(_ref5, _excluded5);
528
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn(contentSpacingClasses[spacing], className) }, props), {}, {
871
+ let { spacing = "md", className, children } = _ref5, props = require_text_truncate._objectWithoutProperties(_ref5, _excluded5);
872
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn(contentSpacingClasses[spacing], className) }, props), {}, {
529
873
  "data-opt-id": "9Y68R",
530
874
  "data-opt-slug": "card.CardContent",
531
875
  children
@@ -533,8 +877,8 @@ function CardContent(_ref5) {
533
877
  }
534
878
  /** Renders the card footer component. */
535
879
  function CardFooter(_ref6) {
536
- let { divider = true, className, children } = _ref6, props = require_highlight._objectWithoutProperties(_ref6, _excluded6);
537
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("mt-4 flex items-center justify-end gap-2 pt-4", divider && `border-t border border-border`, className) }, props), {}, {
880
+ let { divider = true, className, children } = _ref6, props = require_text_truncate._objectWithoutProperties(_ref6, _excluded6);
881
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn("mt-4 flex items-center justify-end gap-2 pt-4", divider && `border-t border border-border`, className) }, props), {}, {
538
882
  "data-opt-id": "GRNTR",
539
883
  "data-opt-slug": "card.CardFooter",
540
884
  children
@@ -542,7 +886,7 @@ function CardFooter(_ref6) {
542
886
  }
543
887
  //#endregion
544
888
  //#region src/core/switch.tsx
545
- const _excluded$12 = [
889
+ const _excluded$9 = [
546
890
  "label",
547
891
  "required",
548
892
  "error",
@@ -559,7 +903,7 @@ const _excluded$12 = [
559
903
  "aria-label",
560
904
  "aria-labelledby"
561
905
  ];
562
- const sizeStyles$7 = {
906
+ const sizeStyles$5 = {
563
907
  sm: {
564
908
  track: "h-5 w-9",
565
909
  thumb: "h-4 w-4",
@@ -578,432 +922,125 @@ const sizeStyles$7 = {
578
922
  };
579
923
  const Switch = (0, react.forwardRef)((_ref, ref) => {
580
924
  var _useInputId;
581
- let { label, required, error, hint, description, checked: controlledChecked, defaultChecked = false, onChange, size = "md", disabled, className, id, onClick, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$12);
925
+ let { label, required, error, hint, description, checked: controlledChecked, defaultChecked = false, onChange, size = "md", disabled, className, id, onClick, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$9);
582
926
  const fallbackId = (0, react.useId)();
583
- const switchId = (_useInputId = require_highlight.useInputId(id, label, "switch")) !== null && _useInputId !== void 0 ? _useInputId : `switch-${fallbackId}`;
927
+ const switchId = (_useInputId = require_text_truncate.useInputId(id, label, "switch")) !== null && _useInputId !== void 0 ? _useInputId : `switch-${fallbackId}`;
584
928
  const hintText = hint !== null && hint !== void 0 ? hint : description;
585
929
  const hasError = Boolean(error);
586
- const styles = sizeStyles$7[size];
587
- const labelId = label ? `${switchId}-label` : void 0;
588
- const switchLabelledBy = ariaLabelledBy !== null && ariaLabelledBy !== void 0 ? ariaLabelledBy : ariaLabel ? void 0 : labelId;
589
- const switchAriaLabel = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : switchLabelledBy ? void 0 : "Switch";
590
- const isControlled = controlledChecked !== void 0;
591
- const [internalChecked, setInternalChecked] = (0, react.useState)(defaultChecked);
592
- const checked = isControlled ? controlledChecked : internalChecked;
593
- const handleClick = (0, react.useCallback)((e) => {
594
- const next = !checked;
595
- if (!isControlled) setInternalChecked(next);
596
- onChange === null || onChange === void 0 || onChange(next);
597
- onClick === null || onClick === void 0 || onClick(e);
598
- }, [
599
- checked,
600
- isControlled,
601
- onChange,
602
- onClick
603
- ]);
604
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
605
- className: require_highlight.cn("flex flex-col gap-1.5", className),
606
- "data-opt-id": "51Z9R",
607
- "data-opt-slug": "switch.Switch",
608
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
609
- className: "flex items-start gap-3",
610
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", require_highlight._objectSpread2(require_highlight._objectSpread2({
611
- ref,
612
- type: "button",
613
- role: "switch",
614
- id: switchId,
615
- "aria-checked": checked,
616
- "aria-label": switchAriaLabel,
617
- "aria-labelledby": switchLabelledBy,
618
- disabled,
619
- className: require_highlight.cn("group relative inline-flex shrink-0 cursor-pointer rounded-full p-0.5 transition-colors", styles.track, "bg-bg-muted", "aria-[checked=true]:bg-accent", "disabled:cursor-not-allowed disabled:opacity-50", require_highlight.OPT_FOCUS_VISIBLE),
620
- "aria-invalid": hasError,
621
- "aria-required": required,
622
- "aria-describedby": require_highlight.getDescribedBy(switchId, error, hintText),
623
- onClick: handleClick
624
- }, props), {}, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: require_highlight.cn("pointer-events-none inline-block transform rounded-full bg-white shadow-sm ring-0 transition-transform", styles.thumb, "translate-x-0", size === "sm" && "group-aria-[checked=true]:translate-x-4", size === "md" && "group-aria-[checked=true]:translate-x-5", size === "lg" && "group-aria-[checked=true]:translate-x-7") }) })), (label || hintText) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
625
- className: "flex flex-col",
626
- children: [label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
627
- id: labelId,
628
- className: require_highlight.cn("text-text-primary text-sm font-medium", disabled && "opacity-50"),
629
- children: [label, required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.RequiredMark, {})]
630
- }), hintText && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
631
- id: `${switchId}-hint`,
632
- className: require_highlight.cn("text-text-tertiary text-sm", disabled && "opacity-50"),
633
- children: hintText
634
- })]
635
- })]
636
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.FieldMessages, {
637
- id: switchId,
638
- error
639
- })]
640
- });
641
- });
642
- Switch.displayName = "Switch";
643
- //#endregion
644
- //#region src/core/skeleton.tsx
645
- const _excluded$11 = [
646
- "variant",
647
- "width",
648
- "height",
649
- "lines",
650
- "animated",
651
- "className",
652
- "style"
653
- ];
654
- const _excluded2$5 = ["lines", "className"];
655
- const _excluded3$2 = ["size", "className"];
656
- const _excluded4$1 = ["className"];
657
- const variantStyles$2 = {
658
- text: "rounded h-4",
659
- circular: "rounded-full",
660
- rectangular: "rounded-lg"
661
- };
662
- /** Renders the skeleton component. */
663
- function Skeleton(_ref) {
664
- let { variant = "text", width, height, lines = 1, animated = true, className, style } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$11);
665
- const baseClass = require_highlight.cn("bg-bg-subtle", animated && "animate-pulse", variantStyles$2[variant], className);
666
- const computedStyle = require_highlight._objectSpread2({
667
- width: typeof width === "number" ? `${width}px` : width,
668
- height: typeof height === "number" ? `${height}px` : height
669
- }, style);
670
- if (variant === "text" && lines > 1) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
671
- className: "gap-element flex flex-col",
672
- role: "status",
673
- "aria-label": "Loading",
674
- "data-opt-id": "EJT87",
675
- "data-opt-slug": "skeleton.Skeleton",
676
- children: [Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_highlight._objectSpread2({
677
- className: require_highlight.cn(baseClass, i === lines - 1 && "w-4/5"),
678
- style: i === lines - 1 ? void 0 : computedStyle
679
- }, props), i)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
680
- className: "sr-only",
681
- children: "Loading..."
682
- })]
683
- });
684
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_highlight._objectSpread2(require_highlight._objectSpread2({
685
- className: baseClass,
686
- style: computedStyle,
687
- role: "status",
688
- "aria-label": "Loading"
689
- }, props), {}, {
690
- "data-opt-id": "EJT87",
691
- "data-opt-slug": "skeleton.Skeleton",
692
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
693
- className: "sr-only",
694
- children: "Loading..."
695
- })
696
- }));
697
- }
698
- /** Renders the skeleton text component. */
699
- function SkeletonText(_ref2) {
700
- let { lines = 3, className } = _ref2, props = require_highlight._objectWithoutProperties(_ref2, _excluded2$5);
701
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Skeleton, require_highlight._objectSpread2(require_highlight._objectSpread2({
702
- variant: "text",
703
- lines,
704
- className
705
- }, props), {}, {
706
- "data-opt-id": "MX3D5",
707
- "data-opt-slug": "skeleton.SkeletonText"
708
- }));
709
- }
710
- /** Renders the skeleton avatar component. */
711
- function SkeletonAvatar(_ref3) {
712
- let { size = 40, className } = _ref3, props = require_highlight._objectWithoutProperties(_ref3, _excluded3$2);
713
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Skeleton, require_highlight._objectSpread2(require_highlight._objectSpread2({
714
- variant: "circular",
715
- width: size,
716
- height: size,
717
- className
718
- }, props), {}, {
719
- "data-opt-id": "MP0HZ",
720
- "data-opt-slug": "skeleton.SkeletonAvatar"
721
- }));
722
- }
723
- /** Renders the skeleton card component. */
724
- function SkeletonCard(_ref4) {
725
- let { className } = _ref4, props = require_highlight._objectWithoutProperties(_ref4, _excluded4$1);
726
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("gap-group flex flex-col", className) }, props), {}, {
727
- "data-opt-id": "34V5D",
728
- "data-opt-slug": "skeleton.SkeletonCard",
729
- children: [
730
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Skeleton, {
731
- variant: "rectangular",
732
- height: 120
733
- }),
734
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Skeleton, {
735
- variant: "text",
736
- width: "60%"
737
- }),
738
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Skeleton, {
739
- variant: "text",
740
- lines: 2
741
- })
742
- ]
743
- }));
744
- }
745
- /** Renders the skeleton table component. */
746
- function SkeletonTable({ rows = 5, columns = 4, className }) {
747
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
748
- className: require_highlight.cn("gap-element flex flex-col", className),
749
- role: "status",
750
- "aria-label": "Loading table",
751
- "data-opt-id": "3KEDN",
752
- "data-opt-slug": "skeleton.SkeletonTable",
753
- children: [
754
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
755
- className: "border-border-subtle gap-group flex border-b pb-2",
756
- children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Skeleton, {
757
- variant: "text",
758
- className: "flex-1",
759
- height: 16
760
- }, i))
761
- }),
762
- Array.from({ length: rows }).map((_, rowIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
763
- className: "gap-group flex py-2",
764
- children: Array.from({ length: columns }).map((_, colIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Skeleton, {
765
- variant: "text",
766
- className: "flex-1",
767
- height: 14
768
- }, colIndex))
769
- }, rowIndex)),
770
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
771
- className: "sr-only",
772
- children: "Loading..."
773
- })
774
- ]
775
- });
776
- }
777
- //#endregion
778
- //#region src/core/textarea.tsx
779
- const _excluded$10 = [
780
- "label",
781
- "error",
782
- "hint",
783
- "fullWidth",
784
- "required",
785
- "resize",
786
- "size",
787
- "className",
788
- "id",
789
- "rows"
790
- ];
791
- const textareaSizeStyles = require_highlight.OPT_TEXTAREA_SIZE;
792
- const resizeStyles = {
793
- none: "resize-none",
794
- vertical: "resize-y",
795
- horizontal: "resize-x",
796
- both: "resize"
797
- };
798
- const Textarea = (0, react.forwardRef)((_ref, ref) => {
799
- var _useInputId;
800
- let { label, error, hint, fullWidth = false, required, resize = "vertical", size = "md", className, id, rows = 4 } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$10);
801
- const fallbackId = (0, react.useId)().replace(/:/g, "");
802
- const textareaId = (_useInputId = require_highlight.useInputId(id, label, "textarea")) !== null && _useInputId !== void 0 ? _useInputId : `textarea-${fallbackId}`;
803
- const hasError = Boolean(error);
804
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
805
- className: require_highlight.cn("flex flex-col gap-1.5", fullWidth && "w-full"),
806
- "data-opt-id": "6T58H",
807
- "data-opt-slug": "textarea.Textarea",
808
- children: [
809
- label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
810
- htmlFor: textareaId,
811
- className: "text-text-primary text-sm font-medium",
812
- children: [label, required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.RequiredMark, {})]
813
- }),
814
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", require_highlight._objectSpread2({
815
- ref,
816
- id: textareaId,
817
- rows,
818
- className: require_highlight.cn("border-border bg-surface text-text-primary placeholder:text-text-tertiary w-full rounded-lg border px-4 py-3 text-sm outline-transparent", require_highlight.OPT_FOCUS_VISIBLE, textareaSizeStyles[size], resizeStyles[resize], hasError && "border-danger focus-visible:outline-danger", !fullWidth && "w-auto", className),
819
- "aria-invalid": hasError,
820
- "aria-describedby": require_highlight.getDescribedBy(textareaId, error, hint)
821
- }, props)),
822
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.FieldMessages, {
823
- id: textareaId,
824
- error,
825
- hint
826
- })
827
- ]
828
- });
829
- });
830
- Textarea.displayName = "Textarea";
831
- //#endregion
832
- //#region src/core/avatar.tsx
833
- const _excluded$9 = [
834
- "src",
835
- "srcSet",
836
- "sizes",
837
- "crossOrigin",
838
- "referrerPolicy",
839
- "alt",
840
- "name",
841
- "size",
842
- "fallback",
843
- "status",
844
- "className",
845
- "onLoadingStatusChange"
846
- ];
847
- const _excluded2$4 = [
848
- "max",
849
- "size",
850
- "children",
851
- "className"
852
- ];
853
- const useIsoLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
854
- /**
855
- * Tracks an image's loading status by preloading it off-DOM, so the avatar can
856
- * show its fallback until the image is actually decoded (no broken-image flash)
857
- * and recover from late `error`/`load` events. Supports responsive `srcSet`/`sizes`.
858
- */
859
- function useImageLoadingStatus(src, { srcSet, sizes, crossOrigin, referrerPolicy }) {
860
- const [status, setStatus] = (0, react.useState)("idle");
861
- useIsoLayoutEffect(() => {
862
- if (!src && !srcSet) {
863
- setStatus("error");
864
- return;
865
- }
866
- let isMounted = true;
867
- const image = new window.Image();
868
- const update = (next) => () => {
869
- if (isMounted) setStatus(next);
870
- };
871
- setStatus("loading");
872
- image.onload = update("loaded");
873
- image.onerror = update("error");
874
- if (referrerPolicy) image.referrerPolicy = referrerPolicy;
875
- image.crossOrigin = crossOrigin !== null && crossOrigin !== void 0 ? crossOrigin : null;
876
- if (sizes) image.sizes = sizes;
877
- if (srcSet) image.srcset = srcSet;
878
- if (src) image.src = src;
879
- if (image.complete) setStatus(image.naturalWidth > 0 ? "loaded" : "error");
880
- return () => {
881
- isMounted = false;
882
- };
883
- }, [
884
- src,
885
- srcSet,
886
- sizes,
887
- crossOrigin,
888
- referrerPolicy
889
- ]);
890
- return status;
891
- }
892
- const sizeStyles$6 = {
893
- xs: "h-6 w-6 text-[10px]",
894
- sm: "h-8 w-8 text-xs",
895
- md: "h-10 w-10 text-sm",
896
- lg: "h-12 w-12 text-base",
897
- xl: "h-16 w-16 text-lg"
898
- };
899
- const statusStyles = {
900
- online: "bg-success",
901
- offline: "bg-bg-muted",
902
- busy: "bg-danger",
903
- away: "bg-warning"
904
- };
905
- const statusSizeStyles = {
906
- xs: "h-1.5 w-1.5 border",
907
- sm: "h-2 w-2 border",
908
- md: "h-2.5 w-2.5 border-2",
909
- lg: "h-3 w-3 border-2",
910
- xl: "h-4 w-4 border-2"
911
- };
912
- function getInitials(name) {
913
- const parts = name.trim().split(/\s+/);
914
- if (parts.length === 1) return parts[0].charAt(0).toUpperCase();
915
- return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();
916
- }
917
- const bgColors = [
918
- "bg-blue-500",
919
- "bg-emerald-500",
920
- "bg-amber-500",
921
- "bg-rose-500",
922
- "bg-purple-500",
923
- "bg-cyan-500",
924
- "bg-orange-500",
925
- "bg-indigo-500"
926
- ];
927
- function getColorFromName(name) {
928
- let hash = 0;
929
- for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
930
- return bgColors[Math.abs(hash) % bgColors.length];
931
- }
932
- /** Renders the avatar component. */
933
- function Avatar(_ref) {
934
- var _ref2, _ref3;
935
- let { src, srcSet, sizes, crossOrigin, referrerPolicy, alt, name, size = "md", fallback, status, className, onLoadingStatusChange } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$9);
936
- const loadingStatus = useImageLoadingStatus(src, {
937
- srcSet,
938
- sizes,
939
- crossOrigin,
940
- referrerPolicy
941
- });
942
- (0, react.useEffect)(() => {
943
- onLoadingStatusChange === null || onLoadingStatusChange === void 0 || onLoadingStatusChange(loadingStatus);
944
- }, [loadingStatus, onLoadingStatusChange]);
945
- const showImage = (Boolean(src) || Boolean(srcSet)) && loadingStatus === "loaded";
946
- const initials = name ? getInitials(name) : null;
947
- const bgColor = name ? getColorFromName(name) : "bg-bg-subtle";
948
- const avatarLabel = status ? `${(_ref2 = name !== null && name !== void 0 ? name : alt) !== null && _ref2 !== void 0 ? _ref2 : "Avatar"} (${status})` : (_ref3 = name !== null && name !== void 0 ? name : alt) !== null && _ref3 !== void 0 ? _ref3 : "Avatar";
949
- let avatarContent;
950
- if (showImage) {
951
- var _ref4;
952
- avatarContent = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
953
- src,
954
- srcSet,
955
- sizes,
956
- crossOrigin,
957
- referrerPolicy,
958
- alt: (_ref4 = alt !== null && alt !== void 0 ? alt : name) !== null && _ref4 !== void 0 ? _ref4 : "Avatar",
959
- className: "h-full w-full object-cover"
960
- });
961
- } else if (fallback) avatarContent = fallback;
962
- else if (initials) avatarContent = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
963
- className: "font-medium text-white",
964
- children: initials
930
+ const styles = sizeStyles$5[size];
931
+ const labelId = label ? `${switchId}-label` : void 0;
932
+ const switchLabelledBy = ariaLabelledBy !== null && ariaLabelledBy !== void 0 ? ariaLabelledBy : ariaLabel ? void 0 : labelId;
933
+ const switchAriaLabel = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : switchLabelledBy ? void 0 : "Switch";
934
+ const isControlled = controlledChecked !== void 0;
935
+ const [internalChecked, setInternalChecked] = (0, react.useState)(defaultChecked);
936
+ const checked = isControlled ? controlledChecked : internalChecked;
937
+ const handleClick = (0, react.useCallback)((e) => {
938
+ const next = !checked;
939
+ if (!isControlled) setInternalChecked(next);
940
+ onChange === null || onChange === void 0 || onChange(next);
941
+ onClick === null || onClick === void 0 || onClick(e);
942
+ }, [
943
+ checked,
944
+ isControlled,
945
+ onChange,
946
+ onClick
947
+ ]);
948
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
949
+ className: require_text_truncate.cn("flex flex-col gap-1.5", className),
950
+ "data-opt-id": "51Z9R",
951
+ "data-opt-slug": "switch.Switch",
952
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
953
+ className: "flex items-start gap-3",
954
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
955
+ ref,
956
+ type: "button",
957
+ role: "switch",
958
+ id: switchId,
959
+ "aria-checked": checked,
960
+ "aria-label": switchAriaLabel,
961
+ "aria-labelledby": switchLabelledBy,
962
+ disabled,
963
+ className: require_text_truncate.cn("group relative inline-flex shrink-0 cursor-pointer rounded-full p-0.5 transition-colors", styles.track, "bg-bg-muted", "aria-[checked=true]:bg-accent", "disabled:cursor-not-allowed disabled:opacity-50", require_text_truncate.OPT_FOCUS_VISIBLE),
964
+ "aria-invalid": hasError,
965
+ "aria-required": required,
966
+ "aria-describedby": require_text_truncate.getDescribedBy(switchId, error, hintText),
967
+ onClick: handleClick
968
+ }, props), {}, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: require_text_truncate.cn("pointer-events-none inline-block transform rounded-full bg-white shadow-sm ring-0 transition-transform", styles.thumb, "translate-x-0", size === "sm" && "group-aria-[checked=true]:translate-x-4", size === "md" && "group-aria-[checked=true]:translate-x-5", size === "lg" && "group-aria-[checked=true]:translate-x-7") }) })), (label || hintText) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
969
+ className: "flex flex-col",
970
+ children: [label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
971
+ id: labelId,
972
+ className: require_text_truncate.cn("text-text-primary text-sm font-medium", disabled && "opacity-50"),
973
+ children: [label, required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.RequiredMark, {})]
974
+ }), hintText && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
975
+ id: `${switchId}-hint`,
976
+ className: require_text_truncate.cn("text-text-tertiary text-sm", disabled && "opacity-50"),
977
+ children: hintText
978
+ })]
979
+ })]
980
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FieldMessages, {
981
+ id: switchId,
982
+ error
983
+ })]
965
984
  });
966
- else avatarContent = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
967
- className: "text-text-tertiary h-3/5 w-3/5",
968
- fill: "currentColor",
969
- viewBox: "0 0 24 24",
970
- "aria-hidden": "true",
971
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" })
985
+ });
986
+ Switch.displayName = "Switch";
987
+ //#endregion
988
+ //#region src/core/textarea.tsx
989
+ const _excluded$8 = [
990
+ "label",
991
+ "error",
992
+ "hint",
993
+ "fullWidth",
994
+ "required",
995
+ "resize",
996
+ "size",
997
+ "className",
998
+ "id",
999
+ "rows"
1000
+ ];
1001
+ const textareaSizeStyles = require_text_truncate.OPT_TEXTAREA_SIZE;
1002
+ const resizeStyles = {
1003
+ none: "resize-none",
1004
+ vertical: "resize-y",
1005
+ horizontal: "resize-x",
1006
+ both: "resize"
1007
+ };
1008
+ const Textarea = (0, react.forwardRef)((_ref, ref) => {
1009
+ var _useInputId;
1010
+ let { label, error, hint, fullWidth = false, required, resize = "vertical", size = "md", className, id, rows = 4 } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$8);
1011
+ const fallbackId = (0, react.useId)().replace(/:/g, "");
1012
+ const textareaId = (_useInputId = require_text_truncate.useInputId(id, label, "textarea")) !== null && _useInputId !== void 0 ? _useInputId : `textarea-${fallbackId}`;
1013
+ const hasError = Boolean(error);
1014
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1015
+ className: require_text_truncate.cn("flex flex-col gap-1.5", fullWidth && "w-full"),
1016
+ "data-opt-id": "6T58H",
1017
+ "data-opt-slug": "textarea.Textarea",
1018
+ children: [
1019
+ label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1020
+ htmlFor: textareaId,
1021
+ className: "text-text-primary text-sm font-medium",
1022
+ children: [label, required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.RequiredMark, {})]
1023
+ }),
1024
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", require_text_truncate._objectSpread2({
1025
+ ref,
1026
+ id: textareaId,
1027
+ rows,
1028
+ className: require_text_truncate.cn("border-border bg-surface text-text-primary placeholder:text-text-tertiary w-full rounded-lg border px-4 py-3 text-sm outline-transparent", require_text_truncate.OPT_FOCUS_VISIBLE, textareaSizeStyles[size], resizeStyles[resize], hasError && "border-danger focus-visible:outline-danger", !fullWidth && "w-auto", className),
1029
+ "aria-invalid": hasError,
1030
+ "aria-describedby": require_text_truncate.getDescribedBy(textareaId, error, hint)
1031
+ }, props)),
1032
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FieldMessages, {
1033
+ id: textareaId,
1034
+ error,
1035
+ hint
1036
+ })
1037
+ ]
972
1038
  });
973
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", require_highlight._objectSpread2(require_highlight._objectSpread2({
974
- role: "img",
975
- "aria-label": avatarLabel,
976
- className: require_highlight.cn("relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full", sizeStyles$6[size], !showImage && bgColor, className)
977
- }, props), {}, {
978
- "data-opt-id": "SCMM0",
979
- "data-opt-slug": "avatar.Avatar",
980
- children: [avatarContent, status && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
981
- className: require_highlight.cn("border-surface absolute right-0 bottom-0 rounded-full", statusStyles[status], statusSizeStyles[size]),
982
- "aria-hidden": "true"
983
- })]
984
- }));
985
- }
986
- /** Renders the avatar group component. */
987
- function AvatarGroup(_ref5) {
988
- let { max = 4, size = "md", children, className } = _ref5, props = require_highlight._objectWithoutProperties(_ref5, _excluded2$4);
989
- const avatars = Array.isArray(children) ? children : [children];
990
- const visibleAvatars = avatars.slice(0, max);
991
- const remainingCount = avatars.length - max;
992
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("flex", className) }, props), {}, {
993
- "data-opt-id": "MVB53",
994
- "data-opt-slug": "avatar.AvatarGroup",
995
- children: [visibleAvatars.map((child, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
996
- className: "ring-surface relative -ml-2 inline-block rounded-full ring-2 first:ml-0",
997
- children: child
998
- }, index)), remainingCount > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
999
- className: require_highlight.cn("bg-bg-subtle text-text-secondary ring-surface relative inline-flex items-center justify-center rounded-full font-medium ring-2", sizeStyles$6[size]),
1000
- children: ["+", remainingCount]
1001
- })]
1002
- }));
1003
- }
1039
+ });
1040
+ Textarea.displayName = "Textarea";
1004
1041
  //#endregion
1005
1042
  //#region src/core/progress.tsx
1006
- const _excluded$8 = [
1043
+ const _excluded$7 = [
1007
1044
  "value",
1008
1045
  "max",
1009
1046
  "size",
@@ -1025,12 +1062,12 @@ const _excluded2$3 = [
1025
1062
  "indeterminate",
1026
1063
  "className"
1027
1064
  ];
1028
- const sizeStyles$5 = {
1065
+ const sizeStyles$4 = {
1029
1066
  sm: "h-1",
1030
1067
  md: "h-2",
1031
1068
  lg: "h-3"
1032
1069
  };
1033
- const variantStyles$1 = {
1070
+ const variantStyles = {
1034
1071
  default: "bg-accent",
1035
1072
  success: "bg-success",
1036
1073
  warning: "bg-warning",
@@ -1049,10 +1086,10 @@ function getProgressValue(value, max) {
1049
1086
  }
1050
1087
  /** Renders the progress component. */
1051
1088
  function Progress(_ref) {
1052
- let { value, max = 100, size = "md", variant = "default", showLabel = false, label, animated = true, indeterminate = false, className } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$8);
1089
+ let { value, max = 100, size = "md", variant = "default", showLabel = false, label, animated = true, indeterminate = false, className } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$7);
1053
1090
  const progress = indeterminate || value === void 0 ? null : getProgressValue(value, max);
1054
1091
  const shouldRenderHeader = Boolean(label) || showLabel && progress;
1055
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("w-full", className) }, props), {}, {
1092
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn("w-full", className) }, props), {}, {
1056
1093
  "data-opt-id": "Y5N8R",
1057
1094
  "data-opt-slug": "progress.Progress",
1058
1095
  children: [shouldRenderHeader && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -1065,7 +1102,7 @@ function Progress(_ref) {
1065
1102
  children: progress.valueText
1066
1103
  })]
1067
1104
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1068
- className: require_highlight.cn("bg-bg-subtle w-full overflow-hidden rounded-full", sizeStyles$5[size]),
1105
+ className: require_text_truncate.cn("bg-bg-subtle w-full overflow-hidden rounded-full", sizeStyles$4[size]),
1069
1106
  role: "progressbar",
1070
1107
  "aria-valuenow": progress === null || progress === void 0 ? void 0 : progress.clampedValue,
1071
1108
  "aria-valuemin": progress ? 0 : void 0,
@@ -1073,7 +1110,7 @@ function Progress(_ref) {
1073
1110
  "aria-valuetext": progress === null || progress === void 0 ? void 0 : progress.valueText,
1074
1111
  "aria-label": label !== null && label !== void 0 ? label : progress ? `${progress.valueText} complete` : "Loading",
1075
1112
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1076
- className: require_highlight.cn("h-full rounded-full", variantStyles$1[variant], !progress && "w-1/3 animate-pulse", animated && (progress ? "transition-all duration-300 ease-out" : "transition-opacity duration-700 ease-in-out")),
1113
+ className: require_text_truncate.cn("h-full rounded-full", variantStyles[variant], !progress && "w-1/3 animate-pulse", animated && (progress ? "transition-all duration-300 ease-out" : "transition-opacity duration-700 ease-in-out")),
1077
1114
  style: progress ? { width: `${progress.percentage}%` } : void 0
1078
1115
  })
1079
1116
  })]
@@ -1088,7 +1125,7 @@ const circularVariantStyles = {
1088
1125
  /** Renders the circular progress component. */
1089
1126
  function CircularProgress(_ref2) {
1090
1127
  var _progress$percentage;
1091
- let { value, max = 100, size = 48, strokeWidth = 4, variant = "default", showLabel = false, label, indeterminate = false, className } = _ref2, props = require_highlight._objectWithoutProperties(_ref2, _excluded2$3);
1128
+ let { value, max = 100, size = 48, strokeWidth = 4, variant = "default", showLabel = false, label, indeterminate = false, className } = _ref2, props = require_text_truncate._objectWithoutProperties(_ref2, _excluded2$3);
1092
1129
  const labelId = (0, react.useId)();
1093
1130
  const isIndeterminate = indeterminate || value === void 0;
1094
1131
  const progress = isIndeterminate ? null : getProgressValue(value, max);
@@ -1106,10 +1143,10 @@ function CircularProgress(_ref2) {
1106
1143
  className: "sr-only",
1107
1144
  children: label
1108
1145
  }),
1109
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", require_highlight._objectSpread2(require_highlight._objectSpread2({
1146
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
1110
1147
  width: size,
1111
1148
  height: size,
1112
- className: require_highlight.cn(isIndeterminate ? "animate-spin" : "-rotate-90", className),
1149
+ className: require_text_truncate.cn(isIndeterminate ? "animate-spin" : "-rotate-90", className),
1113
1150
  role: isIndeterminate ? "progressbar" : "meter",
1114
1151
  "aria-labelledby": label ? labelId : void 0,
1115
1152
  "aria-valuenow": progress === null || progress === void 0 ? void 0 : progress.clampedValue,
@@ -1131,7 +1168,7 @@ function CircularProgress(_ref2) {
1131
1168
  fill: "none",
1132
1169
  strokeWidth,
1133
1170
  strokeLinecap: "round",
1134
- className: require_highlight.cn("transition-all duration-300 ease-out", circularVariantStyles[variant]),
1171
+ className: require_text_truncate.cn("transition-all duration-300 ease-out", circularVariantStyles[variant]),
1135
1172
  style: {
1136
1173
  strokeDasharray: isIndeterminate ? `${circumference * .28} ${circumference}` : circumference,
1137
1174
  strokeDashoffset: isIndeterminate ? 0 : strokeDashoffset,
@@ -1146,65 +1183,6 @@ function CircularProgress(_ref2) {
1146
1183
  });
1147
1184
  }
1148
1185
  //#endregion
1149
- //#region src/core/meter.tsx
1150
- const _excluded$7 = [
1151
- "value",
1152
- "min",
1153
- "max",
1154
- "size",
1155
- "variant",
1156
- "showValue",
1157
- "label",
1158
- "getValueLabel",
1159
- "className"
1160
- ];
1161
- const sizeStyles$4 = {
1162
- sm: "h-1",
1163
- md: "h-2",
1164
- lg: "h-3"
1165
- };
1166
- const variantStyles = {
1167
- default: "bg-accent",
1168
- success: "bg-success",
1169
- warning: "bg-warning",
1170
- error: "bg-danger"
1171
- };
1172
- /**
1173
- * A scalar measurement within a known range (disk usage, score, capacity) —
1174
- * `role="meter"`, distinct from Progress (task completion). Built on the
1175
- * opt-ui-primitives Meter primitive, which owns the role/aria/valuetext.
1176
- */
1177
- function Meter(_ref) {
1178
- let { value, min = 0, max = 100, size = "md", variant = "default", showValue = false, label, getValueLabel, className } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$7);
1179
- const clamped = Math.min(Math.max(value, min), max);
1180
- const percentage = max === min ? 0 : (clamped - min) / (max - min) * 100;
1181
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("w-full", className) }, props), {}, {
1182
- "data-opt-id": "G01TE",
1183
- "data-opt-slug": "meter.Meter",
1184
- children: [(showValue || label) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1185
- className: "mb-1.5 flex items-center justify-between text-sm",
1186
- children: [label && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1187
- className: "text-text-primary font-medium",
1188
- children: label
1189
- }), showValue && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1190
- className: "text-text-tertiary",
1191
- children: [Math.round(percentage), "%"]
1192
- })]
1193
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.Meter, {
1194
- value: clamped,
1195
- min,
1196
- max,
1197
- getValueLabel,
1198
- "aria-label": label !== null && label !== void 0 ? label : `${Math.round(percentage)}%`,
1199
- className: require_highlight.cn("bg-bg-subtle w-full overflow-hidden rounded-full", sizeStyles$4[size]),
1200
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1201
- className: require_highlight.cn("h-full rounded-full transition-all duration-300 ease-out", variantStyles[variant]),
1202
- style: { width: `${percentage}%` }
1203
- })
1204
- })]
1205
- }));
1206
- }
1207
- //#endregion
1208
1186
  //#region src/core/step-builder.tsx
1209
1187
  /** Renders the step builder component. */
1210
1188
  function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps, className, "aria-label": ariaLabel }) {
@@ -1242,7 +1220,7 @@ function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps,
1242
1220
  editingId
1243
1221
  ]);
1244
1222
  const updateStep = (0, react.useCallback)((id, updates) => {
1245
- onChange(steps.map((s) => s.id === id ? require_highlight._objectSpread2(require_highlight._objectSpread2({}, s), updates) : s));
1223
+ onChange(steps.map((s) => s.id === id ? require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, s), updates) : s));
1246
1224
  }, [steps, onChange]);
1247
1225
  const moveStep = (0, react.useCallback)((index, direction) => {
1248
1226
  const target = index + direction;
@@ -1253,7 +1231,7 @@ function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps,
1253
1231
  }, [steps, onChange]);
1254
1232
  const atLimit = Boolean(maxSteps && steps.length >= maxSteps);
1255
1233
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1256
- className: require_highlight.cn("flex flex-col gap-3", className),
1234
+ className: require_text_truncate.cn("flex flex-col gap-3", className),
1257
1235
  role: "list",
1258
1236
  "aria-label": (_ref = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : label) !== null && _ref !== void 0 ? _ref : "Step builder",
1259
1237
  "data-opt-id": "7BQDT",
@@ -1266,7 +1244,7 @@ function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps,
1266
1244
  steps.map((step, index) => {
1267
1245
  var _step$description;
1268
1246
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1269
- className: require_highlight.cn(require_highlight.OPT_SURFACE, require_highlight.OPT_BORDER, "flex items-start gap-3 p-3"),
1247
+ className: require_text_truncate.cn(require_text_truncate.OPT_SURFACE, require_text_truncate.OPT_BORDER, "flex items-start gap-3 p-3"),
1270
1248
  role: "listitem",
1271
1249
  children: [
1272
1250
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -1286,7 +1264,7 @@ function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps,
1286
1264
  onKeyDown: (e) => {
1287
1265
  if (e.key === "Enter") setEditingId(null);
1288
1266
  },
1289
- className: require_highlight.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset w-full rounded-md border px-2 py-1 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1", require_highlight.OPT_TEXT_PRIMARY, require_highlight.OPT_FOCUS_VISIBLE),
1267
+ className: require_text_truncate.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset w-full rounded-md border px-2 py-1 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1", require_text_truncate.OPT_TEXT_PRIMARY, require_text_truncate.OPT_FOCUS_VISIBLE),
1290
1268
  "aria-label": "Step label",
1291
1269
  autoFocus: true
1292
1270
  }),
@@ -1295,10 +1273,10 @@ function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps,
1295
1273
  value: (_step$description = step.description) !== null && _step$description !== void 0 ? _step$description : "",
1296
1274
  onChange: (e) => updateStep(step.id, { description: e.target.value }),
1297
1275
  placeholder: "Description (optional)",
1298
- className: require_highlight.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset w-full rounded-md border px-2 py-1 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1", require_highlight.OPT_TEXT_PRIMARY, "placeholder:text-text-tertiary", require_highlight.OPT_FOCUS_VISIBLE),
1276
+ className: require_text_truncate.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset w-full rounded-md border px-2 py-1 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1", require_text_truncate.OPT_TEXT_PRIMARY, "placeholder:text-text-tertiary", require_text_truncate.OPT_FOCUS_VISIBLE),
1299
1277
  "aria-label": "Step description"
1300
1278
  }),
1301
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.Button, {
1279
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.Button, {
1302
1280
  variant: "ghost",
1303
1281
  size: "sm",
1304
1282
  onClick: () => setEditingId(null),
@@ -1311,10 +1289,10 @@ function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps,
1311
1289
  onClick: () => setEditingId(step.id),
1312
1290
  "aria-label": `Edit ${step.label}`,
1313
1291
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1314
- className: require_highlight.cn(require_highlight.OPT_TEXT_PRIMARY, "text-sm font-medium"),
1292
+ className: require_text_truncate.cn(require_text_truncate.OPT_TEXT_PRIMARY, "text-sm font-medium"),
1315
1293
  children: step.label
1316
1294
  }), step.description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1317
- className: require_highlight.cn("text-text-secondary", "mt-0.5 block text-xs"),
1295
+ className: require_text_truncate.cn("text-text-secondary", "mt-0.5 block text-xs"),
1318
1296
  children: step.description
1319
1297
  })]
1320
1298
  })
@@ -1326,7 +1304,7 @@ function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps,
1326
1304
  type: "button",
1327
1305
  onClick: () => moveStep(index, -1),
1328
1306
  disabled: index === 0,
1329
- className: require_highlight.cn("rounded p-1 text-sm", require_highlight.OPT_TEXT_TERTIARY, "hover:bg-bg-subtle", "disabled:opacity-30", require_highlight.OPT_FOCUS_VISIBLE),
1307
+ className: require_text_truncate.cn("rounded p-1 text-sm", require_text_truncate.OPT_TEXT_TERTIARY, "hover:bg-bg-subtle", "disabled:opacity-30", require_text_truncate.OPT_FOCUS_VISIBLE),
1330
1308
  "aria-label": "Move up",
1331
1309
  children: "▲"
1332
1310
  }),
@@ -1334,14 +1312,14 @@ function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps,
1334
1312
  type: "button",
1335
1313
  onClick: () => moveStep(index, 1),
1336
1314
  disabled: index === steps.length - 1,
1337
- className: require_highlight.cn("rounded p-1 text-sm", require_highlight.OPT_TEXT_TERTIARY, "hover:bg-bg-subtle", "disabled:opacity-30", require_highlight.OPT_FOCUS_VISIBLE),
1315
+ className: require_text_truncate.cn("rounded p-1 text-sm", require_text_truncate.OPT_TEXT_TERTIARY, "hover:bg-bg-subtle", "disabled:opacity-30", require_text_truncate.OPT_FOCUS_VISIBLE),
1338
1316
  "aria-label": "Move down",
1339
1317
  children: "▼"
1340
1318
  }),
1341
1319
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1342
1320
  type: "button",
1343
1321
  onClick: () => removeStep(step.id),
1344
- className: require_highlight.cn("text-danger-fg hover:bg-danger-subtle rounded p-1 text-sm", require_highlight.OPT_FOCUS_VISIBLE),
1322
+ className: require_text_truncate.cn("text-danger-fg hover:bg-danger-subtle rounded p-1 text-sm", require_text_truncate.OPT_FOCUS_VISIBLE),
1345
1323
  "aria-label": `Remove ${step.label}`,
1346
1324
  children: "✕"
1347
1325
  })
@@ -1350,7 +1328,7 @@ function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps,
1350
1328
  ]
1351
1329
  }, step.id);
1352
1330
  }),
1353
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_highlight.Button, {
1331
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.Button, {
1354
1332
  variant: "secondary",
1355
1333
  size: "sm",
1356
1334
  onClick: addStep,
@@ -1363,55 +1341,6 @@ function StepBuilder({ steps, onChange, label, addLabel = "Add step", maxSteps,
1363
1341
  }
1364
1342
  StepBuilder.displayName = "StepBuilder";
1365
1343
  //#endregion
1366
- //#region src/lib/formatters.ts
1367
- const OPT_UI_DEFAULT_LOCALE = "ko-KR";
1368
- const KST_OFFSET_MS = 324e5;
1369
- function getKstDateParts(input) {
1370
- const date = input instanceof Date ? input : new Date(input);
1371
- if (Number.isNaN(date.getTime())) return null;
1372
- const kstDate = new Date(date.getTime() + KST_OFFSET_MS);
1373
- return {
1374
- year: kstDate.getUTCFullYear(),
1375
- month: kstDate.getUTCMonth() + 1,
1376
- day: kstDate.getUTCDate(),
1377
- hour: kstDate.getUTCHours(),
1378
- minute: kstDate.getUTCMinutes(),
1379
- second: kstDate.getUTCSeconds()
1380
- };
1381
- }
1382
- function pad2(value) {
1383
- return String(value).padStart(2, "0");
1384
- }
1385
- function meridiem(hour) {
1386
- return hour < 12 ? "오전" : "오후";
1387
- }
1388
- function hour12(hour) {
1389
- const normalized = hour % 12;
1390
- return normalized === 0 ? 12 : normalized;
1391
- }
1392
- /** Formats a date as Korean short date text in the opt-ui default timezone. */
1393
- function formatOptShortDate(input) {
1394
- const parts = getKstDateParts(input);
1395
- if (!parts) return "-";
1396
- return `${parts.month}월 ${parts.day}일`;
1397
- }
1398
- /** Formats a date as Korean clock time in the opt-ui default timezone. */
1399
- function formatOptTime(input) {
1400
- const parts = getKstDateParts(input);
1401
- if (!parts) return "-";
1402
- return `${meridiem(parts.hour)} ${pad2(hour12(parts.hour))}:${pad2(parts.minute)}`;
1403
- }
1404
- /** Formats a date as Korean date-time text in the opt-ui default timezone. */
1405
- function formatOptDateTime(input) {
1406
- const parts = getKstDateParts(input);
1407
- if (!parts) return "-";
1408
- return `${parts.year}. ${parts.month}. ${parts.day}. ${meridiem(parts.hour)} ${hour12(parts.hour)}:${pad2(parts.minute)}:${pad2(parts.second)}`;
1409
- }
1410
- /** Formats numbers without depending on the runtime default locale. */
1411
- function formatOptNumber(value) {
1412
- return new Intl.NumberFormat(OPT_UI_DEFAULT_LOCALE).format(value);
1413
- }
1414
- //#endregion
1415
1344
  //#region src/core/condition-builder.tsx
1416
1345
  const OPERATOR_LABELS = {
1417
1346
  equals: "equals",
@@ -1526,12 +1455,12 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1526
1455
  onChange(groups.filter((g) => g.id !== groupId));
1527
1456
  }, [groups, onChange]);
1528
1457
  const updateGroupLogic = (0, react.useCallback)((groupId, logic) => {
1529
- onChange(groups.map((g) => g.id === groupId ? require_highlight._objectSpread2(require_highlight._objectSpread2({}, g), {}, { logic }) : g));
1458
+ onChange(groups.map((g) => g.id === groupId ? require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, g), {}, { logic }) : g));
1530
1459
  }, [groups, onChange]);
1531
1460
  const addCondition = (0, react.useCallback)((groupId) => {
1532
1461
  onChange(groups.map((g) => {
1533
1462
  var _properties$2;
1534
- return g.id === groupId ? require_highlight._objectSpread2(require_highlight._objectSpread2({}, g), {}, { conditions: [...g.conditions, {
1463
+ return g.id === groupId ? require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, g), {}, { conditions: [...g.conditions, {
1535
1464
  id: createConditionId(),
1536
1465
  property: (_properties$2 = properties[0]) !== null && _properties$2 !== void 0 ? _properties$2 : "",
1537
1466
  operator: "equals",
@@ -1545,15 +1474,15 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1545
1474
  createConditionId
1546
1475
  ]);
1547
1476
  const removeCondition = (0, react.useCallback)((groupId, condId) => {
1548
- onChange(groups.map((g) => g.id === groupId ? require_highlight._objectSpread2(require_highlight._objectSpread2({}, g), {}, { conditions: g.conditions.filter((c) => c.id !== condId) }) : g));
1477
+ onChange(groups.map((g) => g.id === groupId ? require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, g), {}, { conditions: g.conditions.filter((c) => c.id !== condId) }) : g));
1549
1478
  }, [groups, onChange]);
1550
1479
  const updateCondition = (0, react.useCallback)((groupId, condId, updates) => {
1551
- onChange(groups.map((g) => g.id === groupId ? require_highlight._objectSpread2(require_highlight._objectSpread2({}, g), {}, { conditions: g.conditions.map((c) => c.id === condId ? require_highlight._objectSpread2(require_highlight._objectSpread2({}, c), updates) : c) }) : g));
1480
+ onChange(groups.map((g) => g.id === groupId ? require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, g), {}, { conditions: g.conditions.map((c) => c.id === condId ? require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, c), updates) : c) }) : g));
1552
1481
  }, [groups, onChange]);
1553
1482
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConditionBuilderIdScopeContext.Provider, {
1554
1483
  value: idScope,
1555
1484
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1556
- className: require_highlight.cn("flex flex-col gap-3", className),
1485
+ className: require_text_truncate.cn("flex flex-col gap-3", className),
1557
1486
  "aria-label": (_ref = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : label) !== null && _ref !== void 0 ? _ref : "Condition builder",
1558
1487
  "data-opt-id": "SXXKJ",
1559
1488
  "data-opt-slug": "condition-builder.ConditionBuilder",
@@ -1573,7 +1502,7 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1573
1502
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "bg-border-subtle h-px flex-1" })
1574
1503
  ]
1575
1504
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1576
- className: require_highlight.cn(require_highlight.OPT_SURFACE, require_highlight.OPT_BORDER, "p-3"),
1505
+ className: require_text_truncate.cn(require_text_truncate.OPT_SURFACE, require_text_truncate.OPT_BORDER, "p-3"),
1577
1506
  role: "group",
1578
1507
  "aria-label": `Condition group ${groupIndex + 1}`,
1579
1508
  children: [
@@ -1583,7 +1512,7 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1583
1512
  className: "flex items-center gap-2",
1584
1513
  children: [
1585
1514
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1586
- className: require_highlight.cn(require_highlight.OPT_TEXT_SECONDARY, "text-xs font-medium"),
1515
+ className: require_text_truncate.cn(require_text_truncate.OPT_TEXT_SECONDARY, "text-xs font-medium"),
1587
1516
  children: "Match"
1588
1517
  }),
1589
1518
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
@@ -1592,7 +1521,7 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1592
1521
  const v = e.target.value;
1593
1522
  if (v === "and" || v === "or") updateGroupLogic(group.id, v);
1594
1523
  },
1595
- className: require_highlight.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset rounded border px-2 py-0.5 text-xs font-semibold outline-none focus-visible:ring-2 focus-visible:ring-offset-1", require_highlight.OPT_TEXT_PRIMARY, require_highlight.OPT_FOCUS_VISIBLE),
1524
+ className: require_text_truncate.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset rounded border px-2 py-0.5 text-xs font-semibold outline-none focus-visible:ring-2 focus-visible:ring-offset-1", require_text_truncate.OPT_TEXT_PRIMARY, require_text_truncate.OPT_FOCUS_VISIBLE),
1596
1525
  "aria-label": "Group logic",
1597
1526
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1598
1527
  value: "and",
@@ -1603,14 +1532,14 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1603
1532
  })]
1604
1533
  }),
1605
1534
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1606
- className: require_highlight.cn(require_highlight.OPT_TEXT_SECONDARY, "text-xs"),
1535
+ className: require_text_truncate.cn(require_text_truncate.OPT_TEXT_SECONDARY, "text-xs"),
1607
1536
  children: "of the following"
1608
1537
  })
1609
1538
  ]
1610
1539
  }), groups.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1611
1540
  type: "button",
1612
1541
  onClick: () => removeGroup(group.id),
1613
- className: require_highlight.cn("text-danger-fg hover:bg-danger-subtle rounded p-1 text-xs", "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-ring-offset"),
1542
+ className: require_text_truncate.cn("text-danger-fg hover:bg-danger-subtle rounded p-1 text-xs", "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-ring-offset"),
1614
1543
  "aria-label": "Remove group",
1615
1544
  children: "✕"
1616
1545
  })]
@@ -1623,7 +1552,7 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1623
1552
  className: "flex items-center gap-2",
1624
1553
  children: [
1625
1554
  condIndex > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1626
- className: require_highlight.cn("w-8 text-center text-[10px] font-semibold uppercase", group.logic === "and" ? "text-info-fg" : "text-warning-fg"),
1555
+ className: require_text_truncate.cn("w-8 text-center text-[10px] font-semibold uppercase", group.logic === "and" ? "text-info-fg" : "text-warning-fg"),
1627
1556
  children: group.logic
1628
1557
  }),
1629
1558
  condIndex === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "w-8" }),
@@ -1636,7 +1565,7 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1636
1565
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
1637
1566
  value: cond.property,
1638
1567
  onChange: (e) => updateCondition(group.id, cond.id, { property: e.target.value }),
1639
- className: require_highlight.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset min-w-[120px] rounded border px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1", require_highlight.OPT_TEXT_PRIMARY, require_highlight.OPT_FOCUS_VISIBLE),
1568
+ className: require_text_truncate.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset min-w-[120px] rounded border px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1", require_text_truncate.OPT_TEXT_PRIMARY, require_text_truncate.OPT_FOCUS_VISIBLE),
1640
1569
  "aria-label": "Property",
1641
1570
  children: properties.map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1642
1571
  value: p,
@@ -1649,7 +1578,7 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1649
1578
  const v = e.target.value;
1650
1579
  if (isConditionOperator(v)) updateCondition(group.id, cond.id, { operator: v });
1651
1580
  },
1652
- className: require_highlight.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset min-w-[130px] rounded border px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1", require_highlight.OPT_TEXT_PRIMARY, require_highlight.OPT_FOCUS_VISIBLE),
1581
+ className: require_text_truncate.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset min-w-[130px] rounded border px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1", require_text_truncate.OPT_TEXT_PRIMARY, require_text_truncate.OPT_FOCUS_VISIBLE),
1653
1582
  "aria-label": "Operator",
1654
1583
  children: Object.entries(OPERATOR_LABELS).map(([key, lbl]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1655
1584
  value: key,
@@ -1661,14 +1590,14 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1661
1590
  value: cond.value,
1662
1591
  onChange: (e) => updateCondition(group.id, cond.id, { value: e.target.value }),
1663
1592
  placeholder: "Value",
1664
- className: require_highlight.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset min-w-[100px] flex-1 rounded border px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1", "text-text-primary", "placeholder:text-text-tertiary", "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-ring-offset"),
1593
+ className: require_text_truncate.cn("border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset min-w-[100px] flex-1 rounded border px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1", "text-text-primary", "placeholder:text-text-tertiary", "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-ring-offset"),
1665
1594
  "aria-label": "Value"
1666
1595
  })
1667
1596
  ] }),
1668
1597
  group.conditions.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1669
1598
  type: "button",
1670
1599
  onClick: () => removeCondition(group.id, cond.id),
1671
- className: require_highlight.cn("text-danger-fg hover:bg-danger-subtle rounded p-1 text-sm", "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-ring-offset"),
1600
+ className: require_text_truncate.cn("text-danger-fg hover:bg-danger-subtle rounded p-1 text-sm", "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-ring-offset"),
1672
1601
  "aria-label": "Remove condition",
1673
1602
  children: "✕"
1674
1603
  })
@@ -1681,7 +1610,7 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1681
1610
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConditionBuilder, {
1682
1611
  groups: group.children,
1683
1612
  onChange: (newChildren) => {
1684
- onChange(groups.map((g) => g.id === group.id ? require_highlight._objectSpread2(require_highlight._objectSpread2({}, g), {}, { children: newChildren }) : g));
1613
+ onChange(groups.map((g) => g.id === group.id ? require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, g), {}, { children: newChildren }) : g));
1685
1614
  },
1686
1615
  properties,
1687
1616
  addConditionLabel,
@@ -1694,12 +1623,12 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1694
1623
  }),
1695
1624
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1696
1625
  className: "mt-2 flex items-center gap-2",
1697
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_highlight.Button, {
1626
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.Button, {
1698
1627
  variant: "ghost",
1699
1628
  size: "sm",
1700
1629
  onClick: () => addCondition(group.id),
1701
1630
  children: ["+ ", addConditionLabel]
1702
- }), nested && maxDepth > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_highlight.Button, {
1631
+ }), nested && maxDepth > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.Button, {
1703
1632
  variant: "ghost",
1704
1633
  size: "sm",
1705
1634
  onClick: () => {
@@ -1716,7 +1645,7 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1716
1645
  };
1717
1646
  onChange(groups.map((g) => {
1718
1647
  var _g$children;
1719
- return g.id === group.id ? require_highlight._objectSpread2(require_highlight._objectSpread2({}, g), {}, { children: [...(_g$children = g.children) !== null && _g$children !== void 0 ? _g$children : [], nestedGroup] }) : g;
1648
+ return g.id === group.id ? require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, g), {}, { children: [...(_g$children = g.children) !== null && _g$children !== void 0 ? _g$children : [], nestedGroup] }) : g;
1720
1649
  }));
1721
1650
  },
1722
1651
  children: ["+ ", addNestedGroupLabel]
@@ -1726,15 +1655,15 @@ function ConditionBuilder({ groups, onChange, properties = DEFAULT_PROPERTIES, l
1726
1655
  })] }, group.id)),
1727
1656
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1728
1657
  className: "flex items-center gap-3",
1729
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_highlight.Button, {
1658
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.Button, {
1730
1659
  variant: "secondary",
1731
1660
  size: "sm",
1732
1661
  onClick: addGroup,
1733
1662
  className: "self-start",
1734
1663
  children: ["+ ", addGroupLabel]
1735
1664
  }), previewCount != null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1736
- className: require_highlight.cn("text-text-secondary", "text-sm"),
1737
- children: [formatOptNumber(previewCount), " matches"]
1665
+ className: require_text_truncate.cn("text-text-secondary", "text-sm"),
1666
+ children: [require_text_truncate.formatOptNumber(previewCount), " matches"]
1738
1667
  })]
1739
1668
  })
1740
1669
  ]
@@ -1748,35 +1677,35 @@ const _excluded$6 = ["className"];
1748
1677
  const _excluded2$2 = ["className"];
1749
1678
  const _excluded3$1 = ["className", "variant"];
1750
1679
  const _excluded4 = ["className"];
1751
- const DropdownMenu = require_highlight.MenuRoot;
1680
+ const DropdownMenu = require_text_truncate.MenuRoot;
1752
1681
  /** Renders the dropdown trigger component. */
1753
1682
  function DropdownTrigger(_ref) {
1754
- let { className } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$6);
1755
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.MenuTrigger, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("cursor-pointer gap-2", className) }, props), {}, {
1683
+ let { className } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$6);
1684
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.MenuTrigger, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn("cursor-pointer gap-2", className) }, props), {}, {
1756
1685
  "data-opt-id": "C4BSS",
1757
1686
  "data-opt-slug": "dropdown-menu.DropdownTrigger"
1758
1687
  }));
1759
1688
  }
1760
1689
  /** Renders the dropdown content component. */
1761
1690
  function DropdownContent(_ref2) {
1762
- let { className } = _ref2, props = require_highlight._objectWithoutProperties(_ref2, _excluded2$2);
1763
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.MenuPopover, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn(className) }, props), {}, {
1691
+ let { className } = _ref2, props = require_text_truncate._objectWithoutProperties(_ref2, _excluded2$2);
1692
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.MenuPopover, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn(className) }, props), {}, {
1764
1693
  "data-opt-id": "J6NF7",
1765
1694
  "data-opt-slug": "dropdown-menu.DropdownContent"
1766
1695
  }));
1767
1696
  }
1768
1697
  /** Renders the dropdown item component. */
1769
1698
  function DropdownItem(_ref3) {
1770
- let { className, variant = "default" } = _ref3, props = require_highlight._objectWithoutProperties(_ref3, _excluded3$1);
1771
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.MenuItem, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("cursor-pointer data-[disabled]:cursor-not-allowed", variant === "destructive" && "text-danger-fg data-[active-item]:bg-danger-subtle data-[active-item]:text-danger-fg", className) }, props), {}, {
1699
+ let { className, variant = "default" } = _ref3, props = require_text_truncate._objectWithoutProperties(_ref3, _excluded3$1);
1700
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.MenuItem, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn("cursor-pointer data-[disabled]:cursor-not-allowed", variant === "destructive" && "text-danger-fg data-[active-item]:bg-danger-subtle data-[active-item]:text-danger-fg", className) }, props), {}, {
1772
1701
  "data-opt-id": "5M6GA",
1773
1702
  "data-opt-slug": "dropdown-menu.DropdownItem"
1774
1703
  }));
1775
1704
  }
1776
1705
  /** Renders the dropdown separator component. */
1777
1706
  function DropdownSeparator(_ref4) {
1778
- let { className } = _ref4, props = require_highlight._objectWithoutProperties(_ref4, _excluded4);
1779
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.MenuSeparator, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn(className) }, props), {}, {
1707
+ let { className } = _ref4, props = require_text_truncate._objectWithoutProperties(_ref4, _excluded4);
1708
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.MenuSeparator, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn(className) }, props), {}, {
1780
1709
  "data-opt-id": "K9Y54",
1781
1710
  "data-opt-slug": "dropdown-menu.DropdownSeparator"
1782
1711
  }));
@@ -1824,7 +1753,7 @@ function RadioGroup({ children, value, defaultValue = "", onChange, disabled, si
1824
1753
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RadioGroupContext.Provider, {
1825
1754
  value: ctxValue,
1826
1755
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1827
- className: require_highlight.cn("flex flex-col gap-1.5", className),
1756
+ className: require_text_truncate.cn("flex flex-col gap-1.5", className),
1828
1757
  "data-opt-id": "2F20H",
1829
1758
  "data-opt-slug": "radio-group.RadioGroup",
1830
1759
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_reopt_ai_opt_ui_primitives.RadioGroupRoot, {
@@ -1839,14 +1768,14 @@ function RadioGroup({ children, value, defaultValue = "", onChange, disabled, si
1839
1768
  "aria-labelledby": labelId,
1840
1769
  "aria-required": required,
1841
1770
  "aria-invalid": hasError,
1842
- "aria-describedby": require_highlight.getDescribedBy(groupId, error, void 0),
1843
- className: require_highlight.cn("flex", orientation === "vertical" ? "flex-col gap-3" : "flex-row gap-6"),
1771
+ "aria-describedby": require_text_truncate.getDescribedBy(groupId, error, void 0),
1772
+ className: require_text_truncate.cn("flex", orientation === "vertical" ? "flex-col gap-3" : "flex-row gap-6"),
1844
1773
  children: [label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1845
1774
  id: labelId,
1846
1775
  className: "text-text-secondary mb-1 text-sm font-medium",
1847
- children: [label, required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.RequiredMark, {})]
1776
+ children: [label, required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.RequiredMark, {})]
1848
1777
  }), children]
1849
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.FieldMessages, {
1778
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FieldMessages, {
1850
1779
  id: groupId,
1851
1780
  error
1852
1781
  })]
@@ -1855,7 +1784,7 @@ function RadioGroup({ children, value, defaultValue = "", onChange, disabled, si
1855
1784
  }
1856
1785
  const Radio = (0, react.forwardRef)((_ref, ref) => {
1857
1786
  var _ref2;
1858
- let { label, hint, description, value, name: _name, size: sizeProp, disabled: disabledProp, className } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$5);
1787
+ let { label, hint, description, value, name: _name, size: sizeProp, disabled: disabledProp, className } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$5);
1859
1788
  const groupContext = (0, react.useContext)(RadioGroupContext);
1860
1789
  const primContext = (0, _reopt_ai_opt_ui_primitives.useRadioGroupContext)();
1861
1790
  const size = sizeProp !== null && sizeProp !== void 0 ? sizeProp : groupContext.size;
@@ -1873,10 +1802,10 @@ const Radio = (0, react.forwardRef)((_ref, ref) => {
1873
1802
  value,
1874
1803
  primContext
1875
1804
  ]);
1876
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", require_highlight._objectSpread2(require_highlight._objectSpread2({
1805
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
1877
1806
  ref,
1878
1807
  "aria-checked": isChecked,
1879
- className: require_highlight.cn("group flex items-start gap-3", disabled && "cursor-not-allowed opacity-50", !disabled && "cursor-pointer", className)
1808
+ className: require_text_truncate.cn("group flex items-start gap-3", disabled && "cursor-not-allowed opacity-50", !disabled && "cursor-pointer", className)
1880
1809
  }, props), {}, {
1881
1810
  "data-opt-id": "HY7YG",
1882
1811
  "data-opt-slug": "radio-group.Radio",
@@ -1895,15 +1824,15 @@ const Radio = (0, react.forwardRef)((_ref, ref) => {
1895
1824
  className: "sr-only"
1896
1825
  }),
1897
1826
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1898
- className: require_highlight.cn("relative mt-0.5 inline-flex shrink-0 items-center justify-center rounded-full", styles.radio, "border-border border-2", "bg-surface", "group-aria-checked:border-accent", "transition-colors", "group-has-[:focus-visible]:outline-ring outline-transparent group-has-[:focus-visible]:outline-2 group-has-[:focus-visible]:-outline-offset-1"),
1827
+ className: require_text_truncate.cn("relative mt-0.5 inline-flex shrink-0 items-center justify-center rounded-full", styles.radio, "border-border border-2", "bg-surface", "group-aria-checked:border-accent", "transition-colors", "group-has-[:focus-visible]:outline-ring outline-transparent group-has-[:focus-visible]:outline-2 group-has-[:focus-visible]:-outline-offset-1"),
1899
1828
  "aria-hidden": "true",
1900
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: require_highlight.cn(styles.dot, "bg-accent rounded-full", "scale-0 opacity-0 transition-all", "group-aria-checked:scale-100 group-aria-checked:opacity-100") })
1829
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: require_text_truncate.cn(styles.dot, "bg-accent rounded-full", "scale-0 opacity-0 transition-all", "group-aria-checked:scale-100 group-aria-checked:opacity-100") })
1901
1830
  }),
1902
1831
  (label || hintText) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1903
1832
  className: "flex flex-col",
1904
1833
  children: [label && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1905
1834
  id: labelId,
1906
- className: require_highlight.cn("text-text-primary font-medium", styles.text),
1835
+ className: require_text_truncate.cn("text-text-primary font-medium", styles.text),
1907
1836
  children: label
1908
1837
  }), hintText && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1909
1838
  id: hintId,
@@ -1925,12 +1854,12 @@ const _excluded$4 = [
1925
1854
  ];
1926
1855
  /** Renders the loading overlay component. */
1927
1856
  function LoadingOverlay(_ref) {
1928
- let { loading, children, label = "Loading…", className } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$4);
1929
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", require_highlight._objectSpread2(require_highlight._objectSpread2({
1857
+ let { loading, children, label = "Loading…", className } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$4);
1858
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
1930
1859
  "data-opt-id": "380ZR",
1931
1860
  "data-opt-slug": "loading-overlay.LoadingOverlay"
1932
1861
  }, props), {}, {
1933
- className: require_highlight.cn("relative", className),
1862
+ className: require_text_truncate.cn("relative", className),
1934
1863
  children: [children, loading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1935
1864
  className: "bg-surface/60 absolute inset-0 z-10 flex items-center justify-center rounded-lg backdrop-blur-[1px]",
1936
1865
  role: "status",
@@ -1938,7 +1867,7 @@ function LoadingOverlay(_ref) {
1938
1867
  "aria-label": label,
1939
1868
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1940
1869
  className: "flex flex-col items-center gap-2",
1941
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.Spinner, {
1870
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.Spinner, {
1942
1871
  size: "md",
1943
1872
  "aria-hidden": "true"
1944
1873
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -1974,9 +1903,9 @@ const insetClass = {
1974
1903
  };
1975
1904
  /** Renders the block layout component. */
1976
1905
  function BlockLayout(_ref) {
1977
- let { children, className, spacing = "section", inset, loading, loadingLabel } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$3);
1978
- const layoutClassName = require_highlight.cn("flex flex-col", spacingClass[spacing], inset ? insetClass[inset] : void 0, className);
1979
- if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoadingOverlay, require_highlight._objectSpread2(require_highlight._objectSpread2({
1906
+ let { children, className, spacing = "section", inset, loading, loadingLabel } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$3);
1907
+ const layoutClassName = require_text_truncate.cn("flex flex-col", spacingClass[spacing], inset ? insetClass[inset] : void 0, className);
1908
+ if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoadingOverlay, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
1980
1909
  "data-opt-id": "9D8QR",
1981
1910
  "data-opt-slug": "block-layout.BlockLayout"
1982
1911
  }, props), {}, {
@@ -1985,7 +1914,7 @@ function BlockLayout(_ref) {
1985
1914
  label: loadingLabel,
1986
1915
  children
1987
1916
  }));
1988
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_highlight._objectSpread2(require_highlight._objectSpread2({
1917
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
1989
1918
  "data-opt-id": "9D8QR",
1990
1919
  "data-opt-slug": "block-layout.BlockLayout"
1991
1920
  }, props), {}, {
@@ -2006,7 +1935,7 @@ const _excluded$2 = ["loading", "className"];
2006
1935
  */
2007
1936
  function createBlock(name, render, options) {
2008
1937
  const Component = (props) => {
2009
- const { loading, className } = props, rest = require_highlight._objectWithoutProperties(props, _excluded$2);
1938
+ const { loading, className } = props, rest = require_text_truncate._objectWithoutProperties(props, _excluded$2);
2010
1939
  const layoutCn = (options === null || options === void 0 ? void 0 : options.layoutClassName) ? `${options.layoutClassName}${className ? ` ${className}` : ""}` : className;
2011
1940
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BlockLayout, {
2012
1941
  loading,
@@ -2022,7 +1951,7 @@ function createBlock(name, render, options) {
2022
1951
  /** Renders the page header component. */
2023
1952
  function PageHeader({ title, description, actions, className }) {
2024
1953
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2025
- className: require_highlight.cn("gap-group flex flex-col items-stretch sm:flex-row sm:items-center sm:justify-between", className),
1954
+ className: require_text_truncate.cn("gap-group flex flex-col items-stretch sm:flex-row sm:items-center sm:justify-between", className),
2026
1955
  "data-opt-id": "7AK8Z",
2027
1956
  "data-opt-slug": "page-header.PageHeader",
2028
1957
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -2051,7 +1980,7 @@ const overflowMap = {
2051
1980
  /** Renders the scroll area component. */
2052
1981
  function ScrollArea({ children, className, orientation = "vertical" }) {
2053
1982
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2054
- className: require_highlight.cn(overflowMap[orientation], "scrollbar-thin scrollbar-track-transparent scrollbar-thumb-border hover:scrollbar-thumb-border-hover", className),
1983
+ className: require_text_truncate.cn(overflowMap[orientation], "scrollbar-thin scrollbar-track-transparent scrollbar-thumb-border hover:scrollbar-thumb-border-hover", className),
2055
1984
  "data-opt-id": "A9X4K",
2056
1985
  "data-opt-slug": "scroll-area.ScrollArea",
2057
1986
  children
@@ -2071,7 +2000,7 @@ const maxWidthMap = {
2071
2000
  /** Renders the container component. */
2072
2001
  function Container({ children, maxWidth = "xl", center = true, className }) {
2073
2002
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2074
- className: require_highlight.cn(maxWidthMap[maxWidth], center && "mx-auto", "px-4", className),
2003
+ className: require_text_truncate.cn(maxWidthMap[maxWidth], center && "mx-auto", "px-4", className),
2075
2004
  "data-opt-id": "H3G96",
2076
2005
  "data-opt-slug": "container.Container",
2077
2006
  children
@@ -2084,7 +2013,7 @@ Container.displayName = "Container";
2084
2013
  function Section({ children, title, description, className }) {
2085
2014
  const titleId = `${(0, react.useId)()}-title`;
2086
2015
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2087
- className: require_highlight.cn("gap-group flex flex-col", className),
2016
+ className: require_text_truncate.cn("gap-group flex flex-col", className),
2088
2017
  "aria-labelledby": title ? titleId : void 0,
2089
2018
  "data-opt-id": "M3QXW",
2090
2019
  "data-opt-slug": "section.Section",
@@ -2125,11 +2054,11 @@ function toPanelSize(size) {
2125
2054
  }
2126
2055
  /** Renders the resizable panel group component. */
2127
2056
  function ResizablePanelGroup(_ref) {
2128
- let { direction, children, className, id, autoSaveId } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded$1);
2129
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_resizable_panels.Group, require_highlight._objectSpread2(require_highlight._objectSpread2({
2057
+ let { direction, children, className, id, autoSaveId } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$1);
2058
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_resizable_panels.Group, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
2130
2059
  orientation: direction,
2131
2060
  id: id !== null && id !== void 0 ? id : autoSaveId,
2132
- className: require_highlight.cn("flex h-full w-full", className)
2061
+ className: require_text_truncate.cn("flex h-full w-full", className)
2133
2062
  }, props), {}, {
2134
2063
  "data-opt-id": "BM5RR",
2135
2064
  "data-opt-slug": "resizable.ResizablePanelGroup",
@@ -2139,13 +2068,13 @@ function ResizablePanelGroup(_ref) {
2139
2068
  ResizablePanelGroup.displayName = "ResizablePanelGroup";
2140
2069
  /** Renders the resizable panel component. */
2141
2070
  function ResizablePanel(_ref2) {
2142
- let { collapsedSize, defaultSize, minSize, maxSize, children, className } = _ref2, props = require_highlight._objectWithoutProperties(_ref2, _excluded2$1);
2143
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_resizable_panels.Panel, require_highlight._objectSpread2(require_highlight._objectSpread2({
2071
+ let { collapsedSize, defaultSize, minSize, maxSize, children, className } = _ref2, props = require_text_truncate._objectWithoutProperties(_ref2, _excluded2$1);
2072
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_resizable_panels.Panel, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
2144
2073
  collapsedSize: toPanelSize(collapsedSize),
2145
2074
  defaultSize: toPanelSize(defaultSize),
2146
2075
  minSize: toPanelSize(minSize),
2147
2076
  maxSize: toPanelSize(maxSize),
2148
- className: require_highlight.cn("overflow-auto", className)
2077
+ className: require_text_truncate.cn("overflow-auto", className)
2149
2078
  }, props), {}, {
2150
2079
  "data-opt-id": "88X4V",
2151
2080
  "data-opt-slug": "resizable.ResizablePanel",
@@ -2155,8 +2084,8 @@ function ResizablePanel(_ref2) {
2155
2084
  ResizablePanel.displayName = "ResizablePanel";
2156
2085
  /** Renders the resizable handle component. */
2157
2086
  function ResizableHandle(_ref3) {
2158
- let { className, withHandle = false } = _ref3, props = require_highlight._objectWithoutProperties(_ref3, _excluded3);
2159
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_resizable_panels.Separator, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("bg-border relative flex items-center justify-center", "after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2", "data-[resize-handle-active]:bg-accent", "[&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full", "[&[data-orientation=horizontal]]:h-full [&[data-orientation=horizontal]]:w-px", className) }, props), {}, {
2087
+ let { className, withHandle = false } = _ref3, props = require_text_truncate._objectWithoutProperties(_ref3, _excluded3);
2088
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_resizable_panels.Separator, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn("bg-border relative flex items-center justify-center", "after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2", "data-[resize-handle-active]:bg-accent", "[&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full", "[&[data-orientation=horizontal]]:h-full [&[data-orientation=horizontal]]:w-px", className) }, props), {}, {
2160
2089
  "data-opt-id": "6Z22W",
2161
2090
  "data-opt-slug": "resizable.ResizableHandle",
2162
2091
  children: withHandle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -2190,28 +2119,28 @@ function Logo({ src, icon, text, alt = "Logo", size = "md", href, onClick, class
2190
2119
  if (showImage) mark = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2191
2120
  src,
2192
2121
  alt,
2193
- className: require_highlight.cn("object-contain", markSizeStyles[size]),
2122
+ className: require_text_truncate.cn("object-contain", markSizeStyles[size]),
2194
2123
  onError: () => setImageError(true)
2195
2124
  });
2196
2125
  else if (icon) mark = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2197
- className: require_highlight.cn("flex shrink-0 items-center justify-center", markSizeStyles[size]),
2126
+ className: require_text_truncate.cn("flex shrink-0 items-center justify-center", markSizeStyles[size]),
2198
2127
  "aria-hidden": "true",
2199
2128
  children: icon
2200
2129
  });
2201
2130
  else if (fallbackLetter) mark = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2202
- className: require_highlight.cn("bg-accent text-on-accent flex shrink-0 items-center justify-center rounded-lg font-bold", markSizeStyles[size], textSizeStyles[size]),
2131
+ className: require_text_truncate.cn("bg-accent text-on-accent flex shrink-0 items-center justify-center rounded-lg font-bold", markSizeStyles[size], textSizeStyles[size]),
2203
2132
  "aria-hidden": "true",
2204
2133
  children: fallbackLetter
2205
2134
  });
2206
2135
  const content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [mark, text && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2207
- className: require_highlight.cn("text-text-primary font-semibold", textSizeStyles[size]),
2136
+ className: require_text_truncate.cn("text-text-primary font-semibold", textSizeStyles[size]),
2208
2137
  children: text
2209
2138
  })] });
2210
- const sharedClassName = require_highlight.cn("inline-flex items-center gap-element", className);
2139
+ const sharedClassName = require_text_truncate.cn("inline-flex items-center gap-element", className);
2211
2140
  if (href) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
2212
2141
  href,
2213
2142
  onClick,
2214
- className: require_highlight.cn(sharedClassName, "no-underline"),
2143
+ className: require_text_truncate.cn(sharedClassName, "no-underline"),
2215
2144
  "aria-label": text !== null && text !== void 0 ? text : alt,
2216
2145
  "data-opt-id": "R906A",
2217
2146
  "data-opt-slug": "logo.Logo",
@@ -2264,7 +2193,7 @@ const positionClass = {
2264
2193
  };
2265
2194
  /** Renders the drawer root component. */
2266
2195
  function DrawerRoot(props) {
2267
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.DialogRoot, require_highlight._objectSpread2(require_highlight._objectSpread2({ animated: true }, props), {}, {
2196
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.DialogRoot, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ animated: true }, props), {}, {
2268
2197
  "data-opt-id": "YGJ0M",
2269
2198
  "data-opt-slug": "drawer.DrawerRoot"
2270
2199
  }));
@@ -2280,7 +2209,7 @@ function dismissOffset(side, dx, dy) {
2280
2209
  }
2281
2210
  /** Renders the drawer panel component. */
2282
2211
  function DrawerPanel(_ref) {
2283
- let { className, side = "right", size = "md", swipeToDismiss = true, swipeDismissThreshold = 80, style, onPointerDown } = _ref, props = require_highlight._objectWithoutProperties(_ref, _excluded);
2212
+ let { className, side = "right", size = "md", swipeToDismiss = true, swipeDismissThreshold = 80, style, onPointerDown } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded);
2284
2213
  const isHorizontal = side === "left" || side === "right";
2285
2214
  const close = (0, _reopt_ai_opt_ui_primitives.useDialogClose)();
2286
2215
  const dragStart = (0, react.useRef)(null);
@@ -2342,9 +2271,9 @@ function DrawerPanel(_ref) {
2342
2271
  };
2343
2272
  }, [side]);
2344
2273
  const dragStyle = offset !== 0 ? { transform: `translate${axis}(${offset}px)` } : void 0;
2345
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.DialogPanel, require_highlight._objectSpread2(require_highlight._objectSpread2({
2346
- className: require_highlight.cn("border-border bg-surface z-50 m-0 flex flex-col border p-0 shadow-2xl", "data-[enter]:fade-in data-[leave]:fade-out", dragging ? "touch-none" : require_highlight.OPT_ANIMATE_DRAWER[side], positionClass[side], isHorizontal ? ["h-full w-full", sizeMap[size]] : ["w-full", heightMap[size]], className),
2347
- style: require_highlight._objectSpread2(require_highlight._objectSpread2(require_highlight._objectSpread2(require_highlight._objectSpread2({}, style), dragStyle), keyboardInset > 0 ? { marginBottom: keyboardInset } : null), dragging ? { transition: "none" } : null),
2274
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.DialogPanel, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
2275
+ className: require_text_truncate.cn("border-border bg-surface z-50 m-0 flex flex-col border p-0 shadow-2xl", "data-[enter]:fade-in data-[leave]:fade-out", dragging ? "touch-none" : require_text_truncate.OPT_ANIMATE_DRAWER[side], positionClass[side], isHorizontal ? ["h-full w-full", sizeMap[size]] : ["w-full", heightMap[size]], className),
2276
+ style: require_text_truncate._objectSpread2(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, style), dragStyle), keyboardInset > 0 ? { marginBottom: keyboardInset } : null), dragging ? { transition: "none" } : null),
2348
2277
  onPointerDown: handlePointerDown,
2349
2278
  onPointerMove: swipeToDismiss ? handlePointerMove : void 0,
2350
2279
  onPointerUp: swipeToDismiss ? endDrag : void 0,
@@ -2356,8 +2285,8 @@ function DrawerPanel(_ref) {
2356
2285
  }
2357
2286
  /** Renders the drawer close component. */
2358
2287
  function DrawerClose(_ref2) {
2359
- let { className } = _ref2, props = require_highlight._objectWithoutProperties(_ref2, _excluded2);
2360
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.DialogDismiss, require_highlight._objectSpread2(require_highlight._objectSpread2({ className: require_highlight.cn("hover:bg-bg-subtle rounded-md p-1.5 transition-colors", "cursor-pointer data-[disabled]:cursor-not-allowed", require_highlight.OPT_FOCUS, className) }, props), {}, {
2288
+ let { className } = _ref2, props = require_text_truncate._objectWithoutProperties(_ref2, _excluded2);
2289
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.DialogDismiss, require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn("hover:bg-bg-subtle rounded-md p-1.5 transition-colors", "cursor-pointer data-[disabled]:cursor-not-allowed", require_text_truncate.OPT_FOCUS, className) }, props), {}, {
2361
2290
  "data-opt-id": "M6D6D",
2362
2291
  "data-opt-slug": "drawer.DrawerClose"
2363
2292
  }));
@@ -2464,8 +2393,8 @@ function VirtualList({ items, renderItem, itemHeight, overscan = 3, className, s
2464
2393
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2465
2394
  ref: handleRef,
2466
2395
  onScroll: handleScroll,
2467
- className: require_highlight.cn("overflow-auto", className),
2468
- style: require_highlight._objectSpread2({ position: "relative" }, style),
2396
+ className: require_text_truncate.cn("overflow-auto", className),
2397
+ style: require_text_truncate._objectSpread2({ position: "relative" }, style),
2469
2398
  role: "list",
2470
2399
  "data-opt-id": "VT2NP",
2471
2400
  "data-opt-slug": "virtual-list.VirtualList",
@@ -3638,8 +3567,8 @@ const ShaderSurfaceComponent = (0, react.forwardRef)(function ShaderSurface({ pr
3638
3567
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3639
3568
  ref: containerRef,
3640
3569
  "aria-hidden": ariaHidden,
3641
- className: require_highlight.cn("relative overflow-hidden", className),
3642
- style: require_highlight._objectSpread2({ background: fallbackBackground }, style),
3570
+ className: require_text_truncate.cn("relative overflow-hidden", className),
3571
+ style: require_text_truncate._objectSpread2({ background: fallbackBackground }, style),
3643
3572
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("canvas", {
3644
3573
  ref: canvasRef,
3645
3574
  className: "absolute inset-0 block h-full w-full"
@@ -3673,7 +3602,7 @@ function formatShare(share) {
3673
3602
  */
3674
3603
  function Facet({ item, selected = false, onSelect, showShare = true, share, countFormatter = defaultCountFormat, layout = "vertical", labels, className }) {
3675
3604
  var _ref;
3676
- const text = require_highlight._objectSpread2(require_highlight._objectSpread2({}, defaultLabels$1), labels);
3605
+ const text = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$1), labels);
3677
3606
  const resolvedShare = (_ref = share !== null && share !== void 0 ? share : item.share) !== null && _ref !== void 0 ? _ref : 0;
3678
3607
  const interactive = onSelect !== void 0 && !item.disabled;
3679
3608
  const countText = item.count === void 0 ? "" : countFormatter(item.count);
@@ -3681,7 +3610,7 @@ function Facet({ item, selected = false, onSelect, showShare = true, share, coun
3681
3610
  const content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
3682
3611
  showShare && layout === "vertical" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3683
3612
  "aria-hidden": "true",
3684
- className: require_highlight.cn("absolute inset-y-0 left-0 rounded-[inherit] transition-[width] duration-300", selected ? "bg-accent/25" : "bg-accent/10"),
3613
+ className: require_text_truncate.cn("absolute inset-y-0 left-0 rounded-[inherit] transition-[width] duration-300", selected ? "bg-accent/25" : "bg-accent/10"),
3685
3614
  style: {
3686
3615
  width: `${Math.max(resolvedShare * 100, resolvedShare > 0 ? 1.5 : 0)}%`,
3687
3616
  backgroundColor: item.color ? `color-mix(in oklab, ${item.color} ${selected ? 30 : 16}%, transparent)` : void 0
@@ -3715,7 +3644,7 @@ function Facet({ item, selected = false, onSelect, showShare = true, share, coun
3715
3644
  children: shareText
3716
3645
  })
3717
3646
  ] });
3718
- const shellClass = require_highlight.cn("relative flex w-full items-center gap-element overflow-hidden rounded-md px-2 py-1.5 text-left text-sm", layout === "horizontal" && "w-auto", selected ? "text-text-primary font-medium" : "text-text-secondary", interactive && "hover:bg-accent-subtle hover:text-text-primary cursor-pointer transition-colors", item.disabled && "cursor-not-allowed opacity-50", className);
3647
+ const shellClass = require_text_truncate.cn("relative flex w-full items-center gap-element overflow-hidden rounded-md px-2 py-1.5 text-left text-sm", layout === "horizontal" && "w-auto", selected ? "text-text-primary font-medium" : "text-text-secondary", interactive && "hover:bg-accent-subtle hover:text-text-primary cursor-pointer transition-colors", item.disabled && "cursor-not-allowed opacity-50", className);
3719
3648
  if (!interactive) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3720
3649
  className: shellClass,
3721
3650
  "data-selected": selected || void 0,
@@ -3725,7 +3654,7 @@ function Facet({ item, selected = false, onSelect, showShare = true, share, coun
3725
3654
  });
3726
3655
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3727
3656
  type: "button",
3728
- className: require_highlight.cn(shellClass, require_highlight.OPT_FOCUS_VISIBLE),
3657
+ className: require_text_truncate.cn(shellClass, require_text_truncate.OPT_FOCUS_VISIBLE),
3729
3658
  "aria-pressed": selected,
3730
3659
  "aria-label": text.selectHint(typeof item.label === "string" ? item.label : item.id, countText, shareText),
3731
3660
  disabled: item.disabled,
@@ -3756,7 +3685,7 @@ function Facet({ item, selected = false, onSelect, showShare = true, share, coun
3756
3685
  * ```
3757
3686
  */
3758
3687
  function FacetGroup({ items, selected, onSelectedChange, selection = "multiple", layout = "vertical", showShare = true, countFormatter = defaultCountFormat, max, total, loading = false, emptyState, labels, className, "aria-label": ariaLabel }) {
3759
- const text = require_highlight._objectSpread2(require_highlight._objectSpread2({}, defaultLabels$1), labels);
3688
+ const text = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$1), labels);
3760
3689
  const [uncontrolled, setUncontrolled] = (0, react.useState)([]);
3761
3690
  const [expanded, setExpanded] = (0, react.useState)(false);
3762
3691
  const current = selected !== null && selected !== void 0 ? selected : uncontrolled;
@@ -3777,7 +3706,7 @@ function FacetGroup({ items, selected, onSelectedChange, selection = "multiple",
3777
3706
  onSelectedChange === null || onSelectedChange === void 0 || onSelectedChange(next);
3778
3707
  };
3779
3708
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3780
- className: require_highlight.cn("flex flex-col gap-element", className),
3709
+ className: require_text_truncate.cn("flex flex-col gap-element", className),
3781
3710
  "aria-busy": "true",
3782
3711
  "aria-label": ariaLabel,
3783
3712
  "data-opt-id": "G1RNN",
@@ -3791,14 +3720,14 @@ function FacetGroup({ items, selected, onSelectedChange, selection = "multiple",
3791
3720
  }, index))]
3792
3721
  });
3793
3722
  if (items.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3794
- className: require_highlight.cn("text-text-tertiary px-2 py-1.5 text-sm", className),
3723
+ className: require_text_truncate.cn("text-text-tertiary px-2 py-1.5 text-sm", className),
3795
3724
  "aria-label": ariaLabel,
3796
3725
  "data-opt-id": "G1RNN",
3797
3726
  "data-opt-slug": "facet.FacetGroup",
3798
3727
  children: emptyState !== null && emptyState !== void 0 ? emptyState : text.empty
3799
3728
  });
3800
3729
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3801
- className: require_highlight.cn(layout === "vertical" ? "flex flex-col gap-0.5" : "flex flex-wrap items-center gap-element", className),
3730
+ className: require_text_truncate.cn(layout === "vertical" ? "flex flex-col gap-0.5" : "flex flex-wrap items-center gap-element", className),
3802
3731
  role: selection === "none" ? "list" : "group",
3803
3732
  "aria-label": ariaLabel,
3804
3733
  "data-opt-id": "G1RNN",
@@ -3817,7 +3746,7 @@ function FacetGroup({ items, selected, onSelectedChange, selection = "multiple",
3817
3746
  }, item.id);
3818
3747
  }), (remaining > 0 || expanded) && max !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3819
3748
  type: "button",
3820
- className: require_highlight.cn("text-text-tertiary hover:text-text-primary rounded-md px-2 py-1 text-left text-xs", "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-ring-offset"),
3749
+ className: require_text_truncate.cn("text-text-tertiary hover:text-text-primary rounded-md px-2 py-1 text-left text-xs", "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-ring-offset"),
3821
3750
  onClick: () => setExpanded((value) => !value),
3822
3751
  children: expanded ? text.showLess : text.showMore(remaining)
3823
3752
  })]
@@ -3873,13 +3802,13 @@ function Expression({ description, value, tone = "accent", active = false, inval
3873
3802
  const palette = invalid ? toneStyles.danger : toneStyles[tone];
3874
3803
  const interactive = onClick !== void 0 && !disabled;
3875
3804
  const body = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3876
- className: require_highlight.cn("text-text-secondary text-xs font-semibold tracking-wide uppercase", disabled && "opacity-60"),
3805
+ className: require_text_truncate.cn("text-text-secondary text-xs font-semibold tracking-wide uppercase", disabled && "opacity-60"),
3877
3806
  children: description
3878
3807
  }), value !== void 0 && value !== null && value !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3879
- className: require_highlight.cn("text-sm font-semibold", palette.text, interactive && require_highlight.cn("underline decoration-2 underline-offset-4", palette.rule, active ? "decoration-solid" : "decoration-dotted"), disabled && "opacity-60"),
3808
+ className: require_text_truncate.cn("text-sm font-semibold", palette.text, interactive && require_text_truncate.cn("underline decoration-2 underline-offset-4", palette.rule, active ? "decoration-solid" : "decoration-dotted"), disabled && "opacity-60"),
3880
3809
  children: value
3881
3810
  })] });
3882
- const shell = require_highlight.cn(display === "stacked" ? "flex flex-col items-start gap-0.5" : "inline-flex items-baseline gap-1.5", "rounded-md px-1.5 py-1 text-left", interactive && "hover:bg-accent-subtle cursor-pointer transition-colors", active && "bg-accent-subtle", disabled && "cursor-not-allowed", className);
3811
+ const shell = require_text_truncate.cn(display === "stacked" ? "flex flex-col items-start gap-0.5" : "inline-flex items-baseline gap-1.5", "rounded-md px-1.5 py-1 text-left", interactive && "hover:bg-accent-subtle cursor-pointer transition-colors", active && "bg-accent-subtle", disabled && "cursor-not-allowed", className);
3883
3812
  if (!interactive) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3884
3813
  className: shell,
3885
3814
  "data-invalid": invalid || void 0,
@@ -3889,7 +3818,7 @@ function Expression({ description, value, tone = "accent", active = false, inval
3889
3818
  });
3890
3819
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3891
3820
  type: "button",
3892
- className: require_highlight.cn(shell, require_highlight.OPT_FOCUS_VISIBLE),
3821
+ className: require_text_truncate.cn(shell, require_text_truncate.OPT_FOCUS_VISIBLE),
3893
3822
  onClick,
3894
3823
  disabled,
3895
3824
  "aria-expanded": active,
@@ -3906,7 +3835,7 @@ function Expression({ description, value, tone = "accent", active = false, inval
3906
3835
  */
3907
3836
  function ExpressionGroup({ children, display = "sentence", className, "aria-label": ariaLabel }) {
3908
3837
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3909
- className: require_highlight.cn(display === "sentence" ? "flex flex-wrap items-baseline gap-x-1 gap-y-1" : "grid grid-flow-col auto-cols-fr items-start gap-group", className),
3838
+ className: require_text_truncate.cn(display === "sentence" ? "flex flex-wrap items-baseline gap-x-1 gap-y-1" : "grid grid-flow-col auto-cols-fr items-start gap-group", className),
3910
3839
  role: "group",
3911
3840
  "aria-label": ariaLabel,
3912
3841
  "data-opt-id": "F78CE",
@@ -3915,134 +3844,6 @@ function ExpressionGroup({ children, display = "sentence", className, "aria-labe
3915
3844
  });
3916
3845
  }
3917
3846
  //#endregion
3918
- //#region src/core/text-truncate.tsx
3919
- const useIsomorphicLayoutEffect = typeof window === "undefined" ? react.useEffect : react.useLayoutEffect;
3920
- /** Measures text in the element's own resolved font, not an assumed one. */
3921
- function createMeasurer(element) {
3922
- const context = document.createElement("canvas").getContext("2d");
3923
- if (!context) return null;
3924
- const computed = window.getComputedStyle(element);
3925
- context.font = [
3926
- computed.fontStyle,
3927
- computed.fontVariant,
3928
- computed.fontWeight,
3929
- `${computed.fontSize}/${computed.lineHeight}`,
3930
- computed.fontFamily
3931
- ].join(" ");
3932
- const spacing = Number.parseFloat(computed.letterSpacing) || 0;
3933
- return (value) => context.measureText(value).width + spacing * value.length;
3934
- }
3935
- /** Largest `n` in `[0, max]` for which `fits(n)` holds. */
3936
- function largestFitting(max, fits) {
3937
- let low = 0;
3938
- let high = max;
3939
- while (low < high) {
3940
- const mid = Math.ceil((low + high) / 2);
3941
- if (fits(mid)) low = mid;
3942
- else high = mid - 1;
3943
- }
3944
- return low;
3945
- }
3946
- function truncateToWidth(text, side, ellipsis, available, measure) {
3947
- if (measure(text) <= available) return text;
3948
- const chars = Array.from(text);
3949
- if (side === "end") {
3950
- const keep = largestFitting(chars.length, (n) => measure(chars.slice(0, n).join("") + ellipsis) <= available);
3951
- return chars.slice(0, keep).join("") + ellipsis;
3952
- }
3953
- if (side === "start") {
3954
- const keep = largestFitting(chars.length, (n) => measure(ellipsis + chars.slice(chars.length - n).join("")) <= available);
3955
- return ellipsis + chars.slice(chars.length - keep).join("");
3956
- }
3957
- if (side === "startEnd") {
3958
- const keep = largestFitting(Math.floor(chars.length / 2), (n) => {
3959
- const head = chars.slice(0, n).join("");
3960
- const tail = chars.slice(chars.length - n).join("");
3961
- return measure(head + ellipsis + tail) <= available;
3962
- });
3963
- if (keep === 0) return ellipsis;
3964
- return chars.slice(0, keep).join("") + ellipsis + chars.slice(chars.length - keep).join("");
3965
- }
3966
- const span = largestFitting(chars.length, (n) => {
3967
- const start = Math.floor((chars.length - n) / 2);
3968
- return measure(ellipsis + chars.slice(start, start + n).join("") + ellipsis) <= available;
3969
- });
3970
- if (span === 0) return ellipsis;
3971
- const start = Math.floor((chars.length - span) / 2);
3972
- return ellipsis + chars.slice(start, start + span).join("") + ellipsis;
3973
- }
3974
- /**
3975
- * TextTruncate — drops characters from the part of a string that identifies it
3976
- * least.
3977
- *
3978
- * CSS can only cut the end. That is the wrong end for the strings analytics
3979
- * shows most: two URLs that differ in their query string, two ids that share a
3980
- * prefix, a stack frame whose filename is at the tail. This measures the real
3981
- * text in the real font against the real available width and cuts where the
3982
- * caller says.
3983
- *
3984
- * The full string stays in the accessibility tree and in `title`, so
3985
- * truncation never costs the reader information — only space.
3986
- *
3987
- * @example
3988
- * ```tsx
3989
- * <TextTruncate text={event.url} truncation="startEnd" />
3990
- * ```
3991
- */
3992
- function TextTruncate({ text, truncation = "startEnd", ellipsis = "…", width, children, className }) {
3993
- const ref = (0, react.useRef)(null);
3994
- const [available, setAvailable] = (0, react.useState)(width !== null && width !== void 0 ? width : null);
3995
- useIsomorphicLayoutEffect(() => {
3996
- if (width !== void 0) {
3997
- setAvailable(width);
3998
- return;
3999
- }
4000
- const element = ref.current;
4001
- if (!element || typeof ResizeObserver === "undefined") return;
4002
- const observer = new ResizeObserver((entries) => {
4003
- const entry = entries[0];
4004
- if (entry) setAvailable(entry.contentRect.width);
4005
- });
4006
- observer.observe(element);
4007
- setAvailable(element.getBoundingClientRect().width);
4008
- return () => observer.disconnect();
4009
- }, [width]);
4010
- const [rendered, setRendered] = (0, react.useState)(text);
4011
- useIsomorphicLayoutEffect(() => {
4012
- const element = ref.current;
4013
- if (!element || available === null || available <= 0) {
4014
- setRendered(text);
4015
- return;
4016
- }
4017
- const measure = createMeasurer(element);
4018
- if (!measure) {
4019
- setRendered(text);
4020
- return;
4021
- }
4022
- setRendered(truncateToWidth(text, truncation, ellipsis, available, measure));
4023
- }, [
4024
- text,
4025
- truncation,
4026
- ellipsis,
4027
- available
4028
- ]);
4029
- const truncated = rendered !== text;
4030
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4031
- ref,
4032
- className: require_highlight.cn("block w-full overflow-hidden whitespace-nowrap", className),
4033
- title: truncated ? text : void 0,
4034
- "data-opt-id": "Y6BGX",
4035
- "data-opt-slug": "text-truncate.TextTruncate",
4036
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4037
- "aria-hidden": truncated ? "true" : void 0,
4038
- children: children ? children(rendered) : rendered
4039
- }), truncated && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4040
- className: "sr-only",
4041
- children: text
4042
- })]
4043
- });
4044
- }
4045
- //#endregion
4046
3847
  //#region src/core/live-region.tsx
4047
3848
  /**
4048
3849
  * LiveRegion — says out loud what a live view changed.
@@ -4167,7 +3968,7 @@ function ColorPaletteDisplay({ palette, render, size = "sm", "aria-label": ariaL
4167
3968
  const mode = render !== null && render !== void 0 ? render : palette.kind === "categorical" ? "stops" : "gradient";
4168
3969
  const colors = palette.colors.length > 0 ? palette.colors : ["transparent"];
4169
3970
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4170
- className: require_highlight.cn("flex w-full overflow-hidden rounded-sm", sizeStyles$2[size], className),
3971
+ className: require_text_truncate.cn("flex w-full overflow-hidden rounded-sm", sizeStyles$2[size], className),
4171
3972
  role: "img",
4172
3973
  "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : palette.label,
4173
3974
  style: mode === "gradient" ? { backgroundImage: `linear-gradient(to right, ${colors.join(", ")})` } : void 0,
@@ -4200,22 +4001,22 @@ function ColorPalettePicker({ palettes, value, onValueChange, label = "Colour pa
4200
4001
  const labelId = (0, react.useId)();
4201
4002
  const selected = (_palettes$find = palettes.find((palette) => palette.id === value)) !== null && _palettes$find !== void 0 ? _palettes$find : palettes[0];
4202
4003
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4203
- className: require_highlight.cn("flex flex-col gap-element", className),
4004
+ className: require_text_truncate.cn("flex flex-col gap-element", className),
4204
4005
  "data-opt-id": "5R0PG",
4205
4006
  "data-opt-slug": "color-palette.ColorPalettePicker",
4206
4007
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4207
4008
  id: labelId,
4208
- className: require_highlight.cn("text-text-primary text-sm font-medium", hideLabel && "sr-only"),
4009
+ className: require_text_truncate.cn("text-text-primary text-sm font-medium", hideLabel && "sr-only"),
4209
4010
  children: label
4210
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_highlight.SelectRoot, {
4011
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.SelectRoot, {
4211
4012
  value: (_ref = value !== null && value !== void 0 ? value : selected === null || selected === void 0 ? void 0 : selected.id) !== null && _ref !== void 0 ? _ref : "",
4212
4013
  setValue: (next) => {
4213
4014
  if (typeof next === "string") onValueChange === null || onValueChange === void 0 || onValueChange(next);
4214
4015
  },
4215
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.SelectTrigger, {
4016
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.SelectTrigger, {
4216
4017
  "aria-labelledby": labelId,
4217
4018
  disabled,
4218
- className: require_highlight.cn("gap-group", require_highlight.OPT_FOCUS_VISIBLE),
4019
+ className: require_text_truncate.cn("gap-group", require_text_truncate.OPT_FOCUS_VISIBLE),
4219
4020
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4220
4021
  className: "gap-group flex min-w-0 flex-1 items-center",
4221
4022
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -4224,11 +4025,11 @@ function ColorPalettePicker({ palettes, value, onValueChange, label = "Colour pa
4224
4025
  }), selected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ColorPaletteDisplay, {
4225
4026
  palette: selected,
4226
4027
  size,
4227
- className: require_highlight.cn("min-w-16 flex-1", "border border-border"),
4028
+ className: require_text_truncate.cn("min-w-16 flex-1", "border border-border"),
4228
4029
  "aria-label": ""
4229
4030
  })]
4230
4031
  })
4231
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.SelectPopover, { children: palettes.map((palette) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_highlight.SelectItem, {
4032
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.SelectPopover, { children: palettes.map((palette) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.SelectItem, {
4232
4033
  value: palette.id,
4233
4034
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4234
4035
  className: "gap-group flex w-full min-w-40 items-center",
@@ -4278,7 +4079,7 @@ const sizeStyles$1 = {
4278
4079
  * ```
4279
4080
  */
4280
4081
  function InlineEdit({ value, onSave, as: Tag = "span", size = "md", placeholder, emptyText = "Untitled", disabled = false, maxLength, suffix, labels, className }) {
4281
- const text = require_highlight._objectSpread2(require_highlight._objectSpread2({}, defaultLabels), labels);
4082
+ const text = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels), labels);
4282
4083
  const [editing, setEditing] = (0, react.useState)(false);
4283
4084
  const [draft, setDraft] = (0, react.useState)(value);
4284
4085
  const [rejected, setRejected] = (0, react.useState)(false);
@@ -4329,7 +4130,7 @@ function InlineEdit({ value, onSave, as: Tag = "span", size = "md", placeholder,
4329
4130
  }
4330
4131
  };
4331
4132
  if (editing) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4332
- className: require_highlight.cn("inline-flex items-center gap-element", className),
4133
+ className: require_text_truncate.cn("inline-flex min-w-0 items-center gap-element", className),
4333
4134
  "data-opt-id": "RQ0H2",
4334
4135
  "data-opt-slug": "inline-edit.InlineEdit",
4335
4136
  children: [
@@ -4347,7 +4148,7 @@ function InlineEdit({ value, onSave, as: Tag = "span", size = "md", placeholder,
4347
4148
  disabled: saving,
4348
4149
  "aria-invalid": rejected || void 0,
4349
4150
  "aria-errormessage": rejected ? "inline-edit-error" : void 0,
4350
- className: require_highlight.cn(require_highlight.OPT_INPUT, sizeStyles$1[size], "min-w-0 flex-1")
4151
+ className: require_text_truncate.cn(require_text_truncate.OPT_INPUT, sizeStyles$1[size], "min-w-0 flex-1")
4351
4152
  }),
4352
4153
  rejected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4353
4154
  id: "inline-edit-error",
@@ -4361,7 +4162,7 @@ function InlineEdit({ value, onSave, as: Tag = "span", size = "md", placeholder,
4361
4162
  disabled: saving,
4362
4163
  onMouseDown: (event) => event.preventDefault(),
4363
4164
  onClick: () => void commit(),
4364
- className: require_highlight.cn("text-success hover:bg-success-subtle rounded-md p-1", require_highlight.OPT_FOCUS_VISIBLE),
4165
+ className: require_text_truncate.cn("text-success hover:bg-success-subtle rounded-md p-1", require_text_truncate.OPT_FOCUS_VISIBLE),
4365
4166
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, {
4366
4167
  className: "size-4",
4367
4168
  "aria-hidden": "true"
@@ -4372,7 +4173,7 @@ function InlineEdit({ value, onSave, as: Tag = "span", size = "md", placeholder,
4372
4173
  "aria-label": text.cancel,
4373
4174
  onMouseDown: (event) => event.preventDefault(),
4374
4175
  onClick: cancel,
4375
- className: require_highlight.cn("text-text-tertiary hover:bg-bg-subtle rounded-md p-1", require_highlight.OPT_FOCUS_VISIBLE),
4176
+ className: require_text_truncate.cn("text-text-tertiary hover:bg-bg-subtle rounded-md p-1", require_text_truncate.OPT_FOCUS_VISIBLE),
4376
4177
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, {
4377
4178
  className: "size-4",
4378
4179
  "aria-hidden": "true"
@@ -4381,7 +4182,7 @@ function InlineEdit({ value, onSave, as: Tag = "span", size = "md", placeholder,
4381
4182
  ]
4382
4183
  });
4383
4184
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4384
- className: require_highlight.cn("inline-flex items-center gap-element", className),
4185
+ className: require_text_truncate.cn("inline-flex min-w-0 items-center gap-element", className),
4385
4186
  "data-opt-id": "RQ0H2",
4386
4187
  "data-opt-slug": "inline-edit.InlineEdit",
4387
4188
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
@@ -4389,13 +4190,13 @@ function InlineEdit({ value, onSave, as: Tag = "span", size = "md", placeholder,
4389
4190
  disabled,
4390
4191
  onClick: () => setEditing(true),
4391
4192
  "aria-label": text.edit(value || emptyText),
4392
- className: require_highlight.cn("group -mx-1.5 -my-0.5 inline-flex max-w-full items-center gap-element rounded-md px-1.5 py-0.5 text-left", !disabled && "hover:bg-bg-subtle cursor-pointer", disabled && "cursor-default", require_highlight.OPT_FOCUS_VISIBLE),
4193
+ className: require_text_truncate.cn("group -mx-1.5 -my-0.5 inline-flex min-w-0 items-center gap-element rounded-md px-1.5 py-0.5 text-left", !disabled && "hover:bg-bg-subtle cursor-pointer", disabled && "cursor-default", require_text_truncate.OPT_FOCUS_VISIBLE),
4393
4194
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tag, {
4394
- className: require_highlight.cn("truncate", sizeStyles$1[size], value ? "text-text-primary" : "text-text-tertiary italic"),
4195
+ className: require_text_truncate.cn("truncate", sizeStyles$1[size], value ? "text-text-primary" : "text-text-tertiary italic"),
4395
4196
  children: value || emptyText
4396
4197
  }), !disabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, {
4397
4198
  "aria-hidden": "true",
4398
- className: require_highlight.cn("text-text-tertiary size-3.5 shrink-0 opacity-0 transition-opacity", "group-hover:opacity-100 group-focus-visible:opacity-100")
4199
+ className: require_text_truncate.cn("text-text-tertiary size-3.5 shrink-0 opacity-0 transition-opacity", "group-hover:opacity-100 group-focus-visible:opacity-100")
4399
4200
  })]
4400
4201
  }), suffix]
4401
4202
  });
@@ -4437,11 +4238,11 @@ function KeyPadMenu({ items, label, selection = "single", value, onValueChange,
4437
4238
  onValueChange === null || onValueChange === void 0 || onValueChange(id);
4438
4239
  };
4439
4240
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
4440
- className: require_highlight.cn("min-w-0", className),
4241
+ className: require_text_truncate.cn("min-w-0", className),
4441
4242
  "data-opt-id": "ZZG2R",
4442
4243
  "data-opt-slug": "key-pad-menu.KeyPadMenu",
4443
4244
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
4444
- className: require_highlight.cn("text-text-primary mb-element text-sm font-medium", hideLabel && "sr-only"),
4245
+ className: require_text_truncate.cn("text-text-primary mb-element text-sm font-medium", hideLabel && "sr-only"),
4445
4246
  children: label
4446
4247
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4447
4248
  className: "gap-element grid",
@@ -4449,7 +4250,7 @@ function KeyPadMenu({ items, label, selection = "single", value, onValueChange,
4449
4250
  children: items.map((item) => {
4450
4251
  const isSelected = selected.has(item.id);
4451
4252
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
4452
- className: require_highlight.cn("relative flex cursor-pointer flex-col items-center justify-center gap-1.5 rounded-lg text-center transition-colors", require_highlight.OPT_BORDER, sizeStyles[size], isSelected ? "border-accent bg-accent-subtle text-text-primary" : "text-text-secondary hover:border-border-hover hover:bg-bg-subtle", item.disabled && "cursor-not-allowed opacity-50", "has-[:focus-visible]:outline-ring has-[:focus-visible]:outline-2"),
4253
+ className: require_text_truncate.cn("relative flex cursor-pointer flex-col items-center justify-center gap-1.5 rounded-lg text-center transition-colors", require_text_truncate.OPT_BORDER, sizeStyles[size], isSelected ? "border-accent bg-accent-subtle text-text-primary" : "text-text-secondary hover:border-border-hover hover:bg-bg-subtle", item.disabled && "cursor-not-allowed opacity-50", "has-[:focus-visible]:outline-ring has-[:focus-visible]:outline-2"),
4453
4254
  children: [
4454
4255
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4455
4256
  type: selection === "single" ? "radio" : "checkbox",
@@ -4458,12 +4259,12 @@ function KeyPadMenu({ items, label, selection = "single", value, onValueChange,
4458
4259
  checked: isSelected,
4459
4260
  disabled: item.disabled,
4460
4261
  onChange: () => handleChange(item.id),
4461
- className: require_highlight.cn("sr-only", require_highlight.OPT_FOCUS_VISIBLE)
4262
+ className: require_text_truncate.cn("sr-only", require_text_truncate.OPT_FOCUS_VISIBLE)
4462
4263
  }),
4463
4264
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4464
4265
  "data-keypad-icon": "",
4465
4266
  "aria-hidden": "true",
4466
- className: require_highlight.cn("flex items-center justify-center", isSelected ? "text-accent" : "text-text-tertiary"),
4267
+ className: require_text_truncate.cn("flex items-center justify-center", isSelected ? "text-accent" : "text-text-tertiary"),
4467
4268
  children: item.icon
4468
4269
  }),
4469
4270
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -4599,6 +4400,12 @@ Object.defineProperty(exports, "Container", {
4599
4400
  return Container;
4600
4401
  }
4601
4402
  });
4403
+ Object.defineProperty(exports, "DescriptionList", {
4404
+ enumerable: true,
4405
+ get: function() {
4406
+ return DescriptionList;
4407
+ }
4408
+ });
4602
4409
  Object.defineProperty(exports, "DrawerClose", {
4603
4410
  enumerable: true,
4604
4411
  get: function() {
@@ -4677,6 +4484,12 @@ Object.defineProperty(exports, "Heading", {
4677
4484
  return Heading;
4678
4485
  }
4679
4486
  });
4487
+ Object.defineProperty(exports, "Identity", {
4488
+ enumerable: true,
4489
+ get: function() {
4490
+ return Identity;
4491
+ }
4492
+ });
4680
4493
  Object.defineProperty(exports, "InlineEdit", {
4681
4494
  enumerable: true,
4682
4495
  get: function() {
@@ -4707,12 +4520,6 @@ Object.defineProperty(exports, "Logo", {
4707
4520
  return Logo;
4708
4521
  }
4709
4522
  });
4710
- Object.defineProperty(exports, "Meter", {
4711
- enumerable: true,
4712
- get: function() {
4713
- return Meter;
4714
- }
4715
- });
4716
4523
  Object.defineProperty(exports, "OtpField", {
4717
4524
  enumerable: true,
4718
4525
  get: function() {
@@ -4815,36 +4622,6 @@ Object.defineProperty(exports, "ShaderSurface", {
4815
4622
  return ShaderSurface;
4816
4623
  }
4817
4624
  });
4818
- Object.defineProperty(exports, "Skeleton", {
4819
- enumerable: true,
4820
- get: function() {
4821
- return Skeleton;
4822
- }
4823
- });
4824
- Object.defineProperty(exports, "SkeletonAvatar", {
4825
- enumerable: true,
4826
- get: function() {
4827
- return SkeletonAvatar;
4828
- }
4829
- });
4830
- Object.defineProperty(exports, "SkeletonCard", {
4831
- enumerable: true,
4832
- get: function() {
4833
- return SkeletonCard;
4834
- }
4835
- });
4836
- Object.defineProperty(exports, "SkeletonTable", {
4837
- enumerable: true,
4838
- get: function() {
4839
- return SkeletonTable;
4840
- }
4841
- });
4842
- Object.defineProperty(exports, "SkeletonText", {
4843
- enumerable: true,
4844
- get: function() {
4845
- return SkeletonText;
4846
- }
4847
- });
4848
4625
  Object.defineProperty(exports, "StepBuilder", {
4849
4626
  enumerable: true,
4850
4627
  get: function() {
@@ -4869,12 +4646,6 @@ Object.defineProperty(exports, "Text", {
4869
4646
  return Text;
4870
4647
  }
4871
4648
  });
4872
- Object.defineProperty(exports, "TextTruncate", {
4873
- enumerable: true,
4874
- get: function() {
4875
- return TextTruncate;
4876
- }
4877
- });
4878
4649
  Object.defineProperty(exports, "Textarea", {
4879
4650
  enumerable: true,
4880
4651
  get: function() {
@@ -4905,30 +4676,6 @@ Object.defineProperty(exports, "createBlock", {
4905
4676
  return createBlock;
4906
4677
  }
4907
4678
  });
4908
- Object.defineProperty(exports, "formatOptDateTime", {
4909
- enumerable: true,
4910
- get: function() {
4911
- return formatOptDateTime;
4912
- }
4913
- });
4914
- Object.defineProperty(exports, "formatOptNumber", {
4915
- enumerable: true,
4916
- get: function() {
4917
- return formatOptNumber;
4918
- }
4919
- });
4920
- Object.defineProperty(exports, "formatOptShortDate", {
4921
- enumerable: true,
4922
- get: function() {
4923
- return formatOptShortDate;
4924
- }
4925
- });
4926
- Object.defineProperty(exports, "formatOptTime", {
4927
- enumerable: true,
4928
- get: function() {
4929
- return formatOptTime;
4930
- }
4931
- });
4932
4679
  Object.defineProperty(exports, "getShaderFragment", {
4933
4680
  enumerable: true,
4934
4681
  get: function() {