@combinedk/ui 3.0.0-beta.11

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 (96) hide show
  1. package/dist/index.cjs +1 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +19 -0
  4. package/dist/index10.cjs +2 -0
  5. package/dist/index10.cjs.map +1 -0
  6. package/dist/index10.js +289 -0
  7. package/dist/index10.js.map +1 -0
  8. package/dist/index11.cjs +2 -0
  9. package/dist/index11.cjs.map +1 -0
  10. package/dist/index11.js +52 -0
  11. package/dist/index11.js.map +1 -0
  12. package/dist/index12.cjs +2 -0
  13. package/dist/index12.cjs.map +1 -0
  14. package/dist/index12.js +133 -0
  15. package/dist/index12.js.map +1 -0
  16. package/dist/index13.cjs +2 -0
  17. package/dist/index13.cjs.map +1 -0
  18. package/dist/index13.js +150 -0
  19. package/dist/index13.js.map +1 -0
  20. package/dist/index14.cjs +2 -0
  21. package/dist/index14.cjs.map +1 -0
  22. package/dist/index14.js +100 -0
  23. package/dist/index14.js.map +1 -0
  24. package/dist/index15.cjs +2 -0
  25. package/dist/index15.cjs.map +1 -0
  26. package/dist/index15.js +35 -0
  27. package/dist/index15.js.map +1 -0
  28. package/dist/index16.cjs +2 -0
  29. package/dist/index16.cjs.map +1 -0
  30. package/dist/index16.js +330 -0
  31. package/dist/index16.js.map +1 -0
  32. package/dist/index17.cjs +2 -0
  33. package/dist/index17.cjs.map +1 -0
  34. package/dist/index17.js +114 -0
  35. package/dist/index17.js.map +1 -0
  36. package/dist/index18.cjs +2 -0
  37. package/dist/index18.cjs.map +1 -0
  38. package/dist/index18.js +110 -0
  39. package/dist/index18.js.map +1 -0
  40. package/dist/index19.cjs +2 -0
  41. package/dist/index19.cjs.map +1 -0
  42. package/dist/index19.js +24 -0
  43. package/dist/index19.js.map +1 -0
  44. package/dist/index2.cjs +2 -0
  45. package/dist/index2.cjs.map +1 -0
  46. package/dist/index2.js +90 -0
  47. package/dist/index2.js.map +1 -0
  48. package/dist/index3.cjs +2 -0
  49. package/dist/index3.cjs.map +1 -0
  50. package/dist/index3.js +71 -0
  51. package/dist/index3.js.map +1 -0
  52. package/dist/index4.cjs +2 -0
  53. package/dist/index4.cjs.map +1 -0
  54. package/dist/index4.js +32 -0
  55. package/dist/index4.js.map +1 -0
  56. package/dist/index5.cjs +2 -0
  57. package/dist/index5.cjs.map +1 -0
  58. package/dist/index5.js +27 -0
  59. package/dist/index5.js.map +1 -0
  60. package/dist/index6.cjs +2 -0
  61. package/dist/index6.cjs.map +1 -0
  62. package/dist/index6.js +23 -0
  63. package/dist/index6.js.map +1 -0
  64. package/dist/index7.cjs +2 -0
  65. package/dist/index7.cjs.map +1 -0
  66. package/dist/index7.js +82 -0
  67. package/dist/index7.js.map +1 -0
  68. package/dist/index8.cjs +2 -0
  69. package/dist/index8.cjs.map +1 -0
  70. package/dist/index8.js +93 -0
  71. package/dist/index8.js.map +1 -0
  72. package/dist/index9.cjs +2 -0
  73. package/dist/index9.cjs.map +1 -0
  74. package/dist/index9.js +99 -0
  75. package/dist/index9.js.map +1 -0
  76. package/dist/src/components/Badge.d.ts +9 -0
  77. package/dist/src/components/Button.d.ts +11 -0
  78. package/dist/src/components/Card.d.ts +9 -0
  79. package/dist/src/components/Checkbox.d.ts +22 -0
  80. package/dist/src/components/ConfirmDialog.d.ts +13 -0
  81. package/dist/src/components/DropdownMenu.d.ts +24 -0
  82. package/dist/src/components/EmptyState.d.ts +9 -0
  83. package/dist/src/components/Field.d.ts +24 -0
  84. package/dist/src/components/Input.d.ts +9 -0
  85. package/dist/src/components/Modal.d.ts +12 -0
  86. package/dist/src/components/PageHeader.d.ts +11 -0
  87. package/dist/src/components/PreviewBadge.d.ts +8 -0
  88. package/dist/src/components/Select.d.ts +32 -0
  89. package/dist/src/components/Skeleton.d.ts +21 -0
  90. package/dist/src/components/StatusPill.d.ts +7 -0
  91. package/dist/src/components/Table.d.ts +26 -0
  92. package/dist/src/components/Tag.d.ts +5 -0
  93. package/dist/src/components/Toast.d.ts +13 -0
  94. package/dist/src/index.d.ts +21 -0
  95. package/package.json +43 -0
  96. package/src/tokens.css +151 -0
@@ -0,0 +1,330 @@
1
+ import { useEffect as e, useRef as t, useState as n } from "react";
2
+ import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
3
+ import { createPortal as o } from "react-dom";
4
+ //#region src/components/Select.tsx
5
+ function s({ triggerContent: s, open: c, onOpen: l, triggerRef: u, children: d, minWidth: f = 200 }) {
6
+ let p = t(null), [m, h] = n({
7
+ top: 0,
8
+ left: 0,
9
+ width: 0
10
+ });
11
+ return e(() => {
12
+ if (!c) return;
13
+ let e = (e) => {
14
+ !p.current?.contains(e.target) && !u.current?.contains(e.target) && l();
15
+ }, t = (e) => {
16
+ e.key === "Escape" && l();
17
+ };
18
+ return document.addEventListener("mousedown", e), document.addEventListener("keydown", t), () => {
19
+ document.removeEventListener("mousedown", e), document.removeEventListener("keydown", t);
20
+ };
21
+ }, [c]), /* @__PURE__ */ a(r, { children: [/* @__PURE__ */ i("div", {
22
+ ref: u,
23
+ onClick: () => {
24
+ let e = u.current?.getBoundingClientRect();
25
+ e && (h({
26
+ top: e.bottom + window.scrollY + 4,
27
+ left: e.left + window.scrollX,
28
+ width: e.width
29
+ }), l());
30
+ },
31
+ style: { cursor: "pointer" },
32
+ children: s
33
+ }), c && o(/* @__PURE__ */ i("div", {
34
+ ref: p,
35
+ style: {
36
+ position: "absolute",
37
+ top: m.top,
38
+ left: m.left,
39
+ minWidth: Math.max(m.width, f),
40
+ background: "var(--c-surface)",
41
+ border: "1px solid var(--c-border)",
42
+ borderRadius: 8,
43
+ boxShadow: "0 4px 12px rgba(47,56,67,0.10)",
44
+ padding: 4,
45
+ zIndex: 1100,
46
+ maxHeight: 240,
47
+ overflowY: "auto"
48
+ },
49
+ children: d
50
+ }), document.body)] });
51
+ }
52
+ function c({ label: e, selected: t, onClick: n, checkbox: r }) {
53
+ return /* @__PURE__ */ a("div", {
54
+ onClick: n,
55
+ style: {
56
+ padding: "6px 10px",
57
+ borderRadius: 4,
58
+ cursor: "pointer",
59
+ fontFamily: "var(--font-sans)",
60
+ fontSize: 13,
61
+ color: "var(--c-text)",
62
+ display: "flex",
63
+ alignItems: "center",
64
+ gap: 8,
65
+ background: !r && t ? "#fff4d6" : "transparent"
66
+ },
67
+ onMouseEnter: (e) => {
68
+ e.currentTarget.style.background = !r && t ? "#fff4d6" : "var(--c-elevated)";
69
+ },
70
+ onMouseLeave: (e) => {
71
+ e.currentTarget.style.background = !r && t ? "#fff4d6" : "transparent";
72
+ },
73
+ children: [r ? /* @__PURE__ */ i("span", {
74
+ style: {
75
+ width: 14,
76
+ height: 14,
77
+ borderRadius: 3,
78
+ flexShrink: 0,
79
+ border: `1.5px solid ${t ? "var(--c-text)" : "var(--c-border-strong)"}`,
80
+ background: t ? "var(--c-text)" : "var(--c-surface)",
81
+ color: "#fff",
82
+ fontSize: 10,
83
+ display: "inline-flex",
84
+ alignItems: "center",
85
+ justifyContent: "center"
86
+ },
87
+ children: t ? "✓" : ""
88
+ }) : /* @__PURE__ */ i("span", {
89
+ style: {
90
+ width: 14,
91
+ color: "var(--c-amber)",
92
+ fontWeight: 700
93
+ },
94
+ children: t ? "✓" : ""
95
+ }), /* @__PURE__ */ i("span", { children: e })]
96
+ });
97
+ }
98
+ function l({ value: e, onChange: r, options: o, placeholder: l = "Select…", disabled: u }) {
99
+ let [d, f] = n(!1), p = t(null), m = o.map((e) => typeof e == "string" ? {
100
+ value: e,
101
+ label: e
102
+ } : e), h = m.find((t) => t.value === e);
103
+ return /* @__PURE__ */ i(s, {
104
+ triggerRef: p,
105
+ open: d,
106
+ onOpen: () => !u && f((e) => !e),
107
+ triggerContent: /* @__PURE__ */ a("div", {
108
+ style: {
109
+ display: "flex",
110
+ alignItems: "center",
111
+ gap: 8,
112
+ padding: "8px 12px",
113
+ background: "var(--c-surface)",
114
+ border: `1px solid ${d ? "var(--c-text)" : "var(--c-border)"}`,
115
+ borderRadius: 6,
116
+ fontSize: 13,
117
+ fontFamily: "var(--font-sans)",
118
+ color: h ? "var(--c-text)" : "var(--c-text-muted)",
119
+ boxShadow: d ? "0 0 0 3px rgba(47,56,67,0.08)" : "none",
120
+ opacity: u ? .5 : 1
121
+ },
122
+ children: [/* @__PURE__ */ i("span", {
123
+ style: { flex: 1 },
124
+ children: h?.label ?? l
125
+ }), /* @__PURE__ */ i("span", {
126
+ style: {
127
+ fontSize: 10,
128
+ color: "var(--c-text-subtle)",
129
+ transform: d ? "rotate(180deg)" : "none",
130
+ transition: "transform 160ms"
131
+ },
132
+ children: "▾"
133
+ })]
134
+ }),
135
+ children: m.map((t) => /* @__PURE__ */ i(c, {
136
+ label: t.label,
137
+ selected: t.value === e,
138
+ onClick: () => {
139
+ r(t.value), f(!1);
140
+ }
141
+ }, t.value))
142
+ });
143
+ }
144
+ function u({ values: e, onChange: r, options: o, placeholder: l = "Select…" }) {
145
+ let [u, d] = n(!1), f = t(null), p = o.map((e) => typeof e == "string" ? {
146
+ value: e,
147
+ label: e
148
+ } : e), m = (t) => r(e.includes(t) ? e.filter((e) => e !== t) : [...e, t]);
149
+ return /* @__PURE__ */ i(s, {
150
+ triggerRef: f,
151
+ open: u,
152
+ onOpen: () => d((e) => !e),
153
+ triggerContent: /* @__PURE__ */ a("div", {
154
+ style: {
155
+ display: "flex",
156
+ alignItems: "center",
157
+ gap: 6,
158
+ flexWrap: "wrap",
159
+ padding: "6px 10px",
160
+ background: "var(--c-surface)",
161
+ border: `1px solid ${u ? "var(--c-text)" : "var(--c-border)"}`,
162
+ borderRadius: 6,
163
+ minHeight: 36,
164
+ cursor: "pointer",
165
+ boxShadow: u ? "0 0 0 3px rgba(47,56,67,0.08)" : "none"
166
+ },
167
+ children: [e.length === 0 ? /* @__PURE__ */ i("span", {
168
+ style: {
169
+ fontFamily: "var(--font-sans)",
170
+ fontSize: 13,
171
+ color: "var(--c-text-muted)"
172
+ },
173
+ children: l
174
+ }) : e.map((e) => /* @__PURE__ */ a("span", {
175
+ style: {
176
+ display: "inline-flex",
177
+ alignItems: "center",
178
+ gap: 4,
179
+ padding: "2px 8px",
180
+ background: "var(--color-neutral-100)",
181
+ borderRadius: 999,
182
+ fontFamily: "var(--font-sans)",
183
+ fontSize: 11.5,
184
+ color: "var(--c-text)"
185
+ },
186
+ children: [p.find((t) => t.value === e)?.label ?? e, /* @__PURE__ */ i("span", {
187
+ onClick: (t) => {
188
+ t.stopPropagation(), m(e);
189
+ },
190
+ style: {
191
+ cursor: "pointer",
192
+ color: "var(--c-text-subtle)",
193
+ lineHeight: 1
194
+ },
195
+ children: "×"
196
+ })]
197
+ }, e)), /* @__PURE__ */ i("span", {
198
+ style: {
199
+ marginLeft: "auto",
200
+ fontSize: 10,
201
+ color: "var(--c-text-subtle)",
202
+ flexShrink: 0
203
+ },
204
+ children: "▾"
205
+ })]
206
+ }),
207
+ children: p.map((t) => /* @__PURE__ */ i(c, {
208
+ label: t.label,
209
+ selected: e.includes(t.value),
210
+ onClick: () => m(t.value),
211
+ checkbox: !0
212
+ }, t.value))
213
+ });
214
+ }
215
+ function d(e, t) {
216
+ if (!t) return e;
217
+ let n = e.toLowerCase().indexOf(t.toLowerCase());
218
+ return n < 0 ? e : /* @__PURE__ */ a(r, { children: [
219
+ e.slice(0, n),
220
+ /* @__PURE__ */ i("b", {
221
+ style: {
222
+ background: "#fff4d6",
223
+ color: "var(--c-text)",
224
+ fontWeight: 700
225
+ },
226
+ children: e.slice(n, n + t.length)
227
+ }),
228
+ e.slice(n + t.length)
229
+ ] });
230
+ }
231
+ function f({ value: r, onChange: s, options: c, placeholder: l = "Search…" }) {
232
+ let [u, f] = n(r), [p, m] = n(!1), h = t(null), g = t(null), _ = t(null), [v, y] = n({
233
+ top: 0,
234
+ left: 0,
235
+ width: 0
236
+ }), b = c.map((e) => typeof e == "string" ? {
237
+ value: e,
238
+ label: e
239
+ } : e).filter((e) => e.label.toLowerCase().includes(u.toLowerCase())), x = () => {
240
+ let e = h.current?.getBoundingClientRect();
241
+ e && y({
242
+ top: e.bottom + window.scrollY + 4,
243
+ left: e.left + window.scrollX,
244
+ width: e.width
245
+ }), m(!0);
246
+ };
247
+ return e(() => {
248
+ if (!p) return;
249
+ let e = (e) => {
250
+ !_.current?.contains(e.target) && !h.current?.contains(e.target) && m(!1);
251
+ }, t = (e) => {
252
+ e.key === "Escape" && m(!1);
253
+ };
254
+ return document.addEventListener("mousedown", e), document.addEventListener("keydown", t), () => {
255
+ document.removeEventListener("mousedown", e), document.removeEventListener("keydown", t);
256
+ };
257
+ }, [p]), /* @__PURE__ */ a("div", {
258
+ ref: h,
259
+ children: [/* @__PURE__ */ i("input", {
260
+ ref: g,
261
+ value: u,
262
+ onChange: (e) => {
263
+ f(e.target.value), x();
264
+ },
265
+ onFocus: x,
266
+ placeholder: l,
267
+ style: {
268
+ width: "100%",
269
+ padding: "8px 12px",
270
+ border: `1px solid ${p ? "var(--c-text)" : "var(--c-border)"}`,
271
+ borderRadius: 6,
272
+ fontFamily: "var(--font-sans)",
273
+ fontSize: 13,
274
+ color: "var(--c-text)",
275
+ outline: "none",
276
+ boxSizing: "border-box",
277
+ boxShadow: p ? "0 0 0 3px rgba(47,56,67,0.08)" : "none",
278
+ background: "var(--c-surface)"
279
+ }
280
+ }), p && o(/* @__PURE__ */ i("div", {
281
+ ref: _,
282
+ style: {
283
+ position: "absolute",
284
+ top: v.top,
285
+ left: v.left,
286
+ width: v.width,
287
+ background: "var(--c-surface)",
288
+ border: "1px solid var(--c-border)",
289
+ borderRadius: 8,
290
+ boxShadow: "0 4px 12px rgba(47,56,67,0.10)",
291
+ padding: 4,
292
+ zIndex: 1100,
293
+ maxHeight: 200,
294
+ overflowY: "auto"
295
+ },
296
+ children: b.length === 0 ? /* @__PURE__ */ i("div", {
297
+ style: {
298
+ padding: "8px 10px",
299
+ fontSize: 12,
300
+ color: "var(--c-text-subtle)",
301
+ fontFamily: "var(--font-sans)"
302
+ },
303
+ children: "No matches"
304
+ }) : b.map((e) => /* @__PURE__ */ i("div", {
305
+ onClick: () => {
306
+ s(e.value), f(e.label), m(!1);
307
+ },
308
+ style: {
309
+ padding: "6px 10px",
310
+ borderRadius: 4,
311
+ cursor: "pointer",
312
+ fontFamily: "var(--font-mono)",
313
+ fontSize: 12,
314
+ color: "var(--c-text)"
315
+ },
316
+ onMouseEnter: (e) => {
317
+ e.currentTarget.style.background = "var(--c-elevated)";
318
+ },
319
+ onMouseLeave: (e) => {
320
+ e.currentTarget.style.background = "transparent";
321
+ },
322
+ children: d(e.label, u)
323
+ }, e.value))
324
+ }), document.body)]
325
+ });
326
+ }
327
+ //#endregion
328
+ export { f as Combobox, u as MultiSelect, l as Select };
329
+
330
+ //# sourceMappingURL=index16.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index16.js","names":[],"sources":["../src/components/Select.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\n\n// ── Shared dropdown shell ──────────────────────────────────────────────────\n\ninterface DropdownShellProps {\n triggerContent: ReactNode\n open: boolean\n onOpen: () => void\n triggerRef: React.RefObject<HTMLDivElement | null>\n children: ReactNode\n minWidth?: number\n}\n\nfunction DropdownShell({ triggerContent, open, onOpen, triggerRef, children, minWidth = 200 }: DropdownShellProps) {\n const menuRef = useRef<HTMLDivElement>(null)\n const [pos, setPos] = useState({ top: 0, left: 0, width: 0 })\n\n const handleOpen = () => {\n const rect = triggerRef.current?.getBoundingClientRect()\n if (!rect) return\n setPos({ top: rect.bottom + window.scrollY + 4, left: rect.left + window.scrollX, width: rect.width })\n onOpen()\n }\n\n useEffect(() => {\n if (!open) return\n const handler = (e: MouseEvent) => {\n if (!menuRef.current?.contains(e.target as Node) && !triggerRef.current?.contains(e.target as Node)) {\n onOpen() // caller's toggle closes\n }\n }\n const onEsc = (e: KeyboardEvent) => { if (e.key === 'Escape') onOpen() }\n document.addEventListener('mousedown', handler)\n document.addEventListener('keydown', onEsc)\n return () => { document.removeEventListener('mousedown', handler); document.removeEventListener('keydown', onEsc) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n return (\n <>\n <div ref={triggerRef} onClick={handleOpen} style={{ cursor: 'pointer' }}>\n {triggerContent}\n </div>\n {open && createPortal(\n <div ref={menuRef} style={{\n position: 'absolute',\n top: pos.top,\n left: pos.left,\n minWidth: Math.max(pos.width, minWidth),\n background: 'var(--c-surface)',\n border: '1px solid var(--c-border)',\n borderRadius: 8,\n boxShadow: '0 4px 12px rgba(47,56,67,0.10)',\n padding: 4,\n zIndex: 1100,\n maxHeight: 240,\n overflowY: 'auto',\n }}>\n {children}\n </div>,\n document.body\n )}\n </>\n )\n}\n\nfunction OptionItem({ label, selected, onClick, checkbox }: { label: string; selected: boolean; onClick: () => void; checkbox?: boolean }) {\n return (\n <div\n onClick={onClick}\n style={{\n padding: '6px 10px',\n borderRadius: 4,\n cursor: 'pointer',\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n color: 'var(--c-text)',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n background: !checkbox && selected ? '#fff4d6' : 'transparent',\n }}\n onMouseEnter={e => { e.currentTarget.style.background = !checkbox && selected ? '#fff4d6' : 'var(--c-elevated)' }}\n onMouseLeave={e => { e.currentTarget.style.background = !checkbox && selected ? '#fff4d6' : 'transparent' }}\n >\n {checkbox ? (\n <span style={{\n width: 14, height: 14, borderRadius: 3, flexShrink: 0,\n border: `1.5px solid ${selected ? 'var(--c-text)' : 'var(--c-border-strong)'}`,\n background: selected ? 'var(--c-text)' : 'var(--c-surface)',\n color: '#fff', fontSize: 10, display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n }}>\n {selected ? '✓' : ''}\n </span>\n ) : (\n <span style={{ width: 14, color: 'var(--c-amber)', fontWeight: 700 }}>{selected ? '✓' : ''}</span>\n )}\n <span>{label}</span>\n </div>\n )\n}\n\n// ── Select ─────────────────────────────────────────────────────────────────\n\ninterface SelectProps {\n value: string\n onChange: (v: string) => void\n options: string[] | Array<{ value: string; label: string }>\n placeholder?: string\n disabled?: boolean\n}\n\nexport function Select({ value, onChange, options, placeholder = 'Select…', disabled }: SelectProps) {\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null!)\n const opts = options.map(o => typeof o === 'string' ? { value: o, label: o } : o)\n const selected = opts.find(o => o.value === value)\n\n return (\n <DropdownShell\n triggerRef={ref}\n open={open}\n onOpen={() => !disabled && setOpen(o => !o)}\n triggerContent={\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '8px 12px',\n background: 'var(--c-surface)',\n border: `1px solid ${open ? 'var(--c-text)' : 'var(--c-border)'}`,\n borderRadius: 6,\n fontSize: 13,\n fontFamily: 'var(--font-sans)',\n color: selected ? 'var(--c-text)' : 'var(--c-text-muted)',\n boxShadow: open ? '0 0 0 3px rgba(47,56,67,0.08)' : 'none',\n opacity: disabled ? 0.5 : 1,\n }}>\n <span style={{ flex: 1 }}>{selected?.label ?? placeholder}</span>\n <span style={{ fontSize: 10, color: 'var(--c-text-subtle)', transform: open ? 'rotate(180deg)' : 'none', transition: 'transform 160ms' }}>▾</span>\n </div>\n }\n >\n {opts.map(o => (\n <OptionItem\n key={o.value}\n label={o.label}\n selected={o.value === value}\n onClick={() => { onChange(o.value); setOpen(false) }}\n />\n ))}\n </DropdownShell>\n )\n}\n\n// ── MultiSelect ────────────────────────────────────────────────────────────\n\ninterface MultiSelectProps {\n values: string[]\n onChange: (v: string[]) => void\n options: string[] | Array<{ value: string; label: string }>\n placeholder?: string\n}\n\nexport function MultiSelect({ values, onChange, options, placeholder = 'Select…' }: MultiSelectProps) {\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null!)\n const opts = options.map(o => typeof o === 'string' ? { value: o, label: o } : o)\n\n const toggle = (v: string) =>\n onChange(values.includes(v) ? values.filter(x => x !== v) : [...values, v])\n\n return (\n <DropdownShell\n triggerRef={ref}\n open={open}\n onOpen={() => setOpen(o => !o)}\n triggerContent={\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n flexWrap: 'wrap',\n padding: '6px 10px',\n background: 'var(--c-surface)',\n border: `1px solid ${open ? 'var(--c-text)' : 'var(--c-border)'}`,\n borderRadius: 6,\n minHeight: 36,\n cursor: 'pointer',\n boxShadow: open ? '0 0 0 3px rgba(47,56,67,0.08)' : 'none',\n }}>\n {values.length === 0\n ? <span style={{ fontFamily: 'var(--font-sans)', fontSize: 13, color: 'var(--c-text-muted)' }}>{placeholder}</span>\n : values.map(v => {\n const label = opts.find(o => o.value === v)?.label ?? v\n return (\n <span key={v} style={{\n display: 'inline-flex', alignItems: 'center', gap: 4,\n padding: '2px 8px', background: 'var(--color-neutral-100)',\n borderRadius: 999, fontFamily: 'var(--font-sans)', fontSize: 11.5, color: 'var(--c-text)',\n }}>\n {label}\n <span onClick={e => { e.stopPropagation(); toggle(v) }} style={{ cursor: 'pointer', color: 'var(--c-text-subtle)', lineHeight: 1 }}>×</span>\n </span>\n )\n })}\n <span style={{ marginLeft: 'auto', fontSize: 10, color: 'var(--c-text-subtle)', flexShrink: 0 }}>▾</span>\n </div>\n }\n >\n {opts.map(o => (\n <OptionItem\n key={o.value}\n label={o.label}\n selected={values.includes(o.value)}\n onClick={() => toggle(o.value)}\n checkbox\n />\n ))}\n </DropdownShell>\n )\n}\n\n// ── Combobox ───────────────────────────────────────────────────────────────\n\ninterface ComboboxProps {\n value: string\n onChange: (v: string) => void\n options: string[] | Array<{ value: string; label: string }>\n placeholder?: string\n}\n\nfunction highlight(text: string, query: string): ReactNode {\n if (!query) return text\n const idx = text.toLowerCase().indexOf(query.toLowerCase())\n if (idx < 0) return text\n return (\n <>\n {text.slice(0, idx)}\n <b style={{ background: '#fff4d6', color: 'var(--c-text)', fontWeight: 700 }}>\n {text.slice(idx, idx + query.length)}\n </b>\n {text.slice(idx + query.length)}\n </>\n )\n}\n\nexport function Combobox({ value, onChange, options, placeholder = 'Search…' }: ComboboxProps) {\n const [q, setQ] = useState(value)\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null!)\n const inputRef = useRef<HTMLInputElement>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n const [pos, setPos] = useState({ top: 0, left: 0, width: 0 })\n\n const opts = options.map(o => typeof o === 'string' ? { value: o, label: o } : o)\n const results = opts.filter(o => o.label.toLowerCase().includes(q.toLowerCase()))\n\n const openDropdown = () => {\n const rect = ref.current?.getBoundingClientRect()\n if (rect) setPos({ top: rect.bottom + window.scrollY + 4, left: rect.left + window.scrollX, width: rect.width })\n setOpen(true)\n }\n\n useEffect(() => {\n if (!open) return\n const handler = (e: MouseEvent) => {\n if (!menuRef.current?.contains(e.target as Node) && !ref.current?.contains(e.target as Node)) setOpen(false)\n }\n const onEsc = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false) }\n document.addEventListener('mousedown', handler)\n document.addEventListener('keydown', onEsc)\n return () => { document.removeEventListener('mousedown', handler); document.removeEventListener('keydown', onEsc) }\n }, [open])\n\n return (\n <div ref={ref}>\n <input\n ref={inputRef}\n value={q}\n onChange={e => { setQ(e.target.value); openDropdown() }}\n onFocus={openDropdown}\n placeholder={placeholder}\n style={{\n width: '100%',\n padding: '8px 12px',\n border: `1px solid ${open ? 'var(--c-text)' : 'var(--c-border)'}`,\n borderRadius: 6,\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n color: 'var(--c-text)',\n outline: 'none',\n boxSizing: 'border-box',\n boxShadow: open ? '0 0 0 3px rgba(47,56,67,0.08)' : 'none',\n background: 'var(--c-surface)',\n }}\n />\n {open && createPortal(\n <div ref={menuRef} style={{\n position: 'absolute', top: pos.top, left: pos.left, width: pos.width,\n background: 'var(--c-surface)', border: '1px solid var(--c-border)',\n borderRadius: 8, boxShadow: '0 4px 12px rgba(47,56,67,0.10)',\n padding: 4, zIndex: 1100, maxHeight: 200, overflowY: 'auto',\n }}>\n {results.length === 0\n ? <div style={{ padding: '8px 10px', fontSize: 12, color: 'var(--c-text-subtle)', fontFamily: 'var(--font-sans)' }}>No matches</div>\n : results.map(r => (\n <div\n key={r.value}\n onClick={() => { onChange(r.value); setQ(r.label); setOpen(false) }}\n style={{ padding: '6px 10px', borderRadius: 4, cursor: 'pointer', fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--c-text)' }}\n onMouseEnter={e => { e.currentTarget.style.background = 'var(--c-elevated)' }}\n onMouseLeave={e => { e.currentTarget.style.background = 'transparent' }}\n >\n {highlight(r.label, q)}\n </div>\n ))}\n </div>,\n document.body\n )}\n </div>\n )\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ let e=require(`react/jsx-runtime`);function t({checked:t,onChange:n,label:r,disabled:i}){return(0,e.jsxs)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:8,cursor:i?`default`:`pointer`,fontFamily:`var(--font-sans)`,fontSize:13,color:i?`var(--c-text-muted)`:`var(--c-text)`,opacity:i?.6:1,userSelect:`none`},children:[(0,e.jsx)(`span`,{onClick:()=>!i&&n(!t),style:{width:16,height:16,borderRadius:4,border:`1.5px solid ${t?`var(--c-text)`:`var(--c-border-strong)`}`,background:t?`var(--c-text)`:`var(--c-surface)`,color:`#fff`,display:`inline-flex`,alignItems:`center`,justifyContent:`center`,fontSize:11,fontWeight:700,flexShrink:0,transition:`all 160ms`},children:t?`✓`:``}),r&&(0,e.jsx)(`span`,{children:r})]})}function n({checked:t,onChange:n,label:r,disabled:i}){return(0,e.jsxs)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:8,cursor:i?`default`:`pointer`,fontFamily:`var(--font-sans)`,fontSize:13,color:i?`var(--c-text-muted)`:`var(--c-text)`,opacity:i?.6:1,userSelect:`none`},children:[(0,e.jsx)(`span`,{onClick:()=>!i&&n(),style:{width:16,height:16,borderRadius:`50%`,border:`1.5px solid ${t?`var(--c-text)`:`var(--c-border-strong)`}`,background:`var(--c-surface)`,display:`inline-flex`,alignItems:`center`,justifyContent:`center`,flexShrink:0,transition:`all 160ms`},children:t&&(0,e.jsx)(`span`,{style:{width:8,height:8,borderRadius:`50%`,background:`var(--c-text)`}})}),r&&(0,e.jsx)(`span`,{children:r})]})}function r({checked:t,onChange:n,label:r,disabled:i}){return(0,e.jsxs)(`label`,{style:{display:`inline-flex`,alignItems:`center`,gap:10,cursor:i?`default`:`pointer`,fontFamily:`var(--font-sans)`,fontSize:13,color:i?`var(--c-text-muted)`:`var(--c-text)`,opacity:i?.6:1,userSelect:`none`},children:[(0,e.jsx)(`span`,{onClick:()=>!i&&n(!t),style:{position:`relative`,width:36,height:20,borderRadius:999,background:t?`var(--c-text)`:`var(--c-border-strong)`,flexShrink:0,transition:`background 160ms`},children:(0,e.jsx)(`span`,{style:{position:`absolute`,top:2,left:t?18:2,width:16,height:16,borderRadius:`50%`,background:`#fff`,boxShadow:`0 1px 3px rgba(0,0,0,0.15)`,transition:`left 160ms cubic-bezier(0.2,0,0,1)`}})}),r&&(0,e.jsx)(`span`,{children:r})]})}exports.Checkbox=t,exports.Radio=n,exports.Switch=r;
2
+ //# sourceMappingURL=index17.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index17.cjs","names":[],"sources":["../src/components/Checkbox.tsx"],"sourcesContent":["// Checkbox, Radio, Switch — all boolean form controls\n\ninterface CheckboxProps {\n checked: boolean\n onChange: (v: boolean) => void\n label?: string\n disabled?: boolean\n}\n\nexport function Checkbox({ checked, onChange, label, disabled }: CheckboxProps) {\n return (\n <label style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n cursor: disabled ? 'default' : 'pointer',\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n color: disabled ? 'var(--c-text-muted)' : 'var(--c-text)',\n opacity: disabled ? 0.6 : 1,\n userSelect: 'none',\n }}>\n <span\n onClick={() => !disabled && onChange(!checked)}\n style={{\n width: 16,\n height: 16,\n borderRadius: 4,\n border: `1.5px solid ${checked ? 'var(--c-text)' : 'var(--c-border-strong)'}`,\n background: checked ? 'var(--c-text)' : 'var(--c-surface)',\n color: '#fff',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 11,\n fontWeight: 700,\n flexShrink: 0,\n transition: 'all 160ms',\n }}\n >\n {checked ? '✓' : ''}\n </span>\n {label && <span>{label}</span>}\n </label>\n )\n}\n\n// ── Radio ──────────────────────────────────────────────────────────────────\n\ninterface RadioProps {\n checked: boolean\n onChange: () => void\n label?: string\n disabled?: boolean\n}\n\nexport function Radio({ checked, onChange, label, disabled }: RadioProps) {\n return (\n <label style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n cursor: disabled ? 'default' : 'pointer',\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n color: disabled ? 'var(--c-text-muted)' : 'var(--c-text)',\n opacity: disabled ? 0.6 : 1,\n userSelect: 'none',\n }}>\n <span\n onClick={() => !disabled && onChange()}\n style={{\n width: 16,\n height: 16,\n borderRadius: '50%',\n border: `1.5px solid ${checked ? 'var(--c-text)' : 'var(--c-border-strong)'}`,\n background: 'var(--c-surface)',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n transition: 'all 160ms',\n }}\n >\n {checked && (\n <span style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--c-text)' }} />\n )}\n </span>\n {label && <span>{label}</span>}\n </label>\n )\n}\n\n// ── Switch ─────────────────────────────────────────────────────────────────\n\ninterface SwitchProps {\n checked: boolean\n onChange: (v: boolean) => void\n label?: string\n disabled?: boolean\n}\n\nexport function Switch({ checked, onChange, label, disabled }: SwitchProps) {\n return (\n <label style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 10,\n cursor: disabled ? 'default' : 'pointer',\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n color: disabled ? 'var(--c-text-muted)' : 'var(--c-text)',\n opacity: disabled ? 0.6 : 1,\n userSelect: 'none',\n }}>\n <span\n onClick={() => !disabled && onChange(!checked)}\n style={{\n position: 'relative',\n width: 36,\n height: 20,\n borderRadius: 999,\n background: checked ? 'var(--c-text)' : 'var(--c-border-strong)',\n flexShrink: 0,\n transition: 'background 160ms',\n }}\n >\n <span style={{\n position: 'absolute',\n top: 2,\n left: checked ? 18 : 2,\n width: 16,\n height: 16,\n borderRadius: '50%',\n background: '#fff',\n boxShadow: '0 1px 3px rgba(0,0,0,0.15)',\n transition: 'left 160ms cubic-bezier(0.2,0,0,1)',\n }} />\n </span>\n {label && <span>{label}</span>}\n </label>\n )\n}\n"],"mappings":"mCASA,SAAgB,EAAS,CAAE,UAAS,WAAU,QAAO,YAA2B,CAC9E,OACE,EAAA,EAAA,MAAC,QAAD,CAAO,MAAO,CACZ,QAAY,cACZ,WAAY,SACZ,IAAY,EACZ,OAAY,EAAW,UAAY,UACnC,WAAY,mBACZ,SAAY,GACZ,MAAY,EAAW,sBAAwB,gBAC/C,QAAY,EAAW,GAAM,EAC7B,WAAY,OACb,UAVD,EAWE,EAAA,EAAA,KAAC,OAAD,CACE,YAAe,CAAC,GAAY,EAAS,CAAC,EAAQ,CAC9C,MAAO,CACL,MAAgB,GAChB,OAAgB,GAChB,aAAgB,EAChB,OAAgB,eAAe,EAAU,gBAAkB,2BAC3D,WAAgB,EAAU,gBAAkB,mBAC5C,MAAgB,OAChB,QAAgB,cAChB,WAAgB,SAChB,eAAgB,SAChB,SAAgB,GAChB,WAAgB,IAChB,WAAgB,EAChB,WAAgB,YACjB,UAEA,EAAU,IAAM,GACZ,CAAA,CACN,IAAS,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAa,CAAA,CACxB,GAaZ,SAAgB,EAAM,CAAE,UAAS,WAAU,QAAO,YAAwB,CACxE,OACE,EAAA,EAAA,MAAC,QAAD,CAAO,MAAO,CACZ,QAAY,cACZ,WAAY,SACZ,IAAY,EACZ,OAAY,EAAW,UAAY,UACnC,WAAY,mBACZ,SAAY,GACZ,MAAY,EAAW,sBAAwB,gBAC/C,QAAY,EAAW,GAAM,EAC7B,WAAY,OACb,UAVD,EAWE,EAAA,EAAA,KAAC,OAAD,CACE,YAAe,CAAC,GAAY,GAAU,CACtC,MAAO,CACL,MAAgB,GAChB,OAAgB,GAChB,aAAgB,MAChB,OAAgB,eAAe,EAAU,gBAAkB,2BAC3D,WAAgB,mBAChB,QAAgB,cAChB,WAAgB,SAChB,eAAgB,SAChB,WAAgB,EAChB,WAAgB,YACjB,UAEA,IACC,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,CAAE,MAAO,EAAG,OAAQ,EAAG,aAAc,MAAO,WAAY,gBAAiB,CAAI,CAAA,CAEvF,CAAA,CACN,IAAS,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAa,CAAA,CACxB,GAaZ,SAAgB,EAAO,CAAE,UAAS,WAAU,QAAO,YAAyB,CAC1E,OACE,EAAA,EAAA,MAAC,QAAD,CAAO,MAAO,CACZ,QAAY,cACZ,WAAY,SACZ,IAAY,GACZ,OAAY,EAAW,UAAY,UACnC,WAAY,mBACZ,SAAY,GACZ,MAAY,EAAW,sBAAwB,gBAC/C,QAAY,EAAW,GAAM,EAC7B,WAAY,OACb,UAVD,EAWE,EAAA,EAAA,KAAC,OAAD,CACE,YAAe,CAAC,GAAY,EAAS,CAAC,EAAQ,CAC9C,MAAO,CACL,SAAc,WACd,MAAc,GACd,OAAc,GACd,aAAc,IACd,WAAc,EAAU,gBAAkB,yBAC1C,WAAc,EACd,WAAc,mBACf,WAED,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,CACX,SAAc,WACd,IAAc,EACd,KAAc,EAAU,GAAK,EAC7B,MAAc,GACd,OAAc,GACd,aAAc,MACd,WAAc,OACd,UAAc,6BACd,WAAc,qCACf,CAAI,CAAA,CACA,CAAA,CACN,IAAS,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAa,CAAA,CACxB"}
@@ -0,0 +1,114 @@
1
+ import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
+ //#region src/components/Checkbox.tsx
3
+ function n({ checked: n, onChange: r, label: i, disabled: a }) {
4
+ return /* @__PURE__ */ t("label", {
5
+ style: {
6
+ display: "inline-flex",
7
+ alignItems: "center",
8
+ gap: 8,
9
+ cursor: a ? "default" : "pointer",
10
+ fontFamily: "var(--font-sans)",
11
+ fontSize: 13,
12
+ color: a ? "var(--c-text-muted)" : "var(--c-text)",
13
+ opacity: a ? .6 : 1,
14
+ userSelect: "none"
15
+ },
16
+ children: [/* @__PURE__ */ e("span", {
17
+ onClick: () => !a && r(!n),
18
+ style: {
19
+ width: 16,
20
+ height: 16,
21
+ borderRadius: 4,
22
+ border: `1.5px solid ${n ? "var(--c-text)" : "var(--c-border-strong)"}`,
23
+ background: n ? "var(--c-text)" : "var(--c-surface)",
24
+ color: "#fff",
25
+ display: "inline-flex",
26
+ alignItems: "center",
27
+ justifyContent: "center",
28
+ fontSize: 11,
29
+ fontWeight: 700,
30
+ flexShrink: 0,
31
+ transition: "all 160ms"
32
+ },
33
+ children: n ? "✓" : ""
34
+ }), i && /* @__PURE__ */ e("span", { children: i })]
35
+ });
36
+ }
37
+ function r({ checked: n, onChange: r, label: i, disabled: a }) {
38
+ return /* @__PURE__ */ t("label", {
39
+ style: {
40
+ display: "inline-flex",
41
+ alignItems: "center",
42
+ gap: 8,
43
+ cursor: a ? "default" : "pointer",
44
+ fontFamily: "var(--font-sans)",
45
+ fontSize: 13,
46
+ color: a ? "var(--c-text-muted)" : "var(--c-text)",
47
+ opacity: a ? .6 : 1,
48
+ userSelect: "none"
49
+ },
50
+ children: [/* @__PURE__ */ e("span", {
51
+ onClick: () => !a && r(),
52
+ style: {
53
+ width: 16,
54
+ height: 16,
55
+ borderRadius: "50%",
56
+ border: `1.5px solid ${n ? "var(--c-text)" : "var(--c-border-strong)"}`,
57
+ background: "var(--c-surface)",
58
+ display: "inline-flex",
59
+ alignItems: "center",
60
+ justifyContent: "center",
61
+ flexShrink: 0,
62
+ transition: "all 160ms"
63
+ },
64
+ children: n && /* @__PURE__ */ e("span", { style: {
65
+ width: 8,
66
+ height: 8,
67
+ borderRadius: "50%",
68
+ background: "var(--c-text)"
69
+ } })
70
+ }), i && /* @__PURE__ */ e("span", { children: i })]
71
+ });
72
+ }
73
+ function i({ checked: n, onChange: r, label: i, disabled: a }) {
74
+ return /* @__PURE__ */ t("label", {
75
+ style: {
76
+ display: "inline-flex",
77
+ alignItems: "center",
78
+ gap: 10,
79
+ cursor: a ? "default" : "pointer",
80
+ fontFamily: "var(--font-sans)",
81
+ fontSize: 13,
82
+ color: a ? "var(--c-text-muted)" : "var(--c-text)",
83
+ opacity: a ? .6 : 1,
84
+ userSelect: "none"
85
+ },
86
+ children: [/* @__PURE__ */ e("span", {
87
+ onClick: () => !a && r(!n),
88
+ style: {
89
+ position: "relative",
90
+ width: 36,
91
+ height: 20,
92
+ borderRadius: 999,
93
+ background: n ? "var(--c-text)" : "var(--c-border-strong)",
94
+ flexShrink: 0,
95
+ transition: "background 160ms"
96
+ },
97
+ children: /* @__PURE__ */ e("span", { style: {
98
+ position: "absolute",
99
+ top: 2,
100
+ left: n ? 18 : 2,
101
+ width: 16,
102
+ height: 16,
103
+ borderRadius: "50%",
104
+ background: "#fff",
105
+ boxShadow: "0 1px 3px rgba(0,0,0,0.15)",
106
+ transition: "left 160ms cubic-bezier(0.2,0,0,1)"
107
+ } })
108
+ }), i && /* @__PURE__ */ e("span", { children: i })]
109
+ });
110
+ }
111
+ //#endregion
112
+ export { n as Checkbox, r as Radio, i as Switch };
113
+
114
+ //# sourceMappingURL=index17.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index17.js","names":[],"sources":["../src/components/Checkbox.tsx"],"sourcesContent":["// Checkbox, Radio, Switch — all boolean form controls\n\ninterface CheckboxProps {\n checked: boolean\n onChange: (v: boolean) => void\n label?: string\n disabled?: boolean\n}\n\nexport function Checkbox({ checked, onChange, label, disabled }: CheckboxProps) {\n return (\n <label style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n cursor: disabled ? 'default' : 'pointer',\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n color: disabled ? 'var(--c-text-muted)' : 'var(--c-text)',\n opacity: disabled ? 0.6 : 1,\n userSelect: 'none',\n }}>\n <span\n onClick={() => !disabled && onChange(!checked)}\n style={{\n width: 16,\n height: 16,\n borderRadius: 4,\n border: `1.5px solid ${checked ? 'var(--c-text)' : 'var(--c-border-strong)'}`,\n background: checked ? 'var(--c-text)' : 'var(--c-surface)',\n color: '#fff',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 11,\n fontWeight: 700,\n flexShrink: 0,\n transition: 'all 160ms',\n }}\n >\n {checked ? '✓' : ''}\n </span>\n {label && <span>{label}</span>}\n </label>\n )\n}\n\n// ── Radio ──────────────────────────────────────────────────────────────────\n\ninterface RadioProps {\n checked: boolean\n onChange: () => void\n label?: string\n disabled?: boolean\n}\n\nexport function Radio({ checked, onChange, label, disabled }: RadioProps) {\n return (\n <label style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n cursor: disabled ? 'default' : 'pointer',\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n color: disabled ? 'var(--c-text-muted)' : 'var(--c-text)',\n opacity: disabled ? 0.6 : 1,\n userSelect: 'none',\n }}>\n <span\n onClick={() => !disabled && onChange()}\n style={{\n width: 16,\n height: 16,\n borderRadius: '50%',\n border: `1.5px solid ${checked ? 'var(--c-text)' : 'var(--c-border-strong)'}`,\n background: 'var(--c-surface)',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n transition: 'all 160ms',\n }}\n >\n {checked && (\n <span style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--c-text)' }} />\n )}\n </span>\n {label && <span>{label}</span>}\n </label>\n )\n}\n\n// ── Switch ─────────────────────────────────────────────────────────────────\n\ninterface SwitchProps {\n checked: boolean\n onChange: (v: boolean) => void\n label?: string\n disabled?: boolean\n}\n\nexport function Switch({ checked, onChange, label, disabled }: SwitchProps) {\n return (\n <label style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 10,\n cursor: disabled ? 'default' : 'pointer',\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n color: disabled ? 'var(--c-text-muted)' : 'var(--c-text)',\n opacity: disabled ? 0.6 : 1,\n userSelect: 'none',\n }}>\n <span\n onClick={() => !disabled && onChange(!checked)}\n style={{\n position: 'relative',\n width: 36,\n height: 20,\n borderRadius: 999,\n background: checked ? 'var(--c-text)' : 'var(--c-border-strong)',\n flexShrink: 0,\n transition: 'background 160ms',\n }}\n >\n <span style={{\n position: 'absolute',\n top: 2,\n left: checked ? 18 : 2,\n width: 16,\n height: 16,\n borderRadius: '50%',\n background: '#fff',\n boxShadow: '0 1px 3px rgba(0,0,0,0.15)',\n transition: 'left 160ms cubic-bezier(0.2,0,0,1)',\n }} />\n </span>\n {label && <span>{label}</span>}\n </label>\n )\n}\n"],"mappings":";;AASA,SAAgB,EAAS,EAAE,YAAS,aAAU,UAAO,eAA2B;AAC9E,QACE,kBAAC,SAAD;EAAO,OAAO;GACZ,SAAY;GACZ,YAAY;GACZ,KAAY;GACZ,QAAY,IAAW,YAAY;GACnC,YAAY;GACZ,UAAY;GACZ,OAAY,IAAW,wBAAwB;GAC/C,SAAY,IAAW,KAAM;GAC7B,YAAY;GACb;YAVD,CAWE,kBAAC,QAAD;GACE,eAAe,CAAC,KAAY,EAAS,CAAC,EAAQ;GAC9C,OAAO;IACL,OAAgB;IAChB,QAAgB;IAChB,cAAgB;IAChB,QAAgB,eAAe,IAAU,kBAAkB;IAC3D,YAAgB,IAAU,kBAAkB;IAC5C,OAAgB;IAChB,SAAgB;IAChB,YAAgB;IAChB,gBAAgB;IAChB,UAAgB;IAChB,YAAgB;IAChB,YAAgB;IAChB,YAAgB;IACjB;aAEA,IAAU,MAAM;GACZ,CAAA,EACN,KAAS,kBAAC,QAAD,EAAA,UAAO,GAAa,CAAA,CACxB;;;AAaZ,SAAgB,EAAM,EAAE,YAAS,aAAU,UAAO,eAAwB;AACxE,QACE,kBAAC,SAAD;EAAO,OAAO;GACZ,SAAY;GACZ,YAAY;GACZ,KAAY;GACZ,QAAY,IAAW,YAAY;GACnC,YAAY;GACZ,UAAY;GACZ,OAAY,IAAW,wBAAwB;GAC/C,SAAY,IAAW,KAAM;GAC7B,YAAY;GACb;YAVD,CAWE,kBAAC,QAAD;GACE,eAAe,CAAC,KAAY,GAAU;GACtC,OAAO;IACL,OAAgB;IAChB,QAAgB;IAChB,cAAgB;IAChB,QAAgB,eAAe,IAAU,kBAAkB;IAC3D,YAAgB;IAChB,SAAgB;IAChB,YAAgB;IAChB,gBAAgB;IAChB,YAAgB;IAChB,YAAgB;IACjB;aAEA,KACC,kBAAC,QAAD,EAAM,OAAO;IAAE,OAAO;IAAG,QAAQ;IAAG,cAAc;IAAO,YAAY;IAAiB,EAAI,CAAA;GAEvF,CAAA,EACN,KAAS,kBAAC,QAAD,EAAA,UAAO,GAAa,CAAA,CACxB;;;AAaZ,SAAgB,EAAO,EAAE,YAAS,aAAU,UAAO,eAAyB;AAC1E,QACE,kBAAC,SAAD;EAAO,OAAO;GACZ,SAAY;GACZ,YAAY;GACZ,KAAY;GACZ,QAAY,IAAW,YAAY;GACnC,YAAY;GACZ,UAAY;GACZ,OAAY,IAAW,wBAAwB;GAC/C,SAAY,IAAW,KAAM;GAC7B,YAAY;GACb;YAVD,CAWE,kBAAC,QAAD;GACE,eAAe,CAAC,KAAY,EAAS,CAAC,EAAQ;GAC9C,OAAO;IACL,UAAc;IACd,OAAc;IACd,QAAc;IACd,cAAc;IACd,YAAc,IAAU,kBAAkB;IAC1C,YAAc;IACd,YAAc;IACf;aAED,kBAAC,QAAD,EAAM,OAAO;IACX,UAAc;IACd,KAAc;IACd,MAAc,IAAU,KAAK;IAC7B,OAAc;IACd,QAAc;IACd,cAAc;IACd,YAAc;IACd,WAAc;IACd,YAAc;IACf,EAAI,CAAA;GACA,CAAA,EACN,KAAS,kBAAC,QAAD,EAAA,UAAO,GAAa,CAAA,CACxB"}
@@ -0,0 +1,2 @@
1
+ let e=require(`react/jsx-runtime`);function t({label:t,required:n,error:r,help:i,children:a}){return(0,e.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:4},children:[(0,e.jsxs)(`label`,{style:{fontSize:12,fontWeight:600,color:`var(--c-text)`,fontFamily:`var(--font-sans)`,display:`flex`,alignItems:`center`,gap:4},children:[t,n&&(0,e.jsx)(`span`,{style:{color:`var(--c-error)`},children:`*`})]}),a,r?(0,e.jsx)(`p`,{style:{margin:0,fontSize:11.5,color:`var(--c-error)`,fontFamily:`var(--font-sans)`},children:r}):i&&(0,e.jsx)(`p`,{style:{margin:0,fontSize:11.5,color:`var(--c-text-secondary)`,fontFamily:`var(--font-sans)`},children:i})]})}function n({error:t,mono:n,style:r,...i}){return(0,e.jsx)(`textarea`,{style:{width:`100%`,padding:`8px 12px`,border:`1px solid ${t?`var(--c-error)`:`var(--c-border)`}`,borderRadius:6,fontFamily:n?`var(--font-mono)`:`var(--font-sans)`,fontSize:13,color:`var(--c-text)`,background:`var(--c-surface)`,resize:`vertical`,minHeight:80,outline:`none`,lineHeight:1.6,boxSizing:`border-box`,boxShadow:t?`0 0 0 3px oklch(95% 0.04 25)`:`none`,transition:`border-color 150ms, box-shadow 150ms`,...r},onFocus:e=>{e.currentTarget.style.borderColor=t?`var(--c-error)`:`var(--c-text)`,e.currentTarget.style.boxShadow=t?`0 0 0 3px oklch(95% 0.04 25)`:`0 0 0 3px rgba(47,56,67,0.08)`},onBlur:e=>{e.currentTarget.style.borderColor=t?`var(--c-error)`:`var(--c-border)`,e.currentTarget.style.boxShadow=t?`0 0 0 3px oklch(95% 0.04 25)`:`none`},...i})}function r({options:t,value:n,onChange:r}){return(0,e.jsx)(`div`,{style:{display:`inline-flex`,background:`var(--color-neutral-100)`,borderRadius:999,padding:3,gap:2},children:t.map(e=>typeof e==`string`?{value:e,label:e}:e).map(t=>(0,e.jsx)(`button`,{onClick:()=>r(t.value),style:{border:`none`,background:t.value===n?`var(--c-surface)`:`transparent`,color:t.value===n?`var(--c-text)`:`var(--c-text-subtle)`,padding:`4px 14px`,borderRadius:999,cursor:`pointer`,fontFamily:`var(--font-sans)`,fontSize:11.5,fontWeight:600,boxShadow:t.value===n?`0 1px 2px rgba(0,0,0,0.08)`:`none`,transition:`all 160ms`},children:t.label},t.value))})}exports.Field=t,exports.SegmentedControl=r,exports.Textarea=n;
2
+ //# sourceMappingURL=index18.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index18.cjs","names":[],"sources":["../src/components/Field.tsx"],"sourcesContent":["import type { ReactNode, TextareaHTMLAttributes } from 'react'\n\n// ── Field wrapper ──────────────────────────────────────────────────────────\n\ninterface FieldProps {\n label: string\n required?: boolean\n error?: string\n help?: string\n children: ReactNode\n}\n\nexport function Field({ label, required, error, help, children }: FieldProps) {\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>\n <label style={{\n fontSize: 12,\n fontWeight: 600,\n color: 'var(--c-text)',\n fontFamily: 'var(--font-sans)',\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n }}>\n {label}\n {required && <span style={{ color: 'var(--c-error)' }}>*</span>}\n </label>\n {children}\n {error\n ? <p style={{ margin: 0, fontSize: 11.5, color: 'var(--c-error)', fontFamily: 'var(--font-sans)' }}>{error}</p>\n : help && <p style={{ margin: 0, fontSize: 11.5, color: 'var(--c-text-secondary)', fontFamily: 'var(--font-sans)' }}>{help}</p>\n }\n </div>\n )\n}\n\n// ── Textarea ───────────────────────────────────────────────────────────────\n\ninterface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n error?: boolean\n mono?: boolean\n}\n\nexport function Textarea({ error, mono, style, ...rest }: TextareaProps) {\n return (\n <textarea\n style={{\n width: '100%',\n padding: '8px 12px',\n border: `1px solid ${error ? 'var(--c-error)' : 'var(--c-border)'}`,\n borderRadius: 6,\n fontFamily: mono ? 'var(--font-mono)' : 'var(--font-sans)',\n fontSize: 13,\n color: 'var(--c-text)',\n background: 'var(--c-surface)',\n resize: 'vertical',\n minHeight: 80,\n outline: 'none',\n lineHeight: 1.6,\n boxSizing: 'border-box',\n boxShadow: error ? '0 0 0 3px oklch(95% 0.04 25)' : 'none',\n transition: 'border-color 150ms, box-shadow 150ms',\n ...style,\n }}\n onFocus={e => {\n e.currentTarget.style.borderColor = error ? 'var(--c-error)' : 'var(--c-text)'\n e.currentTarget.style.boxShadow = error ? '0 0 0 3px oklch(95% 0.04 25)' : '0 0 0 3px rgba(47,56,67,0.08)'\n }}\n onBlur={e => {\n e.currentTarget.style.borderColor = error ? 'var(--c-error)' : 'var(--c-border)'\n e.currentTarget.style.boxShadow = error ? '0 0 0 3px oklch(95% 0.04 25)' : 'none'\n }}\n {...rest}\n />\n )\n}\n\n// ── SegmentedControl ───────────────────────────────────────────────────────\n\ninterface SegmentedControlProps {\n options: string[] | Array<{ value: string; label: string }>\n value: string\n onChange: (v: string) => void\n}\n\nexport function SegmentedControl({ options, value, onChange }: SegmentedControlProps) {\n const opts = options.map(o => typeof o === 'string' ? { value: o, label: o } : o)\n return (\n <div style={{\n display: 'inline-flex',\n background: 'var(--color-neutral-100)',\n borderRadius: 999,\n padding: 3,\n gap: 2,\n }}>\n {opts.map(o => (\n <button\n key={o.value}\n onClick={() => onChange(o.value)}\n style={{\n border: 'none',\n background: o.value === value ? 'var(--c-surface)' : 'transparent',\n color: o.value === value ? 'var(--c-text)' : 'var(--c-text-subtle)',\n padding: '4px 14px',\n borderRadius: 999,\n cursor: 'pointer',\n fontFamily: 'var(--font-sans)',\n fontSize: 11.5,\n fontWeight: 600,\n boxShadow: o.value === value ? '0 1px 2px rgba(0,0,0,0.08)' : 'none',\n transition: 'all 160ms',\n }}\n >\n {o.label}\n </button>\n ))}\n </div>\n )\n}\n"],"mappings":"mCAYA,SAAgB,EAAM,CAAE,QAAO,WAAU,QAAO,OAAM,YAAwB,CAC5E,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,EAAG,UAAhE,EACE,EAAA,EAAA,MAAC,QAAD,CAAO,MAAO,CACZ,SAAY,GACZ,WAAY,IACZ,MAAY,gBACZ,WAAY,mBACZ,QAAY,OACZ,WAAY,SACZ,IAAY,EACb,UARD,CASG,EACA,IAAY,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,CAAE,MAAO,iBAAkB,UAAE,IAAQ,CAAA,CACzD,GACP,EACA,GACG,EAAA,EAAA,KAAC,IAAD,CAAG,MAAO,CAAE,OAAQ,EAAG,SAAU,KAAM,MAAO,iBAAkB,WAAY,mBAAoB,UAAG,EAAU,CAAA,CAC7G,IAAQ,EAAA,EAAA,KAAC,IAAD,CAAG,MAAO,CAAE,OAAQ,EAAG,SAAU,KAAM,MAAO,0BAA2B,WAAY,mBAAoB,UAAG,EAAS,CAAA,CAE7H,GAWV,SAAgB,EAAS,CAAE,QAAO,OAAM,QAAO,GAAG,GAAuB,CACvE,OACE,EAAA,EAAA,KAAC,WAAD,CACE,MAAO,CACL,MAAc,OACd,QAAc,WACd,OAAc,aAAa,EAAQ,iBAAmB,oBACtD,aAAc,EACd,WAAc,EAAO,mBAAqB,mBAC1C,SAAc,GACd,MAAc,gBACd,WAAc,mBACd,OAAc,WACd,UAAc,GACd,QAAc,OACd,WAAc,IACd,UAAc,aACd,UAAc,EAAQ,+BAAiC,OACvD,WAAc,uCACd,GAAG,EACJ,CACD,QAAS,GAAK,CACZ,EAAE,cAAc,MAAM,YAAc,EAAQ,iBAAmB,gBAC/D,EAAE,cAAc,MAAM,UAAc,EAAQ,+BAAiC,iCAE/E,OAAQ,GAAK,CACX,EAAE,cAAc,MAAM,YAAc,EAAQ,iBAAmB,kBAC/D,EAAE,cAAc,MAAM,UAAc,EAAQ,+BAAiC,QAE/E,GAAI,EACJ,CAAA,CAYN,SAAgB,EAAiB,CAAE,UAAS,QAAO,YAAmC,CAEpF,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,CACV,QAAc,cACd,WAAc,2BACd,aAAc,IACd,QAAc,EACd,IAAc,EACf,UARU,EAAQ,IAAI,GAAK,OAAO,GAAM,SAAW,CAAE,MAAO,EAAG,MAAO,EAAG,CAAG,EAS1E,CAAK,IAAI,IACR,EAAA,EAAA,KAAC,SAAD,CAEE,YAAe,EAAS,EAAE,MAAM,CAChC,MAAO,CACL,OAAc,OACd,WAAc,EAAE,QAAU,EAAQ,mBAAqB,cACvD,MAAc,EAAE,QAAU,EAAQ,gBAAkB,uBACpD,QAAc,WACd,aAAc,IACd,OAAc,UACd,WAAc,mBACd,SAAc,KACd,WAAc,IACd,UAAc,EAAE,QAAU,EAAQ,6BAA+B,OACjE,WAAc,YACf,UAEA,EAAE,MACI,CAjBF,EAAE,MAiBA,CACT,CACE,CAAA"}
@@ -0,0 +1,110 @@
1
+ import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
+ //#region src/components/Field.tsx
3
+ function n({ label: n, required: r, error: i, help: a, children: o }) {
4
+ return /* @__PURE__ */ t("div", {
5
+ style: {
6
+ display: "flex",
7
+ flexDirection: "column",
8
+ gap: 4
9
+ },
10
+ children: [
11
+ /* @__PURE__ */ t("label", {
12
+ style: {
13
+ fontSize: 12,
14
+ fontWeight: 600,
15
+ color: "var(--c-text)",
16
+ fontFamily: "var(--font-sans)",
17
+ display: "flex",
18
+ alignItems: "center",
19
+ gap: 4
20
+ },
21
+ children: [n, r && /* @__PURE__ */ e("span", {
22
+ style: { color: "var(--c-error)" },
23
+ children: "*"
24
+ })]
25
+ }),
26
+ o,
27
+ i ? /* @__PURE__ */ e("p", {
28
+ style: {
29
+ margin: 0,
30
+ fontSize: 11.5,
31
+ color: "var(--c-error)",
32
+ fontFamily: "var(--font-sans)"
33
+ },
34
+ children: i
35
+ }) : a && /* @__PURE__ */ e("p", {
36
+ style: {
37
+ margin: 0,
38
+ fontSize: 11.5,
39
+ color: "var(--c-text-secondary)",
40
+ fontFamily: "var(--font-sans)"
41
+ },
42
+ children: a
43
+ })
44
+ ]
45
+ });
46
+ }
47
+ function r({ error: t, mono: n, style: r, ...i }) {
48
+ return /* @__PURE__ */ e("textarea", {
49
+ style: {
50
+ width: "100%",
51
+ padding: "8px 12px",
52
+ border: `1px solid ${t ? "var(--c-error)" : "var(--c-border)"}`,
53
+ borderRadius: 6,
54
+ fontFamily: n ? "var(--font-mono)" : "var(--font-sans)",
55
+ fontSize: 13,
56
+ color: "var(--c-text)",
57
+ background: "var(--c-surface)",
58
+ resize: "vertical",
59
+ minHeight: 80,
60
+ outline: "none",
61
+ lineHeight: 1.6,
62
+ boxSizing: "border-box",
63
+ boxShadow: t ? "0 0 0 3px oklch(95% 0.04 25)" : "none",
64
+ transition: "border-color 150ms, box-shadow 150ms",
65
+ ...r
66
+ },
67
+ onFocus: (e) => {
68
+ e.currentTarget.style.borderColor = t ? "var(--c-error)" : "var(--c-text)", e.currentTarget.style.boxShadow = t ? "0 0 0 3px oklch(95% 0.04 25)" : "0 0 0 3px rgba(47,56,67,0.08)";
69
+ },
70
+ onBlur: (e) => {
71
+ e.currentTarget.style.borderColor = t ? "var(--c-error)" : "var(--c-border)", e.currentTarget.style.boxShadow = t ? "0 0 0 3px oklch(95% 0.04 25)" : "none";
72
+ },
73
+ ...i
74
+ });
75
+ }
76
+ function i({ options: t, value: n, onChange: r }) {
77
+ return /* @__PURE__ */ e("div", {
78
+ style: {
79
+ display: "inline-flex",
80
+ background: "var(--color-neutral-100)",
81
+ borderRadius: 999,
82
+ padding: 3,
83
+ gap: 2
84
+ },
85
+ children: t.map((e) => typeof e == "string" ? {
86
+ value: e,
87
+ label: e
88
+ } : e).map((t) => /* @__PURE__ */ e("button", {
89
+ onClick: () => r(t.value),
90
+ style: {
91
+ border: "none",
92
+ background: t.value === n ? "var(--c-surface)" : "transparent",
93
+ color: t.value === n ? "var(--c-text)" : "var(--c-text-subtle)",
94
+ padding: "4px 14px",
95
+ borderRadius: 999,
96
+ cursor: "pointer",
97
+ fontFamily: "var(--font-sans)",
98
+ fontSize: 11.5,
99
+ fontWeight: 600,
100
+ boxShadow: t.value === n ? "0 1px 2px rgba(0,0,0,0.08)" : "none",
101
+ transition: "all 160ms"
102
+ },
103
+ children: t.label
104
+ }, t.value))
105
+ });
106
+ }
107
+ //#endregion
108
+ export { n as Field, i as SegmentedControl, r as Textarea };
109
+
110
+ //# sourceMappingURL=index18.js.map