react-os-shell 4.31.0 → 4.41.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 (27) hide show
  1. package/dist/{Browser-63NYU74S.js → Browser-TKBH4DZ3.js} +4 -4
  2. package/dist/{Browser-63NYU74S.js.map → Browser-TKBH4DZ3.js.map} +1 -1
  3. package/dist/{Documents-YP4GBBRF.js → Documents-YRTLDTLX.js} +4 -4
  4. package/dist/{Documents-YP4GBBRF.js.map → Documents-YRTLDTLX.js.map} +1 -1
  5. package/dist/{Files-6JWIE3VH.js → Files-WHYCDRYU.js} +4 -4
  6. package/dist/{Files-6JWIE3VH.js.map → Files-WHYCDRYU.js.map} +1 -1
  7. package/dist/{Notepad-EHO56UNK.js → Notepad-6UAWRNZH.js} +4 -4
  8. package/dist/{Notepad-EHO56UNK.js.map → Notepad-6UAWRNZH.js.map} +1 -1
  9. package/dist/{Preview-67IPCMSN.js → Preview-VBIWWJLK.js} +4 -4
  10. package/dist/{Preview-67IPCMSN.js.map → Preview-VBIWWJLK.js.map} +1 -1
  11. package/dist/{Spreadsheet-HVXBAFR7.js → Spreadsheet-GRD4P3OI.js} +4 -4
  12. package/dist/{Spreadsheet-HVXBAFR7.js.map → Spreadsheet-GRD4P3OI.js.map} +1 -1
  13. package/dist/apps/index.js +8 -8
  14. package/dist/{chunk-BT3EQNH3.js → chunk-COTCIYLS.js} +3 -3
  15. package/dist/{chunk-BT3EQNH3.js.map → chunk-COTCIYLS.js.map} +1 -1
  16. package/dist/{chunk-7NIFBQUX.js → chunk-D4WFGAUW.js} +217 -61
  17. package/dist/chunk-D4WFGAUW.js.map +1 -0
  18. package/dist/chunk-TQFUNASX.js +7 -0
  19. package/dist/{chunk-SGS3IQEL.js.map → chunk-TQFUNASX.js.map} +1 -1
  20. package/dist/{index-CdxMm6Dk.d.ts → index-B4RRJ5bp.d.ts} +127 -31
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +4 -4
  23. package/dist/ui/index.d.ts +1 -1
  24. package/dist/ui/index.js +2 -2
  25. package/package.json +1 -1
  26. package/dist/chunk-7NIFBQUX.js.map +0 -1
  27. package/dist/chunk-SGS3IQEL.js +0 -7
@@ -13,11 +13,27 @@ var BUTTON_VARIANTS = {
13
13
  secondary: "border border-gray-300 bg-white text-gray-700 shadow-sm hover:bg-gray-50 focus:ring-blue-400/30",
14
14
  ghost: "text-gray-700 hover:bg-gray-100 focus:ring-blue-400/30",
15
15
  "ghost-danger": "text-red-600 hover:bg-red-50 focus:ring-red-400/30",
16
- danger: "bg-red-600 text-white shadow-sm hover:bg-red-700 focus:ring-red-400/40"
16
+ danger: "bg-red-600 text-white shadow-sm hover:bg-red-700 focus:ring-red-400/40",
17
+ /**
18
+ * A button that reads as a link: no box, no padding, underlined on hover.
19
+ * For an action that belongs in running text or beside a field — "Forgot
20
+ * your password?", "Use a different address" — where a boxed button would
21
+ * claim more of the page than the action deserves.
22
+ *
23
+ * It is still a <button>. Anything that NAVIGATES should be an anchor, so it
24
+ * can be middle-clicked and read off the status bar; this is for actions
25
+ * that merely look quiet.
26
+ */
27
+ link: "text-blue-600 underline-offset-4 hover:underline focus:ring-blue-400/30"
17
28
  };
18
29
  var SIZES = {
19
30
  sm: "gap-1 px-2.5 py-1 text-xs",
20
31
  md: "gap-1.5 px-3 py-1.5 text-sm",
32
+ // `py-2.5`, not `py-2`: this rung has to come out 40px to match IconButton's
33
+ // `h-10`, which is the promise IconButton's docblock makes for every rung.
34
+ // `py-2` gives 36px (20px line box + 8px twice) and puts a 4px step between a
35
+ // Button and an IconButton sitting in the same row.
36
+ lg: "gap-2 px-4 py-2.5 text-sm",
21
37
  // 44px is the WCAG 2.5.5 floor, and a floor is not a comfortable size. Use it
22
38
  // ONLY for chrome that sits outside the task — switching screens, ending a
23
39
  // shift — and never on the path someone is actually working through. It
@@ -31,6 +47,16 @@ var SIZES = {
31
47
  "touch-xl": "gap-3 h-20 px-8 text-2xl"
32
48
  // 80px — keypad keys, tender
33
49
  };
50
+ var LINK_BASE = "inline-flex items-center font-medium transition-colors focus:outline-none focus:ring-2 disabled:cursor-not-allowed disabled:opacity-60";
51
+ var LINK_SIZES = {
52
+ sm: "gap-1 text-xs",
53
+ md: "gap-1.5 text-sm",
54
+ lg: "gap-2 text-sm",
55
+ "touch-sm": "gap-1.5 text-base",
56
+ "touch": "gap-2 text-base",
57
+ "touch-lg": "gap-2 text-lg",
58
+ "touch-xl": "gap-3 text-2xl"
59
+ };
34
60
  function Spinner() {
35
61
  return /* @__PURE__ */ jsxs("svg", { className: "h-3.5 w-3.5 animate-spin", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
36
62
  /* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
@@ -63,7 +89,18 @@ var Button = forwardRef(function Button2({
63
89
  disabled: isDisabled,
64
90
  "aria-busy": loading || void 0,
65
91
  "aria-describedby": reasonId,
66
- className: [BUTTON_BASE, BUTTON_VARIANTS[variant], SIZES[size], block ? "w-full" : "", className].filter(Boolean).join(" "),
92
+ className: [
93
+ // `link` takes the base WITHOUT the box: no rounding, no padding from
94
+ // the size table. It cannot cancel those by overriding — two padding
95
+ // utilities in one class attribute resolve by compiled-stylesheet
96
+ // order, not by the order they were written — so it never receives
97
+ // them, and keeps only the size's gap and text size.
98
+ variant === "link" ? LINK_BASE : BUTTON_BASE,
99
+ BUTTON_VARIANTS[variant],
100
+ variant === "link" ? LINK_SIZES[size] : SIZES[size],
101
+ block ? "w-full" : "",
102
+ className
103
+ ].filter(Boolean).join(" "),
67
104
  ...rest,
68
105
  children: [
69
106
  loading ? /* @__PURE__ */ jsx(Spinner, {}) : leftIcon,
@@ -82,6 +119,7 @@ var Button_default = Button;
82
119
  var SQUARE = {
83
120
  sm: "h-6 w-6",
84
121
  md: "h-8 w-8",
122
+ lg: "h-10 w-10",
85
123
  "touch-sm": "h-11 w-11",
86
124
  "touch": "h-14 w-14",
87
125
  "touch-lg": "h-16 w-16",
@@ -105,7 +143,12 @@ var IconButton_default = IconButton;
105
143
  var INPUT_SHAPE_PRE = "block w-full rounded-md border border-gray-300 bg-white";
106
144
  var INPUT_SHAPE_POST = "text-gray-800 placeholder:text-gray-400 shadow-sm focus:border-blue-400 focus:outline-none focus:ring-2 focus:ring-blue-400/30";
107
145
  var INPUT_SIZES = {
146
+ // The desktop rungs carry no explicit height: a text control's height should
147
+ // follow its own font, or a long label wraps out of a box that was pinned.
148
+ // The touch rung does carry one, for the same reason Button's does.
149
+ sm: "px-2.5 py-1 text-xs",
108
150
  md: "px-3 py-1.5 text-sm",
151
+ lg: "px-3.5 py-2 text-base",
109
152
  // 56px, matching Button's `touch`. `text-base` is 16px BY AGREEMENT with the
110
153
  // rule in ui.css that forces `font-size: 16px !important` on every form
111
154
  // control under `(pointer: coarse)` — the rule that stops iOS zooming the
@@ -130,6 +173,7 @@ var Input = forwardRef(function Input2({ invalid, leftIcon, rightAdornment, size
130
173
  "input",
131
174
  {
132
175
  ref,
176
+ "aria-invalid": invalid || void 0,
133
177
  className: inputClasses({ invalid, size, className: [pad2, className].filter(Boolean).join(" ") }),
134
178
  ...rest
135
179
  }
@@ -143,7 +187,7 @@ var Input = forwardRef(function Input2({ invalid, leftIcon, rightAdornment, size
143
187
  ] });
144
188
  });
145
189
  var Input_default = Input;
146
- var Textarea = forwardRef(function Textarea2({ invalid, autoGrow, className = "", onInput, rows = 3, ...rest }, ref) {
190
+ var Textarea = forwardRef(function Textarea2({ invalid, autoGrow, className = "", onInput, rows = 3, size, ...rest }, ref) {
147
191
  const handleInput = useCallback((e) => {
148
192
  if (autoGrow) {
149
193
  const el = e.currentTarget;
@@ -156,9 +200,10 @@ var Textarea = forwardRef(function Textarea2({ invalid, autoGrow, className = ""
156
200
  "textarea",
157
201
  {
158
202
  ref,
203
+ "aria-invalid": invalid || void 0,
159
204
  rows,
160
205
  onInput: handleInput,
161
- className: inputClasses({ invalid, className: `${autoGrow ? "resize-none overflow-hidden" : ""} ${className}`.trim() }),
206
+ className: inputClasses({ invalid, size, className: `${autoGrow ? "resize-none overflow-hidden" : ""} ${className}`.trim() }),
162
207
  ...rest
163
208
  }
164
209
  );
@@ -201,14 +246,15 @@ function matchTypeahead(options, buffer, fromIndex) {
201
246
  var MENU_GAP = 4;
202
247
  var VIEWPORT_MARGIN = 8;
203
248
  var MENU_MAX_HEIGHT = 240;
204
- var NativeSelect = forwardRef(function NativeSelect2({ value, onChange, options, placeholder, invalid, className = "", ...rest }, ref) {
249
+ var NativeSelect = forwardRef(function NativeSelect2({ value, onChange, options, placeholder, invalid, className = "", size, ...rest }, ref) {
205
250
  return /* @__PURE__ */ jsxs(
206
251
  "select",
207
252
  {
208
253
  ref,
209
254
  value,
210
255
  onChange: (e) => onChange(e.target.value),
211
- className: inputClasses({ invalid, className: `pr-8 ${className}`.trim() }),
256
+ "aria-invalid": invalid || void 0,
257
+ className: inputClasses({ invalid, size, className: `pr-8 ${className}`.trim() }),
212
258
  ...rest,
213
259
  children: [
214
260
  placeholder !== void 0 && /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: placeholder }),
@@ -257,7 +303,21 @@ function useAnchoredPosition(triggerRef, open) {
257
303
  }, [open, triggerRef]);
258
304
  return pos;
259
305
  }
260
- var ListboxSelect = forwardRef(function ListboxSelect2({ value, onChange, options, placeholder, invalid, className = "", id, disabled, ...rest }, ref) {
306
+ var ListboxSelect = forwardRef(function ListboxSelect2({
307
+ value,
308
+ onChange,
309
+ options,
310
+ placeholder,
311
+ invalid,
312
+ className = "",
313
+ id,
314
+ disabled,
315
+ size,
316
+ "aria-describedby": describedBy,
317
+ "aria-label": ariaLabel,
318
+ "aria-labelledby": labelledBy,
319
+ ...rest
320
+ }, ref) {
261
321
  const [open, setOpen] = useState(false);
262
322
  const [active, setActive] = useState(-1);
263
323
  const wrapRef = useRef(null);
@@ -391,10 +451,13 @@ var ListboxSelect = forwardRef(function ListboxSelect2({ value, onChange, option
391
451
  "aria-controls": open ? listboxId : void 0,
392
452
  "aria-activedescendant": open && active >= 0 ? optionId(active) : void 0,
393
453
  "aria-invalid": invalid || void 0,
454
+ "aria-describedby": describedBy,
455
+ "aria-label": ariaLabel,
456
+ "aria-labelledby": labelledBy,
394
457
  disabled,
395
458
  onClick: () => open ? close() : openList(),
396
459
  onKeyDown,
397
- className: inputClasses({ invalid, className: `pr-8 text-left ${className}`.trim() }),
460
+ className: inputClasses({ invalid, size, className: `pr-8 text-left ${className}`.trim() }),
398
461
  children: /* @__PURE__ */ jsx("span", { className: `block truncate ${selectedLabel === void 0 ? "text-gray-400" : ""}`, children: selectedLabel ?? placeholder ?? "\xA0" })
399
462
  }
400
463
  ),
@@ -1413,6 +1476,7 @@ var DatePicker = forwardRef(function DatePicker2({ value, onChange, min, max, in
1413
1476
  {
1414
1477
  ref,
1415
1478
  type: "date",
1479
+ "aria-invalid": invalid || void 0,
1416
1480
  value: toInputValue(value),
1417
1481
  min: toInputValue(min) || void 0,
1418
1482
  max: toInputValue(max) || void 0,
@@ -1701,6 +1765,23 @@ var InputNumber = forwardRef(function InputNumber2({
1701
1765
  setText(next);
1702
1766
  onChange(parse(next));
1703
1767
  };
1768
+ const bump = (by) => {
1769
+ const from = parse(textRef.current) ?? 0;
1770
+ let next = from + by;
1771
+ if (min != null && next < min) next = min;
1772
+ if (max != null && next > max) next = max;
1773
+ const places = precision ?? String(step ?? 1).split(".")[1]?.length ?? 0;
1774
+ next = Number(next.toFixed(places));
1775
+ setText(format(next, precision));
1776
+ onChange(next);
1777
+ };
1778
+ const handleKeyDown = (event) => {
1779
+ const unit = step ?? 1;
1780
+ const by = event.key === "ArrowUp" ? unit : event.key === "ArrowDown" ? -unit : event.key === "PageUp" ? unit * 10 : event.key === "PageDown" ? -unit * 10 : null;
1781
+ if (by === null || disabled) return;
1782
+ event.preventDefault();
1783
+ bump(by);
1784
+ };
1704
1785
  const handleBlur = () => {
1705
1786
  const parsed = parse(text);
1706
1787
  if (parsed == null) {
@@ -1710,6 +1791,7 @@ var InputNumber = forwardRef(function InputNumber2({
1710
1791
  let v = parsed;
1711
1792
  if (min != null && v < min) v = min;
1712
1793
  if (max != null && v > max) v = max;
1794
+ if (precision != null) v = Number(v.toFixed(precision));
1713
1795
  setText(format(v, precision));
1714
1796
  if (v !== parsed) onChange(v);
1715
1797
  }
@@ -1727,8 +1809,14 @@ var InputNumber = forwardRef(function InputNumber2({
1727
1809
  disabled,
1728
1810
  placeholder,
1729
1811
  step,
1812
+ role: "spinbutton",
1813
+ "aria-valuenow": value ?? void 0,
1814
+ "aria-valuemin": min,
1815
+ "aria-valuemax": max,
1816
+ "aria-valuetext": value == null ? void 0 : format(value, precision),
1730
1817
  "aria-invalid": invalid || void 0,
1731
1818
  onChange: (e) => handleChange(e.target.value),
1819
+ onKeyDown: handleKeyDown,
1732
1820
  onBlur: handleBlur,
1733
1821
  className: inputClasses({
1734
1822
  invalid,
@@ -2336,7 +2424,8 @@ function DescriptionList({
2336
2424
  bordered = false,
2337
2425
  size = "md",
2338
2426
  title,
2339
- className = ""
2427
+ className = "",
2428
+ emptyText: empty = "\u2014"
2340
2429
  }) {
2341
2430
  const resolved = typeof columns === "number" ? { base: columns } : columns;
2342
2431
  const base = resolved.base ?? 1;
@@ -2361,7 +2450,7 @@ function DescriptionList({
2361
2450
  ].filter(Boolean).join(" "),
2362
2451
  children: [
2363
2452
  /* @__PURE__ */ jsx("dt", { className: `${text} text-gray-500`, children: item.label }),
2364
- /* @__PURE__ */ jsx("dd", { className: `mt-0.5 min-w-0 break-words ${text} text-gray-900`, children: item.value })
2453
+ /* @__PURE__ */ jsx("dd", { className: `mt-0.5 min-w-0 break-words ${text} text-gray-900`, children: item.value === null || item.value === void 0 || item.value === "" ? empty : item.value })
2365
2454
  ]
2366
2455
  },
2367
2456
  item.key ?? i
@@ -2642,49 +2731,89 @@ function Banner({
2642
2731
  }
2643
2732
  );
2644
2733
  }
2645
- function Tabs({ items, value, onChange, variant = "underline", className = "" }) {
2734
+ var tabButtonId = (prefix, id) => `${prefix}-tab-${id}`;
2735
+ var tabPanelId = (prefix, id) => `${prefix}-panel-${id}`;
2736
+ var LIST_CLASS = {
2737
+ underline: "flex items-center gap-1 border-b border-gray-200",
2738
+ pill: "inline-flex items-center gap-1 rounded-lg bg-gray-100 p-1"
2739
+ };
2740
+ function tabClass(variant, active) {
2646
2741
  if (variant === "pill") {
2647
- return /* @__PURE__ */ jsx("div", { role: "tablist", className: `inline-flex items-center gap-1 rounded-lg bg-gray-100 p-1 ${className}`.trim(), children: items.map((t) => {
2648
- const active = t.id === value;
2649
- return /* @__PURE__ */ jsxs(
2650
- "button",
2651
- {
2652
- type: "button",
2653
- role: "tab",
2654
- "aria-selected": active,
2655
- tabIndex: active ? 0 : -1,
2656
- disabled: t.disabled,
2657
- onClick: () => onChange(t.id),
2658
- className: `inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${active ? "bg-blue-600 text-white shadow-sm" : "text-gray-600 hover:text-gray-900"}`,
2659
- children: [
2660
- t.icon,
2661
- t.label
2662
- ]
2663
- },
2664
- t.id
2665
- );
2666
- }) });
2742
+ return `inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${active ? "bg-blue-600 text-white shadow-sm" : "text-gray-600 hover:text-gray-900"}`;
2667
2743
  }
2668
- return /* @__PURE__ */ jsx("div", { role: "tablist", className: `flex items-center gap-1 border-b border-gray-200 ${className}`.trim(), children: items.map((t) => {
2669
- const active = t.id === value;
2670
- return /* @__PURE__ */ jsxs(
2671
- "button",
2672
- {
2673
- type: "button",
2674
- role: "tab",
2675
- "aria-selected": active,
2676
- tabIndex: active ? 0 : -1,
2677
- disabled: t.disabled,
2678
- onClick: () => onChange(t.id),
2679
- className: `-mb-px inline-flex items-center gap-1.5 border-b-2 px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${active ? "border-blue-600 text-blue-600" : "border-transparent text-gray-600 hover:border-gray-300 hover:text-gray-900"}`,
2680
- children: [
2681
- t.icon,
2682
- t.label
2683
- ]
2684
- },
2685
- t.id
2686
- );
2687
- }) });
2744
+ return `-mb-px inline-flex items-center gap-1.5 border-b-2 px-3 py-2 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${active ? "border-blue-600 text-blue-600" : "border-transparent text-gray-600 hover:border-gray-300 hover:text-gray-900"}`;
2745
+ }
2746
+ function Tabs({
2747
+ items,
2748
+ value,
2749
+ onChange,
2750
+ variant = "underline",
2751
+ idPrefix,
2752
+ className = "",
2753
+ "aria-label": ariaLabel,
2754
+ "aria-labelledby": ariaLabelledBy
2755
+ }) {
2756
+ const buttons = useRef([]);
2757
+ const step = (from, direction) => {
2758
+ for (let i = 1; i <= items.length; i += 1) {
2759
+ const at = ((from + direction * i) % items.length + items.length) % items.length;
2760
+ if (!items[at]?.disabled) return at;
2761
+ }
2762
+ return null;
2763
+ };
2764
+ const edge = (direction) => {
2765
+ const order = direction === 1 ? items.map((_, i) => i) : items.map((_, i) => items.length - 1 - i);
2766
+ for (const i of order) if (!items[i]?.disabled) return i;
2767
+ return null;
2768
+ };
2769
+ const onKeyDown = (event) => {
2770
+ const current = items.findIndex((t) => t.id === value);
2771
+ let next = null;
2772
+ if (event.key === "ArrowRight" || event.key === "ArrowDown") next = step(current, 1);
2773
+ else if (event.key === "ArrowLeft" || event.key === "ArrowUp") next = step(current, -1);
2774
+ else if (event.key === "Home") next = edge(1);
2775
+ else if (event.key === "End") next = edge(-1);
2776
+ else return;
2777
+ event.preventDefault();
2778
+ if (next === null || next === current) return;
2779
+ onChange(items[next].id);
2780
+ buttons.current[next]?.focus();
2781
+ };
2782
+ return /* @__PURE__ */ jsx(
2783
+ "div",
2784
+ {
2785
+ role: "tablist",
2786
+ "aria-label": ariaLabel,
2787
+ "aria-labelledby": ariaLabelledBy,
2788
+ onKeyDown,
2789
+ className: `${LIST_CLASS[variant]} ${className}`.trim(),
2790
+ children: items.map((t, i) => {
2791
+ const active = t.id === value;
2792
+ return /* @__PURE__ */ jsxs(
2793
+ "button",
2794
+ {
2795
+ ref: (el) => {
2796
+ buttons.current[i] = el;
2797
+ },
2798
+ type: "button",
2799
+ role: "tab",
2800
+ id: idPrefix ? tabButtonId(idPrefix, t.id) : void 0,
2801
+ "aria-controls": idPrefix ? tabPanelId(idPrefix, t.id) : void 0,
2802
+ "aria-selected": active,
2803
+ tabIndex: active ? 0 : -1,
2804
+ disabled: t.disabled,
2805
+ onClick: () => onChange(t.id),
2806
+ className: tabClass(variant, active),
2807
+ children: [
2808
+ t.icon && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "inline-flex shrink-0", children: t.icon }),
2809
+ t.label
2810
+ ]
2811
+ },
2812
+ t.id
2813
+ );
2814
+ })
2815
+ }
2816
+ );
2688
2817
  }
2689
2818
  function Accordion({
2690
2819
  items,
@@ -2789,11 +2918,6 @@ function Tooltip({ content, side = "top", delay = 200, children }) {
2789
2918
  }
2790
2919
  );
2791
2920
  }
2792
- function ColoredBadge({ colorClass, children, size = "sm", capitalize = false }) {
2793
- const sizeCls = size === "xs" ? "px-2 py-0.5 text-[10px]" : size === "md" ? "px-2.5 py-0.5 text-xs" : "px-2 py-0.5 text-xs";
2794
- const capCls = capitalize ? "capitalize" : "";
2795
- return /* @__PURE__ */ jsx("span", { className: `inline-flex items-center rounded-full font-medium ${sizeCls} ${capCls} ${colorClass}`, children });
2796
- }
2797
2921
  var GROUP_COLORS = {
2798
2922
  success: "bg-green-100 text-green-800",
2799
2923
  active: "bg-blue-100 text-blue-800",
@@ -2819,6 +2943,36 @@ function StatusBadge({ status }) {
2819
2943
  const label = status.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
2820
2944
  return /* @__PURE__ */ jsx("span", { className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${color}`, children: label });
2821
2945
  }
2946
+ function ColoredBadge({
2947
+ colorClass,
2948
+ tone,
2949
+ children,
2950
+ size = "sm",
2951
+ capitalize = false,
2952
+ closable = false,
2953
+ onClose,
2954
+ closeLabel,
2955
+ className = ""
2956
+ }) {
2957
+ const colour = colorClass ?? GROUP_COLORS[tone ?? "neutral"];
2958
+ const sizeCls = size === "xs" ? "px-2 py-0.5 text-[10px]" : size === "md" ? "px-2.5 py-0.5 text-xs" : "px-2 py-0.5 text-xs";
2959
+ const capCls = capitalize ? "capitalize" : "";
2960
+ const closeName = closeLabel ?? (typeof children === "string" ? `Remove ${children}` : "Remove");
2961
+ const closeSize = size === "xs" ? "h-2.5 w-2.5" : "h-3 w-3";
2962
+ return /* @__PURE__ */ jsxs("span", { className: ["inline-flex items-center rounded-full font-medium", sizeCls, capCls, colour, className].filter(Boolean).join(" "), children: [
2963
+ children,
2964
+ closable && /* @__PURE__ */ jsx(
2965
+ "button",
2966
+ {
2967
+ type: "button",
2968
+ onClick: onClose,
2969
+ "aria-label": closeName,
2970
+ className: "-mr-0.5 ml-1 inline-flex shrink-0 items-center justify-center rounded-full opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-blue-400/40",
2971
+ children: /* @__PURE__ */ jsx("svg", { className: closeSize, viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" }) })
2972
+ }
2973
+ )
2974
+ ] });
2975
+ }
2822
2976
  function EmptyState({
2823
2977
  title,
2824
2978
  message,
@@ -2830,12 +2984,14 @@ function EmptyState({
2830
2984
  children
2831
2985
  }) {
2832
2986
  const v = frameless ? "none" : variant ?? "dashed";
2833
- const showIcon = icon ?? v !== "card";
2987
+ const custom = typeof icon !== "boolean" && icon != null ? icon : null;
2988
+ const showIcon = custom ? false : icon ?? v !== "card";
2834
2989
  const primary = message ?? (title ? void 0 : "Nothing here yet.");
2835
2990
  const secondary = description ?? hint;
2836
2991
  const frame = v === "card" ? "rounded-md border border-gray-200 bg-white px-6 py-12" : v === "none" ? "px-6 py-12" : "rounded-lg border-2 border-dashed border-gray-300 px-6 py-12";
2837
2992
  return /* @__PURE__ */ jsxs("div", { className: `flex flex-col items-center justify-center text-center ${frame}`, children: [
2838
- showIcon && /* @__PURE__ */ jsx("svg", { className: "h-10 w-10 text-gray-300 mb-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" }) }),
2993
+ custom && /* @__PURE__ */ jsx("div", { className: "mb-3 flex h-10 w-10 items-center justify-center text-gray-300", "aria-hidden": "true", children: custom }),
2994
+ showIcon && /* @__PURE__ */ jsx("svg", { className: "h-10 w-10 text-gray-300 mb-3", "aria-hidden": "true", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" }) }),
2839
2995
  title && /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-gray-900", children: title }),
2840
2996
  primary && /* @__PURE__ */ jsx("p", { className: `text-sm text-gray-500 ${title ? "mt-2" : ""}`, children: primary }),
2841
2997
  secondary && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 mt-1", children: secondary }),
@@ -5282,6 +5438,6 @@ var ALT_SHIFT_D = isMac ? "\u2325\u21E7D" : "Alt+Shift+D";
5282
5438
  var ALT_SHIFT_E = isMac ? "\u2325\u21E7E" : "Alt+Shift+E";
5283
5439
  var ALT_SHIFT_N = isMac ? "\u2325\u21E7N" : "Alt+Shift+N";
5284
5440
 
5285
- export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, Accordion, AuthScreen, Avatar, AvatarGroup, Banner, BarChart, Button_default, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CMD_SHIFT_Z, CMD_Z, Card, ChatTemplate, Checkbox_default, CheckoutTemplate, ColoredBadge, ContainerFillChart, CountBadge, DashboardTemplate, DataTable, DataTablePage, DatePicker_default, DateRangePicker, DescriptionList, Divider, DonutChart, Drawer, ENTER, EmailTemplate, EmptyState, ErrorPage, FilePicker, FormField, FormLayoutPage, GalleryTemplate, GlobalSearch, Grid, HelpCenter, INPUT_BASE, INPUT_SIZES, IconButton_default, Inline, InputNumber_default, Input_default, Kanban, Label, ListFooter, ListLoadError, LoadingSpinner, MAX_FRACTION_DIGITS, MOD, Markdown, MediaUploadField, MediaUploadGrid, MetricBar, MilestoneTimeline, NativeSelect, NumericKeypad, PageHeader, Pagination, Paragraph, Radio_default, Result, SHIFT, SearchableSelect, Segmented, Select_default, SidebarActionButton, SidebarGroupLabel, SidebarNavItem, Skeleton, Sparkline, Stack, StatCard, Statistic, StatusBadge, StatusBadgeProvider, Switch_default, Tabs, Text, Textarea_default, TileButton_default, Title, Tooltip, TopNav, appendKey, applyThemePrefs, backspace, firstEnabledIndex, formatDate, inputClasses, isMac, isSeverityTone, lastEnabledIndex, matchTypeahead, mediaFileName, nextEnabledIndex, resolveTheme, severityOf, toISODate, useClickOutside, useTheme };
5286
- //# sourceMappingURL=chunk-7NIFBQUX.js.map
5287
- //# sourceMappingURL=chunk-7NIFBQUX.js.map
5441
+ export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, Accordion, AuthScreen, Avatar, AvatarGroup, Banner, BarChart, Button_default, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CMD_SHIFT_Z, CMD_Z, Card, ChatTemplate, Checkbox_default, CheckoutTemplate, ColoredBadge, ContainerFillChart, CountBadge, DashboardTemplate, DataTable, DataTablePage, DatePicker_default, DateRangePicker, DescriptionList, Divider, DonutChart, Drawer, ENTER, EmailTemplate, EmptyState, ErrorPage, FilePicker, FormField, FormLayoutPage, GROUP_COLORS, GalleryTemplate, GlobalSearch, Grid, HelpCenter, INPUT_BASE, INPUT_SIZES, IconButton_default, Inline, InputNumber_default, Input_default, Kanban, Label, ListFooter, ListLoadError, LoadingSpinner, MAX_FRACTION_DIGITS, MOD, Markdown, MediaUploadField, MediaUploadGrid, MetricBar, MilestoneTimeline, NativeSelect, NumericKeypad, PageHeader, Pagination, Paragraph, Radio_default, Result, SHIFT, SearchableSelect, Segmented, Select_default, SidebarActionButton, SidebarGroupLabel, SidebarNavItem, Skeleton, Sparkline, Stack, StatCard, Statistic, StatusBadge, StatusBadgeProvider, Switch_default, Tabs, Text, Textarea_default, TileButton_default, Title, Tooltip, TopNav, appendKey, applyThemePrefs, backspace, firstEnabledIndex, formatDate, inputClasses, isMac, isSeverityTone, lastEnabledIndex, matchTypeahead, mediaFileName, nextEnabledIndex, resolveTheme, severityOf, tabButtonId, tabPanelId, toISODate, useClickOutside, useTheme };
5442
+ //# sourceMappingURL=chunk-D4WFGAUW.js.map
5443
+ //# sourceMappingURL=chunk-D4WFGAUW.js.map