@reopt-ai/opt-ui 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/COMPONENT_CATALOG.md +3000 -0
  3. package/LICENSE +21 -0
  4. package/README.md +244 -0
  5. package/dist/chunk-3GWWZKX7.js +38 -0
  6. package/dist/chunk-AFF2HPE5.cjs +5008 -0
  7. package/dist/chunk-ELWICXYY.js +4745 -0
  8. package/dist/chunk-N4NDU5ET.cjs +4745 -0
  9. package/dist/chunk-ONE3C5RV.cjs +38 -0
  10. package/dist/chunk-QWBHD54V.js +3218 -0
  11. package/dist/chunk-RBM2RNC2.js +5008 -0
  12. package/dist/chunk-X5WCXJAF.cjs +3218 -0
  13. package/dist/core/index.cjs +324 -0
  14. package/dist/core/index.d.cts +5 -0
  15. package/dist/core/index.d.ts +5 -0
  16. package/dist/core/index.js +324 -0
  17. package/dist/docs/01-getting-started.md +129 -0
  18. package/dist/docs/02-components/01-core.md +1841 -0
  19. package/dist/docs/02-components/02-visuals.md +11 -0
  20. package/dist/docs/02-components/03-shells.md +1361 -0
  21. package/dist/docs/02-components/04-surfaces.md +11 -0
  22. package/dist/docs/02-components/index.md +106 -0
  23. package/dist/docs/03-recipes/01-forms.md +471 -0
  24. package/dist/docs/03-recipes/02-dashboards.md +397 -0
  25. package/dist/docs/03-recipes/03-layouts.md +424 -0
  26. package/dist/docs/04-theming.md +232 -0
  27. package/dist/docs/05-migration/01-breaking-changes.md +117 -0
  28. package/dist/docs/05-migration/02-formstore.md +336 -0
  29. package/dist/docs/06-troubleshooting.md +119 -0
  30. package/dist/docs/index.md +71 -0
  31. package/dist/id-registry.cjs +1875 -0
  32. package/dist/id-registry.d.cts +27 -0
  33. package/dist/id-registry.d.ts +27 -0
  34. package/dist/id-registry.js +1875 -0
  35. package/dist/id-registry.json +3799 -0
  36. package/dist/index-BZ_lBlO1.d.ts +474 -0
  37. package/dist/index-BuvxoWHf.d.cts +474 -0
  38. package/dist/index-DlAcuvQp.d.cts +1686 -0
  39. package/dist/index-Slu5hOj1.d.ts +1686 -0
  40. package/dist/index.cjs +9959 -0
  41. package/dist/index.d.cts +2351 -0
  42. package/dist/index.d.ts +2351 -0
  43. package/dist/index.js +9959 -0
  44. package/dist/meta.cjs +6898 -0
  45. package/dist/meta.d.cts +36 -0
  46. package/dist/meta.d.ts +36 -0
  47. package/dist/meta.js +6869 -0
  48. package/dist/shells/index.cjs +65 -0
  49. package/dist/shells/index.d.cts +5 -0
  50. package/dist/shells/index.d.ts +5 -0
  51. package/dist/shells/index.js +65 -0
  52. package/dist/tailwind.css +401 -0
  53. package/dist/theme/presets/default.css +355 -0
  54. package/dist/theme/presets/minimal.css +354 -0
  55. package/dist/theme/presets/mono-dark.css +354 -0
  56. package/dist/theme/presets/natural.css +181 -0
  57. package/dist/theme/presets/pro.css +354 -0
  58. package/dist/types-D4-0lwaE.d.cts +298 -0
  59. package/dist/types-D4-0lwaE.d.ts +298 -0
  60. package/dist/visuals/index.cjs +4 -0
  61. package/dist/visuals/index.d.cts +1 -0
  62. package/dist/visuals/index.d.ts +1 -0
  63. package/dist/visuals/index.js +4 -0
  64. package/package.json +165 -0
@@ -0,0 +1,4745 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }"use client";
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+ var _chunkAFF2HPE5cjs = require('./chunk-AFF2HPE5.cjs');
32
+
33
+
34
+
35
+
36
+ var _chunkONE3C5RVcjs = require('./chunk-ONE3C5RV.cjs');
37
+
38
+ // src/core/text.tsx
39
+
40
+
41
+ var _react = require('react'); var React = _interopRequireWildcard(_react); var React2 = _interopRequireWildcard(_react);
42
+ var toneStyles = {
43
+ primary: "text-text-primary",
44
+ secondary: "text-text-secondary",
45
+ tertiary: "text-text-tertiary",
46
+ inherit: "text-inherit"
47
+ };
48
+ function Text(_a) {
49
+ var _b = _a, {
50
+ as,
51
+ variant = "body",
52
+ tone = "primary",
53
+ truncate = false,
54
+ className,
55
+ children
56
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
57
+ "as",
58
+ "variant",
59
+ "tone",
60
+ "truncate",
61
+ "className",
62
+ "children"
63
+ ]);
64
+ const Component = as != null ? as : "span";
65
+ const elementProps = _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, props), {
66
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
67
+ `opt-type-${variant}`,
68
+ toneStyles[tone],
69
+ truncate && "truncate",
70
+ className
71
+ ),
72
+ "data-opt-component": "text",
73
+ "data-opt-part": "root",
74
+ "data-opt-id": "NFKP2",
75
+ "data-opt-slug": "text.Text",
76
+ "data-role": variant,
77
+ "data-tone": tone
78
+ });
79
+ return _react.createElement.call(void 0,
80
+ Component,
81
+ elementProps,
82
+ children
83
+ );
84
+ }
85
+
86
+ // src/core/heading.tsx
87
+
88
+ function Heading(_a) {
89
+ var _b = _a, {
90
+ level = 2,
91
+ variant = `heading-${level}`,
92
+ className,
93
+ children
94
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
95
+ "level",
96
+ "variant",
97
+ "className",
98
+ "children"
99
+ ]);
100
+ const Component = {
101
+ 1: "h1",
102
+ 2: "h2",
103
+ 3: "h3",
104
+ 4: "h4",
105
+ 5: "h5",
106
+ 6: "h6"
107
+ }[level];
108
+ return _react.createElement.call(void 0,
109
+ Component,
110
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
111
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, `opt-type-${variant}`, "text-text-primary", className)
112
+ }, props), {
113
+ "data-opt-component": "heading",
114
+ "data-opt-part": "root",
115
+ "data-opt-id": "NF0BT",
116
+ "data-opt-slug": "heading.Heading",
117
+ "data-level": level,
118
+ "data-role": variant
119
+ }),
120
+ children
121
+ );
122
+ }
123
+
124
+ // src/core/separator.tsx
125
+ var _optuiprimitives = require('@reopt-ai/opt-ui-primitives');
126
+ var _jsxruntime = require('react/jsx-runtime');
127
+ function Separator({
128
+ orientation = "horizontal",
129
+ decorative = false,
130
+ children,
131
+ className
132
+ }) {
133
+ if (orientation === "horizontal" && children != null) {
134
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
135
+ "div",
136
+ {
137
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "gap-element flex items-center", className),
138
+ "data-opt-id": "7PWJS",
139
+ "data-opt-slug": "separator.Separator",
140
+ children: [
141
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
142
+ _optuiprimitives.Separator,
143
+ {
144
+ decorative: true,
145
+ orientation: "horizontal",
146
+ className: "bg-border h-px flex-1"
147
+ }
148
+ ),
149
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-tertiary shrink-0 text-xs", children }),
150
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
151
+ _optuiprimitives.Separator,
152
+ {
153
+ decorative: true,
154
+ orientation: "horizontal",
155
+ className: "bg-border h-px flex-1"
156
+ }
157
+ )
158
+ ]
159
+ }
160
+ );
161
+ }
162
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
163
+ _optuiprimitives.Separator,
164
+ {
165
+ orientation,
166
+ decorative,
167
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
168
+ "bg-border shrink-0",
169
+ orientation === "horizontal" ? "h-px w-full" : "h-full w-px self-stretch",
170
+ className
171
+ ),
172
+ "data-opt-id": "7PWJS",
173
+ "data-opt-slug": "separator.Separator"
174
+ }
175
+ );
176
+ }
177
+ Separator.displayName = "Separator";
178
+
179
+ // src/core/otp-field.tsx
180
+
181
+
182
+ var PATTERNS = {
183
+ numeric: /[0-9]/,
184
+ alphanumeric: /[a-zA-Z0-9]/
185
+ };
186
+ function OtpField({
187
+ length = 6,
188
+ value: controlledValue,
189
+ defaultValue = "",
190
+ onChange,
191
+ onComplete,
192
+ type = "numeric",
193
+ mask = false,
194
+ disabled = false,
195
+ autoFocus = false,
196
+ name,
197
+ label,
198
+ required,
199
+ error,
200
+ hint,
201
+ className,
202
+ id,
203
+ "aria-label": ariaLabel
204
+ }) {
205
+ const reactId = React.useId();
206
+ const fieldId = id != null ? id : `otp-${reactId}`;
207
+ const hasError = Boolean(error);
208
+ const pattern = PATTERNS[type];
209
+ const inputsRef = React.useRef([]);
210
+ const labelId = label ? `${fieldId}-label` : void 0;
211
+ const groupLabelledBy = ariaLabel ? void 0 : labelId;
212
+ const groupAriaLabel = ariaLabel != null ? ariaLabel : groupLabelledBy ? void 0 : "One-time code";
213
+ const [value, setRawValue] = _chunkAFF2HPE5cjs.useControlledState.call(void 0,
214
+ defaultValue,
215
+ controlledValue,
216
+ onChange
217
+ );
218
+ const completedRef = React.useRef(false);
219
+ const setValue = React.useCallback(
220
+ (next) => {
221
+ const clipped = next.slice(0, length);
222
+ setRawValue(clipped);
223
+ if (clipped.length === length) {
224
+ if (!completedRef.current) {
225
+ completedRef.current = true;
226
+ onComplete == null ? void 0 : onComplete(clipped);
227
+ }
228
+ } else {
229
+ completedRef.current = false;
230
+ }
231
+ },
232
+ [length, setRawValue, onComplete]
233
+ );
234
+ const focusCell = React.useCallback((index) => {
235
+ var _a, _b;
236
+ const target = Math.max(0, Math.min(index, inputsRef.current.length - 1));
237
+ (_a = inputsRef.current[target]) == null ? void 0 : _a.focus();
238
+ (_b = inputsRef.current[target]) == null ? void 0 : _b.select();
239
+ }, []);
240
+ const cells = React.useMemo(
241
+ () => Array.from({ length }, (_, i) => {
242
+ var _a;
243
+ return (_a = value[i]) != null ? _a : "";
244
+ }),
245
+ [length, value]
246
+ );
247
+ const setCell = React.useCallback(
248
+ (index, char) => {
249
+ const arr = Array.from({ length }, (_, i) => {
250
+ var _a;
251
+ return (_a = value[i]) != null ? _a : "";
252
+ });
253
+ arr[index] = char;
254
+ setValue(arr.join(""));
255
+ },
256
+ [length, value, setValue]
257
+ );
258
+ const handleChange = React.useCallback(
259
+ (index) => (e) => {
260
+ var _a;
261
+ const raw = e.target.value;
262
+ const chars = raw.split("").filter((c) => pattern.test(c));
263
+ const char = (_a = chars[chars.length - 1]) != null ? _a : "";
264
+ if (char === "" && raw !== "") return;
265
+ setCell(index, char);
266
+ if (char) focusCell(index + 1);
267
+ },
268
+ [pattern, setCell, focusCell]
269
+ );
270
+ const handleKeyDown = React.useCallback(
271
+ (index) => (e) => {
272
+ switch (e.key) {
273
+ case "Backspace":
274
+ e.preventDefault();
275
+ if (cells[index]) {
276
+ setCell(index, "");
277
+ } else if (index > 0) {
278
+ setCell(index - 1, "");
279
+ focusCell(index - 1);
280
+ }
281
+ break;
282
+ case "ArrowLeft":
283
+ e.preventDefault();
284
+ focusCell(index - 1);
285
+ break;
286
+ case "ArrowRight":
287
+ e.preventDefault();
288
+ focusCell(index + 1);
289
+ break;
290
+ default:
291
+ break;
292
+ }
293
+ },
294
+ [cells, setCell, focusCell]
295
+ );
296
+ const handlePaste = React.useCallback(
297
+ (index) => (e) => {
298
+ e.preventDefault();
299
+ const pasted = e.clipboardData.getData("text").split("").filter((c) => pattern.test(c)).join("");
300
+ if (!pasted) return;
301
+ const arr = Array.from({ length }, (_, i) => {
302
+ var _a;
303
+ return (_a = value[i]) != null ? _a : "";
304
+ });
305
+ for (let i = 0; i < pasted.length && index + i < length; i++) {
306
+ arr[index + i] = pasted[i];
307
+ }
308
+ setValue(arr.join(""));
309
+ focusCell(index + pasted.length);
310
+ },
311
+ [pattern, length, value, setValue, focusCell]
312
+ );
313
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
314
+ "div",
315
+ {
316
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex flex-col gap-1.5", className),
317
+ "data-opt-id": "0083Q",
318
+ "data-opt-slug": "otp-field.OtpField",
319
+ children: [
320
+ label && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: _chunkAFF2HPE5cjs.OPT_TEXT_LABEL, id: labelId, children: [
321
+ label,
322
+ required && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.RequiredMark, {})
323
+ ] }),
324
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
325
+ "div",
326
+ {
327
+ role: "group",
328
+ "aria-label": groupAriaLabel,
329
+ "aria-labelledby": groupLabelledBy,
330
+ "aria-describedby": _chunkAFF2HPE5cjs.getDescribedBy.call(void 0, fieldId, error, hint),
331
+ className: "gap-element flex items-center",
332
+ children: cells.map((cell, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
333
+ "input",
334
+ {
335
+ ref: (node) => {
336
+ inputsRef.current[i] = node;
337
+ },
338
+ type: mask ? "password" : "text",
339
+ inputMode: type === "numeric" ? "numeric" : "text",
340
+ autoComplete: i === 0 ? "one-time-code" : "off",
341
+ autoFocus: autoFocus && i === 0,
342
+ maxLength: 1,
343
+ disabled,
344
+ "aria-label": `${i + 1}\uBC88\uC9F8 \uC790\uB9AC`,
345
+ "aria-invalid": hasError || void 0,
346
+ value: cell,
347
+ onChange: handleChange(i),
348
+ onKeyDown: handleKeyDown(i),
349
+ onPaste: handlePaste(i),
350
+ onFocus: (e) => e.target.select(),
351
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
352
+ _chunkAFF2HPE5cjs.OPT_INPUT,
353
+ "h-12 w-10 text-center text-lg font-medium",
354
+ hasError && _chunkAFF2HPE5cjs.OPT_INPUT_ERROR
355
+ )
356
+ },
357
+ i
358
+ ))
359
+ }
360
+ ),
361
+ name && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { type: "hidden", name, value, disabled }),
362
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FieldMessages, { id: fieldId, error, hint })
363
+ ]
364
+ }
365
+ );
366
+ }
367
+ OtpField.displayName = "OtpField";
368
+
369
+ // src/core/toggle.tsx
370
+
371
+
372
+
373
+
374
+
375
+ var sizeStyles = {
376
+ sm: "h-8 min-w-8 px-2 text-xs gap-1.5",
377
+ md: "h-10 min-w-10 px-3 text-sm gap-2"
378
+ };
379
+ var toggleBase = _chunkAFF2HPE5cjs.cn.call(void 0,
380
+ "inline-flex cursor-pointer items-center justify-center rounded-md border border-border bg-surface font-medium text-text-secondary",
381
+ "hover:bg-bg-subtle hover:text-text-primary",
382
+ "data-[pressed]:border-accent data-[pressed]:bg-accent-subtle data-[pressed]:text-accent",
383
+ "disabled:pointer-events-none disabled:opacity-40",
384
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
385
+ );
386
+ function Toggle(_a) {
387
+ var _b = _a, {
388
+ size = "md",
389
+ className,
390
+ children
391
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
392
+ "size",
393
+ "className",
394
+ "children"
395
+ ]);
396
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
397
+ _optuiprimitives.Toggle,
398
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
399
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, toggleBase, sizeStyles[size], className)
400
+ }, props), {
401
+ "data-opt-id": "GFCMY",
402
+ "data-opt-slug": "toggle.Toggle",
403
+ children
404
+ })
405
+ );
406
+ }
407
+ Toggle.displayName = "Toggle";
408
+ function ToggleGroup(_a) {
409
+ var _b = _a, {
410
+ className,
411
+ children,
412
+ orientation = "horizontal"
413
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
414
+ "className",
415
+ "children",
416
+ "orientation"
417
+ ]);
418
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
419
+ _optuiprimitives.ToggleGroup,
420
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
421
+ orientation,
422
+ "aria-orientation": orientation,
423
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
424
+ "inline-flex gap-1",
425
+ orientation === "vertical" ? "flex-col" : "flex-row",
426
+ className
427
+ )
428
+ }, props), {
429
+ "data-opt-id": "47J37",
430
+ "data-opt-slug": "toggle.ToggleGroup",
431
+ children
432
+ })
433
+ );
434
+ }
435
+ ToggleGroup.displayName = "ToggleGroup";
436
+
437
+ // src/core/accordion.tsx
438
+ var _lucidereact = require('lucide-react');
439
+
440
+
441
+
442
+
443
+
444
+
445
+
446
+ var triggerClass = `group/acc-trigger flex w-full cursor-pointer items-center justify-between gap-2 py-4 text-left text-sm font-medium text-text-primary transition-colors hover:text-text-secondary ${_chunkAFF2HPE5cjs.OPT_FOCUS} disabled:cursor-not-allowed disabled:opacity-50`;
447
+ var contentClass = `overflow-hidden text-sm text-text-secondary ${_chunkAFF2HPE5cjs.OPT_ANIMATE_ENTER_EXIT}`;
448
+ function AccordionRoot(_a) {
449
+ var _b = _a, {
450
+ className
451
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
452
+ "className"
453
+ ]);
454
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
455
+ "div",
456
+ {
457
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "border-border border-y", className),
458
+ "data-opt-id": "CSBA9",
459
+ "data-opt-slug": "accordion.AccordionRoot",
460
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _optuiprimitives.AccordionRoot, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, props))
461
+ }
462
+ );
463
+ }
464
+ AccordionRoot.displayName = "AccordionRoot";
465
+ function AccordionItem(_a) {
466
+ var _b = _a, { className } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, ["className"]);
467
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
468
+ _optuiprimitives.AccordionItem,
469
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
470
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "border-border border-b last:border-b-0", className)
471
+ }, props), {
472
+ "data-opt-id": "JTY9M",
473
+ "data-opt-slug": "accordion.AccordionItem"
474
+ })
475
+ );
476
+ }
477
+ AccordionItem.displayName = "AccordionItem";
478
+ function AccordionTrigger(_a) {
479
+ var _b = _a, {
480
+ className,
481
+ children
482
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
483
+ "className",
484
+ "children"
485
+ ]);
486
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
487
+ _optuiprimitives.AccordionTrigger,
488
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
489
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, triggerClass, className)
490
+ }, props), {
491
+ "data-opt-id": "CWJZZ",
492
+ "data-opt-slug": "accordion.AccordionTrigger",
493
+ children: [
494
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex-1", children }),
495
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
496
+ _lucidereact.ChevronDown,
497
+ {
498
+ "aria-hidden": "true",
499
+ className: "text-text-tertiary h-4 w-4 shrink-0 transition-transform duration-200 group-data-[state=open]/acc-trigger:rotate-180"
500
+ }
501
+ )
502
+ ]
503
+ })
504
+ );
505
+ }
506
+ AccordionTrigger.displayName = "AccordionTrigger";
507
+ function AccordionContent(_a) {
508
+ var _b = _a, {
509
+ className,
510
+ children
511
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
512
+ "className",
513
+ "children"
514
+ ]);
515
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
516
+ _optuiprimitives.AccordionContent,
517
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
518
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, contentClass, className)
519
+ }, props), {
520
+ "data-opt-id": "J98AG",
521
+ "data-opt-slug": "accordion.AccordionContent",
522
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "pb-4", children })
523
+ })
524
+ );
525
+ }
526
+ AccordionContent.displayName = "AccordionContent";
527
+
528
+ // src/core/breadcrumb.tsx
529
+
530
+ function interpolate(template, values) {
531
+ return template.replace(
532
+ /\{(\w+)\}/g,
533
+ (_, key) => key in values ? String(values[key]) : `{${key}}`
534
+ );
535
+ }
536
+ function Breadcrumb({
537
+ items,
538
+ separator = "/",
539
+ className,
540
+ onNavigate,
541
+ "aria-label": ariaLabel = "Breadcrumb"
542
+ }) {
543
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
544
+ "nav",
545
+ {
546
+ "aria-label": ariaLabel,
547
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex items-center gap-1 px-1.5 text-sm", className),
548
+ "data-opt-id": "3FR0Y",
549
+ "data-opt-slug": "breadcrumb.Breadcrumb",
550
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "flex items-center gap-1", children: items.map((item, index) => {
551
+ const isLast = index === items.length - 1;
552
+ const linkClassName = _chunkAFF2HPE5cjs.cn.call(void 0,
553
+ `flex items-center gap-1.5 rounded-sm ${_chunkAFF2HPE5cjs.OPT_FOCUS} transition-colors`,
554
+ item.disabled ? `${_chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY} cursor-not-allowed` : `${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY} hover:text-text-primary cursor-pointer`
555
+ );
556
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: "flex items-center gap-1", children: isLast ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
557
+ "span",
558
+ {
559
+ "aria-current": "page",
560
+ className: `flex items-center gap-1.5 font-medium ${_chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY}`,
561
+ children: [
562
+ item.icon,
563
+ item.label
564
+ ]
565
+ }
566
+ ) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
567
+ item.href ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
568
+ "a",
569
+ {
570
+ href: item.disabled ? void 0 : item.href,
571
+ "aria-disabled": item.disabled || void 0,
572
+ className: linkClassName,
573
+ onClick: () => !item.disabled && (onNavigate == null ? void 0 : onNavigate(item)),
574
+ children: [
575
+ item.icon,
576
+ item.label
577
+ ]
578
+ }
579
+ ) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
580
+ "button",
581
+ {
582
+ type: "button",
583
+ disabled: item.disabled,
584
+ "aria-label": interpolate(_chunkAFF2HPE5cjs.koBreadcrumbLabels.navAriaLabel, {
585
+ label: item.label
586
+ }),
587
+ className: linkClassName,
588
+ onClick: () => !item.disabled && (onNavigate == null ? void 0 : onNavigate(item)),
589
+ children: [
590
+ item.icon,
591
+ item.label
592
+ ]
593
+ }
594
+ ),
595
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { "aria-hidden": "true", className: _chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY, children: separator })
596
+ ] }) }, item.id);
597
+ }) })
598
+ }
599
+ );
600
+ }
601
+
602
+ // src/core/card.tsx
603
+
604
+ function Card(_a) {
605
+ var _b = _a, {
606
+ variant = "default",
607
+ padding = "md",
608
+ shadow = true,
609
+ selectable = false,
610
+ selected = false,
611
+ onSelectedChange,
612
+ className,
613
+ children,
614
+ onClick,
615
+ onKeyDown,
616
+ role,
617
+ tabIndex
618
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
619
+ "variant",
620
+ "padding",
621
+ "shadow",
622
+ "selectable",
623
+ "selected",
624
+ "onSelectedChange",
625
+ "className",
626
+ "children",
627
+ "onClick",
628
+ "onKeyDown",
629
+ "role",
630
+ "tabIndex"
631
+ ]);
632
+ const isInteractive = selectable || !!onClick;
633
+ const handleClick = selectable ? (e) => {
634
+ onSelectedChange == null ? void 0 : onSelectedChange(!selected);
635
+ onClick == null ? void 0 : onClick(e);
636
+ } : onClick;
637
+ const handleKeyDown = selectable ? (e) => {
638
+ if (e.key === "Enter" || e.key === " ") {
639
+ e.preventDefault();
640
+ onSelectedChange == null ? void 0 : onSelectedChange(!selected);
641
+ }
642
+ onKeyDown == null ? void 0 : onKeyDown(e);
643
+ } : isInteractive ? (e) => {
644
+ if (e.key === "Enter" || e.key === " ") {
645
+ e.preventDefault();
646
+ e.currentTarget.click();
647
+ }
648
+ onKeyDown == null ? void 0 : onKeyDown(e);
649
+ } : onKeyDown;
650
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
651
+ "div",
652
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, props), {
653
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
654
+ "rounded-xl",
655
+ variant === "default" && _chunkAFF2HPE5cjs.cn.call(void 0, `${_chunkAFF2HPE5cjs.OPT_BORDER} bg-surface`, shadow && "shadow-sm"),
656
+ variant === "outline" && "border-border border-2 bg-transparent",
657
+ variant === "ghost" && "bg-bg-subtle",
658
+ padding === "none" && "p-0",
659
+ padding === "sm" && "p-3",
660
+ padding === "md" && "p-5",
661
+ padding === "lg" && "p-8",
662
+ selectable && "cursor-pointer transition-colors",
663
+ selectable && selected && "ring-accent border-accent ring-2 ring-offset-1",
664
+ selectable && !selected && "hover:border-accent/50",
665
+ className
666
+ )
667
+ }), isInteractive ? {
668
+ role: selectable ? "option" : "button",
669
+ tabIndex: 0,
670
+ "aria-selected": selectable ? selected : void 0,
671
+ onClick: handleClick,
672
+ onKeyDown: handleKeyDown
673
+ } : {
674
+ role,
675
+ tabIndex,
676
+ "aria-selected": selectable ? selected : void 0,
677
+ onKeyDown
678
+ }), {
679
+ "data-opt-id": "0A18R",
680
+ "data-opt-slug": "card.Card",
681
+ children
682
+ })
683
+ );
684
+ }
685
+ var headerGapClasses = {
686
+ sm: "gap-1",
687
+ md: "gap-1.5",
688
+ lg: "gap-2"
689
+ };
690
+ function CardHeader(_a) {
691
+ var _b = _a, {
692
+ gap = "sm",
693
+ className,
694
+ children
695
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
696
+ "gap",
697
+ "className",
698
+ "children"
699
+ ]);
700
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
701
+ "div",
702
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
703
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex flex-col", headerGapClasses[gap], className)
704
+ }, props), {
705
+ "data-opt-id": "JST3J",
706
+ "data-opt-slug": "card.CardHeader",
707
+ children
708
+ })
709
+ );
710
+ }
711
+ function CardTitle(_a) {
712
+ var _b = _a, {
713
+ as: Tag = "h3",
714
+ className,
715
+ children
716
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
717
+ "as",
718
+ "className",
719
+ "children"
720
+ ]);
721
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
722
+ Tag,
723
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
724
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, `text-lg font-semibold ${_chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY}`, className)
725
+ }, props), {
726
+ "data-opt-id": "V15TX",
727
+ "data-opt-slug": "card.CardTitle",
728
+ children
729
+ })
730
+ );
731
+ }
732
+ function CardDescription(_a) {
733
+ var _b = _a, {
734
+ className,
735
+ children
736
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
737
+ "className",
738
+ "children"
739
+ ]);
740
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
741
+ "p",
742
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
743
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, `text-sm ${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY}`, className)
744
+ }, props), {
745
+ "data-opt-id": "YB1RN",
746
+ "data-opt-slug": "card.CardDescription",
747
+ children
748
+ })
749
+ );
750
+ }
751
+ var contentSpacingClasses = {
752
+ none: "",
753
+ sm: "mt-2",
754
+ md: "mt-4",
755
+ lg: "mt-6"
756
+ };
757
+ function CardContent(_a) {
758
+ var _b = _a, {
759
+ spacing = "md",
760
+ className,
761
+ children
762
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
763
+ "spacing",
764
+ "className",
765
+ "children"
766
+ ]);
767
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
768
+ "div",
769
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
770
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, contentSpacingClasses[spacing], className)
771
+ }, props), {
772
+ "data-opt-id": "9Y68R",
773
+ "data-opt-slug": "card.CardContent",
774
+ children
775
+ })
776
+ );
777
+ }
778
+ function CardFooter(_a) {
779
+ var _b = _a, {
780
+ divider = true,
781
+ className,
782
+ children
783
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
784
+ "divider",
785
+ "className",
786
+ "children"
787
+ ]);
788
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
789
+ "div",
790
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
791
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
792
+ "mt-4 flex items-center justify-end gap-2 pt-4",
793
+ divider && `border-t ${_chunkAFF2HPE5cjs.OPT_BORDER}`,
794
+ className
795
+ )
796
+ }, props), {
797
+ "data-opt-id": "GRNTR",
798
+ "data-opt-slug": "card.CardFooter",
799
+ children
800
+ })
801
+ );
802
+ }
803
+
804
+ // src/core/input.tsx
805
+
806
+
807
+
808
+
809
+
810
+ var inputSizeStyles = _chunkAFF2HPE5cjs.OPT_INPUT_SIZE;
811
+ var Input = _react.forwardRef.call(void 0,
812
+ (_a, ref) => {
813
+ var _b = _a, {
814
+ label,
815
+ error,
816
+ hint,
817
+ leftIcon,
818
+ rightIcon,
819
+ fullWidth = false,
820
+ size = "md",
821
+ required,
822
+ className,
823
+ id
824
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
825
+ "label",
826
+ "error",
827
+ "hint",
828
+ "leftIcon",
829
+ "rightIcon",
830
+ "fullWidth",
831
+ "size",
832
+ "required",
833
+ "className",
834
+ "id"
835
+ ]);
836
+ var _a2;
837
+ const fallbackId = _react.useId.call(void 0, ).replace(/:/g, "");
838
+ const inputId = (_a2 = _chunkAFF2HPE5cjs.useInputId.call(void 0, id, label, "input")) != null ? _a2 : `input-${fallbackId}`;
839
+ const hasError = Boolean(error);
840
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
841
+ "div",
842
+ {
843
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex flex-col gap-1.5", fullWidth && "w-full"),
844
+ "data-opt-id": "7BY1Q",
845
+ "data-opt-slug": "input.Input",
846
+ children: [
847
+ label && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
848
+ "label",
849
+ {
850
+ htmlFor: inputId,
851
+ className: "text-text-primary text-sm font-medium",
852
+ children: [
853
+ label,
854
+ required && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.RequiredMark, {})
855
+ ]
856
+ }
857
+ ),
858
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative", children: [
859
+ leftIcon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-text-tertiary pointer-events-none absolute top-1/2 left-3 -translate-y-1/2", children: leftIcon }),
860
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
861
+ "input",
862
+ _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
863
+ ref,
864
+ id: inputId,
865
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
866
+ _chunkAFF2HPE5cjs.OPT_INPUT,
867
+ inputSizeStyles[size],
868
+ leftIcon && (size === "sm" ? "pl-8" : "pl-10"),
869
+ rightIcon && (size === "sm" ? "pr-8" : "pr-10"),
870
+ hasError && _chunkAFF2HPE5cjs.OPT_INPUT_ERROR,
871
+ !fullWidth && "w-auto",
872
+ className
873
+ ),
874
+ "aria-invalid": hasError,
875
+ "aria-required": required,
876
+ "aria-describedby": _chunkAFF2HPE5cjs.getDescribedBy.call(void 0, inputId, error, hint),
877
+ required
878
+ }, props)
879
+ ),
880
+ rightIcon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-text-tertiary pointer-events-none absolute top-1/2 right-3 -translate-y-1/2", children: rightIcon })
881
+ ] }),
882
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FieldMessages, { id: inputId, error, hint })
883
+ ]
884
+ }
885
+ );
886
+ }
887
+ );
888
+ Input.displayName = "Input";
889
+
890
+ // src/core/switch.tsx
891
+
892
+
893
+
894
+
895
+
896
+
897
+
898
+ var sizeStyles2 = {
899
+ sm: {
900
+ track: "h-5 w-9",
901
+ thumb: "h-4 w-4",
902
+ translate: "translate-x-4"
903
+ },
904
+ md: {
905
+ track: "h-6 w-11",
906
+ thumb: "h-5 w-5",
907
+ translate: "translate-x-5"
908
+ },
909
+ lg: {
910
+ track: "h-7 w-14",
911
+ thumb: "h-6 w-6",
912
+ translate: "translate-x-7"
913
+ }
914
+ };
915
+ var Switch = _react.forwardRef.call(void 0,
916
+ (_a, ref) => {
917
+ var _b = _a, {
918
+ label,
919
+ required,
920
+ error,
921
+ hint,
922
+ description,
923
+ checked: controlledChecked,
924
+ defaultChecked = false,
925
+ onChange,
926
+ size = "md",
927
+ disabled,
928
+ className,
929
+ id,
930
+ onClick,
931
+ "aria-label": ariaLabel,
932
+ "aria-labelledby": ariaLabelledBy
933
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
934
+ "label",
935
+ "required",
936
+ "error",
937
+ "hint",
938
+ "description",
939
+ "checked",
940
+ "defaultChecked",
941
+ "onChange",
942
+ "size",
943
+ "disabled",
944
+ "className",
945
+ "id",
946
+ "onClick",
947
+ "aria-label",
948
+ "aria-labelledby"
949
+ ]);
950
+ var _a2;
951
+ const fallbackId = _react.useId.call(void 0, );
952
+ const switchId = (_a2 = _chunkAFF2HPE5cjs.useInputId.call(void 0, id, label, "switch")) != null ? _a2 : `switch-${fallbackId}`;
953
+ const hintText = hint != null ? hint : description;
954
+ const hasError = Boolean(error);
955
+ const styles = sizeStyles2[size];
956
+ const labelId = label ? `${switchId}-label` : void 0;
957
+ const switchLabelledBy = ariaLabelledBy != null ? ariaLabelledBy : ariaLabel ? void 0 : labelId;
958
+ const switchAriaLabel = ariaLabel != null ? ariaLabel : switchLabelledBy ? void 0 : "Switch";
959
+ const isControlled = controlledChecked !== void 0;
960
+ const [internalChecked, setInternalChecked] = _react.useState.call(void 0, defaultChecked);
961
+ const checked = isControlled ? controlledChecked : internalChecked;
962
+ const handleClick = _react.useCallback.call(void 0,
963
+ (e) => {
964
+ const next = !checked;
965
+ if (!isControlled) setInternalChecked(next);
966
+ onChange == null ? void 0 : onChange(next);
967
+ onClick == null ? void 0 : onClick(e);
968
+ },
969
+ [checked, isControlled, onChange, onClick]
970
+ );
971
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
972
+ "div",
973
+ {
974
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex flex-col gap-1.5", className),
975
+ "data-opt-id": "51Z9R",
976
+ "data-opt-slug": "switch.Switch",
977
+ children: [
978
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-start gap-3", children: [
979
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
980
+ "button",
981
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
982
+ ref,
983
+ type: "button",
984
+ role: "switch",
985
+ id: switchId,
986
+ "aria-checked": checked,
987
+ "aria-label": switchAriaLabel,
988
+ "aria-labelledby": switchLabelledBy,
989
+ disabled,
990
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
991
+ "group relative inline-flex shrink-0 cursor-pointer rounded-full p-0.5 transition-colors",
992
+ styles.track,
993
+ "bg-bg-muted",
994
+ "aria-[checked=true]:bg-accent",
995
+ "disabled:cursor-not-allowed disabled:opacity-50",
996
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
997
+ ),
998
+ "aria-invalid": hasError,
999
+ "aria-required": required,
1000
+ "aria-describedby": _chunkAFF2HPE5cjs.getDescribedBy.call(void 0, switchId, error, hintText),
1001
+ onClick: handleClick
1002
+ }, props), {
1003
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1004
+ "span",
1005
+ {
1006
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1007
+ // eslint-disable-next-line opt-ui/no-raw-color -- switch thumb은 라이트/다크 공통 흰색 (디자인 시스템 표준)
1008
+ "pointer-events-none inline-block transform rounded-full bg-white shadow-sm ring-0 transition-transform",
1009
+ styles.thumb,
1010
+ "translate-x-0",
1011
+ size === "sm" && "group-aria-[checked=true]:translate-x-4",
1012
+ size === "md" && "group-aria-[checked=true]:translate-x-5",
1013
+ size === "lg" && "group-aria-[checked=true]:translate-x-7"
1014
+ )
1015
+ }
1016
+ )
1017
+ })
1018
+ ),
1019
+ (label || hintText) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col", children: [
1020
+ label && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1021
+ "span",
1022
+ {
1023
+ id: labelId,
1024
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1025
+ "text-text-primary text-sm font-medium",
1026
+ disabled && "opacity-50"
1027
+ ),
1028
+ children: [
1029
+ label,
1030
+ required && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.RequiredMark, {})
1031
+ ]
1032
+ }
1033
+ ),
1034
+ hintText && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1035
+ "p",
1036
+ {
1037
+ id: `${switchId}-hint`,
1038
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1039
+ "text-text-tertiary text-sm",
1040
+ disabled && "opacity-50"
1041
+ ),
1042
+ children: hintText
1043
+ }
1044
+ )
1045
+ ] })
1046
+ ] }),
1047
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FieldMessages, { id: switchId, error })
1048
+ ]
1049
+ }
1050
+ );
1051
+ }
1052
+ );
1053
+ Switch.displayName = "Switch";
1054
+
1055
+ // src/core/skeleton.tsx
1056
+
1057
+ var variantStyles = {
1058
+ text: "rounded h-4",
1059
+ circular: "rounded-full",
1060
+ rectangular: "rounded-lg"
1061
+ };
1062
+ function Skeleton(_a) {
1063
+ var _b = _a, {
1064
+ variant = "text",
1065
+ width,
1066
+ height,
1067
+ lines = 1,
1068
+ animated = true,
1069
+ className,
1070
+ style
1071
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
1072
+ "variant",
1073
+ "width",
1074
+ "height",
1075
+ "lines",
1076
+ "animated",
1077
+ "className",
1078
+ "style"
1079
+ ]);
1080
+ const baseClass = _chunkAFF2HPE5cjs.cn.call(void 0,
1081
+ "bg-bg-subtle",
1082
+ animated && "animate-pulse",
1083
+ variantStyles[variant],
1084
+ className
1085
+ );
1086
+ const computedStyle = _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1087
+ width: typeof width === "number" ? `${width}px` : width,
1088
+ height: typeof height === "number" ? `${height}px` : height
1089
+ }, style);
1090
+ if (variant === "text" && lines > 1) {
1091
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1092
+ "div",
1093
+ {
1094
+ className: "gap-element flex flex-col",
1095
+ role: "status",
1096
+ "aria-label": "Loading",
1097
+ "data-opt-id": "EJT87",
1098
+ "data-opt-slug": "skeleton.Skeleton",
1099
+ children: [
1100
+ Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1101
+ "div",
1102
+ _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1103
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, baseClass, i === lines - 1 && "w-4/5"),
1104
+ style: i === lines - 1 ? void 0 : computedStyle
1105
+ }, props),
1106
+ i
1107
+ )),
1108
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "sr-only", children: "Loading..." })
1109
+ ]
1110
+ }
1111
+ );
1112
+ }
1113
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1114
+ "div",
1115
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1116
+ className: baseClass,
1117
+ style: computedStyle,
1118
+ role: "status",
1119
+ "aria-label": "Loading"
1120
+ }, props), {
1121
+ "data-opt-id": "EJT87",
1122
+ "data-opt-slug": "skeleton.Skeleton",
1123
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "sr-only", children: "Loading..." })
1124
+ })
1125
+ );
1126
+ }
1127
+ function SkeletonText(_a) {
1128
+ var _b = _a, {
1129
+ lines = 3,
1130
+ className
1131
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
1132
+ "lines",
1133
+ "className"
1134
+ ]);
1135
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1136
+ Skeleton,
1137
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1138
+ variant: "text",
1139
+ lines,
1140
+ className
1141
+ }, props), {
1142
+ "data-opt-id": "MX3D5",
1143
+ "data-opt-slug": "skeleton.SkeletonText"
1144
+ })
1145
+ );
1146
+ }
1147
+ function SkeletonAvatar(_a) {
1148
+ var _b = _a, {
1149
+ size = 40,
1150
+ className
1151
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
1152
+ "size",
1153
+ "className"
1154
+ ]);
1155
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1156
+ Skeleton,
1157
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1158
+ variant: "circular",
1159
+ width: size,
1160
+ height: size,
1161
+ className
1162
+ }, props), {
1163
+ "data-opt-id": "MP0HZ",
1164
+ "data-opt-slug": "skeleton.SkeletonAvatar"
1165
+ })
1166
+ );
1167
+ }
1168
+ function SkeletonCard(_a) {
1169
+ var _b = _a, {
1170
+ className
1171
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
1172
+ "className"
1173
+ ]);
1174
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1175
+ "div",
1176
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1177
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "gap-group flex flex-col", className)
1178
+ }, props), {
1179
+ "data-opt-id": "34V5D",
1180
+ "data-opt-slug": "skeleton.SkeletonCard",
1181
+ children: [
1182
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Skeleton, { variant: "rectangular", height: 120 }),
1183
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Skeleton, { variant: "text", width: "60%" }),
1184
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Skeleton, { variant: "text", lines: 2 })
1185
+ ]
1186
+ })
1187
+ );
1188
+ }
1189
+ function SkeletonTable({
1190
+ rows = 5,
1191
+ columns = 4,
1192
+ className
1193
+ }) {
1194
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1195
+ "div",
1196
+ {
1197
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "gap-element flex flex-col", className),
1198
+ role: "status",
1199
+ "aria-label": "Loading table",
1200
+ "data-opt-id": "3KEDN",
1201
+ "data-opt-slug": "skeleton.SkeletonTable",
1202
+ children: [
1203
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border-border-subtle gap-group flex border-b pb-2", children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Skeleton, { variant: "text", className: "flex-1", height: 16 }, i)) }),
1204
+ Array.from({ length: rows }).map((_, rowIndex) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "gap-group flex py-2", children: Array.from({ length: columns }).map((_2, colIndex) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1205
+ Skeleton,
1206
+ {
1207
+ variant: "text",
1208
+ className: "flex-1",
1209
+ height: 14
1210
+ },
1211
+ colIndex
1212
+ )) }, rowIndex)),
1213
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "sr-only", children: "Loading..." })
1214
+ ]
1215
+ }
1216
+ );
1217
+ }
1218
+
1219
+ // src/core/textarea.tsx
1220
+
1221
+
1222
+ var textareaSizeStyles = _chunkAFF2HPE5cjs.OPT_TEXTAREA_SIZE;
1223
+ var resizeStyles = {
1224
+ none: "resize-none",
1225
+ vertical: "resize-y",
1226
+ horizontal: "resize-x",
1227
+ both: "resize"
1228
+ };
1229
+ var Textarea = _react.forwardRef.call(void 0,
1230
+ (_a, ref) => {
1231
+ var _b = _a, {
1232
+ label,
1233
+ error,
1234
+ hint,
1235
+ fullWidth = false,
1236
+ required,
1237
+ resize = "vertical",
1238
+ size = "md",
1239
+ className,
1240
+ id,
1241
+ rows = 4
1242
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
1243
+ "label",
1244
+ "error",
1245
+ "hint",
1246
+ "fullWidth",
1247
+ "required",
1248
+ "resize",
1249
+ "size",
1250
+ "className",
1251
+ "id",
1252
+ "rows"
1253
+ ]);
1254
+ var _a2;
1255
+ const fallbackId = _react.useId.call(void 0, ).replace(/:/g, "");
1256
+ const textareaId = (_a2 = _chunkAFF2HPE5cjs.useInputId.call(void 0, id, label, "textarea")) != null ? _a2 : `textarea-${fallbackId}`;
1257
+ const hasError = Boolean(error);
1258
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1259
+ "div",
1260
+ {
1261
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex flex-col gap-1.5", fullWidth && "w-full"),
1262
+ "data-opt-id": "6T58H",
1263
+ "data-opt-slug": "textarea.Textarea",
1264
+ children: [
1265
+ label && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1266
+ "label",
1267
+ {
1268
+ htmlFor: textareaId,
1269
+ className: "text-text-primary text-sm font-medium",
1270
+ children: [
1271
+ label,
1272
+ required && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.RequiredMark, {})
1273
+ ]
1274
+ }
1275
+ ),
1276
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1277
+ "textarea",
1278
+ _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1279
+ ref,
1280
+ id: textareaId,
1281
+ rows,
1282
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1283
+ "border-border bg-surface text-text-primary placeholder:text-text-tertiary w-full rounded-lg border px-4 py-3 text-sm outline-transparent",
1284
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE,
1285
+ textareaSizeStyles[size],
1286
+ resizeStyles[resize],
1287
+ hasError && _chunkAFF2HPE5cjs.OPT_INPUT_ERROR,
1288
+ !fullWidth && "w-auto",
1289
+ className
1290
+ ),
1291
+ "aria-invalid": hasError,
1292
+ "aria-describedby": _chunkAFF2HPE5cjs.getDescribedBy.call(void 0, textareaId, error, hint)
1293
+ }, props)
1294
+ ),
1295
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FieldMessages, { id: textareaId, error, hint })
1296
+ ]
1297
+ }
1298
+ );
1299
+ }
1300
+ );
1301
+ Textarea.displayName = "Textarea";
1302
+
1303
+ // src/core/avatar.tsx
1304
+
1305
+
1306
+
1307
+
1308
+
1309
+
1310
+ var useIsoLayoutEffect = typeof window !== "undefined" ? _react.useLayoutEffect : _react.useEffect;
1311
+ function useImageLoadingStatus(src, {
1312
+ srcSet,
1313
+ sizes,
1314
+ crossOrigin,
1315
+ referrerPolicy
1316
+ }) {
1317
+ const [status, setStatus] = _react.useState.call(void 0, "idle");
1318
+ useIsoLayoutEffect(() => {
1319
+ if (!src && !srcSet) {
1320
+ setStatus("error");
1321
+ return void 0;
1322
+ }
1323
+ let isMounted = true;
1324
+ const image = new window.Image();
1325
+ const update = (next) => () => {
1326
+ if (isMounted) {
1327
+ setStatus(next);
1328
+ }
1329
+ };
1330
+ setStatus("loading");
1331
+ image.onload = update("loaded");
1332
+ image.onerror = update("error");
1333
+ if (referrerPolicy) {
1334
+ image.referrerPolicy = referrerPolicy;
1335
+ }
1336
+ image.crossOrigin = crossOrigin != null ? crossOrigin : null;
1337
+ if (sizes) {
1338
+ image.sizes = sizes;
1339
+ }
1340
+ if (srcSet) {
1341
+ image.srcset = srcSet;
1342
+ }
1343
+ if (src) {
1344
+ image.src = src;
1345
+ }
1346
+ if (image.complete) {
1347
+ setStatus(image.naturalWidth > 0 ? "loaded" : "error");
1348
+ }
1349
+ return () => {
1350
+ isMounted = false;
1351
+ };
1352
+ }, [src, srcSet, sizes, crossOrigin, referrerPolicy]);
1353
+ return status;
1354
+ }
1355
+ var sizeStyles3 = {
1356
+ xs: "h-6 w-6 text-[10px]",
1357
+ sm: "h-8 w-8 text-xs",
1358
+ md: "h-10 w-10 text-sm",
1359
+ lg: "h-12 w-12 text-base",
1360
+ xl: "h-16 w-16 text-lg"
1361
+ };
1362
+ var statusStyles = {
1363
+ online: "bg-success",
1364
+ offline: "bg-bg-muted",
1365
+ busy: "bg-danger",
1366
+ away: "bg-warning"
1367
+ };
1368
+ var statusSizeStyles = {
1369
+ xs: "h-1.5 w-1.5 border",
1370
+ sm: "h-2 w-2 border",
1371
+ md: "h-2.5 w-2.5 border-2",
1372
+ lg: "h-3 w-3 border-2",
1373
+ xl: "h-4 w-4 border-2"
1374
+ };
1375
+ function getInitials(name) {
1376
+ const parts = name.trim().split(/\s+/);
1377
+ if (parts.length === 1) {
1378
+ return parts[0].charAt(0).toUpperCase();
1379
+ }
1380
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();
1381
+ }
1382
+ var bgColors = [
1383
+ "bg-blue-500",
1384
+ "bg-emerald-500",
1385
+ "bg-amber-500",
1386
+ "bg-rose-500",
1387
+ "bg-purple-500",
1388
+ "bg-cyan-500",
1389
+ "bg-orange-500",
1390
+ "bg-indigo-500"
1391
+ ];
1392
+ function getColorFromName(name) {
1393
+ let hash = 0;
1394
+ for (let i = 0; i < name.length; i++) {
1395
+ hash = name.charCodeAt(i) + ((hash << 5) - hash);
1396
+ }
1397
+ return bgColors[Math.abs(hash) % bgColors.length];
1398
+ }
1399
+ function Avatar(_a) {
1400
+ var _b = _a, {
1401
+ src,
1402
+ srcSet,
1403
+ sizes,
1404
+ crossOrigin,
1405
+ referrerPolicy,
1406
+ alt,
1407
+ name,
1408
+ size = "md",
1409
+ fallback,
1410
+ status,
1411
+ className,
1412
+ onLoadingStatusChange
1413
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
1414
+ "src",
1415
+ "srcSet",
1416
+ "sizes",
1417
+ "crossOrigin",
1418
+ "referrerPolicy",
1419
+ "alt",
1420
+ "name",
1421
+ "size",
1422
+ "fallback",
1423
+ "status",
1424
+ "className",
1425
+ "onLoadingStatusChange"
1426
+ ]);
1427
+ var _a2, _b2, _c;
1428
+ const loadingStatus = useImageLoadingStatus(src, {
1429
+ srcSet,
1430
+ sizes,
1431
+ crossOrigin,
1432
+ referrerPolicy
1433
+ });
1434
+ _react.useEffect.call(void 0, () => {
1435
+ onLoadingStatusChange == null ? void 0 : onLoadingStatusChange(loadingStatus);
1436
+ }, [loadingStatus, onLoadingStatusChange]);
1437
+ const showImage = (Boolean(src) || Boolean(srcSet)) && loadingStatus === "loaded";
1438
+ const initials = name ? getInitials(name) : null;
1439
+ const bgColor = name ? getColorFromName(name) : "bg-bg-subtle";
1440
+ const avatarLabel = status ? `${(_a2 = name != null ? name : alt) != null ? _a2 : "Avatar"} (${status})` : (_b2 = name != null ? name : alt) != null ? _b2 : "Avatar";
1441
+ let avatarContent;
1442
+ if (showImage) {
1443
+ avatarContent = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1444
+ "img",
1445
+ {
1446
+ src,
1447
+ srcSet,
1448
+ sizes,
1449
+ crossOrigin,
1450
+ referrerPolicy,
1451
+ alt: (_c = alt != null ? alt : name) != null ? _c : "Avatar",
1452
+ className: "h-full w-full object-cover"
1453
+ }
1454
+ );
1455
+ } else if (fallback) {
1456
+ avatarContent = fallback;
1457
+ } else if (initials) {
1458
+ avatarContent = // eslint-disable-next-line opt-ui/no-raw-color -- saturated bg-{color}-500 위 흰 텍스트는 contrast 의도
1459
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium text-white", children: initials });
1460
+ } else {
1461
+ avatarContent = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1462
+ "svg",
1463
+ {
1464
+ className: "text-text-tertiary h-3/5 w-3/5",
1465
+ fill: "currentColor",
1466
+ viewBox: "0 0 24 24",
1467
+ "aria-hidden": "true",
1468
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" })
1469
+ }
1470
+ );
1471
+ }
1472
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1473
+ "span",
1474
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1475
+ role: "img",
1476
+ "aria-label": avatarLabel,
1477
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1478
+ "relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full",
1479
+ sizeStyles3[size],
1480
+ !showImage && bgColor,
1481
+ className
1482
+ )
1483
+ }, props), {
1484
+ "data-opt-id": "SCMM0",
1485
+ "data-opt-slug": "avatar.Avatar",
1486
+ children: [
1487
+ avatarContent,
1488
+ status && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1489
+ "span",
1490
+ {
1491
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1492
+ "border-surface absolute right-0 bottom-0 rounded-full",
1493
+ statusStyles[status],
1494
+ statusSizeStyles[size]
1495
+ ),
1496
+ "aria-hidden": "true"
1497
+ }
1498
+ )
1499
+ ]
1500
+ })
1501
+ );
1502
+ }
1503
+ function AvatarGroup(_a) {
1504
+ var _b = _a, {
1505
+ max = 4,
1506
+ size = "md",
1507
+ children,
1508
+ className
1509
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
1510
+ "max",
1511
+ "size",
1512
+ "children",
1513
+ "className"
1514
+ ]);
1515
+ const avatars = Array.isArray(children) ? children : [children];
1516
+ const visibleAvatars = avatars.slice(0, max);
1517
+ const remainingCount = avatars.length - max;
1518
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1519
+ "div",
1520
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1521
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex", className)
1522
+ }, props), {
1523
+ "data-opt-id": "MVB53",
1524
+ "data-opt-slug": "avatar.AvatarGroup",
1525
+ children: [
1526
+ visibleAvatars.map((child, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1527
+ "span",
1528
+ {
1529
+ className: "ring-surface relative -ml-2 inline-block rounded-full ring-2 first:ml-0",
1530
+ children: child
1531
+ },
1532
+ index
1533
+ )),
1534
+ remainingCount > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1535
+ "span",
1536
+ {
1537
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1538
+ "bg-bg-subtle text-text-secondary ring-surface relative inline-flex items-center justify-center rounded-full font-medium ring-2",
1539
+ sizeStyles3[size]
1540
+ ),
1541
+ children: [
1542
+ "+",
1543
+ remainingCount
1544
+ ]
1545
+ }
1546
+ )
1547
+ ]
1548
+ })
1549
+ );
1550
+ }
1551
+
1552
+ // src/core/progress.tsx
1553
+
1554
+
1555
+ var sizeStyles4 = {
1556
+ sm: "h-1",
1557
+ md: "h-2",
1558
+ lg: "h-3"
1559
+ };
1560
+ var variantStyles2 = {
1561
+ default: "bg-accent",
1562
+ success: "bg-success",
1563
+ warning: "bg-warning",
1564
+ error: "bg-danger"
1565
+ };
1566
+ function getProgressValue(value, max) {
1567
+ const safeMax = Number.isFinite(max) ? Math.max(0, max) : 100;
1568
+ const safeValue = Number.isFinite(value) ? value : 0;
1569
+ const clampedValue = safeMax > 0 ? Math.min(Math.max(safeValue, 0), safeMax) : 0;
1570
+ const percentage = safeMax > 0 ? clampedValue / safeMax * 100 : 0;
1571
+ const roundedPercentage = Math.round(percentage);
1572
+ return {
1573
+ clampedValue,
1574
+ max: safeMax,
1575
+ percentage,
1576
+ valueText: `${roundedPercentage}%`
1577
+ };
1578
+ }
1579
+ function Progress(_a) {
1580
+ var _b = _a, {
1581
+ value,
1582
+ max = 100,
1583
+ size = "md",
1584
+ variant = "default",
1585
+ showLabel = false,
1586
+ label,
1587
+ animated = true,
1588
+ indeterminate = false,
1589
+ className
1590
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
1591
+ "value",
1592
+ "max",
1593
+ "size",
1594
+ "variant",
1595
+ "showLabel",
1596
+ "label",
1597
+ "animated",
1598
+ "indeterminate",
1599
+ "className"
1600
+ ]);
1601
+ const isIndeterminate = indeterminate || value === void 0;
1602
+ const progress = isIndeterminate ? null : getProgressValue(value, max);
1603
+ const shouldRenderHeader = Boolean(label) || showLabel && progress;
1604
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1605
+ "div",
1606
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1607
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "w-full", className)
1608
+ }, props), {
1609
+ "data-opt-id": "Y5N8R",
1610
+ "data-opt-slug": "progress.Progress",
1611
+ children: [
1612
+ shouldRenderHeader && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-1.5 flex items-center justify-between text-sm", children: [
1613
+ label && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-primary font-medium", children: label }),
1614
+ showLabel && progress && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-tertiary", children: progress.valueText })
1615
+ ] }),
1616
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1617
+ "div",
1618
+ {
1619
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1620
+ "bg-bg-subtle w-full overflow-hidden rounded-full",
1621
+ sizeStyles4[size]
1622
+ ),
1623
+ role: "progressbar",
1624
+ "aria-valuenow": progress == null ? void 0 : progress.clampedValue,
1625
+ "aria-valuemin": progress ? 0 : void 0,
1626
+ "aria-valuemax": progress == null ? void 0 : progress.max,
1627
+ "aria-valuetext": progress == null ? void 0 : progress.valueText,
1628
+ "aria-label": label != null ? label : progress ? `${progress.valueText} complete` : "Loading",
1629
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1630
+ "div",
1631
+ {
1632
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1633
+ "h-full rounded-full",
1634
+ variantStyles2[variant],
1635
+ !progress && "w-1/3 animate-pulse",
1636
+ animated && (progress ? "transition-all duration-300 ease-out" : "transition-opacity duration-700 ease-in-out")
1637
+ ),
1638
+ style: progress ? { width: `${progress.percentage}%` } : void 0
1639
+ }
1640
+ )
1641
+ }
1642
+ )
1643
+ ]
1644
+ })
1645
+ );
1646
+ }
1647
+ var circularVariantStyles = {
1648
+ default: "text-accent",
1649
+ success: "text-success",
1650
+ warning: "text-warning",
1651
+ error: "text-danger"
1652
+ };
1653
+ function CircularProgress(_a) {
1654
+ var _b = _a, {
1655
+ value,
1656
+ max = 100,
1657
+ size = 48,
1658
+ strokeWidth = 4,
1659
+ variant = "default",
1660
+ showLabel = false,
1661
+ label,
1662
+ indeterminate = false,
1663
+ className
1664
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
1665
+ "value",
1666
+ "max",
1667
+ "size",
1668
+ "strokeWidth",
1669
+ "variant",
1670
+ "showLabel",
1671
+ "label",
1672
+ "indeterminate",
1673
+ "className"
1674
+ ]);
1675
+ var _a2;
1676
+ const labelId = _react.useId.call(void 0, );
1677
+ const isIndeterminate = indeterminate || value === void 0;
1678
+ const progress = isIndeterminate ? null : getProgressValue(value, max);
1679
+ const accessibleName = label != null ? label : progress ? `${progress.valueText} complete` : "Loading";
1680
+ const radius = (size - strokeWidth) / 2;
1681
+ const circumference = radius * 2 * Math.PI;
1682
+ const strokeDashoffset = circumference - ((_a2 = progress == null ? void 0 : progress.percentage) != null ? _a2 : 0) / 100 * circumference;
1683
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1684
+ "div",
1685
+ {
1686
+ className: "relative inline-flex items-center justify-center",
1687
+ "data-opt-id": "Q69KP",
1688
+ "data-opt-slug": "progress.CircularProgress",
1689
+ children: [
1690
+ label && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { id: labelId, className: "sr-only", children: label }),
1691
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1692
+ "svg",
1693
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1694
+ width: size,
1695
+ height: size,
1696
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1697
+ isIndeterminate ? "animate-spin" : "-rotate-90",
1698
+ className
1699
+ ),
1700
+ role: isIndeterminate ? "progressbar" : "meter",
1701
+ "aria-labelledby": label ? labelId : void 0,
1702
+ "aria-valuenow": progress == null ? void 0 : progress.clampedValue,
1703
+ "aria-valuemin": progress ? 0 : void 0,
1704
+ "aria-valuemax": progress == null ? void 0 : progress.max,
1705
+ "aria-valuetext": progress == null ? void 0 : progress.valueText,
1706
+ "aria-label": label ? void 0 : accessibleName
1707
+ }, props), {
1708
+ children: [
1709
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1710
+ "circle",
1711
+ {
1712
+ cx: size / 2,
1713
+ cy: size / 2,
1714
+ r: radius,
1715
+ fill: "none",
1716
+ strokeWidth,
1717
+ className: "stroke-border-subtle"
1718
+ }
1719
+ ),
1720
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1721
+ "circle",
1722
+ {
1723
+ cx: size / 2,
1724
+ cy: size / 2,
1725
+ r: radius,
1726
+ fill: "none",
1727
+ strokeWidth,
1728
+ strokeLinecap: "round",
1729
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1730
+ "transition-all duration-300 ease-out",
1731
+ circularVariantStyles[variant]
1732
+ ),
1733
+ style: {
1734
+ strokeDasharray: isIndeterminate ? `${circumference * 0.28} ${circumference}` : circumference,
1735
+ strokeDashoffset: isIndeterminate ? 0 : strokeDashoffset,
1736
+ stroke: "currentColor"
1737
+ }
1738
+ }
1739
+ )
1740
+ ]
1741
+ })
1742
+ ),
1743
+ showLabel && progress && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-primary absolute text-xs font-medium", children: progress.valueText })
1744
+ ]
1745
+ }
1746
+ );
1747
+ }
1748
+
1749
+ // src/core/meter.tsx
1750
+
1751
+
1752
+ var sizeStyles5 = {
1753
+ sm: "h-1",
1754
+ md: "h-2",
1755
+ lg: "h-3"
1756
+ };
1757
+ var variantStyles3 = {
1758
+ default: "bg-accent",
1759
+ success: "bg-success",
1760
+ warning: "bg-warning",
1761
+ error: "bg-danger"
1762
+ };
1763
+ function Meter(_a) {
1764
+ var _b = _a, {
1765
+ value,
1766
+ min = 0,
1767
+ max = 100,
1768
+ size = "md",
1769
+ variant = "default",
1770
+ showValue = false,
1771
+ label,
1772
+ getValueLabel,
1773
+ className
1774
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
1775
+ "value",
1776
+ "min",
1777
+ "max",
1778
+ "size",
1779
+ "variant",
1780
+ "showValue",
1781
+ "label",
1782
+ "getValueLabel",
1783
+ "className"
1784
+ ]);
1785
+ const clamped = Math.min(Math.max(value, min), max);
1786
+ const percentage = max === min ? 0 : (clamped - min) / (max - min) * 100;
1787
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1788
+ "div",
1789
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
1790
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "w-full", className)
1791
+ }, props), {
1792
+ "data-opt-id": "G01TE",
1793
+ "data-opt-slug": "meter.Meter",
1794
+ children: [
1795
+ (showValue || label) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-1.5 flex items-center justify-between text-sm", children: [
1796
+ label && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-primary font-medium", children: label }),
1797
+ showValue && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-text-tertiary", children: [
1798
+ Math.round(percentage),
1799
+ "%"
1800
+ ] })
1801
+ ] }),
1802
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1803
+ _optuiprimitives.Meter,
1804
+ {
1805
+ value: clamped,
1806
+ min,
1807
+ max,
1808
+ getValueLabel,
1809
+ "aria-label": label != null ? label : `${Math.round(percentage)}%`,
1810
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1811
+ "bg-bg-subtle w-full overflow-hidden rounded-full",
1812
+ sizeStyles5[size]
1813
+ ),
1814
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1815
+ "div",
1816
+ {
1817
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1818
+ "h-full rounded-full transition-all duration-300 ease-out",
1819
+ variantStyles3[variant]
1820
+ ),
1821
+ style: { width: `${percentage}%` }
1822
+ }
1823
+ )
1824
+ }
1825
+ )
1826
+ ]
1827
+ })
1828
+ );
1829
+ }
1830
+
1831
+ // src/core/step-builder.tsx
1832
+
1833
+
1834
+ function StepBuilder({
1835
+ steps,
1836
+ onChange,
1837
+ label,
1838
+ addLabel = "Add step",
1839
+ maxSteps,
1840
+ className,
1841
+ "aria-label": ariaLabel
1842
+ }) {
1843
+ var _a;
1844
+ const [editingId, setEditingId] = _react.useState.call(void 0, null);
1845
+ const nextStepIdRef = _react.useRef.call(void 0, 1);
1846
+ const createStepId = _react.useCallback.call(void 0, () => {
1847
+ const existingIds = new Set(steps.map((step) => step.id));
1848
+ let id = "";
1849
+ do {
1850
+ id = `step-${nextStepIdRef.current++}`;
1851
+ } while (existingIds.has(id));
1852
+ return id;
1853
+ }, [steps]);
1854
+ const addStep = _react.useCallback.call(void 0, () => {
1855
+ if (maxSteps && steps.length >= maxSteps) return;
1856
+ const newStep = {
1857
+ id: createStepId(),
1858
+ label: `Step ${steps.length + 1}`
1859
+ };
1860
+ onChange([...steps, newStep]);
1861
+ setEditingId(newStep.id);
1862
+ }, [steps, onChange, maxSteps, createStepId]);
1863
+ const removeStep = _react.useCallback.call(void 0,
1864
+ (id) => {
1865
+ onChange(steps.filter((s) => s.id !== id));
1866
+ if (editingId === id) setEditingId(null);
1867
+ },
1868
+ [steps, onChange, editingId]
1869
+ );
1870
+ const updateStep = _react.useCallback.call(void 0,
1871
+ (id, updates) => {
1872
+ onChange(steps.map((s) => s.id === id ? _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, s), updates) : s));
1873
+ },
1874
+ [steps, onChange]
1875
+ );
1876
+ const moveStep = _react.useCallback.call(void 0,
1877
+ (index, direction) => {
1878
+ const target = index + direction;
1879
+ if (target < 0 || target >= steps.length) return;
1880
+ const newSteps = [...steps];
1881
+ [newSteps[index], newSteps[target]] = [newSteps[target], newSteps[index]];
1882
+ onChange(newSteps);
1883
+ },
1884
+ [steps, onChange]
1885
+ );
1886
+ const atLimit = Boolean(maxSteps && steps.length >= maxSteps);
1887
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1888
+ "div",
1889
+ {
1890
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex flex-col gap-3", className),
1891
+ role: "list",
1892
+ "aria-label": (_a = ariaLabel != null ? ariaLabel : label) != null ? _a : "Step builder",
1893
+ "data-opt-id": "7BQDT",
1894
+ "data-opt-slug": "step-builder.StepBuilder",
1895
+ children: [
1896
+ label && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkAFF2HPE5cjs.OPT_TEXT_LABEL, children: label }),
1897
+ steps.map((step, index) => {
1898
+ var _a2;
1899
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1900
+ "div",
1901
+ {
1902
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_SURFACE, _chunkAFF2HPE5cjs.OPT_BORDER, "flex items-start gap-3 p-3"),
1903
+ role: "listitem",
1904
+ children: [
1905
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1906
+ "span",
1907
+ {
1908
+ className: "bg-accent text-accent-fg flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full text-xs font-bold",
1909
+ "aria-hidden": "true",
1910
+ children: index + 1
1911
+ }
1912
+ ),
1913
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-w-0 flex-1", children: editingId === step.id ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2", children: [
1914
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1915
+ "input",
1916
+ {
1917
+ type: "text",
1918
+ value: step.label,
1919
+ onChange: (e) => updateStep(step.id, { label: e.target.value }),
1920
+ onKeyDown: (e) => {
1921
+ if (e.key === "Enter") setEditingId(null);
1922
+ },
1923
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1924
+ "border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset w-full rounded-md border px-2 py-1 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1",
1925
+ _chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY,
1926
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
1927
+ ),
1928
+ "aria-label": "Step label",
1929
+ autoFocus: true
1930
+ }
1931
+ ),
1932
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1933
+ "input",
1934
+ {
1935
+ type: "text",
1936
+ value: (_a2 = step.description) != null ? _a2 : "",
1937
+ onChange: (e) => updateStep(step.id, { description: e.target.value }),
1938
+ placeholder: "Description (optional)",
1939
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1940
+ "border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset w-full rounded-md border px-2 py-1 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1",
1941
+ _chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY,
1942
+ "placeholder:text-text-tertiary",
1943
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
1944
+ ),
1945
+ "aria-label": "Step description"
1946
+ }
1947
+ ),
1948
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1949
+ _chunkAFF2HPE5cjs.Button,
1950
+ {
1951
+ variant: "ghost",
1952
+ size: "sm",
1953
+ onClick: () => setEditingId(null),
1954
+ children: "Done"
1955
+ }
1956
+ )
1957
+ ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1958
+ "button",
1959
+ {
1960
+ type: "button",
1961
+ className: "w-full text-left",
1962
+ onClick: () => setEditingId(step.id),
1963
+ "aria-label": `Edit ${step.label}`,
1964
+ children: [
1965
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY, "text-sm font-medium"), children: step.label }),
1966
+ step.description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1967
+ "span",
1968
+ {
1969
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY, "mt-0.5 block text-xs"),
1970
+ children: step.description
1971
+ }
1972
+ )
1973
+ ]
1974
+ }
1975
+ ) }),
1976
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-shrink-0 items-center gap-1", children: [
1977
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1978
+ "button",
1979
+ {
1980
+ type: "button",
1981
+ onClick: () => moveStep(index, -1),
1982
+ disabled: index === 0,
1983
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
1984
+ "rounded p-1 text-sm",
1985
+ _chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY,
1986
+ "hover:bg-bg-subtle",
1987
+ "disabled:opacity-30",
1988
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
1989
+ ),
1990
+ "aria-label": "Move up",
1991
+ children: "\u25B2"
1992
+ }
1993
+ ),
1994
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1995
+ "button",
1996
+ {
1997
+ type: "button",
1998
+ onClick: () => moveStep(index, 1),
1999
+ disabled: index === steps.length - 1,
2000
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2001
+ "rounded p-1 text-sm",
2002
+ _chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY,
2003
+ "hover:bg-bg-subtle",
2004
+ "disabled:opacity-30",
2005
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
2006
+ ),
2007
+ "aria-label": "Move down",
2008
+ children: "\u25BC"
2009
+ }
2010
+ ),
2011
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2012
+ "button",
2013
+ {
2014
+ type: "button",
2015
+ onClick: () => removeStep(step.id),
2016
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2017
+ "text-danger-fg hover:bg-danger-subtle rounded p-1 text-sm",
2018
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
2019
+ ),
2020
+ "aria-label": `Remove ${step.label}`,
2021
+ children: "\u2715"
2022
+ }
2023
+ )
2024
+ ] })
2025
+ ]
2026
+ },
2027
+ step.id
2028
+ );
2029
+ }),
2030
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2031
+ _chunkAFF2HPE5cjs.Button,
2032
+ {
2033
+ variant: "secondary",
2034
+ size: "sm",
2035
+ onClick: addStep,
2036
+ disabled: atLimit,
2037
+ className: "self-start",
2038
+ children: [
2039
+ "+ ",
2040
+ addLabel
2041
+ ]
2042
+ }
2043
+ )
2044
+ ]
2045
+ }
2046
+ );
2047
+ }
2048
+ StepBuilder.displayName = "StepBuilder";
2049
+
2050
+ // src/lib/formatters.ts
2051
+ var OPT_UI_DEFAULT_LOCALE = "ko-KR";
2052
+ var KST_OFFSET_MS = 9 * 60 * 60 * 1e3;
2053
+ function getKstDateParts(input) {
2054
+ const date = input instanceof Date ? input : new Date(input);
2055
+ if (Number.isNaN(date.getTime())) {
2056
+ return null;
2057
+ }
2058
+ const kstDate = new Date(date.getTime() + KST_OFFSET_MS);
2059
+ return {
2060
+ year: kstDate.getUTCFullYear(),
2061
+ month: kstDate.getUTCMonth() + 1,
2062
+ day: kstDate.getUTCDate(),
2063
+ hour: kstDate.getUTCHours(),
2064
+ minute: kstDate.getUTCMinutes(),
2065
+ second: kstDate.getUTCSeconds()
2066
+ };
2067
+ }
2068
+ function pad2(value) {
2069
+ return String(value).padStart(2, "0");
2070
+ }
2071
+ function meridiem(hour) {
2072
+ return hour < 12 ? "\uC624\uC804" : "\uC624\uD6C4";
2073
+ }
2074
+ function hour12(hour) {
2075
+ const normalized = hour % 12;
2076
+ return normalized === 0 ? 12 : normalized;
2077
+ }
2078
+ function formatOptShortDate(input) {
2079
+ const parts = getKstDateParts(input);
2080
+ if (!parts) {
2081
+ return "-";
2082
+ }
2083
+ return `${parts.month}\uC6D4 ${parts.day}\uC77C`;
2084
+ }
2085
+ function formatOptTime(input) {
2086
+ const parts = getKstDateParts(input);
2087
+ if (!parts) {
2088
+ return "-";
2089
+ }
2090
+ return `${meridiem(parts.hour)} ${pad2(hour12(parts.hour))}:${pad2(
2091
+ parts.minute
2092
+ )}`;
2093
+ }
2094
+ function formatOptDateTime(input) {
2095
+ const parts = getKstDateParts(input);
2096
+ if (!parts) {
2097
+ return "-";
2098
+ }
2099
+ return `${parts.year}. ${parts.month}. ${parts.day}. ${meridiem(
2100
+ parts.hour
2101
+ )} ${hour12(parts.hour)}:${pad2(parts.minute)}:${pad2(parts.second)}`;
2102
+ }
2103
+ function formatOptNumber(value) {
2104
+ return new Intl.NumberFormat(OPT_UI_DEFAULT_LOCALE).format(value);
2105
+ }
2106
+
2107
+ // src/core/condition-builder.tsx
2108
+
2109
+
2110
+
2111
+ var OPERATOR_LABELS = {
2112
+ equals: "equals",
2113
+ not_equals: "does not equal",
2114
+ contains: "contains",
2115
+ not_contains: "does not contain",
2116
+ gt: ">",
2117
+ lt: "<",
2118
+ gte: ">=",
2119
+ lte: "<=",
2120
+ is_set: "is set",
2121
+ is_not_set: "is not set"
2122
+ };
2123
+ var OPERATORS = /* @__PURE__ */ new Set([
2124
+ "equals",
2125
+ "not_equals",
2126
+ "contains",
2127
+ "not_contains",
2128
+ "gt",
2129
+ "lt",
2130
+ "gte",
2131
+ "lte",
2132
+ "is_set",
2133
+ "is_not_set"
2134
+ ]);
2135
+ function isConditionOperator(v) {
2136
+ return OPERATORS.has(v);
2137
+ }
2138
+ var NO_VALUE_OPS = ["is_set", "is_not_set"];
2139
+ var DEFAULT_PROPERTIES = [
2140
+ "event_name",
2141
+ "user_id",
2142
+ "email",
2143
+ "country",
2144
+ "browser",
2145
+ "os",
2146
+ "device",
2147
+ "page_url",
2148
+ "referrer",
2149
+ "amount"
2150
+ ];
2151
+ var ConditionBuilderIdScopeContext = React2.createContext(null);
2152
+ function collectConditionBuilderIds(groups) {
2153
+ const groupIds = /* @__PURE__ */ new Set();
2154
+ const conditionIds = /* @__PURE__ */ new Set();
2155
+ const visit = (items) => {
2156
+ for (const group of items) {
2157
+ groupIds.add(group.id);
2158
+ for (const condition of group.conditions) {
2159
+ conditionIds.add(condition.id);
2160
+ }
2161
+ if (group.children) {
2162
+ visit(group.children);
2163
+ }
2164
+ }
2165
+ };
2166
+ visit(groups);
2167
+ return { groupIds, conditionIds };
2168
+ }
2169
+ function ConditionBuilder({
2170
+ groups,
2171
+ onChange,
2172
+ properties = DEFAULT_PROPERTIES,
2173
+ label,
2174
+ addConditionLabel = "Add condition",
2175
+ addGroupLabel = "Add group",
2176
+ addNestedGroupLabel = "Add nested group",
2177
+ nested = false,
2178
+ maxDepth = 3,
2179
+ conditionTypes,
2180
+ onPreview,
2181
+ previewCount,
2182
+ className,
2183
+ "aria-label": ariaLabel
2184
+ }) {
2185
+ var _a;
2186
+ const inheritedIdScope = React2.useContext(ConditionBuilderIdScopeContext);
2187
+ const nextGroupIdRef = React2.useRef(1);
2188
+ const nextConditionIdRef = React2.useRef(1);
2189
+ const getLocalReservedIds = _react.useCallback.call(void 0,
2190
+ () => collectConditionBuilderIds(groups),
2191
+ [groups]
2192
+ );
2193
+ const localIdScope = React2.useMemo(
2194
+ () => ({
2195
+ nextGroupIdRef,
2196
+ nextConditionIdRef,
2197
+ getReservedIds: getLocalReservedIds
2198
+ }),
2199
+ [getLocalReservedIds]
2200
+ );
2201
+ const idScope = inheritedIdScope != null ? inheritedIdScope : localIdScope;
2202
+ const createGroupId = _react.useCallback.call(void 0,
2203
+ (suffix = "") => {
2204
+ const { groupIds } = idScope.getReservedIds();
2205
+ let id = "";
2206
+ do {
2207
+ id = `group-${idScope.nextGroupIdRef.current++}${suffix}`;
2208
+ } while (groupIds.has(id));
2209
+ return id;
2210
+ },
2211
+ [idScope]
2212
+ );
2213
+ const createConditionId = _react.useCallback.call(void 0,
2214
+ (suffix = "") => {
2215
+ const { conditionIds } = idScope.getReservedIds();
2216
+ let id = "";
2217
+ do {
2218
+ id = `cond-${idScope.nextConditionIdRef.current++}${suffix}`;
2219
+ } while (conditionIds.has(id));
2220
+ return id;
2221
+ },
2222
+ [idScope]
2223
+ );
2224
+ _react.useEffect.call(void 0, () => {
2225
+ onPreview == null ? void 0 : onPreview(groups);
2226
+ }, [groups, onPreview]);
2227
+ const addGroup = _react.useCallback.call(void 0, () => {
2228
+ var _a2;
2229
+ const newGroup = {
2230
+ id: createGroupId(),
2231
+ logic: "and",
2232
+ conditions: [
2233
+ {
2234
+ id: createConditionId(),
2235
+ property: (_a2 = properties[0]) != null ? _a2 : "",
2236
+ operator: "equals",
2237
+ value: ""
2238
+ }
2239
+ ]
2240
+ };
2241
+ onChange([...groups, newGroup]);
2242
+ }, [groups, onChange, properties, createGroupId, createConditionId]);
2243
+ const removeGroup = _react.useCallback.call(void 0,
2244
+ (groupId) => {
2245
+ onChange(groups.filter((g) => g.id !== groupId));
2246
+ },
2247
+ [groups, onChange]
2248
+ );
2249
+ const updateGroupLogic = _react.useCallback.call(void 0,
2250
+ (groupId, logic) => {
2251
+ onChange(groups.map((g) => g.id === groupId ? _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, g), { logic }) : g));
2252
+ },
2253
+ [groups, onChange]
2254
+ );
2255
+ const addCondition = _react.useCallback.call(void 0,
2256
+ (groupId) => {
2257
+ onChange(
2258
+ groups.map(
2259
+ (g) => {
2260
+ var _a2;
2261
+ return g.id === groupId ? _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, g), {
2262
+ conditions: [
2263
+ ...g.conditions,
2264
+ {
2265
+ id: createConditionId(),
2266
+ property: (_a2 = properties[0]) != null ? _a2 : "",
2267
+ operator: "equals",
2268
+ value: ""
2269
+ }
2270
+ ]
2271
+ }) : g;
2272
+ }
2273
+ )
2274
+ );
2275
+ },
2276
+ [groups, onChange, properties, createConditionId]
2277
+ );
2278
+ const removeCondition = _react.useCallback.call(void 0,
2279
+ (groupId, condId) => {
2280
+ onChange(
2281
+ groups.map(
2282
+ (g) => g.id === groupId ? _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, g), {
2283
+ conditions: g.conditions.filter((c) => c.id !== condId)
2284
+ }) : g
2285
+ )
2286
+ );
2287
+ },
2288
+ [groups, onChange]
2289
+ );
2290
+ const updateCondition = _react.useCallback.call(void 0,
2291
+ (groupId, condId, updates) => {
2292
+ onChange(
2293
+ groups.map(
2294
+ (g) => g.id === groupId ? _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, g), {
2295
+ conditions: g.conditions.map(
2296
+ (c) => c.id === condId ? _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, c), updates) : c
2297
+ )
2298
+ }) : g
2299
+ )
2300
+ );
2301
+ },
2302
+ [groups, onChange]
2303
+ );
2304
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ConditionBuilderIdScopeContext.Provider, { value: idScope, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2305
+ "div",
2306
+ {
2307
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex flex-col gap-3", className),
2308
+ "aria-label": (_a = ariaLabel != null ? ariaLabel : label) != null ? _a : "Condition builder",
2309
+ "data-opt-id": "SXXKJ",
2310
+ "data-opt-slug": "condition-builder.ConditionBuilder",
2311
+ children: [
2312
+ label && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkAFF2HPE5cjs.OPT_TEXT_LABEL, children: label }),
2313
+ groups.map((group, groupIndex) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
2314
+ groupIndex > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "my-2 flex items-center gap-2", children: [
2315
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-border-subtle h-px flex-1" }),
2316
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-warning-fg text-xs font-semibold uppercase", children: "OR" }),
2317
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-border-subtle h-px flex-1" })
2318
+ ] }),
2319
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2320
+ "div",
2321
+ {
2322
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_SURFACE, _chunkAFF2HPE5cjs.OPT_BORDER, "p-3"),
2323
+ role: "group",
2324
+ "aria-label": `Condition group ${groupIndex + 1}`,
2325
+ children: [
2326
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-2 flex items-center justify-between", children: [
2327
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
2328
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2329
+ "span",
2330
+ {
2331
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY, "text-xs font-medium"),
2332
+ children: "Match"
2333
+ }
2334
+ ),
2335
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2336
+ "select",
2337
+ {
2338
+ value: group.logic,
2339
+ onChange: (e) => {
2340
+ const v = e.target.value;
2341
+ if (v === "and" || v === "or")
2342
+ updateGroupLogic(group.id, v);
2343
+ },
2344
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2345
+ "border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset rounded border px-2 py-0.5 text-xs font-semibold outline-none focus-visible:ring-2 focus-visible:ring-offset-1",
2346
+ _chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY,
2347
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
2348
+ ),
2349
+ "aria-label": "Group logic",
2350
+ children: [
2351
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "option", { value: "and", children: "ALL" }),
2352
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "option", { value: "or", children: "ANY" })
2353
+ ]
2354
+ }
2355
+ ),
2356
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY, "text-xs"), children: "of the following" })
2357
+ ] }),
2358
+ groups.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2359
+ "button",
2360
+ {
2361
+ type: "button",
2362
+ onClick: () => removeGroup(group.id),
2363
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2364
+ "text-danger-fg hover:bg-danger-subtle rounded p-1 text-xs",
2365
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
2366
+ ),
2367
+ "aria-label": "Remove group",
2368
+ children: "\u2715"
2369
+ }
2370
+ )
2371
+ ] }),
2372
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-col gap-2", children: group.conditions.map((cond, condIndex) => {
2373
+ const customRenderer = cond.type != null ? conditionTypes == null ? void 0 : conditionTypes[cond.type] : void 0;
2374
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
2375
+ condIndex > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2376
+ "span",
2377
+ {
2378
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2379
+ "w-8 text-center text-[10px] font-semibold uppercase",
2380
+ group.logic === "and" ? "text-info-fg" : "text-warning-fg"
2381
+ ),
2382
+ children: group.logic
2383
+ }
2384
+ ),
2385
+ condIndex === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "w-8" }),
2386
+ customRenderer ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2387
+ "div",
2388
+ {
2389
+ className: "min-w-[100px] flex-1",
2390
+ role: "group",
2391
+ "aria-label": customRenderer.label,
2392
+ children: customRenderer.render(
2393
+ cond,
2394
+ (updates) => updateCondition(group.id, cond.id, updates)
2395
+ )
2396
+ }
2397
+ ) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2398
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2399
+ "select",
2400
+ {
2401
+ value: cond.property,
2402
+ onChange: (e) => updateCondition(group.id, cond.id, {
2403
+ property: e.target.value
2404
+ }),
2405
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2406
+ "border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset min-w-[120px] rounded border px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1",
2407
+ _chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY,
2408
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
2409
+ ),
2410
+ "aria-label": "Property",
2411
+ children: properties.map((p) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "option", { value: p, children: p }, p))
2412
+ }
2413
+ ),
2414
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2415
+ "select",
2416
+ {
2417
+ value: cond.operator,
2418
+ onChange: (e) => {
2419
+ const v = e.target.value;
2420
+ if (isConditionOperator(v))
2421
+ updateCondition(group.id, cond.id, {
2422
+ operator: v
2423
+ });
2424
+ },
2425
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2426
+ "border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset min-w-[130px] rounded border px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1",
2427
+ _chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY,
2428
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
2429
+ ),
2430
+ "aria-label": "Operator",
2431
+ children: Object.entries(OPERATOR_LABELS).map(
2432
+ ([key, lbl]) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "option", { value: key, children: lbl }, key)
2433
+ )
2434
+ }
2435
+ ),
2436
+ !NO_VALUE_OPS.includes(cond.operator) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2437
+ "input",
2438
+ {
2439
+ type: "text",
2440
+ value: cond.value,
2441
+ onChange: (e) => updateCondition(group.id, cond.id, {
2442
+ value: e.target.value
2443
+ }),
2444
+ placeholder: "Value",
2445
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2446
+ "border-border bg-surface focus-visible:ring-ring focus-visible:ring-offset-ring-offset min-w-[100px] flex-1 rounded border px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-1",
2447
+ _chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY,
2448
+ "placeholder:text-text-tertiary",
2449
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
2450
+ ),
2451
+ "aria-label": "Value"
2452
+ }
2453
+ )
2454
+ ] }),
2455
+ group.conditions.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2456
+ "button",
2457
+ {
2458
+ type: "button",
2459
+ onClick: () => removeCondition(group.id, cond.id),
2460
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2461
+ "text-danger-fg hover:bg-danger-subtle rounded p-1 text-sm",
2462
+ _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
2463
+ ),
2464
+ "aria-label": "Remove condition",
2465
+ children: "\u2715"
2466
+ }
2467
+ )
2468
+ ] }, cond.id);
2469
+ }) }),
2470
+ nested && group.children && group.children.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border-accent/30 mt-2 ml-4 border-l-2 pl-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2471
+ ConditionBuilder,
2472
+ {
2473
+ groups: group.children,
2474
+ onChange: (newChildren) => {
2475
+ onChange(
2476
+ groups.map(
2477
+ (g) => g.id === group.id ? _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, g), { children: newChildren }) : g
2478
+ )
2479
+ );
2480
+ },
2481
+ properties,
2482
+ addConditionLabel,
2483
+ addGroupLabel,
2484
+ addNestedGroupLabel,
2485
+ nested,
2486
+ maxDepth: maxDepth - 1,
2487
+ conditionTypes
2488
+ }
2489
+ ) }),
2490
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-2 flex items-center gap-2", children: [
2491
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2492
+ _chunkAFF2HPE5cjs.Button,
2493
+ {
2494
+ variant: "ghost",
2495
+ size: "sm",
2496
+ onClick: () => addCondition(group.id),
2497
+ children: [
2498
+ "+ ",
2499
+ addConditionLabel
2500
+ ]
2501
+ }
2502
+ ),
2503
+ nested && maxDepth > 1 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2504
+ _chunkAFF2HPE5cjs.Button,
2505
+ {
2506
+ variant: "ghost",
2507
+ size: "sm",
2508
+ onClick: () => {
2509
+ var _a2;
2510
+ const nestedGroup = {
2511
+ id: createGroupId("-nested"),
2512
+ logic: group.logic === "and" ? "or" : "and",
2513
+ conditions: [
2514
+ {
2515
+ id: createConditionId("-nested"),
2516
+ property: (_a2 = properties[0]) != null ? _a2 : "",
2517
+ operator: "equals",
2518
+ value: ""
2519
+ }
2520
+ ]
2521
+ };
2522
+ onChange(
2523
+ groups.map(
2524
+ (g) => {
2525
+ var _a3;
2526
+ return g.id === group.id ? _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, g), {
2527
+ children: [...(_a3 = g.children) != null ? _a3 : [], nestedGroup]
2528
+ }) : g;
2529
+ }
2530
+ )
2531
+ );
2532
+ },
2533
+ children: [
2534
+ "+ ",
2535
+ addNestedGroupLabel
2536
+ ]
2537
+ }
2538
+ )
2539
+ ] })
2540
+ ]
2541
+ }
2542
+ )
2543
+ ] }, group.id)),
2544
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3", children: [
2545
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2546
+ _chunkAFF2HPE5cjs.Button,
2547
+ {
2548
+ variant: "secondary",
2549
+ size: "sm",
2550
+ onClick: addGroup,
2551
+ className: "self-start",
2552
+ children: [
2553
+ "+ ",
2554
+ addGroupLabel
2555
+ ]
2556
+ }
2557
+ ),
2558
+ previewCount != null && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY, "text-sm"), children: [
2559
+ formatOptNumber(previewCount),
2560
+ " matches"
2561
+ ] })
2562
+ ] })
2563
+ ]
2564
+ }
2565
+ ) });
2566
+ }
2567
+ ConditionBuilder.displayName = "ConditionBuilder";
2568
+
2569
+ // src/core/dropdown-menu.tsx
2570
+
2571
+ var DropdownMenu = _chunkAFF2HPE5cjs.MenuRoot;
2572
+ function DropdownTrigger(_a) {
2573
+ var _b = _a, { className } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, ["className"]);
2574
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2575
+ _chunkAFF2HPE5cjs.MenuTrigger,
2576
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
2577
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "cursor-pointer gap-2", className)
2578
+ }, props), {
2579
+ "data-opt-id": "C4BSS",
2580
+ "data-opt-slug": "dropdown-menu.DropdownTrigger"
2581
+ })
2582
+ );
2583
+ }
2584
+ function DropdownContent(_a) {
2585
+ var _b = _a, { className } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, ["className"]);
2586
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2587
+ _chunkAFF2HPE5cjs.MenuPopover,
2588
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
2589
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, className)
2590
+ }, props), {
2591
+ "data-opt-id": "J6NF7",
2592
+ "data-opt-slug": "dropdown-menu.DropdownContent"
2593
+ })
2594
+ );
2595
+ }
2596
+ function DropdownItem(_a) {
2597
+ var _b = _a, {
2598
+ className,
2599
+ variant = "default"
2600
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
2601
+ "className",
2602
+ "variant"
2603
+ ]);
2604
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2605
+ _chunkAFF2HPE5cjs.MenuItem,
2606
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
2607
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2608
+ "cursor-pointer data-[disabled]:cursor-not-allowed",
2609
+ variant === "destructive" && "text-danger-fg data-[active-item]:bg-danger-subtle data-[active-item]:text-danger-fg",
2610
+ className
2611
+ )
2612
+ }, props), {
2613
+ "data-opt-id": "5M6GA",
2614
+ "data-opt-slug": "dropdown-menu.DropdownItem"
2615
+ })
2616
+ );
2617
+ }
2618
+ function DropdownSeparator(_a) {
2619
+ var _b = _a, {
2620
+ className
2621
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
2622
+ "className"
2623
+ ]);
2624
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2625
+ _chunkAFF2HPE5cjs.MenuSeparator,
2626
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
2627
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, className)
2628
+ }, props), {
2629
+ "data-opt-id": "K9Y54",
2630
+ "data-opt-slug": "dropdown-menu.DropdownSeparator"
2631
+ })
2632
+ );
2633
+ }
2634
+
2635
+ // src/core/radio-group.tsx
2636
+
2637
+
2638
+
2639
+
2640
+
2641
+
2642
+
2643
+
2644
+
2645
+
2646
+
2647
+
2648
+
2649
+ var sizeStyles6 = {
2650
+ sm: {
2651
+ radio: "h-4 w-4",
2652
+ dot: "h-2 w-2",
2653
+ text: "text-sm"
2654
+ },
2655
+ md: {
2656
+ radio: "h-5 w-5",
2657
+ dot: "h-2.5 w-2.5",
2658
+ text: "text-sm"
2659
+ },
2660
+ lg: {
2661
+ radio: "h-6 w-6",
2662
+ dot: "h-3 w-3",
2663
+ text: "text-base"
2664
+ }
2665
+ };
2666
+ var RadioGroupContext = _react.createContext.call(void 0, {
2667
+ size: "md"
2668
+ });
2669
+ function RadioGroup({
2670
+ children,
2671
+ value,
2672
+ defaultValue = "",
2673
+ onChange,
2674
+ disabled,
2675
+ size = "md",
2676
+ error,
2677
+ required,
2678
+ className,
2679
+ orientation = "vertical",
2680
+ label,
2681
+ name
2682
+ }) {
2683
+ const ctxValue = _react.useMemo.call(void 0, () => ({ size, disabled }), [size, disabled]);
2684
+ const hasError = Boolean(error);
2685
+ const fallbackGroupId = _react.useId.call(void 0, ).replace(/:/g, "");
2686
+ const groupId = label ? `radio-group-${label.replace(/\s+/g, "-").toLowerCase()}` : `radio-group-${fallbackGroupId}`;
2687
+ const labelId = label ? `${groupId}-label` : void 0;
2688
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RadioGroupContext.Provider, { value: ctxValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2689
+ "div",
2690
+ {
2691
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex flex-col gap-1.5", className),
2692
+ "data-opt-id": "2F20H",
2693
+ "data-opt-slug": "radio-group.RadioGroup",
2694
+ children: [
2695
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2696
+ _optuiprimitives.RadioGroupRoot,
2697
+ {
2698
+ value,
2699
+ defaultValue,
2700
+ onChange,
2701
+ disabled,
2702
+ orientation,
2703
+ name,
2704
+ id: groupId,
2705
+ "aria-label": label ? void 0 : "Radio group",
2706
+ "aria-labelledby": labelId,
2707
+ "aria-required": required,
2708
+ "aria-invalid": hasError,
2709
+ "aria-describedby": _chunkAFF2HPE5cjs.getDescribedBy.call(void 0, groupId, error, void 0),
2710
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2711
+ "flex",
2712
+ orientation === "vertical" ? "flex-col gap-3" : "flex-row gap-6"
2713
+ ),
2714
+ children: [
2715
+ label && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2716
+ "div",
2717
+ {
2718
+ id: labelId,
2719
+ className: "text-text-secondary mb-1 text-sm font-medium",
2720
+ children: [
2721
+ label,
2722
+ required && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.RequiredMark, {})
2723
+ ]
2724
+ }
2725
+ ),
2726
+ children
2727
+ ]
2728
+ }
2729
+ ),
2730
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FieldMessages, { id: groupId, error })
2731
+ ]
2732
+ }
2733
+ ) });
2734
+ }
2735
+ var Radio = _react.forwardRef.call(void 0,
2736
+ (_a, ref) => {
2737
+ var _b = _a, {
2738
+ label,
2739
+ hint,
2740
+ description,
2741
+ value,
2742
+ name: _name,
2743
+ size: sizeProp,
2744
+ disabled: disabledProp,
2745
+ className
2746
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
2747
+ "label",
2748
+ "hint",
2749
+ "description",
2750
+ "value",
2751
+ "name",
2752
+ "size",
2753
+ "disabled",
2754
+ "className"
2755
+ ]);
2756
+ var _a2;
2757
+ const groupContext = _react.useContext.call(void 0, RadioGroupContext);
2758
+ const primContext = _optuiprimitives.useRadioGroupContext.call(void 0, );
2759
+ const size = sizeProp != null ? sizeProp : groupContext.size;
2760
+ const disabled = (_a2 = disabledProp != null ? disabledProp : groupContext.disabled) != null ? _a2 : primContext == null ? void 0 : primContext.disabled;
2761
+ const hintText = hint != null ? hint : description;
2762
+ const styles = sizeStyles6[size];
2763
+ const isChecked = (primContext == null ? void 0 : primContext.value) === value;
2764
+ const fallbackRadioId = _react.useId.call(void 0, ).replace(/:/g, "");
2765
+ const radioId = `radio-${fallbackRadioId}`;
2766
+ const labelId = label ? `${radioId}-label` : void 0;
2767
+ const hintId = hintText ? `${radioId}-hint` : void 0;
2768
+ const handleChange = _react.useCallback.call(void 0, () => {
2769
+ if (!disabled && value != null) {
2770
+ primContext == null ? void 0 : primContext.setValue(value);
2771
+ }
2772
+ }, [disabled, value, primContext]);
2773
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2774
+ "label",
2775
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
2776
+ ref,
2777
+ "aria-checked": isChecked,
2778
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2779
+ "group flex items-start gap-3",
2780
+ disabled && "cursor-not-allowed opacity-50",
2781
+ !disabled && "cursor-pointer",
2782
+ className
2783
+ )
2784
+ }, props), {
2785
+ "data-opt-id": "HY7YG",
2786
+ "data-opt-slug": "radio-group.Radio",
2787
+ children: [
2788
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2789
+ "input",
2790
+ {
2791
+ id: radioId,
2792
+ type: "radio",
2793
+ name: primContext == null ? void 0 : primContext.name,
2794
+ value,
2795
+ checked: isChecked,
2796
+ disabled,
2797
+ onChange: handleChange,
2798
+ "aria-label": label ? void 0 : value != null ? value : "Radio option",
2799
+ "aria-labelledby": labelId,
2800
+ "aria-describedby": hintId,
2801
+ className: "sr-only"
2802
+ }
2803
+ ),
2804
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2805
+ "span",
2806
+ {
2807
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2808
+ "relative mt-0.5 inline-flex shrink-0 items-center justify-center rounded-full",
2809
+ styles.radio,
2810
+ "border-border border-2",
2811
+ "bg-surface",
2812
+ "group-aria-checked:border-accent",
2813
+ "transition-colors",
2814
+ "group-has-[:focus-visible]:outline-ring outline-transparent group-has-[:focus-visible]:outline-2 group-has-[:focus-visible]:-outline-offset-1"
2815
+ ),
2816
+ "aria-hidden": "true",
2817
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2818
+ "span",
2819
+ {
2820
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2821
+ styles.dot,
2822
+ "bg-accent rounded-full",
2823
+ "scale-0 opacity-0 transition-all",
2824
+ "group-aria-checked:scale-100 group-aria-checked:opacity-100"
2825
+ )
2826
+ }
2827
+ )
2828
+ }
2829
+ ),
2830
+ (label || hintText) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col", children: [
2831
+ label && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2832
+ "span",
2833
+ {
2834
+ id: labelId,
2835
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "text-text-primary font-medium", styles.text),
2836
+ children: label
2837
+ }
2838
+ ),
2839
+ hintText && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { id: hintId, className: "text-text-tertiary text-sm", children: hintText })
2840
+ ] })
2841
+ ]
2842
+ })
2843
+ );
2844
+ }
2845
+ );
2846
+ Radio.displayName = "Radio";
2847
+
2848
+ // src/core/loading-overlay.tsx
2849
+
2850
+ function LoadingOverlay(_a) {
2851
+ var _b = _a, {
2852
+ loading,
2853
+ children,
2854
+ label = "Loading\u2026",
2855
+ className
2856
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
2857
+ "loading",
2858
+ "children",
2859
+ "label",
2860
+ "className"
2861
+ ]);
2862
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2863
+ "div",
2864
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
2865
+ "data-opt-id": "380ZR",
2866
+ "data-opt-slug": "loading-overlay.LoadingOverlay"
2867
+ }, props), {
2868
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "relative", className),
2869
+ children: [
2870
+ children,
2871
+ loading && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2872
+ "div",
2873
+ {
2874
+ className: "bg-surface/60 absolute inset-0 z-10 flex items-center justify-center rounded-lg backdrop-blur-[1px]",
2875
+ role: "status",
2876
+ "aria-live": "polite",
2877
+ "aria-label": label,
2878
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-2", children: [
2879
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.Spinner, { size: "md", "aria-hidden": "true" }),
2880
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-tertiary text-sm", children: label })
2881
+ ] })
2882
+ }
2883
+ )
2884
+ ]
2885
+ })
2886
+ );
2887
+ }
2888
+ LoadingOverlay.displayName = "LoadingOverlay";
2889
+
2890
+ // src/core/block-layout.tsx
2891
+
2892
+ var spacingClass = {
2893
+ section: "gap-section",
2894
+ group: "gap-group",
2895
+ element: "gap-element",
2896
+ none: "gap-0"
2897
+ };
2898
+ function BlockLayout(_a) {
2899
+ var _b = _a, {
2900
+ children,
2901
+ className,
2902
+ spacing = "section",
2903
+ loading,
2904
+ loadingLabel
2905
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
2906
+ "children",
2907
+ "className",
2908
+ "spacing",
2909
+ "loading",
2910
+ "loadingLabel"
2911
+ ]);
2912
+ const layoutClassName = _chunkAFF2HPE5cjs.cn.call(void 0, "flex flex-col", spacingClass[spacing], className);
2913
+ if (loading) {
2914
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2915
+ LoadingOverlay,
2916
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
2917
+ "data-opt-id": "6RHZW",
2918
+ "data-opt-slug": "block-layout.BlockLayout"
2919
+ }, props), {
2920
+ className: layoutClassName,
2921
+ loading,
2922
+ label: loadingLabel,
2923
+ children
2924
+ })
2925
+ );
2926
+ }
2927
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2928
+ "div",
2929
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
2930
+ "data-opt-id": "6RHZW",
2931
+ "data-opt-slug": "block-layout.BlockLayout"
2932
+ }, props), {
2933
+ className: layoutClassName,
2934
+ children
2935
+ })
2936
+ );
2937
+ }
2938
+ BlockLayout.displayName = "BlockLayout";
2939
+
2940
+ // src/core/create-block.tsx
2941
+
2942
+ function createBlock(name, render, options) {
2943
+ const Component = (props) => {
2944
+ const _a = props, { loading, className } = _a, rest = _chunkONE3C5RVcjs.__objRest.call(void 0, _a, ["loading", "className"]);
2945
+ const layoutCn = (options == null ? void 0 : options.layoutClassName) ? `${options.layoutClassName}${className ? ` ${className}` : ""}` : className;
2946
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BlockLayout, { loading, className: layoutCn, children: render(rest) });
2947
+ };
2948
+ Component.displayName = name;
2949
+ return Component;
2950
+ }
2951
+
2952
+ // src/core/page-header.tsx
2953
+
2954
+ function PageHeader({
2955
+ title,
2956
+ description,
2957
+ actions,
2958
+ className
2959
+ }) {
2960
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2961
+ "div",
2962
+ {
2963
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "gap-group flex items-center justify-between", className),
2964
+ "data-opt-id": "7AK8Z",
2965
+ "data-opt-slug": "page-header.PageHeader",
2966
+ children: [
2967
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "gap-element flex flex-col", children: [
2968
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "text-text-primary text-lg font-semibold", children: title }),
2969
+ description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-text-tertiary text-sm", children: description })
2970
+ ] }),
2971
+ actions && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "gap-element flex shrink-0 items-center", children: actions })
2972
+ ]
2973
+ }
2974
+ );
2975
+ }
2976
+ PageHeader.displayName = "PageHeader";
2977
+
2978
+ // src/core/scroll-area.tsx
2979
+
2980
+ var overflowMap = {
2981
+ vertical: "overflow-y-auto overflow-x-hidden",
2982
+ horizontal: "overflow-x-auto overflow-y-hidden",
2983
+ both: "overflow-auto"
2984
+ };
2985
+ function ScrollArea({
2986
+ children,
2987
+ className,
2988
+ orientation = "vertical"
2989
+ }) {
2990
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2991
+ "div",
2992
+ {
2993
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
2994
+ overflowMap[orientation],
2995
+ // Custom scrollbar styling
2996
+ "scrollbar-thin scrollbar-track-transparent scrollbar-thumb-border hover:scrollbar-thumb-border-hover",
2997
+ className
2998
+ ),
2999
+ "data-opt-id": "A9X4K",
3000
+ "data-opt-slug": "scroll-area.ScrollArea",
3001
+ children
3002
+ }
3003
+ );
3004
+ }
3005
+ ScrollArea.displayName = "ScrollArea";
3006
+
3007
+ // src/core/container.tsx
3008
+
3009
+ var maxWidthMap = {
3010
+ sm: "max-w-screen-sm",
3011
+ md: "max-w-screen-md",
3012
+ lg: "max-w-screen-lg",
3013
+ xl: "max-w-screen-xl",
3014
+ "2xl": "max-w-screen-2xl",
3015
+ full: "max-w-full"
3016
+ };
3017
+ function Container({
3018
+ children,
3019
+ maxWidth = "xl",
3020
+ center = true,
3021
+ className
3022
+ }) {
3023
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3024
+ "div",
3025
+ {
3026
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
3027
+ maxWidthMap[maxWidth],
3028
+ center && "mx-auto",
3029
+ "px-4",
3030
+ className
3031
+ ),
3032
+ "data-opt-id": "H3G96",
3033
+ "data-opt-slug": "container.Container",
3034
+ children
3035
+ }
3036
+ );
3037
+ }
3038
+ Container.displayName = "Container";
3039
+
3040
+ // src/core/section.tsx
3041
+
3042
+
3043
+ function Section({
3044
+ children,
3045
+ title,
3046
+ description,
3047
+ className
3048
+ }) {
3049
+ const id = _react.useId.call(void 0, );
3050
+ const titleId = `${id}-title`;
3051
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3052
+ "section",
3053
+ {
3054
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "gap-group flex flex-col", className),
3055
+ "aria-labelledby": title ? titleId : void 0,
3056
+ "data-opt-id": "M3QXW",
3057
+ "data-opt-slug": "section.Section",
3058
+ children: [
3059
+ (title || description) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "gap-element flex flex-col", children: [
3060
+ title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3061
+ "h3",
3062
+ {
3063
+ id: titleId,
3064
+ className: "text-text-primary text-base font-semibold",
3065
+ children: title
3066
+ }
3067
+ ),
3068
+ description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-text-tertiary text-sm", children: description })
3069
+ ] }),
3070
+ children
3071
+ ]
3072
+ }
3073
+ );
3074
+ }
3075
+ Section.displayName = "Section";
3076
+
3077
+ // src/core/resizable.tsx
3078
+ var _reactresizablepanels = require('react-resizable-panels');
3079
+
3080
+ function ResizablePanelGroup({
3081
+ direction,
3082
+ children,
3083
+ className,
3084
+ autoSaveId
3085
+ }) {
3086
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3087
+ _reactresizablepanels.Group,
3088
+ {
3089
+ orientation: direction,
3090
+ id: autoSaveId,
3091
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "flex h-full w-full", className),
3092
+ "data-opt-id": "MW6TZ",
3093
+ "data-opt-slug": "resizable.ResizablePanelGroup",
3094
+ children
3095
+ }
3096
+ );
3097
+ }
3098
+ ResizablePanelGroup.displayName = "ResizablePanelGroup";
3099
+ function ResizablePanel({
3100
+ defaultSize,
3101
+ minSize,
3102
+ maxSize,
3103
+ collapsible,
3104
+ children,
3105
+ className,
3106
+ id
3107
+ }) {
3108
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3109
+ _reactresizablepanels.Panel,
3110
+ {
3111
+ id,
3112
+ defaultSize,
3113
+ minSize,
3114
+ maxSize,
3115
+ collapsible,
3116
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "overflow-auto", className),
3117
+ "data-opt-id": "QRQV9",
3118
+ "data-opt-slug": "resizable.ResizablePanel",
3119
+ children
3120
+ }
3121
+ );
3122
+ }
3123
+ ResizablePanel.displayName = "ResizablePanel";
3124
+ function ResizableHandle({
3125
+ className,
3126
+ withHandle = false
3127
+ }) {
3128
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3129
+ _reactresizablepanels.Separator,
3130
+ {
3131
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
3132
+ "bg-border relative flex items-center justify-center",
3133
+ "after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2",
3134
+ "data-[resize-handle-active]:bg-accent",
3135
+ "[&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full",
3136
+ "[&[data-orientation=horizontal]]:h-full [&[data-orientation=horizontal]]:w-px",
3137
+ className
3138
+ ),
3139
+ "data-opt-id": "7QWEQ",
3140
+ "data-opt-slug": "resizable.ResizableHandle",
3141
+ children: withHandle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border-border bg-surface z-10 flex h-4 w-3 items-center justify-center rounded-sm border", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3142
+ "svg",
3143
+ {
3144
+ width: "6",
3145
+ height: "10",
3146
+ viewBox: "0 0 6 10",
3147
+ fill: "none",
3148
+ className: "text-text-tertiary",
3149
+ children: [
3150
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "1", cy: "2", r: "0.75", fill: "currentColor" }),
3151
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "1", cy: "5", r: "0.75", fill: "currentColor" }),
3152
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "1", cy: "8", r: "0.75", fill: "currentColor" }),
3153
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "5", cy: "2", r: "0.75", fill: "currentColor" }),
3154
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "5", cy: "5", r: "0.75", fill: "currentColor" }),
3155
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "5", cy: "8", r: "0.75", fill: "currentColor" })
3156
+ ]
3157
+ }
3158
+ ) })
3159
+ }
3160
+ );
3161
+ }
3162
+ ResizableHandle.displayName = "ResizableHandle";
3163
+
3164
+ // src/core/logo.tsx
3165
+
3166
+
3167
+ var markSizeStyles = {
3168
+ sm: "h-6 w-6",
3169
+ md: "h-8 w-8",
3170
+ lg: "h-10 w-10"
3171
+ };
3172
+ var textSizeStyles = {
3173
+ sm: "text-sm",
3174
+ md: "text-base",
3175
+ lg: "text-lg"
3176
+ };
3177
+ function Logo({
3178
+ src,
3179
+ icon,
3180
+ text,
3181
+ alt = "Logo",
3182
+ size = "md",
3183
+ href,
3184
+ onClick,
3185
+ className
3186
+ }) {
3187
+ const [imageError, setImageError] = _react.useState.call(void 0, false);
3188
+ const showImage = src && !imageError;
3189
+ const fallbackLetter = text ? text.charAt(0).toUpperCase() : null;
3190
+ let mark = null;
3191
+ if (showImage) {
3192
+ mark = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3193
+ "img",
3194
+ {
3195
+ src,
3196
+ alt,
3197
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "object-contain", markSizeStyles[size]),
3198
+ onError: () => setImageError(true)
3199
+ }
3200
+ );
3201
+ } else if (icon) {
3202
+ mark = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3203
+ "span",
3204
+ {
3205
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
3206
+ "flex shrink-0 items-center justify-center",
3207
+ markSizeStyles[size]
3208
+ ),
3209
+ "aria-hidden": "true",
3210
+ children: icon
3211
+ }
3212
+ );
3213
+ } else if (fallbackLetter) {
3214
+ mark = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3215
+ "span",
3216
+ {
3217
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
3218
+ "bg-accent text-on-accent flex shrink-0 items-center justify-center rounded-lg font-bold",
3219
+ markSizeStyles[size],
3220
+ textSizeStyles[size]
3221
+ ),
3222
+ "aria-hidden": "true",
3223
+ children: fallbackLetter
3224
+ }
3225
+ );
3226
+ }
3227
+ const content = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
3228
+ mark,
3229
+ text && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3230
+ "span",
3231
+ {
3232
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
3233
+ "text-text-primary font-semibold",
3234
+ textSizeStyles[size]
3235
+ ),
3236
+ children: text
3237
+ }
3238
+ )
3239
+ ] });
3240
+ const sharedClassName = _chunkAFF2HPE5cjs.cn.call(void 0, "inline-flex items-center gap-element", className);
3241
+ if (href) {
3242
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3243
+ "a",
3244
+ {
3245
+ href,
3246
+ onClick,
3247
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, sharedClassName, "no-underline"),
3248
+ "aria-label": text != null ? text : alt,
3249
+ "data-opt-id": "R906A",
3250
+ "data-opt-slug": "logo.Logo",
3251
+ children: content
3252
+ }
3253
+ );
3254
+ }
3255
+ if (onClick) {
3256
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3257
+ "button",
3258
+ {
3259
+ type: "button",
3260
+ onClick,
3261
+ className: sharedClassName,
3262
+ "aria-label": text != null ? text : alt,
3263
+ "data-opt-id": "R906A",
3264
+ "data-opt-slug": "logo.Logo",
3265
+ children: content
3266
+ }
3267
+ );
3268
+ }
3269
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3270
+ "div",
3271
+ {
3272
+ className: sharedClassName,
3273
+ "data-opt-id": "R906A",
3274
+ "data-opt-slug": "logo.Logo",
3275
+ children: content
3276
+ }
3277
+ );
3278
+ }
3279
+
3280
+ // src/core/drawer.tsx
3281
+
3282
+
3283
+
3284
+
3285
+
3286
+
3287
+
3288
+
3289
+
3290
+
3291
+
3292
+
3293
+
3294
+ var sizeMap = {
3295
+ sm: "max-w-xs",
3296
+ md: "max-w-md",
3297
+ lg: "max-w-xl",
3298
+ full: "max-w-full"
3299
+ };
3300
+ var heightMap = {
3301
+ sm: "max-h-[320px]",
3302
+ md: "max-h-[480px]",
3303
+ lg: "max-h-[640px]",
3304
+ full: "max-h-full"
3305
+ };
3306
+ var positionClass = {
3307
+ right: "fixed inset-y-0 right-0",
3308
+ left: "fixed inset-y-0 left-0",
3309
+ bottom: "fixed inset-x-0 bottom-0"
3310
+ };
3311
+ function DrawerRoot(props) {
3312
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3313
+ _optuiprimitives.DialogRoot,
3314
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
3315
+ animated: true
3316
+ }, props), {
3317
+ "data-opt-id": "YGJ0M",
3318
+ "data-opt-slug": "drawer.DrawerRoot"
3319
+ })
3320
+ );
3321
+ }
3322
+ function dismissOffset(side, dx, dy) {
3323
+ switch (side) {
3324
+ case "right":
3325
+ return Math.max(0, dx);
3326
+ case "left":
3327
+ return Math.min(0, dx);
3328
+ case "bottom":
3329
+ return Math.max(0, dy);
3330
+ default:
3331
+ return 0;
3332
+ }
3333
+ }
3334
+ function DrawerPanel(_a) {
3335
+ var _b = _a, {
3336
+ className,
3337
+ side = "right",
3338
+ size = "md",
3339
+ swipeToDismiss = true,
3340
+ swipeDismissThreshold = 80,
3341
+ style,
3342
+ onPointerDown
3343
+ } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
3344
+ "className",
3345
+ "side",
3346
+ "size",
3347
+ "swipeToDismiss",
3348
+ "swipeDismissThreshold",
3349
+ "style",
3350
+ "onPointerDown"
3351
+ ]);
3352
+ const isHorizontal = side === "left" || side === "right";
3353
+ const close = _optuiprimitives.useDialogClose.call(void 0, );
3354
+ const dragStart = _react.useRef.call(void 0, null);
3355
+ const [offset, setOffset] = _react.useState.call(void 0, 0);
3356
+ const [dragging, setDragging] = _react.useState.call(void 0, false);
3357
+ const axis = side === "bottom" ? "Y" : "X";
3358
+ const DRAG_ACTIVATE = 6;
3359
+ const handlePointerDown = _react.useCallback.call(void 0,
3360
+ (e) => {
3361
+ onPointerDown == null ? void 0 : onPointerDown(e);
3362
+ if (!swipeToDismiss || e.button !== 0) return;
3363
+ dragStart.current = { x: e.clientX, y: e.clientY };
3364
+ },
3365
+ [swipeToDismiss, onPointerDown]
3366
+ );
3367
+ const handlePointerMove = _react.useCallback.call(void 0,
3368
+ (e) => {
3369
+ const start = dragStart.current;
3370
+ if (!start) return;
3371
+ const next = dismissOffset(
3372
+ side,
3373
+ e.clientX - start.x,
3374
+ e.clientY - start.y
3375
+ );
3376
+ if (!dragging) {
3377
+ if (Math.abs(next) < DRAG_ACTIVATE) return;
3378
+ setDragging(true);
3379
+ try {
3380
+ e.currentTarget.setPointerCapture(e.pointerId);
3381
+ } catch (e2) {
3382
+ }
3383
+ }
3384
+ setOffset(next);
3385
+ },
3386
+ [side, dragging]
3387
+ );
3388
+ const endDrag = _react.useCallback.call(void 0,
3389
+ (e) => {
3390
+ const wasDragging = dragging;
3391
+ dragStart.current = null;
3392
+ setDragging(false);
3393
+ try {
3394
+ e.currentTarget.releasePointerCapture(e.pointerId);
3395
+ } catch (e2) {
3396
+ }
3397
+ if (wasDragging && Math.abs(offset) >= swipeDismissThreshold) {
3398
+ close();
3399
+ }
3400
+ setOffset(0);
3401
+ },
3402
+ [dragging, offset, swipeDismissThreshold, close]
3403
+ );
3404
+ const [keyboardInset, setKeyboardInset] = _react.useState.call(void 0, 0);
3405
+ _react.useEffect.call(void 0, () => {
3406
+ if (side !== "bottom" || typeof window === "undefined") return;
3407
+ const vv = window.visualViewport;
3408
+ if (!vv) return;
3409
+ const onResize = () => {
3410
+ const inset = Math.max(0, window.innerHeight - vv.height - vv.offsetTop);
3411
+ setKeyboardInset(inset);
3412
+ };
3413
+ onResize();
3414
+ vv.addEventListener("resize", onResize);
3415
+ vv.addEventListener("scroll", onResize);
3416
+ return () => {
3417
+ vv.removeEventListener("resize", onResize);
3418
+ vv.removeEventListener("scroll", onResize);
3419
+ };
3420
+ }, [side]);
3421
+ const dragStyle = offset !== 0 ? { transform: `translate${axis}(${offset}px)` } : void 0;
3422
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3423
+ _optuiprimitives.DialogPanel,
3424
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
3425
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
3426
+ "border-border bg-surface z-50 m-0 flex flex-col border p-0 shadow-2xl",
3427
+ "data-[enter]:fade-in data-[leave]:fade-out",
3428
+ // Suppress the slide animation while actively dragging.
3429
+ dragging ? "touch-none" : _chunkAFF2HPE5cjs.OPT_ANIMATE_DRAWER[side],
3430
+ positionClass[side],
3431
+ isHorizontal ? ["h-full w-full", sizeMap[size]] : ["w-full", heightMap[size]],
3432
+ className
3433
+ ),
3434
+ style: _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, style), dragStyle), keyboardInset > 0 ? { marginBottom: keyboardInset } : null), dragging ? { transition: "none" } : null),
3435
+ onPointerDown: handlePointerDown,
3436
+ onPointerMove: swipeToDismiss ? handlePointerMove : void 0,
3437
+ onPointerUp: swipeToDismiss ? endDrag : void 0,
3438
+ onPointerCancel: swipeToDismiss ? endDrag : void 0
3439
+ }, props), {
3440
+ "data-opt-id": "RQERV",
3441
+ "data-opt-slug": "drawer.DrawerPanel"
3442
+ })
3443
+ );
3444
+ }
3445
+ function DrawerClose(_a) {
3446
+ var _b = _a, { className } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, ["className"]);
3447
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3448
+ _optuiprimitives.DialogDismiss,
3449
+ _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
3450
+ className: _chunkAFF2HPE5cjs.cn.call(void 0,
3451
+ "hover:bg-bg-subtle rounded-md p-1.5 transition-colors",
3452
+ "cursor-pointer data-[disabled]:cursor-not-allowed",
3453
+ _chunkAFF2HPE5cjs.OPT_FOCUS,
3454
+ className
3455
+ )
3456
+ }, props), {
3457
+ "data-opt-id": "M6D6D",
3458
+ "data-opt-slug": "drawer.DrawerClose"
3459
+ })
3460
+ );
3461
+ }
3462
+
3463
+ // src/core/virtual-list.tsx
3464
+
3465
+
3466
+
3467
+
3468
+
3469
+
3470
+
3471
+
3472
+ function VirtualList({
3473
+ items,
3474
+ renderItem,
3475
+ itemHeight,
3476
+ overscan = 3,
3477
+ className,
3478
+ style
3479
+ }) {
3480
+ const containerRef = _react.useRef.call(void 0, null);
3481
+ const scrollTopRef = _react.useRef.call(void 0, 0);
3482
+ const containerHeightRef = _react.useRef.call(void 0, 0);
3483
+ const rafIdRef = _react.useRef.call(void 0, 0);
3484
+ const [visibleRange, setVisibleRange] = _react.useState.call(void 0, { start: 0, end: 0 });
3485
+ const totalHeight = items.length * itemHeight;
3486
+ const computeRange = _react.useCallback.call(void 0,
3487
+ (scrollTop, height) => {
3488
+ const start = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);
3489
+ const visibleCount = Math.ceil(height / itemHeight);
3490
+ const end = Math.min(
3491
+ items.length - 1,
3492
+ start + visibleCount + overscan * 2
3493
+ );
3494
+ return { start, end };
3495
+ },
3496
+ [itemHeight, overscan, items.length]
3497
+ );
3498
+ const scheduleUpdate = _react.useCallback.call(void 0, () => {
3499
+ if (rafIdRef.current) return;
3500
+ rafIdRef.current = requestAnimationFrame(() => {
3501
+ rafIdRef.current = 0;
3502
+ const newRange = computeRange(
3503
+ scrollTopRef.current,
3504
+ containerHeightRef.current
3505
+ );
3506
+ setVisibleRange(
3507
+ (prev) => prev.start === newRange.start && prev.end === newRange.end ? prev : newRange
3508
+ );
3509
+ });
3510
+ }, [computeRange]);
3511
+ const handleScroll = _react.useCallback.call(void 0, () => {
3512
+ const el = containerRef.current;
3513
+ if (el) {
3514
+ scrollTopRef.current = el.scrollTop;
3515
+ if (el.clientHeight !== containerHeightRef.current) {
3516
+ containerHeightRef.current = el.clientHeight;
3517
+ }
3518
+ scheduleUpdate();
3519
+ }
3520
+ }, [scheduleUpdate]);
3521
+ const handleRef = _react.useCallback.call(void 0,
3522
+ (el) => {
3523
+ containerRef.current = el;
3524
+ if (el) {
3525
+ containerHeightRef.current = el.clientHeight;
3526
+ const range = computeRange(0, el.clientHeight);
3527
+ setVisibleRange(range);
3528
+ }
3529
+ },
3530
+ [computeRange]
3531
+ );
3532
+ _react.useEffect.call(void 0, () => {
3533
+ const el = containerRef.current;
3534
+ if (!el || typeof ResizeObserver === "undefined") return;
3535
+ const observer = new ResizeObserver(() => {
3536
+ const nextHeight = el.clientHeight;
3537
+ if (nextHeight !== containerHeightRef.current) {
3538
+ containerHeightRef.current = nextHeight;
3539
+ scheduleUpdate();
3540
+ }
3541
+ });
3542
+ observer.observe(el);
3543
+ return () => {
3544
+ observer.disconnect();
3545
+ };
3546
+ }, [scheduleUpdate]);
3547
+ _react.useEffect.call(void 0, () => {
3548
+ scheduleUpdate();
3549
+ return () => {
3550
+ if (rafIdRef.current) {
3551
+ cancelAnimationFrame(rafIdRef.current);
3552
+ rafIdRef.current = 0;
3553
+ }
3554
+ };
3555
+ }, [scheduleUpdate, items.length, itemHeight, overscan]);
3556
+ const visibleItems = _react.useMemo.call(void 0, () => {
3557
+ const result = [];
3558
+ for (let i = visibleRange.start; i <= visibleRange.end && i < items.length; i++) {
3559
+ result.push(
3560
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3561
+ "div",
3562
+ {
3563
+ role: "listitem",
3564
+ style: {
3565
+ position: "absolute",
3566
+ top: i * itemHeight,
3567
+ left: 0,
3568
+ right: 0,
3569
+ height: itemHeight
3570
+ },
3571
+ children: renderItem(items[i], i)
3572
+ },
3573
+ i
3574
+ )
3575
+ );
3576
+ }
3577
+ return result;
3578
+ }, [visibleRange.start, visibleRange.end, items, itemHeight, renderItem]);
3579
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3580
+ "div",
3581
+ {
3582
+ ref: handleRef,
3583
+ onScroll: handleScroll,
3584
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "overflow-auto", className),
3585
+ style: _chunkONE3C5RVcjs.__spreadValues.call(void 0, { position: "relative" }, style),
3586
+ role: "list",
3587
+ "data-opt-id": "VT2NP",
3588
+ "data-opt-slug": "virtual-list.VirtualList",
3589
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { height: totalHeight, position: "relative" }, children: visibleItems })
3590
+ }
3591
+ );
3592
+ }
3593
+
3594
+ // src/core/shader-presets.ts
3595
+ var SHADER_VERTEX = (
3596
+ /* glsl */
3597
+ `
3598
+ attribute vec2 position;
3599
+ attribute vec2 uv;
3600
+ varying vec2 vUv;
3601
+ void main() {
3602
+ vUv = uv;
3603
+ gl_Position = vec4(position, 0.0, 1.0);
3604
+ }
3605
+ `
3606
+ );
3607
+ var SHADER_PRELUDE = (
3608
+ /* glsl */
3609
+ `
3610
+ precision highp float;
3611
+ varying vec2 vUv;
3612
+ uniform float u_time;
3613
+ uniform vec2 u_resolution;
3614
+ uniform float u_scale;
3615
+ uniform float u_speed;
3616
+ uniform float u_distortion;
3617
+ uniform float u_grain;
3618
+ uniform float u_contrast;
3619
+ uniform float u_angle;
3620
+ uniform float u_dim;
3621
+ uniform float u_vignette;
3622
+ uniform float u_scrim;
3623
+ uniform vec2 u_mouse;
3624
+ uniform float u_interactive;
3625
+ uniform float u_bars;
3626
+ uniform float u_blur;
3627
+ uniform float u_peak;
3628
+ uniform float u_valley;
3629
+ uniform vec3 u_color1;
3630
+ uniform vec3 u_color2;
3631
+ uniform vec3 u_color3;
3632
+
3633
+ const float PI = 3.14159265359;
3634
+
3635
+ mat2 rot(float a){ float c = cos(a), s = sin(a); return mat2(c, -s, s, c); }
3636
+
3637
+ float hash21(vec2 p){
3638
+ p = fract(p * vec2(123.34, 345.45));
3639
+ p += dot(p, p + 34.345);
3640
+ return fract(p.x * p.y);
3641
+ }
3642
+
3643
+ float vnoise(vec2 p){
3644
+ vec2 i = floor(p);
3645
+ vec2 f = fract(p);
3646
+ vec2 u = f * f * (3.0 - 2.0 * f);
3647
+ float a = hash21(i);
3648
+ float b = hash21(i + vec2(1.0, 0.0));
3649
+ float c = hash21(i + vec2(0.0, 1.0));
3650
+ float d = hash21(i + vec2(1.0, 1.0));
3651
+ return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
3652
+ }
3653
+
3654
+ float fbm(vec2 p){
3655
+ float v = 0.0;
3656
+ float amp = 0.5;
3657
+ for (int i = 0; i < 5; i++){
3658
+ v += amp * vnoise(p);
3659
+ p = rot(0.5) * p * 2.0;
3660
+ amp *= 0.5;
3661
+ }
3662
+ return v;
3663
+ }
3664
+
3665
+ // fine film grain \u2014 subtle, premium texture
3666
+ vec3 grain(vec3 col, vec2 uv){
3667
+ float g = hash21(uv * u_resolution.xy + fract(u_time));
3668
+ return col + (g - 0.5) * u_grain;
3669
+ }
3670
+
3671
+ // premium finish: gentle desaturation for an understated, refined look.
3672
+ vec3 lux(vec3 col){
3673
+ float l = dot(col, vec3(0.299, 0.587, 0.114));
3674
+ return clamp(mix(vec3(l), col, 0.82), 0.0, 1.0);
3675
+ }
3676
+
3677
+ // shared output finish: refine + legibility overlays (dim / vignette / bottom
3678
+ // scrim) + film grain. Every preset ends with finish(col, vUv).
3679
+ vec3 finish(vec3 col, vec2 uv){
3680
+ col = lux(col);
3681
+ col *= 1.0 - u_dim * 0.85;
3682
+ float edge = length(uv - 0.5);
3683
+ col *= 1.0 - u_vignette * smoothstep(0.35, 0.85, edge);
3684
+ col *= 1.0 - u_scrim * smoothstep(0.2, 1.0, uv.y);
3685
+ col = grain(col, uv);
3686
+ return col;
3687
+ }
3688
+
3689
+ // aspect-correct, angle-rotated, centered coords + pointer parallax
3690
+ vec2 coords(){
3691
+ vec2 uv = vUv - 0.5;
3692
+ uv.x *= u_resolution.x / max(u_resolution.y, 1.0);
3693
+ uv += (u_mouse - 0.5) * u_interactive * 0.3;
3694
+ uv = rot(radians(u_angle)) * uv;
3695
+ return uv;
3696
+ }
3697
+ `
3698
+ );
3699
+ var PARAM_RANGE = {
3700
+ scale: { min: 0.4, max: 3, step: 0.1, default: 1 },
3701
+ speed: { min: 0, max: 3, step: 0.1, default: 0.5 },
3702
+ distortion: { min: 0, max: 1, step: 0.01, default: 0.4 },
3703
+ grain: { min: 0, max: 0.5, step: 0.01, default: 0.04 },
3704
+ contrast: { min: 0, max: 1, step: 0.01, default: 0.4 },
3705
+ angle: { min: 0, max: 360, step: 1, default: 0 },
3706
+ dim: { min: 0, max: 1, step: 0.01, default: 0 },
3707
+ vignette: { min: 0, max: 1, step: 0.01, default: 0 },
3708
+ scrim: { min: 0, max: 1, step: 0.01, default: 0 },
3709
+ interactive: { min: 0, max: 1, step: 0.01, default: 0 },
3710
+ bars: { min: 2, max: 40, step: 1, default: 19 },
3711
+ blur: { min: 0, max: 1, step: 0.01, default: 0.29 },
3712
+ peak: { min: 0, max: 1, step: 0.01, default: 0.98 },
3713
+ valley: { min: 0, max: 1, step: 0.01, default: 0.55 }
3714
+ };
3715
+ var SHADER_PARAM_FALLBACK = {
3716
+ scale: PARAM_RANGE.scale.default,
3717
+ speed: PARAM_RANGE.speed.default,
3718
+ distortion: PARAM_RANGE.distortion.default,
3719
+ grain: PARAM_RANGE.grain.default,
3720
+ contrast: PARAM_RANGE.contrast.default,
3721
+ angle: PARAM_RANGE.angle.default,
3722
+ dim: PARAM_RANGE.dim.default,
3723
+ vignette: PARAM_RANGE.vignette.default,
3724
+ scrim: PARAM_RANGE.scrim.default,
3725
+ interactive: PARAM_RANGE.interactive.default,
3726
+ bars: PARAM_RANGE.bars.default,
3727
+ blur: PARAM_RANGE.blur.default,
3728
+ peak: PARAM_RANGE.peak.default,
3729
+ valley: PARAM_RANGE.valley.default
3730
+ };
3731
+ function param(key, defaultValue) {
3732
+ const range = PARAM_RANGE[key];
3733
+ return {
3734
+ key,
3735
+ min: range.min,
3736
+ max: range.max,
3737
+ step: range.step,
3738
+ default: defaultValue != null ? defaultValue : range.default
3739
+ };
3740
+ }
3741
+ var SHADER_PRESETS = [
3742
+ {
3743
+ id: "felix-metallic",
3744
+ category: "luxury",
3745
+ colorSlots: 3,
3746
+ defaultColors: ["#0a1424", "#3a5a8c", "#c4d4e8"],
3747
+ params: [
3748
+ param("scale"),
3749
+ param("speed", 0.4),
3750
+ param("distortion", 0.45),
3751
+ param("contrast", 0.4),
3752
+ param("grain", 0.04)
3753
+ ],
3754
+ body: (
3755
+ /* glsl */
3756
+ `
3757
+ void main(){
3758
+ vec2 uv = coords() * u_scale;
3759
+ float t = u_time * u_speed * 0.3;
3760
+ vec2 q = vec2(fbm(uv + t), fbm(uv - t + 5.2));
3761
+ vec2 r = vec2(
3762
+ fbm(uv + q * 2.0 + vec2(1.7, 9.2) + t),
3763
+ fbm(uv + q * 2.0 + vec2(8.3, 2.8) - t)
3764
+ );
3765
+ float f = fbm(uv + r * (1.0 + u_distortion * 2.0));
3766
+ float band = sin((f + r.x * 0.5) * 6.2831 * 2.0);
3767
+ float spec = pow(abs(band), mix(2.0, 5.0, u_contrast));
3768
+ vec3 col = mix(u_color1, u_color2, smoothstep(0.0, 1.0, f + r.y * 0.4));
3769
+ col = mix(col, u_color3, spec * 0.5);
3770
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
3771
+ }
3772
+ `
3773
+ )
3774
+ },
3775
+ {
3776
+ id: "liquid-silk",
3777
+ category: "luxury",
3778
+ colorSlots: 3,
3779
+ defaultColors: ["#1c1428", "#6a5a8c", "#d8cfe4"],
3780
+ params: [
3781
+ param("scale"),
3782
+ param("speed", 0.4),
3783
+ param("distortion", 0.4),
3784
+ param("grain", 0.04),
3785
+ param("angle", 30)
3786
+ ],
3787
+ body: (
3788
+ /* glsl */
3789
+ `
3790
+ void main(){
3791
+ vec2 uv = coords() * u_scale;
3792
+ float t = u_time * u_speed * 0.25;
3793
+ float warp = fbm(uv * 1.5 + t);
3794
+ float folds = sin((uv.x * 3.0 + uv.y * 1.5 + warp * (2.0 + u_distortion * 4.0)) * PI);
3795
+ float sheen = 0.5 + 0.5 * folds;
3796
+ vec3 col = mix(u_color1, u_color2, sheen);
3797
+ col = mix(col, u_color3, pow(sheen, 5.0) * 0.6);
3798
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
3799
+ }
3800
+ `
3801
+ )
3802
+ },
3803
+ {
3804
+ id: "iridescent-pearl",
3805
+ category: "luxury",
3806
+ colorSlots: 3,
3807
+ defaultColors: ["#c9b8d6", "#a8c4d4", "#e4d4dc"],
3808
+ params: [
3809
+ param("scale"),
3810
+ param("speed", 0.35),
3811
+ param("distortion", 0.4),
3812
+ param("grain", 0.04)
3813
+ ],
3814
+ body: (
3815
+ /* glsl */
3816
+ `
3817
+ vec3 palette3(float t){
3818
+ t = fract(t);
3819
+ float s = t * 3.0;
3820
+ if (s < 1.0) return mix(u_color1, u_color2, smoothstep(0.0, 1.0, s));
3821
+ if (s < 2.0) return mix(u_color2, u_color3, smoothstep(0.0, 1.0, s - 1.0));
3822
+ return mix(u_color3, u_color1, smoothstep(0.0, 1.0, s - 2.0));
3823
+ }
3824
+ void main(){
3825
+ vec2 uv = coords() * u_scale;
3826
+ float t = u_time * u_speed * 0.2;
3827
+ float n = fbm(uv * 1.2 + vec2(t, -t));
3828
+ float thin = fbm(uv * 2.5 - n * (1.0 + u_distortion * 3.0) + t * 0.5);
3829
+ vec3 col = palette3(thin * 1.5 + n * 0.5 + t * 0.1);
3830
+ col += pow(thin, 3.0) * 0.12;
3831
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
3832
+ }
3833
+ `
3834
+ )
3835
+ },
3836
+ {
3837
+ id: "molten-gold",
3838
+ category: "luxury",
3839
+ colorSlots: 3,
3840
+ defaultColors: ["#1c1208", "#b08848", "#e8d4a8"],
3841
+ params: [
3842
+ param("scale"),
3843
+ param("speed", 0.4),
3844
+ param("contrast", 0.4),
3845
+ param("grain", 0.05)
3846
+ ],
3847
+ body: (
3848
+ /* glsl */
3849
+ `
3850
+ void main(){
3851
+ vec2 uv = coords() * u_scale;
3852
+ float t = u_time * u_speed * 0.3;
3853
+ vec2 q = vec2(fbm(uv + t), fbm(uv * 1.3 - t));
3854
+ float f = fbm(uv * 1.5 + q * 2.5);
3855
+ float heat = smoothstep(0.25, 0.95, f);
3856
+ vec3 col = mix(u_color1, u_color2, heat);
3857
+ float hot = pow(smoothstep(0.6, 1.0, f + q.x * 0.3), mix(3.0, 6.0, u_contrast));
3858
+ col = mix(col, u_color3, hot * 0.7);
3859
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
3860
+ }
3861
+ `
3862
+ )
3863
+ },
3864
+ {
3865
+ id: "liquid-glass",
3866
+ category: "luxury",
3867
+ colorSlots: 3,
3868
+ defaultColors: ["#0c1c2c", "#3a6a88", "#bcdce4"],
3869
+ params: [
3870
+ param("scale"),
3871
+ param("speed", 0.4),
3872
+ param("distortion", 0.4),
3873
+ param("grain", 0.03)
3874
+ ],
3875
+ body: (
3876
+ /* glsl */
3877
+ `
3878
+ void main(){
3879
+ vec2 uv = coords() * u_scale;
3880
+ float t = u_time * u_speed * 0.2;
3881
+ vec2 p = uv;
3882
+ for (int i = 1; i < 5; i++){
3883
+ float fi = float(i);
3884
+ p += (1.0 + u_distortion) * vec2(
3885
+ 0.3 / fi * sin(fi * p.y + t + 0.3 * fi),
3886
+ 0.3 / fi * cos(fi * p.x + t + 0.3 * fi)
3887
+ );
3888
+ }
3889
+ float caustic = 0.5 + 0.5 * sin(p.x * 3.0) * cos(p.y * 3.0);
3890
+ vec3 col = mix(u_color1, u_color2, caustic);
3891
+ col = mix(col, u_color3, pow(caustic, 6.0) * 0.6);
3892
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
3893
+ }
3894
+ `
3895
+ )
3896
+ },
3897
+ {
3898
+ id: "aurora-veil",
3899
+ category: "luxury",
3900
+ colorSlots: 3,
3901
+ defaultColors: ["#050d18", "#2a8a8c", "#6a5a9c"],
3902
+ params: [
3903
+ param("scale"),
3904
+ param("speed", 0.4),
3905
+ param("distortion", 0.45),
3906
+ param("grain", 0.03),
3907
+ param("angle", 0)
3908
+ ],
3909
+ body: (
3910
+ /* glsl */
3911
+ `
3912
+ void main(){
3913
+ vec2 uv = coords() * u_scale;
3914
+ float t = u_time * u_speed * 0.3;
3915
+ vec3 col = u_color1;
3916
+ for (int i = 0; i < 3; i++){
3917
+ float fi = float(i);
3918
+ float band = uv.y * 1.5
3919
+ + sin(uv.x * 2.0 + t + fi * 1.7) * (0.3 + u_distortion * 0.5)
3920
+ + fbm(uv * 1.5 + t * 0.5 + fi) * 0.6;
3921
+ float glow = exp(-abs(band) * 3.0);
3922
+ vec3 rib = mix(u_color2, u_color3, fi * 0.5);
3923
+ col += rib * glow * 0.5;
3924
+ }
3925
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
3926
+ }
3927
+ `
3928
+ )
3929
+ },
3930
+ {
3931
+ id: "holographic",
3932
+ category: "luxury",
3933
+ colorSlots: 3,
3934
+ defaultColors: ["#14101e", "#8a6a9c", "#7a9caa"],
3935
+ params: [
3936
+ param("scale"),
3937
+ param("speed", 0.35),
3938
+ param("distortion", 0.4),
3939
+ param("grain", 0.03)
3940
+ ],
3941
+ body: (
3942
+ /* glsl */
3943
+ `
3944
+ vec3 hsv2rgb(vec3 c){
3945
+ vec3 p = abs(fract(c.xxx + vec3(0.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0);
3946
+ return c.z * mix(vec3(1.0), clamp(p - 1.0, 0.0, 1.0), c.y);
3947
+ }
3948
+ void main(){
3949
+ vec2 uv = coords() * u_scale;
3950
+ float t = u_time * u_speed * 0.2;
3951
+ float n = fbm(uv * 1.5 + t);
3952
+ float ripple = fbm(uv * 3.0 - n * (1.0 + u_distortion * 2.0) + t);
3953
+ float hue = fract(ripple * 1.2 + n * 0.5 + length(uv) * 0.3 + t * 0.1);
3954
+ vec3 holo = hsv2rgb(vec3(hue, 0.3, 0.92));
3955
+ vec3 base = mix(u_color1, u_color2, n);
3956
+ vec3 col = mix(base, holo, 0.35);
3957
+ col = mix(col, u_color3, pow(ripple, 4.0) * 0.5);
3958
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
3959
+ }
3960
+ `
3961
+ )
3962
+ },
3963
+ {
3964
+ id: "chrome-ripple",
3965
+ category: "luxury",
3966
+ colorSlots: 3,
3967
+ defaultColors: ["#0e1420", "#6a7a92", "#d4dce4"],
3968
+ params: [
3969
+ param("scale"),
3970
+ param("speed", 0.4),
3971
+ param("contrast", 0.4),
3972
+ param("grain", 0.04)
3973
+ ],
3974
+ body: (
3975
+ /* glsl */
3976
+ `
3977
+ void main(){
3978
+ vec2 uv = coords() * u_scale;
3979
+ float t = u_time * u_speed * 0.3;
3980
+ vec2 p = uv;
3981
+ for (int i = 1; i < 6; i++){
3982
+ float fi = float(i);
3983
+ p.x += (0.4 / fi) * sin(fi * 1.5 * p.y + t + fi);
3984
+ p.y += (0.4 / fi) * cos(fi * 1.5 * p.x + t + fi);
3985
+ }
3986
+ float sheen = 0.5 + 0.5 * sin(p.x * 3.0 + p.y * 2.0);
3987
+ float spec = pow(sheen, mix(3.0, 6.0, u_contrast));
3988
+ vec3 col = mix(u_color1, u_color2, sheen);
3989
+ col = mix(col, u_color3, spec * 0.5);
3990
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
3991
+ }
3992
+ `
3993
+ )
3994
+ },
3995
+ {
3996
+ id: "mesh-flow",
3997
+ category: "flow",
3998
+ colorSlots: 3,
3999
+ defaultColors: ["#3a4a6a", "#6a5a7c", "#4a7a82"],
4000
+ params: [param("scale"), param("speed", 0.5), param("grain", 0.04)],
4001
+ body: (
4002
+ /* glsl */
4003
+ `
4004
+ void main(){
4005
+ vec2 uv = coords() * u_scale;
4006
+ float t = u_time * u_speed * 0.4;
4007
+ vec2 p1 = vec2(sin(t * 0.7), cos(t * 0.9)) * 0.5;
4008
+ vec2 p2 = vec2(cos(t * 0.8 + 1.0), sin(t * 0.6 + 2.0)) * 0.5;
4009
+ vec2 p3 = vec2(sin(t * 0.5 + 3.0), cos(t * 0.7 + 4.0)) * 0.5;
4010
+ float d1 = 1.0 / (0.15 + dot(uv - p1, uv - p1));
4011
+ float d2 = 1.0 / (0.15 + dot(uv - p2, uv - p2));
4012
+ float d3 = 1.0 / (0.15 + dot(uv - p3, uv - p3));
4013
+ float sum = d1 + d2 + d3;
4014
+ vec3 col = (u_color1 * d1 + u_color2 * d2 + u_color3 * d3) / sum;
4015
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
4016
+ }
4017
+ `
4018
+ )
4019
+ },
4020
+ {
4021
+ id: "plasma-wave",
4022
+ category: "flow",
4023
+ colorSlots: 3,
4024
+ defaultColors: ["#2a2440", "#4a5a7c", "#8a6a7c"],
4025
+ params: [
4026
+ param("scale"),
4027
+ param("speed", 0.4),
4028
+ param("distortion", 0.4),
4029
+ param("grain", 0.03)
4030
+ ],
4031
+ body: (
4032
+ /* glsl */
4033
+ `
4034
+ void main(){
4035
+ vec2 uv = coords() * u_scale * 3.0;
4036
+ float t = u_time * u_speed * 0.5;
4037
+ float v = sin(uv.x + t)
4038
+ + sin(uv.y + t * 1.3)
4039
+ + sin((uv.x + uv.y) * 0.7 + t)
4040
+ + sin(length(uv) * (1.0 + u_distortion * 2.0) - t * 1.5);
4041
+ v *= 0.25;
4042
+ float m = 0.5 + 0.5 * sin(v * PI);
4043
+ vec3 col = mix(u_color1, u_color2, m);
4044
+ col = mix(col, u_color3, (0.5 + 0.5 * sin(v * 6.2831)) * 0.5);
4045
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
4046
+ }
4047
+ `
4048
+ )
4049
+ },
4050
+ {
4051
+ id: "swirl-vortex",
4052
+ category: "flow",
4053
+ colorSlots: 3,
4054
+ defaultColors: ["#0a0e16", "#7c4a5c", "#3a7a72"],
4055
+ params: [
4056
+ param("scale"),
4057
+ param("speed", 0.4),
4058
+ param("distortion", 0.45),
4059
+ param("grain", 0.03)
4060
+ ],
4061
+ body: (
4062
+ /* glsl */
4063
+ `
4064
+ void main(){
4065
+ vec2 uv = coords() * u_scale;
4066
+ float t = u_time * u_speed * 0.3;
4067
+ float r = length(uv);
4068
+ float a = atan(uv.y, uv.x);
4069
+ a += (1.0 + u_distortion * 3.0) * (0.5 / (r + 0.2)) + t;
4070
+ vec2 p = vec2(cos(a), sin(a)) * r;
4071
+ float n = fbm(p * 2.0 + t);
4072
+ float bands = sin((a * 3.0 + r * 6.0 - t * 2.0) + n * 4.0);
4073
+ float m = 0.5 + 0.5 * bands;
4074
+ vec3 col = mix(u_color1, u_color2, m);
4075
+ col = mix(col, u_color3, pow(m, 3.0) * 0.6);
4076
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
4077
+ }
4078
+ `
4079
+ )
4080
+ },
4081
+ {
4082
+ id: "caustics",
4083
+ category: "flow",
4084
+ colorSlots: 3,
4085
+ defaultColors: ["#04161f", "#2a6a7c", "#a8d4d0"],
4086
+ params: [
4087
+ param("scale"),
4088
+ param("speed", 0.4),
4089
+ param("distortion", 0.4),
4090
+ param("grain", 0.03)
4091
+ ],
4092
+ body: (
4093
+ /* glsl */
4094
+ `
4095
+ void main(){
4096
+ vec2 uv = coords() * u_scale * 3.0;
4097
+ float t = u_time * u_speed * 0.4;
4098
+ vec2 p = uv;
4099
+ float c = 0.0;
4100
+ for (int i = 0; i < 4; i++){
4101
+ float fi = float(i);
4102
+ p += vec2(sin(p.y * 1.5 + t + fi), cos(p.x * 1.5 + t * 1.1 + fi))
4103
+ * (0.4 + u_distortion * 0.5);
4104
+ c += 1.0 / (length(fract(p) - 0.5) + 0.1);
4105
+ }
4106
+ c = pow(c * 0.06, 2.0);
4107
+ vec3 col = mix(u_color1, u_color2, clamp(c, 0.0, 1.0));
4108
+ col += u_color3 * pow(clamp(c - 0.6, 0.0, 1.0), 2.0) * 0.6;
4109
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
4110
+ }
4111
+ `
4112
+ )
4113
+ },
4114
+ {
4115
+ id: "nebula",
4116
+ category: "flow",
4117
+ colorSlots: 3,
4118
+ defaultColors: ["#06040e", "#4a3a6c", "#8a5a7c"],
4119
+ params: [
4120
+ param("scale"),
4121
+ param("speed", 0.35),
4122
+ param("distortion", 0.5),
4123
+ param("grain", 0.03)
4124
+ ],
4125
+ body: (
4126
+ /* glsl */
4127
+ `
4128
+ void main(){
4129
+ vec2 uv = coords() * u_scale;
4130
+ float t = u_time * u_speed * 0.15;
4131
+ vec2 q = vec2(fbm(uv + t), fbm(uv * 1.2 - t + 3.0));
4132
+ float density = fbm(uv * 1.5 + q * (2.0 + u_distortion * 2.0));
4133
+ density = pow(density, 2.0);
4134
+ vec3 col = mix(u_color1, u_color2, density);
4135
+ col = mix(col, u_color3, pow(density, 3.0) * 0.8);
4136
+ float stars = step(0.99, hash21(floor(vUv * u_resolution.xy / 2.5)));
4137
+ col += vec3(stars) * 0.35;
4138
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
4139
+ }
4140
+ `
4141
+ )
4142
+ },
4143
+ {
4144
+ id: "voronoi-crystal",
4145
+ category: "geometric",
4146
+ colorSlots: 3,
4147
+ defaultColors: ["#121a30", "#3a5a82", "#c4d0e0"],
4148
+ params: [
4149
+ param("scale"),
4150
+ param("speed", 0.35),
4151
+ param("contrast", 0.4),
4152
+ param("grain", 0.03)
4153
+ ],
4154
+ body: (
4155
+ /* glsl */
4156
+ `
4157
+ vec2 hash22(vec2 p){
4158
+ p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)));
4159
+ return fract(sin(p) * 43758.5453);
4160
+ }
4161
+ void main(){
4162
+ vec2 uv = coords() * u_scale * 3.0;
4163
+ float t = u_time * u_speed * 0.3;
4164
+ vec2 ip = floor(uv);
4165
+ vec2 fp = fract(uv);
4166
+ float f1 = 8.0;
4167
+ float f2 = 8.0;
4168
+ vec2 cellId = vec2(0.0);
4169
+ for (int j = -1; j <= 1; j++){
4170
+ for (int i = -1; i <= 1; i++){
4171
+ vec2 n = vec2(float(i), float(j));
4172
+ vec2 pnt = n + 0.5 + 0.4 * sin(t + 6.2831 * hash22(ip + n));
4173
+ float d = length(pnt - fp);
4174
+ if (d < f1){ f2 = f1; f1 = d; cellId = ip + n; }
4175
+ else if (d < f2){ f2 = d; }
4176
+ }
4177
+ }
4178
+ float facet = f2 - f1;
4179
+ float cell = hash22(cellId).x;
4180
+ vec3 col = mix(u_color1, u_color2, cell);
4181
+ col = mix(col, u_color3, smoothstep(0.05, 0.0, facet) * mix(0.4, 0.7, u_contrast));
4182
+ col += pow(max(0.0, 1.0 - f1), 4.0) * 0.1;
4183
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
4184
+ }
4185
+ `
4186
+ )
4187
+ },
4188
+ {
4189
+ id: "kaleidoscope",
4190
+ category: "geometric",
4191
+ colorSlots: 3,
4192
+ defaultColors: ["#1a1428", "#7c5a6c", "#b09a6a"],
4193
+ params: [
4194
+ param("scale"),
4195
+ param("speed", 0.35),
4196
+ param("distortion", 0.4),
4197
+ param("grain", 0.03)
4198
+ ],
4199
+ body: (
4200
+ /* glsl */
4201
+ `
4202
+ void main(){
4203
+ vec2 uv = coords() * u_scale;
4204
+ float t = u_time * u_speed * 0.3;
4205
+ float r = length(uv);
4206
+ float a = atan(uv.y, uv.x);
4207
+ float seg = 6.0 + floor(u_distortion * 6.0);
4208
+ a = mod(a, 6.2831 / seg);
4209
+ a = abs(a - 3.14159 / seg);
4210
+ vec2 p = vec2(cos(a), sin(a)) * r;
4211
+ float pattern = fbm(p * 3.0 + t);
4212
+ float m = 0.5 + 0.5 * sin(pattern * 6.2831 + r * 4.0 - t);
4213
+ vec3 col = mix(u_color1, u_color2, m);
4214
+ col = mix(col, u_color3, pow(m, 3.0) * 0.6);
4215
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
4216
+ }
4217
+ `
4218
+ )
4219
+ },
4220
+ {
4221
+ id: "dither-gradient",
4222
+ category: "retro",
4223
+ colorSlots: 3,
4224
+ defaultColors: ["#14202e", "#7c4a54", "#d4d0c8"],
4225
+ params: [param("scale"), param("speed", 0.35), param("distortion", 0.35)],
4226
+ body: (
4227
+ /* glsl */
4228
+ `
4229
+ float bayer2(vec2 a){ a = floor(a); return fract(dot(a, vec2(0.5, a.y * 0.75))); }
4230
+ float bayer4(vec2 a){ return bayer2(0.5 * a) * 0.25 + bayer2(a); }
4231
+ void main(){
4232
+ vec2 uv = coords() * u_scale;
4233
+ float t = u_time * u_speed * 0.2;
4234
+ float g = fbm(uv * 1.5 + vec2(t, -t) * (0.5 + u_distortion));
4235
+ float levels = 5.0;
4236
+ float d = bayer4(gl_FragCoord.xy);
4237
+ float q = floor(g * levels + d) / levels;
4238
+ vec3 col = mix(u_color1, u_color2, clamp(q, 0.0, 1.0));
4239
+ col = mix(col, u_color3, smoothstep(0.7, 1.0, q));
4240
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
4241
+ }
4242
+ `
4243
+ )
4244
+ },
4245
+ {
4246
+ id: "halftone",
4247
+ category: "retro",
4248
+ colorSlots: 3,
4249
+ defaultColors: ["#161616", "#8a5a3a", "#c4a06a"],
4250
+ params: [param("scale"), param("speed", 0.35), param("distortion", 0.45)],
4251
+ body: (
4252
+ /* glsl */
4253
+ `
4254
+ void main(){
4255
+ vec2 uv = coords() * u_scale;
4256
+ float t = u_time * u_speed * 0.2;
4257
+ float g = fbm(uv * 1.5 + t);
4258
+ vec2 gp = gl_FragCoord.xy / mix(22.0, 9.0, clamp(u_distortion, 0.0, 1.0));
4259
+ vec2 cell = fract(gp) - 0.5;
4260
+ float radius = g * 0.7;
4261
+ float dot = smoothstep(radius, radius - 0.12, length(cell));
4262
+ vec3 col = mix(u_color1, u_color2, g);
4263
+ col = mix(col, u_color3, dot * 0.85);
4264
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
4265
+ }
4266
+ `
4267
+ )
4268
+ },
4269
+ {
4270
+ id: "dia-gradient",
4271
+ category: "gradient",
4272
+ colorSlots: 3,
4273
+ defaultColors: ["#FF9ECF", "#A9C9FF", "#FFF3A8"],
4274
+ params: [
4275
+ param("bars"),
4276
+ param("blur"),
4277
+ param("peak"),
4278
+ param("valley"),
4279
+ param("speed", 0.3)
4280
+ ],
4281
+ body: (
4282
+ /* glsl */
4283
+ `
4284
+ void main(){
4285
+ vec2 uv = vUv;
4286
+ float t = u_time * u_speed * 0.15;
4287
+ float cx = 0.5 + sin(t) * 0.04;
4288
+ float peakShape = clamp(1.0 - abs(uv.x - cx) * 2.0, 0.0, 1.0);
4289
+ peakShape = pow(peakShape, 0.85);
4290
+ float profile = mix(u_valley, u_peak, peakShape);
4291
+ float heightFromBottom = 1.0 - uv.y;
4292
+ float h = heightFromBottom / max(profile, 0.02);
4293
+ float bars = max(1.0, floor(u_bars));
4294
+ float hb = h * bars;
4295
+ float band = floor(hb);
4296
+ float frac = hb - band;
4297
+ float soft = mix(0.04, 0.5, clamp(u_blur, 0.0, 1.0));
4298
+ float sm = smoothstep(0.5 - soft, 0.5 + soft, frac);
4299
+ float hv = clamp((band + sm) / bars, 0.0, 1.0);
4300
+ vec3 col;
4301
+ if (hv < 0.33) col = mix(u_color1, u_color2, smoothstep(0.0, 0.33, hv));
4302
+ else if (hv < 0.66) col = mix(u_color2, u_color3, smoothstep(0.33, 0.66, hv));
4303
+ else col = mix(u_color3, vec3(1.0), smoothstep(0.66, 1.0, hv));
4304
+ float above = smoothstep(1.0, 1.0 + soft * 0.5, h);
4305
+ col = mix(col, vec3(1.0), above);
4306
+ gl_FragColor = vec4(finish(col, vUv), 1.0);
4307
+ }
4308
+ `
4309
+ )
4310
+ }
4311
+ ];
4312
+ var SHADER_PRESET_IDS = SHADER_PRESETS.map(
4313
+ (preset) => preset.id
4314
+ );
4315
+ var SHADER_PARAM_KEYS = [
4316
+ "scale",
4317
+ "speed",
4318
+ "distortion",
4319
+ "grain",
4320
+ "contrast",
4321
+ "angle",
4322
+ "dim",
4323
+ "vignette",
4324
+ "scrim",
4325
+ "interactive",
4326
+ "bars",
4327
+ "blur",
4328
+ "peak",
4329
+ "valley"
4330
+ ];
4331
+ var SHADER_OVERLAY_PARAM_KEYS = [
4332
+ "dim",
4333
+ "vignette",
4334
+ "scrim"
4335
+ ];
4336
+ var PRESET_BY_ID = new Map(
4337
+ SHADER_PRESETS.map((preset) => [preset.id, preset])
4338
+ );
4339
+ function getShaderPreset(id) {
4340
+ var _a;
4341
+ return (_a = PRESET_BY_ID.get(id)) != null ? _a : SHADER_PRESETS[0];
4342
+ }
4343
+ function getShaderFragment(preset) {
4344
+ return `${SHADER_PRELUDE}
4345
+ ${preset.body}`;
4346
+ }
4347
+
4348
+ // src/core/shader-surface.tsx
4349
+
4350
+
4351
+
4352
+
4353
+
4354
+
4355
+
4356
+ var _ogl = require('ogl');
4357
+ var _optpalette = require('@reopt-ai/opt-palette');
4358
+
4359
+ var STATIC_TIME = 8;
4360
+ function toRgbFloat(hex) {
4361
+ try {
4362
+ const [r, g, b] = _optpalette.hexToSrgb.call(void 0, hex);
4363
+ return [r / 255, g / 255, b / 255];
4364
+ } catch (e) {
4365
+ return [0, 0, 0];
4366
+ }
4367
+ }
4368
+ function resolveColors(presetId, colors) {
4369
+ var _a, _b, _c, _d, _e, _f;
4370
+ const preset = getShaderPreset(presetId);
4371
+ const source = colors && colors.length > 0 ? colors : preset.defaultColors;
4372
+ return [
4373
+ (_a = source[0]) != null ? _a : preset.defaultColors[0],
4374
+ (_c = (_b = source[1]) != null ? _b : source[0]) != null ? _c : preset.defaultColors[1],
4375
+ (_f = (_e = (_d = source[2]) != null ? _d : source[1]) != null ? _e : source[0]) != null ? _f : preset.defaultColors[2]
4376
+ ];
4377
+ }
4378
+ function resolveParam(presetId, key, override) {
4379
+ var _a;
4380
+ if (typeof override === "number" && Number.isFinite(override))
4381
+ return override;
4382
+ const spec = getShaderPreset(presetId).params.find((p) => p.key === key);
4383
+ return (_a = spec == null ? void 0 : spec.default) != null ? _a : SHADER_PARAM_FALLBACK[key];
4384
+ }
4385
+ function prefersReducedMotion() {
4386
+ return typeof window !== "undefined" && window.matchMedia ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : false;
4387
+ }
4388
+ var ShaderSurfaceComponent = _react.forwardRef.call(void 0, function ShaderSurface({
4389
+ preset,
4390
+ colors,
4391
+ scale,
4392
+ speed,
4393
+ distortion,
4394
+ grain,
4395
+ contrast,
4396
+ angle,
4397
+ dim,
4398
+ vignette,
4399
+ scrim,
4400
+ interactive,
4401
+ params,
4402
+ time,
4403
+ paused = false,
4404
+ dpr,
4405
+ className,
4406
+ style,
4407
+ "aria-hidden": ariaHidden = true
4408
+ }, ref) {
4409
+ const containerRef = _react.useRef.call(void 0, null);
4410
+ const canvasRef = _react.useRef.call(void 0, null);
4411
+ const stateRef = _react.useRef.call(void 0, {
4412
+ preset,
4413
+ colors,
4414
+ scale,
4415
+ speed,
4416
+ distortion,
4417
+ grain,
4418
+ contrast,
4419
+ angle,
4420
+ dim,
4421
+ vignette,
4422
+ scrim,
4423
+ interactive,
4424
+ params,
4425
+ time,
4426
+ paused
4427
+ });
4428
+ stateRef.current = {
4429
+ preset,
4430
+ colors,
4431
+ scale,
4432
+ speed,
4433
+ distortion,
4434
+ grain,
4435
+ contrast,
4436
+ angle,
4437
+ dim,
4438
+ vignette,
4439
+ scrim,
4440
+ interactive,
4441
+ params,
4442
+ time,
4443
+ paused
4444
+ };
4445
+ const rendererRef = _react.useRef.call(void 0, null);
4446
+ const programRef = _react.useRef.call(void 0, null);
4447
+ const renderAtRef = _react.useRef.call(void 0, null);
4448
+ const loopRef = _react.useRef.call(void 0, null);
4449
+ const mouseRef = _react.useRef.call(void 0, [0.5, 0.5]);
4450
+ const fallbackBackground = _react.useMemo.call(void 0, () => {
4451
+ const [c1, c2, c3] = resolveColors(preset, colors);
4452
+ const deg = resolveParam(preset, "angle", angle);
4453
+ return `linear-gradient(${deg + 120}deg, ${c1}, ${c2}, ${c3})`;
4454
+ }, [preset, colors, angle]);
4455
+ _react.useImperativeHandle.call(void 0,
4456
+ ref,
4457
+ () => ({
4458
+ capture: () => {
4459
+ var _a;
4460
+ const canvas = canvasRef.current;
4461
+ if (!canvas || !renderAtRef.current || !programRef.current) return null;
4462
+ const now = stateRef.current.paused ? (_a = stateRef.current.time) != null ? _a : STATIC_TIME : performance.now() / 1e3;
4463
+ renderAtRef.current(now);
4464
+ try {
4465
+ return canvas.toDataURL("image/png");
4466
+ } catch (e) {
4467
+ return null;
4468
+ }
4469
+ }
4470
+ }),
4471
+ []
4472
+ );
4473
+ _react.useEffect.call(void 0, () => {
4474
+ const container = containerRef.current;
4475
+ const canvas = canvasRef.current;
4476
+ if (!container || !canvas) return;
4477
+ let renderer;
4478
+ try {
4479
+ renderer = new (0, _ogl.Renderer)({
4480
+ canvas,
4481
+ dpr: dpr != null ? dpr : typeof window !== "undefined" ? Math.min(window.devicePixelRatio || 1, 2) : 1,
4482
+ alpha: true,
4483
+ premultipliedAlpha: false
4484
+ });
4485
+ } catch (e) {
4486
+ return;
4487
+ }
4488
+ const gl = renderer.gl;
4489
+ rendererRef.current = { renderer, gl };
4490
+ const resize = () => {
4491
+ const rect = container.getBoundingClientRect();
4492
+ renderer.setSize(Math.max(1, rect.width), Math.max(1, rect.height));
4493
+ };
4494
+ resize();
4495
+ const renderAt = (timeSeconds) => {
4496
+ const current = programRef.current;
4497
+ if (!current) return;
4498
+ const s = stateRef.current;
4499
+ const [c1, c2, c3] = resolveColors(s.preset, s.colors);
4500
+ const u = current.program.uniforms;
4501
+ const val = (key, override) => {
4502
+ var _a;
4503
+ return resolveParam(s.preset, key, override != null ? override : (_a = s.params) == null ? void 0 : _a[key]);
4504
+ };
4505
+ u.u_time.value = timeSeconds;
4506
+ u.u_resolution.value = [gl.canvas.width, gl.canvas.height];
4507
+ u.u_scale.value = val("scale", s.scale);
4508
+ u.u_speed.value = val("speed", s.speed);
4509
+ u.u_distortion.value = val("distortion", s.distortion);
4510
+ u.u_grain.value = val("grain", s.grain);
4511
+ u.u_contrast.value = val("contrast", s.contrast);
4512
+ u.u_angle.value = val("angle", s.angle);
4513
+ u.u_dim.value = val("dim", s.dim);
4514
+ u.u_vignette.value = val("vignette", s.vignette);
4515
+ u.u_scrim.value = val("scrim", s.scrim);
4516
+ u.u_interactive.value = val("interactive", s.interactive);
4517
+ u.u_bars.value = val("bars", void 0);
4518
+ u.u_blur.value = val("blur", void 0);
4519
+ u.u_peak.value = val("peak", void 0);
4520
+ u.u_valley.value = val("valley", void 0);
4521
+ u.u_mouse.value = mouseRef.current;
4522
+ u.u_color1.value = toRgbFloat(c1);
4523
+ u.u_color2.value = toRgbFloat(c2);
4524
+ u.u_color3.value = toRgbFloat(c3);
4525
+ renderer.render({ scene: current.mesh });
4526
+ };
4527
+ renderAtRef.current = renderAt;
4528
+ const staticTime = () => {
4529
+ var _a;
4530
+ return (_a = stateRef.current.time) != null ? _a : STATIC_TIME;
4531
+ };
4532
+ const reduced = prefersReducedMotion();
4533
+ let inView = true;
4534
+ const isAnimating = () => !stateRef.current.paused && !reduced && inView;
4535
+ let raf = 0;
4536
+ let startTime = performance.now();
4537
+ const loop = (nowMs) => {
4538
+ renderAt((nowMs - startTime) / 1e3);
4539
+ raf = requestAnimationFrame(loop);
4540
+ };
4541
+ const start = () => {
4542
+ if (raf) return;
4543
+ startTime = performance.now();
4544
+ raf = requestAnimationFrame(loop);
4545
+ };
4546
+ const stop = () => {
4547
+ if (raf) cancelAnimationFrame(raf);
4548
+ raf = 0;
4549
+ };
4550
+ loopRef.current = { start, stop, isAnimating };
4551
+ const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
4552
+ resize();
4553
+ if (!isAnimating()) renderAt(staticTime());
4554
+ }) : null;
4555
+ resizeObserver == null ? void 0 : resizeObserver.observe(container);
4556
+ const intersectionObserver = typeof IntersectionObserver !== "undefined" ? new IntersectionObserver(
4557
+ (entries) => {
4558
+ var _a, _b;
4559
+ inView = (_b = (_a = entries[0]) == null ? void 0 : _a.isIntersecting) != null ? _b : true;
4560
+ if (inView && isAnimating()) start();
4561
+ else stop();
4562
+ },
4563
+ { threshold: 0 }
4564
+ ) : null;
4565
+ intersectionObserver == null ? void 0 : intersectionObserver.observe(container);
4566
+ const handlePointer = (event) => {
4567
+ const rect = container.getBoundingClientRect();
4568
+ mouseRef.current = [
4569
+ (event.clientX - rect.left) / Math.max(1, rect.width),
4570
+ (event.clientY - rect.top) / Math.max(1, rect.height)
4571
+ ];
4572
+ const s = stateRef.current;
4573
+ if (!isAnimating() && resolveParam(s.preset, "interactive", s.interactive) > 0) {
4574
+ renderAt(staticTime());
4575
+ }
4576
+ };
4577
+ container.addEventListener("pointermove", handlePointer);
4578
+ if (isAnimating()) start();
4579
+ return () => {
4580
+ stop();
4581
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
4582
+ intersectionObserver == null ? void 0 : intersectionObserver.disconnect();
4583
+ container.removeEventListener("pointermove", handlePointer);
4584
+ loopRef.current = null;
4585
+ renderAtRef.current = null;
4586
+ rendererRef.current = null;
4587
+ };
4588
+ }, [dpr]);
4589
+ _react.useEffect.call(void 0, () => {
4590
+ var _a, _b;
4591
+ const engine = rendererRef.current;
4592
+ if (!engine) return;
4593
+ const { gl } = engine;
4594
+ const presetDef = getShaderPreset(preset);
4595
+ const geometry = new (0, _ogl.Triangle)(gl);
4596
+ const program = new (0, _ogl.Program)(gl, {
4597
+ vertex: SHADER_VERTEX,
4598
+ fragment: getShaderFragment(presetDef),
4599
+ uniforms: {
4600
+ u_time: { value: 0 },
4601
+ u_resolution: { value: [1, 1] },
4602
+ u_scale: { value: 1 },
4603
+ u_speed: { value: 1 },
4604
+ u_distortion: { value: 0.5 },
4605
+ u_grain: { value: 0 },
4606
+ u_contrast: { value: 0.5 },
4607
+ u_angle: { value: 0 },
4608
+ u_dim: { value: 0 },
4609
+ u_vignette: { value: 0 },
4610
+ u_scrim: { value: 0 },
4611
+ u_mouse: { value: [0.5, 0.5] },
4612
+ u_interactive: { value: 0 },
4613
+ u_bars: { value: 19 },
4614
+ u_blur: { value: 0.29 },
4615
+ u_peak: { value: 0.98 },
4616
+ u_valley: { value: 0.55 },
4617
+ u_color1: { value: [0, 0, 0] },
4618
+ u_color2: { value: [0, 0, 0] },
4619
+ u_color3: { value: [0, 0, 0] }
4620
+ }
4621
+ });
4622
+ const mesh = new (0, _ogl.Mesh)(gl, { geometry, program });
4623
+ programRef.current = { program, mesh, geometry };
4624
+ const loop = loopRef.current;
4625
+ if (loop == null ? void 0 : loop.isAnimating()) loop.start();
4626
+ else (_b = renderAtRef.current) == null ? void 0 : _b.call(renderAtRef, (_a = stateRef.current.time) != null ? _a : STATIC_TIME);
4627
+ return () => {
4628
+ programRef.current = null;
4629
+ program.remove();
4630
+ geometry.remove();
4631
+ };
4632
+ }, [preset]);
4633
+ _react.useEffect.call(void 0, () => {
4634
+ var _a, _b;
4635
+ const loop = loopRef.current;
4636
+ if (!loop) return;
4637
+ if (loop.isAnimating()) loop.start();
4638
+ else {
4639
+ loop.stop();
4640
+ (_b = renderAtRef.current) == null ? void 0 : _b.call(renderAtRef, (_a = stateRef.current.time) != null ? _a : STATIC_TIME);
4641
+ }
4642
+ }, [
4643
+ paused,
4644
+ colors,
4645
+ scale,
4646
+ speed,
4647
+ distortion,
4648
+ grain,
4649
+ contrast,
4650
+ angle,
4651
+ dim,
4652
+ vignette,
4653
+ scrim,
4654
+ interactive,
4655
+ params,
4656
+ time
4657
+ ]);
4658
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4659
+ "div",
4660
+ {
4661
+ ref: containerRef,
4662
+ "aria-hidden": ariaHidden,
4663
+ className: _chunkAFF2HPE5cjs.cn.call(void 0, "relative overflow-hidden", className),
4664
+ style: _chunkONE3C5RVcjs.__spreadValues.call(void 0, { background: fallbackBackground }, style),
4665
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4666
+ "canvas",
4667
+ {
4668
+ ref: canvasRef,
4669
+ className: "absolute inset-0 block h-full w-full"
4670
+ }
4671
+ )
4672
+ }
4673
+ );
4674
+ });
4675
+ ShaderSurfaceComponent.displayName = "ShaderSurface";
4676
+ var ShaderSurface2 = ShaderSurfaceComponent;
4677
+
4678
+
4679
+
4680
+
4681
+
4682
+
4683
+
4684
+
4685
+
4686
+
4687
+
4688
+
4689
+
4690
+
4691
+
4692
+
4693
+
4694
+
4695
+
4696
+
4697
+
4698
+
4699
+
4700
+
4701
+
4702
+
4703
+
4704
+
4705
+
4706
+
4707
+
4708
+
4709
+
4710
+
4711
+
4712
+
4713
+
4714
+
4715
+
4716
+
4717
+
4718
+
4719
+
4720
+
4721
+
4722
+
4723
+
4724
+
4725
+
4726
+
4727
+
4728
+
4729
+
4730
+
4731
+
4732
+
4733
+
4734
+
4735
+
4736
+
4737
+
4738
+
4739
+
4740
+
4741
+
4742
+
4743
+
4744
+
4745
+ exports.Text = Text; exports.Heading = Heading; exports.Separator = Separator; exports.OtpField = OtpField; exports.Toggle = Toggle; exports.ToggleGroup = ToggleGroup; exports.AccordionRoot = AccordionRoot; exports.AccordionItem = AccordionItem; exports.AccordionTrigger = AccordionTrigger; exports.AccordionContent = AccordionContent; exports.Breadcrumb = Breadcrumb; exports.Card = Card; exports.CardHeader = CardHeader; exports.CardTitle = CardTitle; exports.CardDescription = CardDescription; exports.CardContent = CardContent; exports.CardFooter = CardFooter; exports.Input = Input; exports.Switch = Switch; exports.Skeleton = Skeleton; exports.SkeletonText = SkeletonText; exports.SkeletonAvatar = SkeletonAvatar; exports.SkeletonCard = SkeletonCard; exports.SkeletonTable = SkeletonTable; exports.Textarea = Textarea; exports.Avatar = Avatar; exports.AvatarGroup = AvatarGroup; exports.Progress = Progress; exports.CircularProgress = CircularProgress; exports.Meter = Meter; exports.StepBuilder = StepBuilder; exports.formatOptShortDate = formatOptShortDate; exports.formatOptTime = formatOptTime; exports.formatOptDateTime = formatOptDateTime; exports.formatOptNumber = formatOptNumber; exports.ConditionBuilder = ConditionBuilder; exports.DropdownMenu = DropdownMenu; exports.DropdownTrigger = DropdownTrigger; exports.DropdownContent = DropdownContent; exports.DropdownItem = DropdownItem; exports.DropdownSeparator = DropdownSeparator; exports.RadioGroup = RadioGroup; exports.Radio = Radio; exports.LoadingOverlay = LoadingOverlay; exports.BlockLayout = BlockLayout; exports.createBlock = createBlock; exports.PageHeader = PageHeader; exports.ScrollArea = ScrollArea; exports.Container = Container; exports.Section = Section; exports.ResizablePanelGroup = ResizablePanelGroup; exports.ResizablePanel = ResizablePanel; exports.ResizableHandle = ResizableHandle; exports.Logo = Logo; exports.DrawerRoot = DrawerRoot; exports.DrawerPanel = DrawerPanel; exports.DrawerClose = DrawerClose; exports.VirtualList = VirtualList; exports.SHADER_PARAM_FALLBACK = SHADER_PARAM_FALLBACK; exports.SHADER_PRESETS = SHADER_PRESETS; exports.SHADER_PRESET_IDS = SHADER_PRESET_IDS; exports.SHADER_PARAM_KEYS = SHADER_PARAM_KEYS; exports.SHADER_OVERLAY_PARAM_KEYS = SHADER_OVERLAY_PARAM_KEYS; exports.getShaderPreset = getShaderPreset; exports.getShaderFragment = getShaderFragment; exports.ShaderSurface = ShaderSurface2;