@nocoo/basalt 2.1.2 → 2.1.7

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 (68) hide show
  1. package/ai/INTEGRATION.md +17 -1
  2. package/ai/USAGE.md +1 -1
  3. package/ai/registry.json +75 -75
  4. package/dist/charts/charts.d.ts +1 -1
  5. package/dist/charts/charts.js +3 -16
  6. package/dist/charts/charts.js.map +1 -1
  7. package/dist/charts/custom-chart.d.ts +1 -1
  8. package/dist/charts/custom-chart.js +3 -16
  9. package/dist/charts/custom-chart.js.map +1 -1
  10. package/dist/charts/grouped-bar.d.ts +1 -1
  11. package/dist/charts/grouped-bar.js +11 -48
  12. package/dist/charts/grouped-bar.js.map +1 -1
  13. package/dist/charts/heatmap-calendar.js +80 -136
  14. package/dist/charts/heatmap-calendar.js.map +1 -1
  15. package/dist/charts/slot-bar.js +2 -12
  16. package/dist/charts/slot-bar.js.map +1 -1
  17. package/dist/charts/stat-card.js +2 -7
  18. package/dist/charts/stat-card.js.map +1 -1
  19. package/dist/charts/timeseries.d.ts +1 -1
  20. package/dist/charts/timeseries.js +3 -16
  21. package/dist/charts/timeseries.js.map +1 -1
  22. package/dist/charts/tooltip.js +13 -51
  23. package/dist/charts/tooltip.js.map +1 -1
  24. package/dist/components/autocomplete.d.ts +1 -1
  25. package/dist/components/autocomplete.js +3 -16
  26. package/dist/components/autocomplete.js.map +1 -1
  27. package/dist/components/banner.js +28 -28
  28. package/dist/components/banner.js.map +1 -1
  29. package/dist/components/button.js +6 -7
  30. package/dist/components/button.js.map +1 -1
  31. package/dist/components/chat-composer.js +1 -2
  32. package/dist/components/chat-composer.js.map +1 -1
  33. package/dist/components/checkbox.js +50 -82
  34. package/dist/components/checkbox.js.map +1 -1
  35. package/dist/components/code.js +1 -1
  36. package/dist/components/code.js.map +1 -1
  37. package/dist/components/combobox.d.ts +1 -1
  38. package/dist/components/combobox.js +3 -16
  39. package/dist/components/combobox.js.map +1 -1
  40. package/dist/components/context-menu.d.ts +1 -67
  41. package/dist/components/context-menu.js.map +1 -1
  42. package/dist/components/data-table.js +111 -123
  43. package/dist/components/data-table.js.map +1 -1
  44. package/dist/components/date-picker.js +236 -245
  45. package/dist/components/date-picker.js.map +1 -1
  46. package/dist/components/dock.js +15 -16
  47. package/dist/components/dock.js.map +1 -1
  48. package/dist/components/field.js +20 -23
  49. package/dist/components/field.js.map +1 -1
  50. package/dist/components/layer-card.d.ts +1 -1
  51. package/dist/components/layer-card.js +44 -51
  52. package/dist/components/layer-card.js.map +1 -1
  53. package/dist/components/skeleton-line.d.ts +2 -2
  54. package/dist/components/skeleton-line.js +1 -1
  55. package/dist/components/skeleton-line.js.map +1 -1
  56. package/dist/components/switch.js +46 -78
  57. package/dist/components/switch.js.map +1 -1
  58. package/dist/providers/accent.js +89 -198
  59. package/dist/providers/accent.js.map +1 -1
  60. package/dist/providers/theme.js +46 -144
  61. package/dist/providers/theme.js.map +1 -1
  62. package/dist/utils/preference-store.d.ts +16 -0
  63. package/dist/utils/preference-store.js +106 -0
  64. package/dist/utils/preference-store.js.map +1 -0
  65. package/dist/utils/use-checkable-group.d.ts +19 -0
  66. package/dist/utils/use-checkable-group.js +61 -0
  67. package/dist/utils/use-checkable-group.js.map +1 -0
  68. package/package.json +1 -2
@@ -15,72 +15,69 @@ var d = `${t} overflow-hidden rounded-basalt-lg text-basalt-foreground`, f = {
15
15
  function p(e) {
16
16
  return c(e);
17
17
  }
18
- function m(e) {
19
- return e.type;
18
+ function m(e, t) {
19
+ return i.toArray(e).some((e) => p(e) ? t(e.type) ? !0 : e.type === a && m(e.props.children, t) : !1);
20
20
  }
21
- function h(e, t) {
22
- return i.toArray(e).some((e) => p(e) ? t(m(e)) ? !0 : m(e) === a && h(e.props.children, t) : !1);
23
- }
24
- function g(t, n) {
21
+ function h(t, n) {
25
22
  return n ? i.map(t, (t) => {
26
23
  if (!p(t)) return t;
27
- if (m(t) === a) return o(t, { children: g(t.props.children, n) });
28
- if (m(t) === v || m(t) === S) {
24
+ if (t.type === a) return o(t, { children: h(t.props.children, n) });
25
+ if (t.type === _ || t.type === x) {
29
26
  let n = t;
30
27
  return o(n, { className: e(n.props.className, "border-b border-basalt-border") });
31
28
  }
32
29
  return t;
33
30
  }) : t;
34
31
  }
35
- var _ = s(({ className: t, children: n, outlined: r = !1, padding: i = "md", ...a }, o) => {
36
- let s = h(n, (e) => E.has(e)), c = h(n, (e) => e === b || e === x), u = h(n, (e) => e === y) && !c;
32
+ var g = s(({ className: t, children: n, outlined: r = !1, padding: i = "md", ...a }, o) => {
33
+ let s = m(n, (e) => T.has(e)), c = m(n, (e) => e === y || e === b), u = m(n, (e) => e === v) && !c;
37
34
  return /* @__PURE__ */ l("div", {
38
35
  ref: o,
39
36
  "data-basalt-surface": "",
40
37
  className: e(d, s ? "flex w-full flex-col" : f[i], r && "ring-1 ring-basalt-border/40", t),
41
38
  ...a,
42
- children: g(n, u)
39
+ children: h(n, u)
43
40
  });
44
41
  });
45
- _.displayName = "LayerCard";
46
- function v({ className: t, ...n }) {
42
+ g.displayName = "LayerCard";
43
+ function _({ className: t, ...n }) {
47
44
  return /* @__PURE__ */ l("div", {
48
45
  className: e("flex min-w-0 items-start justify-between gap-4 px-4 py-3 text-basalt-muted-foreground", t),
49
46
  ...n
50
47
  });
51
48
  }
52
- v.displayName = "LayerCard.Header";
53
- function y({ className: t, ...n }) {
49
+ _.displayName = "LayerCard.Header";
50
+ function v({ className: t, ...n }) {
54
51
  return /* @__PURE__ */ l("div", {
55
52
  className: e("min-w-0 p-4", t),
56
53
  ...n
57
54
  });
58
55
  }
59
- y.displayName = "LayerCard.Body";
60
- function b({ className: t, outlined: n = !1, ...r }) {
56
+ v.displayName = "LayerCard.Body";
57
+ function y({ className: t, outlined: n = !1, ...r }) {
61
58
  return /* @__PURE__ */ l("div", {
62
59
  "data-basalt-surface": "",
63
60
  className: e("min-w-0 p-4", n && "ring-1 ring-basalt-border/40", t),
64
61
  ...r
65
62
  });
66
63
  }
67
- b.displayName = "LayerCard.Well";
68
- function x(e) {
69
- return /* @__PURE__ */ l(b, { ...e });
64
+ y.displayName = "LayerCard.Well";
65
+ function b(e) {
66
+ return /* @__PURE__ */ l(y, { ...e });
70
67
  }
71
- x.displayName = "LayerCard.Primary";
72
- function S(e) {
73
- return /* @__PURE__ */ l(v, { ...e });
68
+ b.displayName = "LayerCard.Primary";
69
+ function x(e) {
70
+ return /* @__PURE__ */ l(_, { ...e });
74
71
  }
75
- S.displayName = "LayerCard.Secondary";
76
- function C({ className: t, ...n }) {
72
+ x.displayName = "LayerCard.Secondary";
73
+ function S({ className: t, ...n }) {
77
74
  return /* @__PURE__ */ l("div", {
78
75
  className: e("flex flex-wrap items-center justify-end gap-2 border-t border-basalt-border px-4 py-3", t),
79
76
  ...n
80
77
  });
81
78
  }
82
- C.displayName = "LayerCard.Footer";
83
- function w({ label: t = "Loading", className: n, ...i }) {
79
+ S.displayName = "LayerCard.Footer";
80
+ function C({ label: t = "Loading", className: n, ...i }) {
84
81
  return /* @__PURE__ */ u("div", {
85
82
  role: "status",
86
83
  "aria-label": t,
@@ -102,39 +99,35 @@ function w({ label: t = "Loading", className: n, ...i }) {
102
99
  ]
103
100
  });
104
101
  }
105
- w.displayName = "LayerCard.Loading";
106
- function T({ title: t = "No content", description: r, icon: i, action: a, children: o, className: s, ...c }) {
102
+ C.displayName = "LayerCard.Loading";
103
+ function w({ title: t = "No content", className: r, ...i }) {
107
104
  return /* @__PURE__ */ l(n, {
108
105
  title: t,
109
- description: r,
110
- icon: i,
111
- action: a,
112
- className: e("p-8", s),
113
- ...c,
114
- children: o
106
+ className: e("p-8", r),
107
+ ...i
115
108
  });
116
109
  }
117
- T.displayName = "LayerCard.Empty";
118
- var E = /* @__PURE__ */ new Set([
110
+ w.displayName = "LayerCard.Empty";
111
+ var T = /* @__PURE__ */ new Set([
112
+ _,
119
113
  v,
120
114
  y,
121
- b,
115
+ S,
122
116
  C,
123
117
  w,
124
- T,
125
- x,
126
- S
127
- ]), D = Object.assign(_, {
128
- Primary: x,
129
- Secondary: S,
130
- Header: v,
131
- Body: y,
132
- Well: b,
133
- Footer: C,
134
- Loading: w,
135
- Empty: T
118
+ b,
119
+ x
120
+ ]), E = Object.assign(g, {
121
+ Primary: b,
122
+ Secondary: x,
123
+ Header: _,
124
+ Body: v,
125
+ Well: y,
126
+ Footer: S,
127
+ Loading: C,
128
+ Empty: w
136
129
  });
137
130
  //#endregion
138
- export { D as LayerCard };
131
+ export { E as LayerCard };
139
132
 
140
133
  //# sourceMappingURL=layer-card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layer-card.js","names":[],"sources":["../../src/components/layer-card.tsx"],"sourcesContent":["import {\n\tChildren,\n\tcloneElement,\n\tFragment,\n\tforwardRef,\n\ttype HTMLAttributes,\n\tisValidElement,\n\ttype ReactElement,\n\ttype ReactNode,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Empty } from \"./empty\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nconst ROOT_CLASSES = `${BASALT_UI_CLASS} overflow-hidden rounded-basalt-lg text-basalt-foreground`;\nconst PADDING_CLASSES = {\n\tnone: \"\",\n\tsm: \"p-3\",\n\tmd: \"p-4\",\n\tlg: \"p-6\",\n} as const;\n\nexport type LayerCardPadding = keyof typeof PADDING_CLASSES;\n\nexport type LayerCardProps = Omit<HTMLAttributes<HTMLDivElement>, \"className\"> & {\n\t/**\n\t * Additional classes for the card root.\n\t */\n\tclassName?: string;\n\t/**\n\t * Draw a hairline ring. Default grouping is luminance only.\n\t * @default false\n\t */\n\toutlined?: boolean;\n\t/**\n\t * Inner spacing for unstructured card content.\n\t * @default \"md\"\n\t */\n\tpadding?: LayerCardPadding;\n};\nexport type LayerCardSectionProps = HTMLAttributes<HTMLDivElement>;\nexport type LayerCardWellProps = LayerCardSectionProps & {\n\t/**\n\t * Draw a hairline ring on a nested well.\n\t * @default false\n\t */\n\toutlined?: boolean;\n};\nexport type LayerCardLoadingProps = Omit<HTMLAttributes<HTMLDivElement>, \"aria-label\"> & {\n\t/**\n\t * Accessible label announced for the loading state.\n\t * @default \"Loading\"\n\t */\n\tlabel?: string;\n};\nexport type LayerCardEmptyProps = Omit<HTMLAttributes<HTMLDivElement>, \"title\" | \"children\"> & {\n\t/**\n\t * Empty-state heading.\n\t * @default \"No content\"\n\t */\n\ttitle?: string;\n\t/**\n\t * Supporting empty-state text.\n\t */\n\tdescription?: string;\n\t/**\n\t * Optional empty-state icon.\n\t */\n\ticon?: ReactNode;\n\t/**\n\t * Optional interactive action element rendered below empty content.\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Custom supporting content or custom layout rendered between description and action.\n\t */\n\tchildren?: ReactNode;\n};\n\nfunction isElement(child: ReactNode): child is ReactElement<{ children?: ReactNode }> {\n\treturn isValidElement(child);\n}\n\nfunction childType(child: ReactElement): unknown {\n\treturn child.type;\n}\n\nfunction hasSlot(children: ReactNode, match: (type: unknown) => boolean): boolean {\n\treturn Children.toArray(children).some((child) => {\n\t\tif (!isElement(child)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (match(childType(child))) {\n\t\t\treturn true;\n\t\t}\n\t\tif (childType(child) === Fragment) {\n\t\t\treturn hasSlot(child.props.children, match);\n\t\t}\n\t\treturn false;\n\t});\n}\n\nfunction decorateHeaders(children: ReactNode, divided: boolean): ReactNode {\n\tif (!divided) {\n\t\treturn children;\n\t}\n\treturn Children.map(children, (child) => {\n\t\tif (!isElement(child)) {\n\t\t\treturn child;\n\t\t}\n\t\tif (childType(child) === Fragment) {\n\t\t\treturn cloneElement(child, {\n\t\t\t\tchildren: decorateHeaders(child.props.children, divided),\n\t\t\t});\n\t\t}\n\t\tif (childType(child) === LayerCardHeader || childType(child) === LayerCardSecondary) {\n\t\t\tconst typed = child as ReactElement<{ className?: string }>;\n\t\t\treturn cloneElement(typed, {\n\t\t\t\tclassName: cn(typed.props.className, \"border-b border-basalt-border\"),\n\t\t\t});\n\t\t}\n\t\treturn child;\n\t});\n}\n\nconst LayerCardRoot = forwardRef<HTMLDivElement, LayerCardProps>(\n\t({ className, children, outlined = false, padding = \"md\", ...props }, ref) => {\n\t\tconst structured = hasSlot(children, (type) => STRUCTURED_TYPES.has(type));\n\t\tconst hasWell = hasSlot(\n\t\t\tchildren,\n\t\t\t(type) => type === LayerCardWell || type === LayerCardPrimary,\n\t\t);\n\t\tconst hasBody = hasSlot(children, (type) => type === LayerCardBody);\n\t\tconst headerDivided = hasBody && !hasWell;\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-basalt-surface=\"\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\tROOT_CLASSES,\n\t\t\t\t\tstructured ? \"flex w-full flex-col\" : PADDING_CLASSES[padding],\n\t\t\t\t\toutlined && \"ring-1 ring-basalt-border/40\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{decorateHeaders(children, headerDivided)}\n\t\t\t</div>\n\t\t);\n\t},\n);\nLayerCardRoot.displayName = \"LayerCard\";\n\nfunction LayerCardHeader({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex min-w-0 items-start justify-between gap-4 px-4 py-3 text-basalt-muted-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardHeader.displayName = \"LayerCard.Header\";\n\nfunction LayerCardBody({ className, ...props }: LayerCardSectionProps) {\n\treturn <div className={cn(\"min-w-0 p-4\", className)} {...props} />;\n}\nLayerCardBody.displayName = \"LayerCard.Body\";\n\nfunction LayerCardWell({ className, outlined = false, ...props }: LayerCardWellProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface=\"\"\n\t\t\tclassName={cn(\"min-w-0 p-4\", outlined && \"ring-1 ring-basalt-border/40\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardWell.displayName = \"LayerCard.Well\";\n\nfunction LayerCardPrimary(props: LayerCardWellProps) {\n\treturn <LayerCardWell {...props} />;\n}\nLayerCardPrimary.displayName = \"LayerCard.Primary\";\n\nfunction LayerCardSecondary(props: LayerCardSectionProps) {\n\treturn <LayerCardHeader {...props} />;\n}\nLayerCardSecondary.displayName = \"LayerCard.Secondary\";\n\nfunction LayerCardFooter({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex flex-wrap items-center justify-end gap-2 border-t border-basalt-border px-4 py-3\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardFooter.displayName = \"LayerCard.Footer\";\n\nfunction LayerCardLoading({ label = \"Loading\", className, ...props }: LayerCardLoadingProps) {\n\treturn (\n\t\t<div role=\"status\" aria-label={label} className={cn(\"space-y-3 p-4\", className)} {...props}>\n\t\t\t<SkeletonLine minWidth={100} maxWidth={100} />\n\t\t\t<SkeletonLine minWidth={72} maxWidth={72} />\n\t\t\t<SkeletonLine minWidth={88} maxWidth={88} />\n\t\t</div>\n\t);\n}\nLayerCardLoading.displayName = \"LayerCard.Loading\";\n\nfunction LayerCardEmpty({\n\ttitle = \"No content\",\n\tdescription,\n\ticon,\n\taction,\n\tchildren,\n\tclassName,\n\t...props\n}: LayerCardEmptyProps) {\n\treturn (\n\t\t<Empty\n\t\t\ttitle={title}\n\t\t\tdescription={description}\n\t\t\ticon={icon}\n\t\t\taction={action}\n\t\t\tclassName={cn(\"p-8\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Empty>\n\t);\n}\nLayerCardEmpty.displayName = \"LayerCard.Empty\";\n\nconst STRUCTURED_TYPES = new Set<unknown>([\n\tLayerCardHeader,\n\tLayerCardBody,\n\tLayerCardWell,\n\tLayerCardFooter,\n\tLayerCardLoading,\n\tLayerCardEmpty,\n\tLayerCardPrimary,\n\tLayerCardSecondary,\n]);\n\nexport const LayerCard = Object.assign(LayerCardRoot, {\n\tPrimary: LayerCardPrimary,\n\tSecondary: LayerCardSecondary,\n\tHeader: LayerCardHeader,\n\tBody: LayerCardBody,\n\tWell: LayerCardWell,\n\tFooter: LayerCardFooter,\n\tLoading: LayerCardLoading,\n\tEmpty: LayerCardEmpty,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"layer-card.js","names":[],"sources":["../../src/components/layer-card.tsx"],"sourcesContent":["import {\n\tChildren,\n\tcloneElement,\n\tFragment,\n\tforwardRef,\n\ttype HTMLAttributes,\n\tisValidElement,\n\ttype ReactElement,\n\ttype ReactNode,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Empty } from \"./empty\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nconst ROOT_CLASSES = `${BASALT_UI_CLASS} overflow-hidden rounded-basalt-lg text-basalt-foreground`;\nconst PADDING_CLASSES = {\n\tnone: \"\",\n\tsm: \"p-3\",\n\tmd: \"p-4\",\n\tlg: \"p-6\",\n} as const;\n\nexport type LayerCardPadding = keyof typeof PADDING_CLASSES;\n\nexport type LayerCardProps = Omit<HTMLAttributes<HTMLDivElement>, \"className\"> & {\n\t/**\n\t * Additional classes for the card root.\n\t */\n\tclassName?: string;\n\t/**\n\t * Draw a hairline ring. Default grouping is luminance only.\n\t * @default false\n\t */\n\toutlined?: boolean;\n\t/**\n\t * Inner spacing for unstructured card content.\n\t * @default \"md\"\n\t */\n\tpadding?: LayerCardPadding;\n};\nexport type LayerCardSectionProps = HTMLAttributes<HTMLDivElement>;\nexport type LayerCardWellProps = LayerCardSectionProps & {\n\t/**\n\t * Draw a hairline ring on a nested well.\n\t * @default false\n\t */\n\toutlined?: boolean;\n};\nexport type LayerCardLoadingProps = Omit<HTMLAttributes<HTMLDivElement>, \"aria-label\"> & {\n\t/**\n\t * Accessible label announced for the loading state.\n\t * @default \"Loading\"\n\t */\n\tlabel?: string;\n};\nexport type LayerCardEmptyProps = Omit<HTMLAttributes<HTMLDivElement>, \"title\" | \"children\"> & {\n\t/**\n\t * Empty-state heading.\n\t * @default \"No content\"\n\t */\n\ttitle?: string;\n\t/**\n\t * Supporting empty-state text.\n\t */\n\tdescription?: string;\n\t/**\n\t * Optional empty-state icon.\n\t */\n\ticon?: ReactNode;\n\t/**\n\t * Optional interactive action element rendered below empty content.\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Custom supporting content or custom layout rendered between description and action.\n\t */\n\tchildren?: ReactNode;\n};\n\nfunction isElement(child: ReactNode): child is ReactElement<{ children?: ReactNode }> {\n\treturn isValidElement(child);\n}\n\nfunction hasSlot(children: ReactNode, match: (type: unknown) => boolean): boolean {\n\treturn Children.toArray(children).some((child) => {\n\t\tif (!isElement(child)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (match(child.type)) {\n\t\t\treturn true;\n\t\t}\n\t\tif (child.type === Fragment) {\n\t\t\treturn hasSlot(child.props.children, match);\n\t\t}\n\t\treturn false;\n\t});\n}\n\nfunction decorateHeaders(children: ReactNode, divided: boolean): ReactNode {\n\tif (!divided) {\n\t\treturn children;\n\t}\n\treturn Children.map(children, (child) => {\n\t\tif (!isElement(child)) {\n\t\t\treturn child;\n\t\t}\n\t\tif (child.type === Fragment) {\n\t\t\treturn cloneElement(child, {\n\t\t\t\tchildren: decorateHeaders(child.props.children, divided),\n\t\t\t});\n\t\t}\n\t\tif (child.type === LayerCardHeader || child.type === LayerCardSecondary) {\n\t\t\tconst typed = child as ReactElement<{ className?: string }>;\n\t\t\treturn cloneElement(typed, {\n\t\t\t\tclassName: cn(typed.props.className, \"border-b border-basalt-border\"),\n\t\t\t});\n\t\t}\n\t\treturn child;\n\t});\n}\n\nconst LayerCardRoot = forwardRef<HTMLDivElement, LayerCardProps>(\n\t({ className, children, outlined = false, padding = \"md\", ...props }, ref) => {\n\t\tconst structured = hasSlot(children, (type) => STRUCTURED_TYPES.has(type));\n\t\tconst hasWell = hasSlot(\n\t\t\tchildren,\n\t\t\t(type) => type === LayerCardWell || type === LayerCardPrimary,\n\t\t);\n\t\tconst hasBody = hasSlot(children, (type) => type === LayerCardBody);\n\t\tconst headerDivided = hasBody && !hasWell;\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-basalt-surface=\"\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\tROOT_CLASSES,\n\t\t\t\t\tstructured ? \"flex w-full flex-col\" : PADDING_CLASSES[padding],\n\t\t\t\t\toutlined && \"ring-1 ring-basalt-border/40\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{decorateHeaders(children, headerDivided)}\n\t\t\t</div>\n\t\t);\n\t},\n);\nLayerCardRoot.displayName = \"LayerCard\";\n\nfunction LayerCardHeader({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex min-w-0 items-start justify-between gap-4 px-4 py-3 text-basalt-muted-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardHeader.displayName = \"LayerCard.Header\";\n\nfunction LayerCardBody({ className, ...props }: LayerCardSectionProps) {\n\treturn <div className={cn(\"min-w-0 p-4\", className)} {...props} />;\n}\nLayerCardBody.displayName = \"LayerCard.Body\";\n\nfunction LayerCardWell({ className, outlined = false, ...props }: LayerCardWellProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface=\"\"\n\t\t\tclassName={cn(\"min-w-0 p-4\", outlined && \"ring-1 ring-basalt-border/40\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardWell.displayName = \"LayerCard.Well\";\n\nfunction LayerCardPrimary(props: LayerCardWellProps) {\n\treturn <LayerCardWell {...props} />;\n}\nLayerCardPrimary.displayName = \"LayerCard.Primary\";\n\nfunction LayerCardSecondary(props: LayerCardSectionProps) {\n\treturn <LayerCardHeader {...props} />;\n}\nLayerCardSecondary.displayName = \"LayerCard.Secondary\";\n\nfunction LayerCardFooter({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex flex-wrap items-center justify-end gap-2 border-t border-basalt-border px-4 py-3\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardFooter.displayName = \"LayerCard.Footer\";\n\nfunction LayerCardLoading({ label = \"Loading\", className, ...props }: LayerCardLoadingProps) {\n\treturn (\n\t\t<div role=\"status\" aria-label={label} className={cn(\"space-y-3 p-4\", className)} {...props}>\n\t\t\t<SkeletonLine minWidth={100} maxWidth={100} />\n\t\t\t<SkeletonLine minWidth={72} maxWidth={72} />\n\t\t\t<SkeletonLine minWidth={88} maxWidth={88} />\n\t\t</div>\n\t);\n}\nLayerCardLoading.displayName = \"LayerCard.Loading\";\n\nfunction LayerCardEmpty({ title = \"No content\", className, ...props }: LayerCardEmptyProps) {\n\treturn <Empty title={title} className={cn(\"p-8\", className)} {...props} />;\n}\nLayerCardEmpty.displayName = \"LayerCard.Empty\";\n\nconst STRUCTURED_TYPES = new Set<unknown>([\n\tLayerCardHeader,\n\tLayerCardBody,\n\tLayerCardWell,\n\tLayerCardFooter,\n\tLayerCardLoading,\n\tLayerCardEmpty,\n\tLayerCardPrimary,\n\tLayerCardSecondary,\n]);\n\nexport const LayerCard = Object.assign(LayerCardRoot, {\n\tPrimary: LayerCardPrimary,\n\tSecondary: LayerCardSecondary,\n\tHeader: LayerCardHeader,\n\tBody: LayerCardBody,\n\tWell: LayerCardWell,\n\tFooter: LayerCardFooter,\n\tLoading: LayerCardLoading,\n\tEmpty: LayerCardEmpty,\n});\n"],"mappings":";;;;;;;;AAeA,IAAM,IAAe,GAAG,EAAgB,4DAClC,IAAkB;CACvB,MAAM;CACN,IAAI;CACJ,IAAI;CACJ,IAAI;AACL;AA2DA,SAAS,EAAU,GAAmE;CACrF,OAAO,EAAe,CAAK;AAC5B;AAEA,SAAS,EAAQ,GAAqB,GAA4C;CACjF,OAAO,EAAS,QAAQ,CAAQ,CAAC,CAAC,MAAM,MAClC,EAAU,CAAK,IAGhB,EAAM,EAAM,IAAI,IACZ,KAEJ,EAAM,SAAS,KACX,EAAQ,EAAM,MAAM,UAAU,CAAK,IANnC,EASR;AACF;AAEA,SAAS,EAAgB,GAAqB,GAA6B;CAI1E,OAHK,IAGE,EAAS,IAAI,IAAW,MAAU;EACxC,IAAI,CAAC,EAAU,CAAK,GACnB,OAAO;EAER,IAAI,EAAM,SAAS,GAClB,OAAO,EAAa,GAAO,EAC1B,UAAU,EAAgB,EAAM,MAAM,UAAU,CAAO,EACxD,CAAC;EAEF,IAAI,EAAM,SAAS,KAAmB,EAAM,SAAS,GAAoB;GACxE,IAAM,IAAQ;GACd,OAAO,EAAa,GAAO,EAC1B,WAAW,EAAG,EAAM,MAAM,WAAW,+BAA+B,EACrE,CAAC;EACF;EACA,OAAO;CACR,CAAC,IAlBO;AAmBT;AAEA,IAAM,IAAgB,GACpB,EAAE,cAAW,aAAU,cAAW,IAAO,aAAU,MAAM,GAAG,KAAS,MAAQ;CAC7E,IAAM,IAAa,EAAQ,IAAW,MAAS,EAAiB,IAAI,CAAI,CAAC,GACnE,IAAU,EACf,IACC,MAAS,MAAS,KAAiB,MAAS,CAC9C,GAEM,IADU,EAAQ,IAAW,MAAS,MAAS,CAC/B,KAAW,CAAC;CAClC,OACC,kBAAC,OAAD;EACM;EACL,uBAAoB;EACpB,WAAW,EACV,GACA,IAAa,yBAAyB,EAAgB,IACtD,KAAY,gCACZ,CACD;EACA,GAAI;EAEH,UAAA,EAAgB,GAAU,CAAa;CACpC,CAAA;AAEP,CACD;AACA,EAAc,cAAc;AAE5B,SAAS,EAAgB,EAAE,cAAW,GAAG,KAAgC;CACxE,OACC,kBAAC,OAAD;EACC,WAAW,EACV,yFACA,CACD;EACA,GAAI;CACJ,CAAA;AAEH;AACA,EAAgB,cAAc;AAE9B,SAAS,EAAc,EAAE,cAAW,GAAG,KAAgC;CACtE,OAAO,kBAAC,OAAD;EAAK,WAAW,EAAG,eAAe,CAAS;EAAG,GAAI;CAAQ,CAAA;AAClE;AACA,EAAc,cAAc;AAE5B,SAAS,EAAc,EAAE,cAAW,cAAW,IAAO,GAAG,KAA6B;CACrF,OACC,kBAAC,OAAD;EACC,uBAAoB;EACpB,WAAW,EAAG,eAAe,KAAY,gCAAgC,CAAS;EAClF,GAAI;CACJ,CAAA;AAEH;AACA,EAAc,cAAc;AAE5B,SAAS,EAAiB,GAA2B;CACpD,OAAO,kBAAC,GAAD,EAAe,GAAI,EAAQ,CAAA;AACnC;AACA,EAAiB,cAAc;AAE/B,SAAS,EAAmB,GAA8B;CACzD,OAAO,kBAAC,GAAD,EAAiB,GAAI,EAAQ,CAAA;AACrC;AACA,EAAmB,cAAc;AAEjC,SAAS,EAAgB,EAAE,cAAW,GAAG,KAAgC;CACxE,OACC,kBAAC,OAAD;EACC,WAAW,EACV,yFACA,CACD;EACA,GAAI;CACJ,CAAA;AAEH;AACA,EAAgB,cAAc;AAE9B,SAAS,EAAiB,EAAE,WAAQ,WAAW,cAAW,GAAG,KAAgC;CAC5F,OACC,kBAAC,OAAD;EAAK,MAAK;EAAS,cAAY;EAAO,WAAW,EAAG,iBAAiB,CAAS;EAAG,GAAI;EAArF,UAAA;GACC,kBAAC,GAAD;IAAc,UAAU;IAAK,UAAU;GAAM,CAAA;GAC7C,kBAAC,GAAD;IAAc,UAAU;IAAI,UAAU;GAAK,CAAA;GAC3C,kBAAC,GAAD;IAAc,UAAU;IAAI,UAAU;GAAK,CAAA;EACvC;;AAEP;AACA,EAAiB,cAAc;AAE/B,SAAS,EAAe,EAAE,WAAQ,cAAc,cAAW,GAAG,KAA8B;CAC3F,OAAO,kBAAC,GAAD;EAAc;EAAO,WAAW,EAAG,OAAO,CAAS;EAAG,GAAI;CAAQ,CAAA;AAC1E;AACA,EAAe,cAAc;AAE7B,IAAM,oBAAmB,IAAI,IAAa;CACzC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD,CAAC,GAEY,IAAY,OAAO,OAAO,GAAe;CACrD,SAAS;CACT,WAAW;CACX,QAAQ;CACR,MAAM;CACN,MAAM;CACN,QAAQ;CACR,SAAS;CACT,OAAO;AACR,CAAC"}
@@ -3,7 +3,7 @@ export interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {
3
3
  /**
4
4
  * Minimum width percentage used for deterministic width computation.
5
5
  *
6
- * Note: Sorted with maxWidth to compute the midpoint width percentage.
6
+ * Note: Averaged with maxWidth to compute the midpoint width percentage.
7
7
  *
8
8
  * @default 30
9
9
  */
@@ -11,7 +11,7 @@ export interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {
11
11
  /**
12
12
  * Maximum width percentage used for deterministic width computation.
13
13
  *
14
- * Note: Sorted with minWidth to compute the midpoint width percentage.
14
+ * Note: Averaged with minWidth to compute the midpoint width percentage.
15
15
  *
16
16
  * @default 100
17
17
  */
@@ -4,7 +4,7 @@ import { jsx as t } from "react/jsx-runtime";
4
4
  //#region src/components/skeleton-line.tsx
5
5
  function n({ className: n, minWidth: r = 30, maxWidth: i = 100, height: a, style: o, ...s }) {
6
6
  let c = {
7
- width: `${(Math.min(r, i) + Math.max(r, i)) / 2}%`,
7
+ width: `${(r + i) / 2}%`,
8
8
  ...a === void 0 ? {} : { height: a },
9
9
  ...o
10
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton-line.js","names":[],"sources":["../../src/components/skeleton-line.tsx"],"sourcesContent":["import type { CSSProperties, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {\n\t/**\n\t * Minimum width percentage used for deterministic width computation.\n\t *\n\t * Note: Sorted with maxWidth to compute the midpoint width percentage.\n\t *\n\t * @default 30\n\t */\n\tminWidth?: number;\n\n\t/**\n\t * Maximum width percentage used for deterministic width computation.\n\t *\n\t * Note: Sorted with minWidth to compute the midpoint width percentage.\n\t *\n\t * @default 100\n\t */\n\tmaxWidth?: number;\n\n\t/**\n\t * Explicit height of the skeleton line in pixels.\n\t *\n\t * Note: When omitted, default height is governed by CSS class tokens (h-2).\n\t */\n\theight?: number;\n}\n\nexport function SkeletonLine({\n\tclassName,\n\tminWidth = 30,\n\tmaxWidth = 100,\n\theight,\n\tstyle,\n\t...props\n}: SkeletonLineProps) {\n\tconst low = Math.min(minWidth, maxWidth);\n\tconst high = Math.max(minWidth, maxWidth);\n\tconst width = (low + high) / 2;\n\tconst lineStyle: CSSProperties = {\n\t\twidth: `${width}%`,\n\t\t...(height !== undefined ? { height } : {}),\n\t\t...style,\n\t};\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"relative h-2 overflow-hidden rounded-sm bg-basalt-muted\", className)}\n\t\t\tstyle={lineStyle}\n\t\t\taria-hidden=\"true\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"pointer-events-none absolute inset-0 animate-basalt-shimmer bg-gradient-to-r from-transparent via-black/10 to-transparent motion-reduce:animate-none\" />\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;AA8BA,SAAgB,EAAa,EAC5B,cACA,cAAW,IACX,cAAW,KACX,WACA,UACA,GAAG,KACkB;CAIrB,IAAM,IAA2B;EAChC,OAAO,IAJI,KAAK,IAAI,GAAU,CAEhB,IADF,KAAK,IAAI,GAAU,CACX,KAAQ,EAEZ;EAChB,GAAI,MAAW,KAAA,IAAyB,CAAC,IAAd,EAAE,UAAO;EACpC,GAAG;CACJ;CACA,OACC,kBAAC,OAAD;EACC,WAAW,EAAG,2DAA2D,CAAS;EAClF,OAAO;EACP,eAAY;EACZ,GAAI;EAEJ,UAAA,kBAAC,QAAD,EAAM,WAAU,uJAAwJ,CAAA;CACpK,CAAA;AAEP"}
1
+ {"version":3,"file":"skeleton-line.js","names":[],"sources":["../../src/components/skeleton-line.tsx"],"sourcesContent":["import type { CSSProperties, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {\n\t/**\n\t * Minimum width percentage used for deterministic width computation.\n\t *\n\t * Note: Averaged with maxWidth to compute the midpoint width percentage.\n\t *\n\t * @default 30\n\t */\n\tminWidth?: number;\n\n\t/**\n\t * Maximum width percentage used for deterministic width computation.\n\t *\n\t * Note: Averaged with minWidth to compute the midpoint width percentage.\n\t *\n\t * @default 100\n\t */\n\tmaxWidth?: number;\n\n\t/**\n\t * Explicit height of the skeleton line in pixels.\n\t *\n\t * Note: When omitted, default height is governed by CSS class tokens (h-2).\n\t */\n\theight?: number;\n}\n\nexport function SkeletonLine({\n\tclassName,\n\tminWidth = 30,\n\tmaxWidth = 100,\n\theight,\n\tstyle,\n\t...props\n}: SkeletonLineProps) {\n\tconst width = (minWidth + maxWidth) / 2;\n\tconst lineStyle: CSSProperties = {\n\t\twidth: `${width}%`,\n\t\t...(height !== undefined ? { height } : {}),\n\t\t...style,\n\t};\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"relative h-2 overflow-hidden rounded-sm bg-basalt-muted\", className)}\n\t\t\tstyle={lineStyle}\n\t\t\taria-hidden=\"true\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"pointer-events-none absolute inset-0 animate-basalt-shimmer bg-gradient-to-r from-transparent via-black/10 to-transparent motion-reduce:animate-none\" />\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;AA8BA,SAAgB,EAAa,EAC5B,cACA,cAAW,IACX,cAAW,KACX,WACA,UACA,GAAG,KACkB;CAErB,IAAM,IAA2B;EAChC,OAAO,IAFO,IAAW,KAAY,EAErB;EAChB,GAAI,MAAW,KAAA,IAAyB,CAAC,IAAd,EAAE,UAAO;EACpC,GAAG;CACJ;CACA,OACC,kBAAC,OAAD;EACC,WAAW,EAAG,2DAA2D,CAAS;EAClF,OAAO;EACP,eAAY;EACZ,GAAI;EAEJ,UAAA,kBAAC,QAAD,EAAM,WAAU,uJAAwJ,CAAA;CACpK,CAAA;AAEP"}
@@ -2,81 +2,49 @@
2
2
  import { cn as e } from "../utils/cn.js";
3
3
  import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
4
4
  import { FOCUS_RING as n } from "./overlay.js";
5
- import * as r from "react";
6
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
- import * as o from "@radix-ui/react-switch";
5
+ import { useCheckableGroup as r } from "../utils/use-checkable-group.js";
6
+ import * as i from "react";
7
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
8
+ import * as s from "@radix-ui/react-switch";
8
9
  //#region src/components/switch.tsx
9
- var s = r.createContext(null);
10
- function c(e, t, n) {
10
+ var c = i.createContext(null);
11
+ function l(e, t, n) {
11
12
  return n ? e.includes(t) ? e : [...e, t] : e.filter((e) => e !== t);
12
13
  }
13
- var l = r.forwardRef(({ className: r, size: a = "default", ...s }, c) => /* @__PURE__ */ i(o.Root, {
14
- className: e(t, "peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors data-[state=checked]:bg-basalt-primary data-[state=unchecked]:bg-basalt-input disabled:cursor-not-allowed disabled:opacity-50", n, a === "sm" ? "h-4 w-7" : "h-6 w-11", r),
15
- ...s,
14
+ var u = i.forwardRef(({ className: r, size: i = "default", ...o }, c) => /* @__PURE__ */ a(s.Root, {
15
+ className: e(t, "peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors data-[state=checked]:bg-basalt-primary data-[state=unchecked]:bg-basalt-input disabled:cursor-not-allowed disabled:opacity-50", n, i === "sm" ? "h-4 w-7" : "h-6 w-11", r),
16
+ ...o,
16
17
  ref: c,
17
- children: /* @__PURE__ */ i(o.Thumb, { className: e("pointer-events-none block rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0", a === "sm" ? "h-3 w-3 data-[state=checked]:translate-x-3" : "h-5 w-5 data-[state=checked]:translate-x-5") })
18
+ children: /* @__PURE__ */ a(s.Thumb, { className: e("pointer-events-none block rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0", i === "sm" ? "h-3 w-3 data-[state=checked]:translate-x-3" : "h-5 w-5 data-[state=checked]:translate-x-5") })
18
19
  }));
19
- l.displayName = o.Root.displayName;
20
- var u = r.forwardRef(({ className: t, value: n, defaultValue: o, onValueChange: c, error: l, disabled: u = !1, children: d, "aria-describedby": f, "aria-invalid": p, ...m }, h) => {
21
- let g = r.useId(), _ = r.useRef(null), [v, y] = r.useState(o ?? []), b = n ?? v, x = !!l, S = `${g}-error`, C = [x ? S : null, f].filter(Boolean).join(" ") || void 0, w = r.useRef(null), T = r.useCallback((e) => {
22
- let t = w.current;
23
- t && t.eventPhase !== Event.NONE || (n === void 0 && y(e), c?.(e));
24
- }, [c, n]), E = r.useCallback((e) => {
25
- if (_.current = e, h) {
26
- if (typeof h == "function") {
27
- let t = h(e);
28
- return typeof t == "function" ? () => {
29
- _.current = null, t();
30
- } : () => {
31
- _.current = null, h(null);
32
- };
33
- }
34
- return h.current = e, () => {
35
- _.current = null, h.current = null;
36
- };
37
- }
38
- }, [h]), D = m.form, O = r.useRef({
39
- defaultValue: o,
40
- value: n
20
+ u.displayName = s.Root.displayName;
21
+ var d = i.forwardRef(({ className: t, value: n, defaultValue: i, onValueChange: s, error: l, disabled: u = !1, children: d, "aria-describedby": f, "aria-invalid": p, ...m }, h) => {
22
+ let g = r({
23
+ value: n,
24
+ defaultValue: i,
25
+ onValueChange: s,
26
+ error: l,
27
+ describedBy: f,
28
+ ariaInvalid: p,
29
+ form: m.form,
30
+ ref: h
41
31
  });
42
- return r.useEffect(() => {
43
- O.current = {
44
- defaultValue: o,
45
- value: n
46
- };
47
- }), r.useEffect(() => {
48
- let e = _.current?.form;
49
- if (!e || D && e.id !== D) return;
50
- let t = !1, n = /* @__PURE__ */ new Set(), r = (e) => {
51
- w.current = e;
52
- let r = setTimeout(() => {
53
- if (n.delete(r), t || e.defaultPrevented) return;
54
- let i = O.current;
55
- i.value === void 0 && y(i.defaultValue ?? []);
56
- }, 0);
57
- n.add(r);
58
- };
59
- return e.addEventListener("reset", r, !0), () => {
60
- t = !0, w.current = null;
61
- for (let e of n) clearTimeout(e);
62
- n.clear(), e.removeEventListener("reset", r, !0);
63
- };
64
- }, [D]), /* @__PURE__ */ i(s.Provider, {
32
+ return /* @__PURE__ */ a(c.Provider, {
65
33
  value: {
66
- value: b,
67
- setValue: T,
34
+ value: g.current,
35
+ setValue: g.setValue,
68
36
  disabled: u,
69
- invalid: x
37
+ invalid: g.invalid
70
38
  },
71
- children: /* @__PURE__ */ a("fieldset", {
72
- ref: E,
39
+ children: /* @__PURE__ */ o("fieldset", {
40
+ ref: g.setRefs,
73
41
  ...m,
74
42
  disabled: u,
75
- "aria-invalid": x ? !0 : p,
76
- "aria-describedby": C,
43
+ "aria-invalid": g.ariaInvalid,
44
+ "aria-describedby": g.mergedDescribedBy,
77
45
  className: e("flex flex-col gap-2", t),
78
- children: [d, x ? /* @__PURE__ */ i("p", {
79
- id: S,
46
+ children: [d, g.invalid ? /* @__PURE__ */ a("p", {
47
+ id: g.errorId,
80
48
  className: "text-xs text-basalt-destructive",
81
49
  role: "alert",
82
50
  children: l
@@ -84,42 +52,42 @@ var u = r.forwardRef(({ className: t, value: n, defaultValue: o, onValueChange:
84
52
  })
85
53
  });
86
54
  });
87
- u.displayName = "Switch.Group";
88
- var d = r.forwardRef(({ className: t, ...n }, r) => /* @__PURE__ */ i("legend", {
55
+ d.displayName = "Switch.Group";
56
+ var f = i.forwardRef(({ className: t, ...n }, r) => /* @__PURE__ */ a("legend", {
89
57
  ref: r,
90
58
  className: e("text-sm font-medium text-basalt-foreground", t),
91
59
  ...n
92
60
  }));
93
- d.displayName = "Switch.Legend";
94
- var f = r.forwardRef(({ className: e, value: t, children: n, disabled: o, size: u, id: d, ...f }, p) => {
95
- let m = r.useContext(s), h = m != null, g = r.useId(), _ = d ?? g, v = h ? m.value.includes(t) : void 0, y = /* @__PURE__ */ i(l, {
61
+ f.displayName = "Switch.Legend";
62
+ var p = i.forwardRef(({ className: e, value: t, children: n, disabled: r, size: s, id: d, ...f }, p) => {
63
+ let m = i.useContext(c), h = m != null, g = i.useId(), _ = d ?? g, v = h ? m.value.includes(t) : void 0, y = /* @__PURE__ */ a(u, {
96
64
  ref: p,
97
65
  ...f,
98
66
  id: _,
99
67
  value: t,
100
- size: u,
68
+ size: s,
101
69
  checked: v,
102
70
  defaultChecked: h ? v : void 0,
103
- disabled: o || m?.disabled,
71
+ disabled: r || m?.disabled,
104
72
  "aria-invalid": m?.invalid || void 0,
105
73
  className: e,
106
74
  onCheckedChange: (e) => {
107
- h && m.setValue(c(m.value, t, e));
75
+ h && m.setValue(l(m.value, t, e));
108
76
  }
109
77
  });
110
- return n == null ? y : /* @__PURE__ */ a("label", {
78
+ return n == null ? y : /* @__PURE__ */ o("label", {
111
79
  htmlFor: _,
112
80
  className: "flex items-center gap-2 text-sm text-basalt-foreground",
113
81
  children: [y, n]
114
82
  });
115
83
  });
116
- f.displayName = "Switch.Item";
117
- var p = Object.assign(l, {
118
- Group: u,
119
- Legend: d,
120
- Item: f
84
+ p.displayName = "Switch.Item";
85
+ var m = Object.assign(u, {
86
+ Group: d,
87
+ Legend: f,
88
+ Item: p
121
89
  });
122
90
  //#endregion
123
- export { p as Switch };
91
+ export { m as Switch };
124
92
 
125
93
  //# sourceMappingURL=switch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"switch.js","names":[],"sources":["../../src/components/switch.tsx"],"sourcesContent":["import * as SwitchPrimitives from \"@radix-ui/react-switch\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { FOCUS_RING } from \"./overlay\";\n\ntype SwitchGroupContextValue = {\n\tvalue: string[];\n\tsetValue: (next: string[]) => void;\n\tdisabled: boolean;\n\tinvalid: boolean;\n};\n\nconst SwitchGroupContext = React.createContext<SwitchGroupContextValue | null>(null);\n\nfunction nextSwitchGroupValue(current: string[], itemValue: string, checked: boolean): string[] {\n\tif (checked) {\n\t\treturn current.includes(itemValue) ? current : [...current, itemValue];\n\t}\n\treturn current.filter((entry) => entry !== itemValue);\n}\n\nexport type SwitchProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>,\n\t\"checked\"\n> & {\n\t/**\n\t * The controlled checked state of the switch.\n\t */\n\tchecked?: boolean;\n\t/**\n\t * The visual size of the switch.\n\t * @default default\n\t */\n\tsize?: \"default\" | \"sm\";\n};\n\nexport type SwitchGroupProps = Omit<\n\tReact.ComponentPropsWithoutRef<\"fieldset\">,\n\t\"onChange\" | \"defaultValue\" | \"disabled\"\n> & {\n\t/**\n\t * The controlled selected values.\n\t */\n\tvalue?: string[];\n\t/**\n\t * The initially selected values.\n\t */\n\tdefaultValue?: string[];\n\t/**\n\t * Called when the selected values change.\n\t */\n\tonValueChange?: (value: string[]) => void;\n\t/**\n\t * Marks the group invalid and shows alert copy.\n\t */\n\terror?: React.ReactNode;\n\t/**\n\t * Disable every item in the group.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nexport type SwitchLegendProps = React.ComponentPropsWithoutRef<\"legend\">;\n\nexport type SwitchItemProps = Omit<\n\tSwitchProps,\n\t\"checked\" | \"defaultChecked\" | \"onCheckedChange\" | \"value\"\n> & {\n\t/**\n\t * The value stored in the group when this item is on.\n\t */\n\tvalue: string;\n};\n\nconst SwitchRoot = React.forwardRef<React.ElementRef<typeof SwitchPrimitives.Root>, SwitchProps>(\n\t({ className, size = \"default\", ...props }, ref) => (\n\t\t<SwitchPrimitives.Root\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors data-[state=checked]:bg-basalt-primary data-[state=unchecked]:bg-basalt-input disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tFOCUS_RING,\n\t\t\t\tsize === \"sm\" ? \"h-4 w-7\" : \"h-6 w-11\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t\tref={ref}\n\t\t>\n\t\t\t<SwitchPrimitives.Thumb\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"pointer-events-none block rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0\",\n\t\t\t\t\tsize === \"sm\"\n\t\t\t\t\t\t? \"h-3 w-3 data-[state=checked]:translate-x-3\"\n\t\t\t\t\t\t: \"h-5 w-5 data-[state=checked]:translate-x-5\",\n\t\t\t\t)}\n\t\t\t/>\n\t\t</SwitchPrimitives.Root>\n\t),\n);\nSwitchRoot.displayName = SwitchPrimitives.Root.displayName;\n\nconst SwitchGroup = React.forwardRef<HTMLFieldSetElement, SwitchGroupProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\n\t\t\terror,\n\t\t\tdisabled = false,\n\t\t\tchildren,\n\t\t\t\"aria-describedby\": describedBy,\n\t\t\t\"aria-invalid\": ariaInvalid,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst generatedId = React.useId();\n\t\tconst nodeRef = React.useRef<HTMLFieldSetElement | null>(null);\n\t\tconst [uncontrolled, setUncontrolled] = React.useState(defaultValue ?? []);\n\t\tconst current = value ?? uncontrolled;\n\t\tconst invalid = Boolean(error);\n\t\tconst errorId = `${generatedId}-error`;\n\t\tconst mergedDescribedBy =\n\t\t\t[invalid ? errorId : null, describedBy].filter(Boolean).join(\" \") || undefined;\n\t\tconst resetEventRef = React.useRef<Event | null>(null);\n\t\tconst setValue = React.useCallback(\n\t\t\t(next: string[]) => {\n\t\t\t\tconst activeReset = resetEventRef.current;\n\t\t\t\tif (activeReset && activeReset.eventPhase !== Event.NONE) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tsetUncontrolled(next);\n\t\t\t\t}\n\t\t\t\tonValueChange?.(next);\n\t\t\t},\n\t\t\t[onValueChange, value],\n\t\t);\n\t\tconst setRefs = React.useCallback(\n\t\t\t(node: HTMLFieldSetElement | null) => {\n\t\t\t\tnodeRef.current = node;\n\t\t\t\tif (!ref) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (typeof ref === \"function\") {\n\t\t\t\t\tconst cleanup = (ref as React.RefCallback<HTMLFieldSetElement>)(node);\n\t\t\t\t\tif (typeof cleanup === \"function\") {\n\t\t\t\t\t\treturn () => {\n\t\t\t\t\t\t\tnodeRef.current = null;\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\treturn () => {\n\t\t\t\t\t\tnodeRef.current = null;\n\t\t\t\t\t\tref(null);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t(ref as React.RefObject<HTMLFieldSetElement | null>).current = node;\n\t\t\t\treturn () => {\n\t\t\t\t\tnodeRef.current = null;\n\t\t\t\t\t(ref as React.RefObject<HTMLFieldSetElement | null>).current = null;\n\t\t\t\t};\n\t\t\t},\n\t\t\t[ref],\n\t\t);\n\t\tconst formAttr = props.form;\n\t\tconst latestConfigRef = React.useRef({\n\t\t\tdefaultValue,\n\t\t\tvalue,\n\t\t});\n\t\tReact.useEffect(() => {\n\t\t\tlatestConfigRef.current = {\n\t\t\t\tdefaultValue,\n\t\t\t\tvalue,\n\t\t\t};\n\t\t});\n\n\t\tReact.useEffect(() => {\n\t\t\tconst form = nodeRef.current?.form;\n\t\t\tif (!form || (formAttr && form.id !== formAttr)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet disposed = false;\n\t\t\tconst timers = new Set<ReturnType<typeof setTimeout>>();\n\t\t\tconst onReset = (event: Event) => {\n\t\t\t\tresetEventRef.current = event;\n\t\t\t\tconst timer = setTimeout(() => {\n\t\t\t\t\ttimers.delete(timer);\n\t\t\t\t\tif (disposed || event.defaultPrevented) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst cfg = latestConfigRef.current;\n\t\t\t\t\tif (cfg.value === undefined) {\n\t\t\t\t\t\tsetUncontrolled(cfg.defaultValue ?? []);\n\t\t\t\t\t}\n\t\t\t\t}, 0);\n\t\t\t\ttimers.add(timer);\n\t\t\t};\n\t\t\tform.addEventListener(\"reset\", onReset, true);\n\t\t\treturn () => {\n\t\t\t\tdisposed = true;\n\t\t\t\tresetEventRef.current = null;\n\t\t\t\tfor (const timer of timers) {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t}\n\t\t\t\ttimers.clear();\n\t\t\t\tform.removeEventListener(\"reset\", onReset, true);\n\t\t\t};\n\t\t}, [formAttr]);\n\t\treturn (\n\t\t\t<SwitchGroupContext.Provider value={{ value: current, setValue, disabled, invalid }}>\n\t\t\t\t<fieldset\n\t\t\t\t\tref={setRefs}\n\t\t\t\t\t{...props}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\taria-invalid={invalid ? true : ariaInvalid}\n\t\t\t\t\taria-describedby={mergedDescribedBy}\n\t\t\t\t\tclassName={cn(\"flex flex-col gap-2\", className)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t\t{invalid ? (\n\t\t\t\t\t\t<p id={errorId} className=\"text-xs text-basalt-destructive\" role=\"alert\">\n\t\t\t\t\t\t\t{error}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</fieldset>\n\t\t\t</SwitchGroupContext.Provider>\n\t\t);\n\t},\n);\nSwitchGroup.displayName = \"Switch.Group\";\n\nconst SwitchLegend = React.forwardRef<HTMLLegendElement, SwitchLegendProps>(\n\t({ className, ...props }, ref) => (\n\t\t<legend\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"text-sm font-medium text-basalt-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nSwitchLegend.displayName = \"Switch.Legend\";\n\nconst SwitchItem = React.forwardRef<\n\tReact.ElementRef<typeof SwitchPrimitives.Root>,\n\tSwitchItemProps\n>(({ className, value, children, disabled, size, id, ...props }, ref) => {\n\tconst group = React.useContext(SwitchGroupContext);\n\tconst grouped = group != null;\n\tconst generatedId = React.useId();\n\tconst controlId = id ?? generatedId;\n\tconst isChecked = grouped ? group.value.includes(value) : undefined;\n\tconst box = (\n\t\t<SwitchRoot\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t\tid={controlId}\n\t\t\tvalue={value}\n\t\t\tsize={size}\n\t\t\tchecked={isChecked}\n\t\t\tdefaultChecked={grouped ? isChecked : undefined}\n\t\t\tdisabled={disabled || group?.disabled}\n\t\t\taria-invalid={group?.invalid || undefined}\n\t\t\tclassName={className}\n\t\t\tonCheckedChange={(next) => {\n\t\t\t\tif (grouped) {\n\t\t\t\t\tgroup.setValue(nextSwitchGroupValue(group.value, value, next));\n\t\t\t\t}\n\t\t\t}}\n\t\t/>\n\t);\n\tif (children == null) {\n\t\treturn box;\n\t}\n\treturn (\n\t\t<label htmlFor={controlId} className=\"flex items-center gap-2 text-sm text-basalt-foreground\">\n\t\t\t{box}\n\t\t\t{children}\n\t\t</label>\n\t);\n});\nSwitchItem.displayName = \"Switch.Item\";\n\nexport const Switch = Object.assign(SwitchRoot, {\n\tGroup: SwitchGroup,\n\tLegend: SwitchLegend,\n\tItem: SwitchItem,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"switch.js","names":[],"sources":["../../src/components/switch.tsx"],"sourcesContent":["import * as SwitchPrimitives from \"@radix-ui/react-switch\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { useCheckableGroup } from \"../utils/use-checkable-group\";\nimport { FOCUS_RING } from \"./overlay\";\n\ntype SwitchGroupContextValue = {\n\tvalue: string[];\n\tsetValue: (next: string[]) => void;\n\tdisabled: boolean;\n\tinvalid: boolean;\n};\n\nconst SwitchGroupContext = React.createContext<SwitchGroupContextValue | null>(null);\n\nfunction nextSwitchGroupValue(current: string[], itemValue: string, checked: boolean): string[] {\n\tif (checked) {\n\t\treturn current.includes(itemValue) ? current : [...current, itemValue];\n\t}\n\treturn current.filter((entry) => entry !== itemValue);\n}\n\nexport type SwitchProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>,\n\t\"checked\"\n> & {\n\t/**\n\t * The controlled checked state of the switch.\n\t */\n\tchecked?: boolean;\n\t/**\n\t * The visual size of the switch.\n\t * @default default\n\t */\n\tsize?: \"default\" | \"sm\";\n};\n\nexport type SwitchGroupProps = Omit<\n\tReact.ComponentPropsWithoutRef<\"fieldset\">,\n\t\"onChange\" | \"defaultValue\" | \"disabled\"\n> & {\n\t/**\n\t * The controlled selected values.\n\t */\n\tvalue?: string[];\n\t/**\n\t * The initially selected values.\n\t */\n\tdefaultValue?: string[];\n\t/**\n\t * Called when the selected values change.\n\t */\n\tonValueChange?: (value: string[]) => void;\n\t/**\n\t * Marks the group invalid and shows alert copy.\n\t */\n\terror?: React.ReactNode;\n\t/**\n\t * Disable every item in the group.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nexport type SwitchLegendProps = React.ComponentPropsWithoutRef<\"legend\">;\n\nexport type SwitchItemProps = Omit<\n\tSwitchProps,\n\t\"checked\" | \"defaultChecked\" | \"onCheckedChange\" | \"value\"\n> & {\n\t/**\n\t * The value stored in the group when this item is on.\n\t */\n\tvalue: string;\n};\n\nconst SwitchRoot = React.forwardRef<React.ElementRef<typeof SwitchPrimitives.Root>, SwitchProps>(\n\t({ className, size = \"default\", ...props }, ref) => (\n\t\t<SwitchPrimitives.Root\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors data-[state=checked]:bg-basalt-primary data-[state=unchecked]:bg-basalt-input disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tFOCUS_RING,\n\t\t\t\tsize === \"sm\" ? \"h-4 w-7\" : \"h-6 w-11\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t\tref={ref}\n\t\t>\n\t\t\t<SwitchPrimitives.Thumb\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"pointer-events-none block rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0\",\n\t\t\t\t\tsize === \"sm\"\n\t\t\t\t\t\t? \"h-3 w-3 data-[state=checked]:translate-x-3\"\n\t\t\t\t\t\t: \"h-5 w-5 data-[state=checked]:translate-x-5\",\n\t\t\t\t)}\n\t\t\t/>\n\t\t</SwitchPrimitives.Root>\n\t),\n);\nSwitchRoot.displayName = SwitchPrimitives.Root.displayName;\n\nconst SwitchGroup = React.forwardRef<HTMLFieldSetElement, SwitchGroupProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\n\t\t\terror,\n\t\t\tdisabled = false,\n\t\t\tchildren,\n\t\t\t\"aria-describedby\": describedBy,\n\t\t\t\"aria-invalid\": ariaInvalid,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst group = useCheckableGroup({\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\n\t\t\terror,\n\t\t\tdescribedBy,\n\t\t\tariaInvalid,\n\t\t\tform: props.form,\n\t\t\tref,\n\t\t});\n\t\treturn (\n\t\t\t<SwitchGroupContext.Provider\n\t\t\t\tvalue={{ value: group.current, setValue: group.setValue, disabled, invalid: group.invalid }}\n\t\t\t>\n\t\t\t\t<fieldset\n\t\t\t\t\tref={group.setRefs}\n\t\t\t\t\t{...props}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\taria-invalid={group.ariaInvalid}\n\t\t\t\t\taria-describedby={group.mergedDescribedBy}\n\t\t\t\t\tclassName={cn(\"flex flex-col gap-2\", className)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t\t{group.invalid ? (\n\t\t\t\t\t\t<p id={group.errorId} className=\"text-xs text-basalt-destructive\" role=\"alert\">\n\t\t\t\t\t\t\t{error}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</fieldset>\n\t\t\t</SwitchGroupContext.Provider>\n\t\t);\n\t},\n);\nSwitchGroup.displayName = \"Switch.Group\";\n\nconst SwitchLegend = React.forwardRef<HTMLLegendElement, SwitchLegendProps>(\n\t({ className, ...props }, ref) => (\n\t\t<legend\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"text-sm font-medium text-basalt-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nSwitchLegend.displayName = \"Switch.Legend\";\n\nconst SwitchItem = React.forwardRef<\n\tReact.ElementRef<typeof SwitchPrimitives.Root>,\n\tSwitchItemProps\n>(({ className, value, children, disabled, size, id, ...props }, ref) => {\n\tconst group = React.useContext(SwitchGroupContext);\n\tconst grouped = group != null;\n\tconst generatedId = React.useId();\n\tconst controlId = id ?? generatedId;\n\tconst isChecked = grouped ? group.value.includes(value) : undefined;\n\tconst box = (\n\t\t<SwitchRoot\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t\tid={controlId}\n\t\t\tvalue={value}\n\t\t\tsize={size}\n\t\t\tchecked={isChecked}\n\t\t\tdefaultChecked={grouped ? isChecked : undefined}\n\t\t\tdisabled={disabled || group?.disabled}\n\t\t\taria-invalid={group?.invalid || undefined}\n\t\t\tclassName={className}\n\t\t\tonCheckedChange={(next) => {\n\t\t\t\tif (grouped) {\n\t\t\t\t\tgroup.setValue(nextSwitchGroupValue(group.value, value, next));\n\t\t\t\t}\n\t\t\t}}\n\t\t/>\n\t);\n\tif (children == null) {\n\t\treturn box;\n\t}\n\treturn (\n\t\t<label htmlFor={controlId} className=\"flex items-center gap-2 text-sm text-basalt-foreground\">\n\t\t\t{box}\n\t\t\t{children}\n\t\t</label>\n\t);\n});\nSwitchItem.displayName = \"Switch.Item\";\n\nexport const Switch = Object.assign(SwitchRoot, {\n\tGroup: SwitchGroup,\n\tLegend: SwitchLegend,\n\tItem: SwitchItem,\n});\n"],"mappings":";;;;;;;;;AAcA,IAAM,IAAqB,EAAM,cAA8C,IAAI;AAEnF,SAAS,EAAqB,GAAmB,GAAmB,GAA4B;CAI/F,OAHI,IACI,EAAQ,SAAS,CAAS,IAAI,IAAU,CAAC,GAAG,GAAS,CAAS,IAE/D,EAAQ,QAAQ,MAAU,MAAU,CAAS;AACrD;AAwDA,IAAM,IAAa,EAAM,YACvB,EAAE,cAAW,UAAO,WAAW,GAAG,KAAS,MAC3C,kBAAC,EAAiB,MAAlB;CACC,WAAW,EACV,GACA,kPACA,GACA,MAAS,OAAO,YAAY,YAC5B,CACD;CACA,GAAI;CACC;CAEL,UAAA,kBAAC,EAAiB,OAAlB,EACC,WAAW,EACV,8HACA,MAAS,OACN,+CACA,4CACJ,EACA,CAAA;AACqB,CAAA,CAEzB;AACA,EAAW,cAAc,EAAiB,KAAK;AAE/C,IAAM,IAAc,EAAM,YAExB,EACC,cACA,UACA,iBACA,kBACA,UACA,cAAW,IACX,aACA,oBAAoB,GACpB,gBAAgB,GAChB,GAAG,KAEJ,MACI;CACJ,IAAM,IAAQ,EAAkB;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA,MAAM,EAAM;EACZ;CACD,CAAC;CACD,OACC,kBAAC,EAAmB,UAApB;EACC,OAAO;GAAE,OAAO,EAAM;GAAS,UAAU,EAAM;GAAU;GAAU,SAAS,EAAM;EAAQ;EAE1F,UAAA,kBAAC,YAAD;GACC,KAAK,EAAM;GACX,GAAI;GACM;GACV,gBAAc,EAAM;GACpB,oBAAkB,EAAM;GACxB,WAAW,EAAG,uBAAuB,CAAS;GAN/C,UAAA,CAQE,GACA,EAAM,UACN,kBAAC,KAAD;IAAG,IAAI,EAAM;IAAS,WAAU;IAAkC,MAAK;IACrE,UAAA;GACC,CAAA,IACA,IACK;;CACkB,CAAA;AAE/B,CACD;AACA,EAAY,cAAc;AAE1B,IAAM,IAAe,EAAM,YACzB,EAAE,cAAW,GAAG,KAAS,MACzB,kBAAC,UAAD;CACM;CACL,WAAW,EAAG,8CAA8C,CAAS;CACrE,GAAI;AACJ,CAAA,CAEH;AACA,EAAa,cAAc;AAE3B,IAAM,IAAa,EAAM,YAGtB,EAAE,cAAW,UAAO,aAAU,aAAU,SAAM,OAAI,GAAG,KAAS,MAAQ;CACxE,IAAM,IAAQ,EAAM,WAAW,CAAkB,GAC3C,IAAU,KAAS,MACnB,IAAc,EAAM,MAAM,GAC1B,IAAY,KAAM,GAClB,IAAY,IAAU,EAAM,MAAM,SAAS,CAAK,IAAI,KAAA,GACpD,IACL,kBAAC,GAAD;EACM;EACL,GAAI;EACJ,IAAI;EACG;EACD;EACN,SAAS;EACT,gBAAgB,IAAU,IAAY,KAAA;EACtC,UAAU,KAAY,GAAO;EAC7B,gBAAc,GAAO,WAAW,KAAA;EACrB;EACX,kBAAkB,MAAS;GAC1B,AAAI,KACH,EAAM,SAAS,EAAqB,EAAM,OAAO,GAAO,CAAI,CAAC;EAE/D;CACA,CAAA;CAKF,OAHI,KAAY,OACR,IAGP,kBAAC,SAAD;EAAO,SAAS;EAAW,WAAU;EAArC,UAAA,CACE,GACA,CACK;;AAET,CAAC;AACD,EAAW,cAAc;AAEzB,IAAa,IAAS,OAAO,OAAO,GAAY;CAC/C,OAAO;CACP,QAAQ;CACR,MAAM;AACP,CAAC"}