@reopt-ai/opt-ui 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/COMPONENT_CATALOG.md +178 -50
  2. package/README.md +28 -7
  3. package/dist/app.css +170 -0
  4. package/dist/core/index.cjs +164 -324
  5. package/dist/core/index.d.cts +3 -6
  6. package/dist/core/index.d.ts +3 -6
  7. package/dist/core/index.js +3 -323
  8. package/dist/docs/01-getting-started.md +25 -5
  9. package/dist/docs/02-components/01-core.md +36 -28
  10. package/dist/docs/02-components/02-visuals.md +1 -1
  11. package/dist/docs/02-components/03-shells.md +144 -23
  12. package/dist/docs/02-components/04-surfaces.md +1 -1
  13. package/dist/docs/02-components/index.md +4 -4
  14. package/dist/docs/03-recipes/03-layouts.md +16 -12
  15. package/dist/docs/05-migration/01-breaking-changes.md +46 -1
  16. package/dist/field-sidebar-BTZCBviA.d.cts +1031 -0
  17. package/dist/field-sidebar-BTZCBviA.d.cts.map +1 -0
  18. package/dist/field-sidebar-CB8vjvUM.d.ts +1031 -0
  19. package/dist/field-sidebar-CB8vjvUM.d.ts.map +1 -0
  20. package/dist/field-sidebar-Cs-J-5VE.js +4233 -0
  21. package/dist/field-sidebar-Cs-J-5VE.js.map +1 -0
  22. package/dist/field-sidebar-CzIQX70-.cjs +4561 -0
  23. package/dist/id-registry.cjs +1939 -1872
  24. package/dist/id-registry.d.cts +14 -11
  25. package/dist/id-registry.d.cts.map +1 -0
  26. package/dist/id-registry.d.ts +14 -11
  27. package/dist/id-registry.d.ts.map +1 -0
  28. package/dist/id-registry.js +1937 -1871
  29. package/dist/id-registry.js.map +1 -0
  30. package/dist/id-registry.json +113 -28
  31. package/dist/index.cjs +8380 -9790
  32. package/dist/index.d.cts +1555 -1442
  33. package/dist/index.d.cts.map +1 -0
  34. package/dist/index.d.ts +1555 -1442
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +7996 -9778
  37. package/dist/index.js.map +1 -0
  38. package/dist/meta.cjs +7753 -6875
  39. package/dist/meta.d.cts.map +1 -0
  40. package/dist/meta.d.ts.map +1 -0
  41. package/dist/meta.js +7752 -6846
  42. package/dist/meta.js.map +1 -0
  43. package/dist/pagination-DWbvACuN.js +3850 -0
  44. package/dist/pagination-DWbvACuN.js.map +1 -0
  45. package/dist/pagination-DjfxBcjX.cjs +4739 -0
  46. package/dist/query.cjs +386 -0
  47. package/dist/query.d.cts +141 -0
  48. package/dist/query.d.cts.map +1 -0
  49. package/dist/query.d.ts +141 -0
  50. package/dist/query.d.ts.map +1 -0
  51. package/dist/query.js +371 -0
  52. package/dist/query.js.map +1 -0
  53. package/dist/shader-surface-BUPZ0P-n.js +3654 -0
  54. package/dist/shader-surface-BUPZ0P-n.js.map +1 -0
  55. package/dist/shader-surface-BfTP9c1Q.d.ts +1788 -0
  56. package/dist/shader-surface-BfTP9c1Q.d.ts.map +1 -0
  57. package/dist/shader-surface-DRrcLrWf.d.cts +1788 -0
  58. package/dist/shader-surface-DRrcLrWf.d.cts.map +1 -0
  59. package/dist/shader-surface-Fav5K9UC.cjs +4041 -0
  60. package/dist/shells/index.cjs +58 -65
  61. package/dist/shells/index.d.cts +4 -5
  62. package/dist/shells/index.d.ts +4 -5
  63. package/dist/shells/index.js +4 -64
  64. package/dist/tailwind.css +49 -0
  65. package/dist/theme/presets/default.css +2 -2
  66. package/dist/theme/presets/minimal.css +2 -2
  67. package/dist/theme/presets/mono-dark.css +2 -2
  68. package/dist/theme/presets/natural.css +1 -1
  69. package/dist/theme/presets/pro.css +2 -2
  70. package/dist/theme/server.cjs +257 -228
  71. package/dist/theme/server.d.cts +48 -60
  72. package/dist/theme/server.d.cts.map +1 -0
  73. package/dist/theme/server.d.ts +48 -60
  74. package/dist/theme/server.d.ts.map +1 -0
  75. package/dist/theme/server.js +234 -189
  76. package/dist/theme/server.js.map +1 -0
  77. package/dist/types-D0FlcYnM.d.cts +301 -0
  78. package/dist/types-D0FlcYnM.d.cts.map +1 -0
  79. package/dist/types-D0FlcYnM.d.ts +301 -0
  80. package/dist/types-D0FlcYnM.d.ts.map +1 -0
  81. package/dist/visuals/index.cjs +10 -4
  82. package/dist/visuals/index.d.cts +2 -1
  83. package/dist/visuals/index.d.ts +2 -1
  84. package/dist/visuals/index.js +1 -2
  85. package/package.json +27 -11
  86. package/dist/chunk-3GWWZKX7.js +0 -38
  87. package/dist/chunk-3QFYBBL6.cjs +0 -4759
  88. package/dist/chunk-3XD4HIFL.js +0 -3241
  89. package/dist/chunk-AFF2HPE5.cjs +0 -5008
  90. package/dist/chunk-NXZJIHEZ.cjs +0 -3241
  91. package/dist/chunk-ONE3C5RV.cjs +0 -38
  92. package/dist/chunk-RBM2RNC2.js +0 -5008
  93. package/dist/chunk-VBGPEW45.js +0 -4759
  94. package/dist/index-BZ_lBlO1.d.ts +0 -474
  95. package/dist/index-BuvxoWHf.d.cts +0 -474
  96. package/dist/index-DWyqDIkH.d.cts +0 -1689
  97. package/dist/index-Uyijm14M.d.ts +0 -1689
  98. package/dist/types-D4-0lwaE.d.cts +0 -298
  99. package/dist/types-D4-0lwaE.d.ts +0 -298
@@ -1,3241 +0,0 @@
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; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }"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
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
- var _chunkAFF2HPE5cjs = require('./chunk-AFF2HPE5.cjs');
97
-
98
-
99
-
100
-
101
- var _chunkONE3C5RVcjs = require('./chunk-ONE3C5RV.cjs');
102
-
103
- // src/core/command.tsx
104
- var _lucidereact = require('lucide-react');
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
- var _optuiprimitives = require('@reopt-ai/opt-ui-primitives');
114
- var _jsxruntime = require('react/jsx-runtime');
115
- function Command(_a) {
116
- var _b = _a, { className } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, ["className"]);
117
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
118
- _optuiprimitives.CommandRoot,
119
- _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
120
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
121
- "bg-surface text-text-primary flex w-full flex-col overflow-hidden rounded-xl",
122
- className
123
- )
124
- }, props), {
125
- "data-opt-id": "4FYBW",
126
- "data-opt-slug": "command.Command"
127
- })
128
- );
129
- }
130
- function CommandDialog({
131
- open,
132
- onOpenChange,
133
- title = "Command Palette",
134
- description = "\uAC80\uC0C9 \uD6C4 Enter \uB610\uB294 \uD074\uB9AD\uC73C\uB85C \uBA85\uB839\uC744 \uC2E4\uD589\uD558\uC138\uC694.",
135
- className,
136
- commandClassName,
137
- shouldFilter,
138
- filter,
139
- children
140
- }) {
141
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
142
- _chunkAFF2HPE5cjs.DialogRoot,
143
- {
144
- open,
145
- onOpenChange,
146
- "data-opt-id": "DVRSX",
147
- "data-opt-slug": "command.CommandDialog",
148
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
149
- _chunkAFF2HPE5cjs.DialogPanel,
150
- {
151
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
152
- "top-[20%] left-1/2 -translate-x-1/2",
153
- "w-full max-w-lg overflow-hidden p-0 shadow-2xl",
154
- className
155
- ),
156
- children: [
157
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.DialogHeading, { className: "sr-only", children: title }),
158
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.DialogDescription, { className: "sr-only", children: description }),
159
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
160
- Command,
161
- {
162
- shouldFilter,
163
- filter,
164
- className: commandClassName,
165
- children
166
- }
167
- )
168
- ]
169
- }
170
- )
171
- }
172
- );
173
- }
174
- function CommandInput(_a) {
175
- var _b = _a, {
176
- className,
177
- trailing,
178
- wrapperClassName,
179
- placeholder,
180
- "aria-label": ariaLabel
181
- } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
182
- "className",
183
- "trailing",
184
- "wrapperClassName",
185
- "placeholder",
186
- "aria-label"
187
- ]);
188
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
189
- "div",
190
- {
191
- "data-slot": "command-input-wrapper",
192
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
193
- "border-border-subtle gap-element flex h-12 items-center border-b px-3",
194
- wrapperClassName
195
- ),
196
- "data-opt-id": "HB1K3",
197
- "data-opt-slug": "command.CommandInput",
198
- children: [
199
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.SearchIcon, { "aria-hidden": true, className: "text-text-tertiary size-4 shrink-0" }),
200
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
201
- _optuiprimitives.CommandInput,
202
- _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
203
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
204
- // cmdk 컨벤션 — input 자체는 ring 없이 자연스러운 검색 경험.
205
- // 포커스 표시는 wrapper(border-b)가 시각적 컨텍스트로 제공.
206
- "text-text-primary placeholder:text-text-tertiary flex h-full w-full bg-transparent text-sm outline-none focus-visible:ring-0 focus-visible:outline-none",
207
- "disabled:cursor-not-allowed disabled:opacity-50",
208
- className
209
- ),
210
- placeholder,
211
- "aria-label": ariaLabel != null ? ariaLabel : typeof placeholder === "string" ? placeholder : "Command search"
212
- }, props)
213
- ),
214
- trailing
215
- ]
216
- }
217
- );
218
- }
219
- function CommandList(_a) {
220
- var _b = _a, {
221
- className,
222
- "aria-label": ariaLabel
223
- } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
224
- "className",
225
- "aria-label"
226
- ]);
227
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
228
- _optuiprimitives.CommandList,
229
- _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
230
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
231
- "max-h-80 scroll-py-1 overflow-x-hidden overflow-y-auto p-1",
232
- className
233
- ),
234
- "aria-label": ariaLabel != null ? ariaLabel : "Commands"
235
- }, props), {
236
- "data-opt-id": "NPXC5",
237
- "data-opt-slug": "command.CommandList"
238
- })
239
- );
240
- }
241
- function CommandEmpty(_a) {
242
- var _b = _a, { className } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, ["className"]);
243
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
244
- _optuiprimitives.CommandEmpty,
245
- _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
246
- className: _chunkAFF2HPE5cjs.cn.call(void 0, "text-text-tertiary py-6 text-center text-sm", className)
247
- }, props), {
248
- "data-opt-id": "A8BZM",
249
- "data-opt-slug": "command.CommandEmpty"
250
- })
251
- );
252
- }
253
- function CommandGroup(_a) {
254
- var _b = _a, {
255
- className,
256
- heading
257
- } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
258
- "className",
259
- "heading"
260
- ]);
261
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
262
- _optuiprimitives.CommandGroup,
263
- _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
264
- heading: heading != null ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-text-tertiary px-2 py-1.5 text-xs font-medium", children: heading }) : void 0,
265
- className: _chunkAFF2HPE5cjs.cn.call(void 0, "py-1", className)
266
- }, props), {
267
- "data-opt-id": "JPK1Y",
268
- "data-opt-slug": "command.CommandGroup"
269
- })
270
- );
271
- }
272
- function CommandSeparator(_a) {
273
- var _b = _a, {
274
- className
275
- } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
276
- "className"
277
- ]);
278
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
279
- _optuiprimitives.CommandSeparator,
280
- _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
281
- className: _chunkAFF2HPE5cjs.cn.call(void 0, "bg-border-subtle -mx-1 my-1 h-px", className)
282
- }, props), {
283
- "data-opt-id": "10P0E",
284
- "data-opt-slug": "command.CommandSeparator"
285
- })
286
- );
287
- }
288
- function CommandItem(_a) {
289
- var _b = _a, { className } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, ["className"]);
290
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
291
- _optuiprimitives.CommandItem,
292
- _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
293
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
294
- "text-text-primary flex cursor-pointer items-center gap-2 rounded-md px-2 py-2 text-sm select-none",
295
- "data-[active-item]:bg-accent data-[active-item]:text-accent-fg",
296
- "data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50",
297
- "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
298
- className
299
- )
300
- }, props), {
301
- "data-opt-id": "K674W",
302
- "data-opt-slug": "command.CommandItem"
303
- })
304
- );
305
- }
306
- function CommandShortcut(_a) {
307
- var _b = _a, {
308
- className
309
- } = _b, props = _chunkONE3C5RVcjs.__objRest.call(void 0, _b, [
310
- "className"
311
- ]);
312
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
313
- "span",
314
- _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
315
- "data-slot": "command-shortcut",
316
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
317
- "text-text-tertiary ml-auto text-xs tracking-widest",
318
- "data-[active-item]:text-accent-fg/80",
319
- className
320
- )
321
- }, props), {
322
- "data-opt-id": "75CQK",
323
- "data-opt-slug": "command.CommandShortcut"
324
- })
325
- );
326
- }
327
-
328
- // src/shells/command-palette.tsx
329
- var _react = require('react'); var React = _interopRequireWildcard(_react);
330
-
331
- var DEFAULT_LABELS = {
332
- title: "Command Palette",
333
- description: "\uAC80\uC0C9 \uD6C4 Enter \uB610\uB294 \uD074\uB9AD\uC73C\uB85C \uBA85\uB839\uC744 \uC2E4\uD589\uD558\uC138\uC694.",
334
- input: "\uBA85\uB839\uC5B4 \uAC80\uC0C9",
335
- placeholder: "\uBA85\uB839\uC5B4\uB97C \uAC80\uC0C9\uD558\uC138\uC694...",
336
- list: "\uBA85\uB839\uC5B4 \uBAA9\uB85D",
337
- empty: "\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
338
- escape: "ESC"
339
- };
340
- function CommandPalette({
341
- commands,
342
- open,
343
- onOpenChange,
344
- onSelect,
345
- inline = false,
346
- labels,
347
- footer,
348
- empty,
349
- inputTrailing,
350
- className
351
- }) {
352
- const resolvedLabels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, DEFAULT_LABELS), labels);
353
- const hasCommands = commands.length > 0;
354
- const grouped = _react.useMemo.call(void 0, () => {
355
- var _a;
356
- const map = /* @__PURE__ */ new Map();
357
- for (const cmd of commands) {
358
- const list = (_a = map.get(cmd.group)) != null ? _a : [];
359
- list.push(cmd);
360
- map.set(cmd.group, list);
361
- }
362
- return map;
363
- }, [commands]);
364
- const handleSelect = (cmdId) => {
365
- const cmd = commands.find((c) => c.id === cmdId);
366
- if (!cmd) return;
367
- onSelect == null ? void 0 : onSelect(cmd);
368
- onOpenChange(false);
369
- };
370
- const handleInputKeyDown = (e) => {
371
- if (e.key === "Escape" && !inline) {
372
- e.preventDefault();
373
- onOpenChange(false);
374
- }
375
- };
376
- const body = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
377
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
378
- CommandInput,
379
- {
380
- "aria-label": resolvedLabels.input,
381
- placeholder: resolvedLabels.placeholder,
382
- onKeyDown: handleInputKeyDown,
383
- trailing: inputTrailing != null ? inputTrailing : !inline ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.Kbd, { children: resolvedLabels.escape }) : void 0
384
- }
385
- ),
386
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, CommandList, { "aria-label": resolvedLabels.list, children: [
387
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CommandEmpty, { children: empty != null ? empty : resolvedLabels.empty }),
388
- hasCommands ? Array.from(grouped.entries()).map(([group, items]) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CommandGroup, { heading: group, children: items.map((cmd) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
389
- CommandItem,
390
- {
391
- value: cmd.id,
392
- keywords: [
393
- cmd.label,
394
- cmd.group,
395
- ...cmd.shortcut ? [cmd.shortcut] : []
396
- ],
397
- onSelect: handleSelect,
398
- children: [
399
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: cmd.label }),
400
- cmd.shortcut && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CommandShortcut, { children: cmd.shortcut })
401
- ]
402
- },
403
- cmd.id
404
- )) }, group)) : null
405
- ] }),
406
- footer
407
- ] });
408
- if (inline) {
409
- if (!open) return null;
410
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
411
- Command,
412
- {
413
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
414
- "border-border bg-surface w-full max-w-lg border shadow-lg",
415
- className
416
- ),
417
- "data-opt-id": "ATTF5",
418
- "data-opt-slug": "command-palette.CommandPalette",
419
- children: body
420
- }
421
- );
422
- }
423
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
424
- CommandDialog,
425
- {
426
- open,
427
- onOpenChange,
428
- title: resolvedLabels.title,
429
- description: resolvedLabels.description,
430
- className,
431
- "data-opt-id": "ATTF5",
432
- "data-opt-slug": "command-palette.CommandPalette",
433
- children: body
434
- }
435
- );
436
- }
437
-
438
- // src/shells/command-palette-trigger.tsx
439
-
440
-
441
- function CommandPaletteTrigger({
442
- commands,
443
- onSelect,
444
- labels
445
- }) {
446
- if (commands.length === 0) return null;
447
- const [open, setOpen] = _react.useState.call(void 0, false);
448
- const handleKeyDown = _react.useCallback.call(void 0, (e) => {
449
- if ((e.metaKey || e.ctrlKey) && e.key === "k") {
450
- e.preventDefault();
451
- setOpen(true);
452
- }
453
- }, []);
454
- _react.useEffect.call(void 0, () => {
455
- document.addEventListener("keydown", handleKeyDown);
456
- return () => document.removeEventListener("keydown", handleKeyDown);
457
- }, [handleKeyDown]);
458
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
459
- CommandPalette,
460
- {
461
- commands,
462
- open,
463
- onOpenChange: setOpen,
464
- onSelect,
465
- labels,
466
- "data-opt-id": "4FCDB",
467
- "data-opt-slug": "command-palette-trigger.CommandPaletteTrigger"
468
- }
469
- );
470
- }
471
-
472
- // src/shells/dashboard-grid.tsx
473
-
474
- var defaultLabels = {
475
- ariaLabel: "\uB300\uC2DC\uBCF4\uB4DC \uD1B5\uACC4"
476
- };
477
- var MIN_DASHBOARD_COLUMNS = 1;
478
- var MAX_DASHBOARD_COLUMNS = 12;
479
- function normalizeDashboardColumns(columns) {
480
- if (!Number.isFinite(columns)) return MIN_DASHBOARD_COLUMNS;
481
- return Math.min(
482
- MAX_DASHBOARD_COLUMNS,
483
- Math.max(MIN_DASHBOARD_COLUMNS, Math.floor(columns))
484
- );
485
- }
486
- function DashboardGrid({
487
- stats,
488
- columns = 3,
489
- labels: customLabels
490
- }) {
491
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels), customLabels);
492
- const columnCount = normalizeDashboardColumns(columns);
493
- const rowStyle = {
494
- "--opt-dashboard-grid-columns": `repeat(${columnCount}, minmax(0, 1fr))`
495
- };
496
- const rows = [];
497
- for (let i = 0; i < stats.length; i += columnCount) {
498
- rows.push(stats.slice(i, i + columnCount));
499
- }
500
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
501
- _chunkAFF2HPE5cjs.CompositeProvider,
502
- {
503
- focusLoop: true,
504
- focusWrap: true,
505
- "data-opt-id": "BM7NA",
506
- "data-opt-slug": "dashboard-grid.DashboardGrid",
507
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
508
- _chunkAFF2HPE5cjs.Composite,
509
- {
510
- role: "grid",
511
- "aria-label": labels.ariaLabel,
512
- className: "gap-group flex flex-col",
513
- children: rows.map((row, ri) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
514
- _chunkAFF2HPE5cjs.CompositeRow,
515
- {
516
- className: "gap-group grid grid-cols-1 sm:[grid-template-columns:var(--opt-dashboard-grid-columns)]",
517
- style: rowStyle,
518
- children: row.map((stat) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
519
- _chunkAFF2HPE5cjs.CompositeItem,
520
- {
521
- className: "data-[active-item]:ring-ring data-[active-item]:ring-offset-ring-offset data-[focus-visible]:ring-ring data-[focus-visible]:ring-offset-ring-offset rounded-xl outline-none data-[active-item]:ring-2 data-[active-item]:ring-offset-2 data-[focus-visible]:ring-2 data-[focus-visible]:ring-offset-2",
522
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { role: "gridcell" }),
523
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.StatCard, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, stat))
524
- },
525
- stat.id
526
- ))
527
- },
528
- ri
529
- ))
530
- }
531
- )
532
- }
533
- );
534
- }
535
-
536
- // src/shells/search-combobox.tsx
537
- var _matchsorter = require('match-sorter');
538
-
539
-
540
- var defaultLabels2 = {
541
- noResults: "\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
542
- loading: "Loading\u2026"
543
- };
544
- function SearchCombobox({
545
- items,
546
- placeholder = "\uAC80\uC0C9...",
547
- label = "\uAC80\uC0C9",
548
- onSelect,
549
- labels: customLabels,
550
- async: isAsync = false,
551
- onSearch,
552
- debounceMs = 300
553
- }) {
554
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels2), customLabels);
555
- const inputId = _react.useId.call(void 0, );
556
- const [query, setQuery] = _react.useState.call(void 0, "");
557
- const [asyncResults, setAsyncResults] = _react.useState.call(void 0, []);
558
- const [loading, setLoading] = _react.useState.call(void 0, false);
559
- const timerRef = _react.useRef.call(void 0, void 0);
560
- const searchGenerationRef = _react.useRef.call(void 0, 0);
561
- const syncMatches = _react.useMemo.call(void 0, () => {
562
- if (isAsync) return [];
563
- if (!query) return items;
564
- return _matchsorter.matchSorter.call(void 0, items, query);
565
- }, [query, items, isAsync]);
566
- const handleInput = (event) => {
567
- searchGenerationRef.current += 1;
568
- setQuery(event.currentTarget.value);
569
- };
570
- const handleValueChange = (item) => {
571
- searchGenerationRef.current += 1;
572
- setQuery(item);
573
- onSelect == null ? void 0 : onSelect(item);
574
- };
575
- _react.useEffect.call(void 0, () => {
576
- const generation = ++searchGenerationRef.current;
577
- if (timerRef.current) clearTimeout(timerRef.current);
578
- if (!isAsync || !onSearch) {
579
- setLoading(false);
580
- return;
581
- }
582
- if (!query) {
583
- setAsyncResults([]);
584
- setLoading(false);
585
- return;
586
- }
587
- setLoading(true);
588
- timerRef.current = setTimeout(async () => {
589
- try {
590
- const results = await onSearch(query);
591
- if (searchGenerationRef.current !== generation) {
592
- return;
593
- }
594
- setAsyncResults(results);
595
- } finally {
596
- if (searchGenerationRef.current === generation) {
597
- setLoading(false);
598
- }
599
- }
600
- }, debounceMs);
601
- return () => {
602
- if (timerRef.current) clearTimeout(timerRef.current);
603
- };
604
- }, [query, isAsync, onSearch, debounceMs]);
605
- const matches = isAsync ? asyncResults : syncMatches;
606
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
607
- "div",
608
- {
609
- className: "gap-element flex flex-col",
610
- "data-opt-id": "KH4TQ",
611
- "data-opt-slug": "search-combobox.SearchCombobox",
612
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.ComboboxRoot, { onValueChange: handleValueChange, children: [
613
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { htmlFor: inputId, className: _chunkAFF2HPE5cjs.OPT_TEXT_LABEL, children: label }),
614
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
615
- _chunkAFF2HPE5cjs.ComboboxInput,
616
- {
617
- id: inputId,
618
- placeholder,
619
- className: "max-w-xs",
620
- "aria-busy": loading || void 0,
621
- onInput: handleInput
622
- }
623
- ),
624
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.ComboboxPopover, { className: "max-w-xs", children: isAsync && loading ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
625
- "div",
626
- {
627
- className: "text-text-secondary gap-element flex items-center px-3 py-2 text-sm",
628
- role: "status",
629
- "aria-live": "polite",
630
- "aria-busy": "true",
631
- children: [
632
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.Spinner, { size: "sm", "aria-hidden": "true" }),
633
- labels.loading
634
- ]
635
- }
636
- ) : matches.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.ComboboxEmpty, { children: labels.noResults }) : matches.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.ComboboxItem, { value: item, children: item }, item)) })
637
- ] })
638
- }
639
- );
640
- }
641
-
642
- // src/shells/status-select.tsx
643
-
644
-
645
- var defaultLabels3 = {
646
- selectLabel: "\uC0C1\uD0DC",
647
- emptyMessage: "\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uC0C1\uD0DC \uC635\uC158\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."
648
- };
649
- function StatusSelect({
650
- options,
651
- value: controlledValue,
652
- onChange,
653
- label,
654
- labels: customLabels
655
- }) {
656
- var _a, _b;
657
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels3), customLabels);
658
- const resolvedLabel = label != null ? label : labels.selectLabel;
659
- const [internalValue, setInternalValue] = _react.useState.call(void 0, (_b = (_a = options[0]) == null ? void 0 : _a.value) != null ? _b : "");
660
- const value = controlledValue != null ? controlledValue : internalValue;
661
- const selected = options.find((s) => s.value === value);
662
- if (options.length === 0) {
663
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
664
- "div",
665
- {
666
- className: "gap-element flex flex-col",
667
- "data-opt-id": "R46E6",
668
- "data-opt-slug": "status-select.StatusSelect",
669
- children: [
670
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkAFF2HPE5cjs.OPT_TEXT_LABEL, children: resolvedLabel }),
671
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-tertiary text-sm", children: labels.emptyMessage })
672
- ]
673
- }
674
- );
675
- }
676
- const handleChange = (v) => {
677
- var _a2;
678
- const next = Array.isArray(v) ? (_a2 = v[0]) != null ? _a2 : "" : v;
679
- if (onChange) onChange(next);
680
- else setInternalValue(next);
681
- };
682
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
683
- "div",
684
- {
685
- className: "gap-element flex flex-col",
686
- "data-opt-id": "R46E6",
687
- "data-opt-slug": "status-select.StatusSelect",
688
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.SelectRoot, { value, onValueChange: handleChange, children: [
689
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.SelectLabel, { className: _chunkAFF2HPE5cjs.OPT_TEXT_LABEL, children: resolvedLabel }),
690
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
691
- _chunkAFF2HPE5cjs.SelectTrigger,
692
- {
693
- className: `${_chunkAFF2HPE5cjs.OPT_INPUT} max-w-xs items-center justify-between ${_chunkAFF2HPE5cjs.OPT_FOCUS}`,
694
- children: [
695
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "gap-element flex items-center", children: [
696
- (selected == null ? void 0 : selected.color) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `h-2 w-2 rounded-full ${selected.color}` }),
697
- selected == null ? void 0 : selected.label
698
- ] }),
699
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
700
- "svg",
701
- {
702
- className: "text-text-tertiary h-4 w-4",
703
- fill: "none",
704
- viewBox: "0 0 24 24",
705
- stroke: "currentColor",
706
- strokeWidth: 2,
707
- "aria-hidden": "true",
708
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
709
- "path",
710
- {
711
- strokeLinecap: "round",
712
- strokeLinejoin: "round",
713
- d: "m19.5 8.25-7.5 7.5-7.5-7.5"
714
- }
715
- )
716
- }
717
- )
718
- ]
719
- }
720
- ),
721
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
722
- _chunkAFF2HPE5cjs.SelectPopover,
723
- {
724
- className: `${_chunkAFF2HPE5cjs.OPT_SURFACE_POPOVER} ${_chunkAFF2HPE5cjs.OPT_ANIMATE_ENTER_EXIT} max-w-xs`,
725
- children: options.map((option) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.SelectItem, { value: option.value, children: [
726
- option.color && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `h-2 w-2 rounded-full ${option.color}` }),
727
- option.label
728
- ] }, option.value))
729
- }
730
- )
731
- ] })
732
- }
733
- );
734
- }
735
-
736
- // src/shells/app-menubar.tsx
737
-
738
- var defaultLabels4 = {
739
- ariaLabel: "Application menu"
740
- };
741
- function MenuSection({ menu }) {
742
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.MenuRoot, { children: [
743
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.MenuTrigger, { children: [
744
- menu.label,
745
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.MenuButtonArrow, {})
746
- ] }),
747
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.MenuPopover, { children: menu.items.map((item, i) => {
748
- var _a, _b, _c, _d;
749
- if (item.type === "separator") {
750
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.MenuSeparator, {}, `sep-${i}`);
751
- }
752
- if (item.type === "checkbox") {
753
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
754
- _chunkAFF2HPE5cjs.MenuItemCheckbox,
755
- {
756
- name: (_a = item.name) != null ? _a : item.id,
757
- value: (_b = item.value) != null ? _b : item.id,
758
- checked: item.checked,
759
- onChange: item.onChange,
760
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "gap-element flex items-center", children: [
761
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "w-4 text-center", children: item.checked ? "\u2713" : "" }),
762
- item.label
763
- ] })
764
- },
765
- item.id
766
- );
767
- }
768
- if (item.type === "radio") {
769
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
770
- _chunkAFF2HPE5cjs.MenuItemRadio,
771
- {
772
- name: (_c = item.name) != null ? _c : "",
773
- value: (_d = item.value) != null ? _d : "",
774
- checked: item.checked,
775
- onChange: item.onChange,
776
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "gap-element flex items-center", children: [
777
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "w-4 text-center", children: item.checked ? "\u25CF" : "" }),
778
- item.label
779
- ] })
780
- },
781
- item.id
782
- );
783
- }
784
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.MenuItem, { onClick: item.onClick, children: [
785
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: item.label }),
786
- item.shortcut && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.Kbd, { children: item.shortcut })
787
- ] }, item.id);
788
- }) })
789
- ] });
790
- }
791
- function AppMenubar({ menus, labels: customLabels }) {
792
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels4), customLabels);
793
- if (menus.length === 0) return null;
794
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.MenubarRoot, { "data-opt-id": "BGKHW", "data-opt-slug": "app-menubar.AppMenubar", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.MenubarContainer, { "aria-label": labels.ariaLabel, children: menus.map((menu) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MenuSection, { menu }, menu.id)) }) });
795
- }
796
- AppMenubar.displayName = "AppMenubar";
797
-
798
- // src/shells/sidebar-nav.tsx
799
- var _link = require('next/link'); var _link2 = _interopRequireDefault(_link);
800
- var _navigation = require('next/navigation');
801
-
802
-
803
- var NAV_ID_PREFIX = "sidebar-nav-";
804
- function domId(id) {
805
- return `${NAV_ID_PREFIX}${id}`;
806
- }
807
- var sectionStyles = {
808
- // 한글 키
809
- \uC2DC\uC791\uD558\uAE30: "text-accent",
810
- "\uD575\uC2EC \uAC1C\uB150": "text-info-fg",
811
- "\uAD6C\uCD95\xB7\uC6B4\uC601": "text-success-fg",
812
- \uB3C4\uAD6C: "text-warning-fg",
813
- DataGrid: "text-accent",
814
- "\uCEF4\uD3EC\uB10C\uD2B8 \xB7 Core": "text-accent",
815
- "\uCEF4\uD3EC\uB10C\uD2B8 \xB7 Visuals": "text-success-fg",
816
- "\uCEF4\uD3EC\uB10C\uD2B8 \xB7 Shells": "text-warning-fg",
817
- "\uCEF4\uD3EC\uB10C\uD2B8 \xB7 Surfaces": "text-info-fg",
818
- "\uAE30\uBCF8 \uCEF4\uD3EC\uB10C\uD2B8": "text-accent",
819
- "\uBE14\uB85D \uCEF4\uD3EC\uB10C\uD2B8": "text-info-fg",
820
- "\uC870\uD569 \uCEF4\uD3EC\uB10C\uD2B8": "text-warning-fg",
821
- \uD15C\uD50C\uB9BF: "text-text-tertiary",
822
- \uB9B4\uB9AC\uC988: "text-text-tertiary",
823
- // 영문 키 (하위 호환)
824
- Primitives: "text-accent",
825
- Blocks: "text-info-fg",
826
- Compositions: "text-warning-fg",
827
- Templates: "text-text-tertiary"
828
- };
829
- var defaultSectionStyle = "text-text-secondary";
830
- var defaultLabels5 = {
831
- ariaLabel: "\uBB38\uC11C \uB124\uBE44\uAC8C\uC774\uC158"
832
- };
833
- function SidebarNav({ items, labels: customLabels }) {
834
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels5), customLabels);
835
- if (items.length === 0) {
836
- return null;
837
- }
838
- const pathname = _navigation.usePathname.call(void 0, );
839
- const activeItem = items.find((item) => item.href === pathname);
840
- const [activeId, setActiveId] = _react.useState.call(void 0,
841
- activeItem ? domId(activeItem.id) : void 0
842
- );
843
- _react.useEffect.call(void 0, () => {
844
- const match = items.find((item) => item.href === pathname);
845
- if (match) {
846
- setActiveId(domId(match.id));
847
- }
848
- }, [pathname, items]);
849
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
850
- _chunkAFF2HPE5cjs.CompositeProvider,
851
- {
852
- focusLoop: true,
853
- orientation: "vertical",
854
- activeId,
855
- onActiveIdChange: setActiveId,
856
- "data-opt-id": "1FZNH",
857
- "data-opt-slug": "sidebar-nav.SidebarNav",
858
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
859
- _chunkAFF2HPE5cjs.Composite,
860
- {
861
- role: "navigation",
862
- "aria-label": labels.ariaLabel,
863
- className: "flex flex-col",
864
- children: items.map((item, index) => {
865
- var _a, _b;
866
- const isSelected = pathname === item.href;
867
- const isFirstItem = index === 0;
868
- const sectionTextStyle = item.sectionLabel ? (_a = sectionStyles[item.sectionLabel]) != null ? _a : defaultSectionStyle : defaultSectionStyle;
869
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
870
- item.separator && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkAFF2HPE5cjs.cn.call(void 0, "mb-2 pt-2", !isFirstItem && "mt-7"), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
871
- "span",
872
- {
873
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
874
- "px-2 text-[11px] font-semibold tracking-wider uppercase",
875
- sectionTextStyle
876
- ),
877
- children: (_b = item.sectionLabel) != null ? _b : ""
878
- }
879
- ) }),
880
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
881
- _chunkAFF2HPE5cjs.CompositeItem,
882
- {
883
- id: domId(item.id),
884
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
885
- _link2.default,
886
- {
887
- href: item.href,
888
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
889
- // Base styles
890
- "group relative block rounded-md px-2 py-1.5 text-[13px] leading-snug outline-none",
891
- "transition-all duration-150",
892
- // Default state
893
- !isSelected && [
894
- "text-text-secondary",
895
- // Hover
896
- "hover:bg-bg-subtle hover:text-text-primary"
897
- ],
898
- // Selected (current page)
899
- isSelected && [
900
- "bg-bg-subtle text-text-primary font-medium"
901
- ],
902
- // Keyboard navigation focus (roving tabindex active)
903
- "data-[active-item]:bg-accent-subtle data-[active-item]:text-accent",
904
- // Focus visible (actual keyboard focus indicator)
905
- "data-[focus-visible]:ring-ring data-[focus-visible]:ring-2",
906
- "data-[focus-visible]:ring-offset-ring-offset data-[focus-visible]:ring-offset-2",
907
- // Combined: selected + keyboard active
908
- isSelected && [
909
- "data-[active-item]:bg-accent-subtle data-[active-item]:text-accent"
910
- ]
911
- )
912
- }
913
- ),
914
- children: [
915
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
916
- "span",
917
- {
918
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
919
- "absolute top-1/2 left-0 h-4 w-0.5 -translate-y-1/2 rounded-full transition-all duration-150",
920
- // Selected: solid accent bar
921
- isSelected && "bg-accent",
922
- // Keyboard active (not selected): lighter bar
923
- !isSelected && "group-data-[active-item]:bg-accent bg-transparent",
924
- // Focus visible: ensure bar is visible
925
- "group-data-[focus-visible]:bg-accent"
926
- )
927
- }
928
- ),
929
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "pl-2", children: item.label })
930
- ]
931
- }
932
- )
933
- ] }, item.id);
934
- })
935
- }
936
- )
937
- }
938
- );
939
- }
940
-
941
- // src/shells/editor-toolbar.tsx
942
-
943
- var defaultLabels6 = {
944
- ariaLabel: "\uD14D\uC2A4\uD2B8 \uD3B8\uC9D1\uAE30 \uD234\uBC14"
945
- };
946
- function ToolbarButtonWithTooltip({
947
- button,
948
- active,
949
- onAction
950
- }) {
951
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.TooltipProvider, { children: [
952
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.TooltipAnchor, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
953
- _chunkAFF2HPE5cjs.ToolbarButton,
954
- {
955
- className: `text-text-primary data-[active-item]:bg-bg-subtle data-[focus-visible]:ring-ring rounded-md p-2 transition-colors outline-none data-[focus-visible]:ring-2 ${active ? "bg-bg-muted" : "hover:bg-bg-subtle"}`,
956
- onClick: () => onAction == null ? void 0 : onAction(button.id),
957
- children: button.icon
958
- }
959
- ) }),
960
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.Tooltip, { children: button.label })
961
- ] });
962
- }
963
- function EditorToolbar({
964
- buttons,
965
- onAction,
966
- activeButtons = [],
967
- labels: customLabels
968
- }) {
969
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels6), customLabels);
970
- const groups = [];
971
- let current = [];
972
- for (const btn of buttons) {
973
- if (btn.separator) {
974
- groups.push(current);
975
- current = [];
976
- }
977
- current.push(btn);
978
- }
979
- if (current.length) groups.push(current);
980
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
981
- _chunkAFF2HPE5cjs.ToolbarRoot,
982
- {
983
- "data-opt-id": "Z73K6",
984
- "data-opt-slug": "editor-toolbar.EditorToolbar",
985
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.ToolbarContainer, { "aria-label": labels.ariaLabel, children: groups.map((group, gi) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "contents", children: [
986
- gi > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.ToolbarSeparator, {}),
987
- group.map((item) => {
988
- if (item === "separator") return null;
989
- const btn = item;
990
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
991
- ToolbarButtonWithTooltip,
992
- {
993
- button: btn,
994
- active: activeButtons.includes(btn.id),
995
- onAction
996
- },
997
- btn.id
998
- );
999
- })
1000
- ] }, gi)) })
1001
- }
1002
- );
1003
- }
1004
-
1005
- // src/shells/content-tabs.tsx
1006
-
1007
-
1008
- var defaultLabels7 = {
1009
- ariaLabel: "\uCF58\uD150\uCE20 \uD0ED",
1010
- emptyMessage: "\uD45C\uC2DC\uD560 \uD0ED\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."
1011
- };
1012
- function ContentTabs({
1013
- tabs,
1014
- defaultTabId,
1015
- labels: customLabels
1016
- }) {
1017
- var _a, _b;
1018
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels7), customLabels);
1019
- if (tabs.length === 0) {
1020
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1021
- "div",
1022
- {
1023
- className: "text-text-secondary text-sm",
1024
- "data-opt-id": "9W97K",
1025
- "data-opt-slug": "content-tabs.ContentTabs",
1026
- children: labels.emptyMessage
1027
- }
1028
- );
1029
- }
1030
- const [selectedTabId, setSelectedTabId] = _react.useState.call(void 0,
1031
- defaultTabId != null ? defaultTabId : (_a = tabs[0]) == null ? void 0 : _a.id
1032
- );
1033
- const handleSelectedTabId = (nextId) => {
1034
- var _a2;
1035
- setSelectedTabId(nextId != null ? nextId : (_a2 = tabs[0]) == null ? void 0 : _a2.id);
1036
- };
1037
- const activeTab = (_b = tabs.find((tab) => tab.id === selectedTabId)) != null ? _b : tabs[0];
1038
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1039
- _chunkAFF2HPE5cjs.TabsRoot,
1040
- {
1041
- selectedId: selectedTabId,
1042
- onSelectedIdChange: handleSelectedTabId,
1043
- "data-opt-id": "9W97K",
1044
- "data-opt-slug": "content-tabs.ContentTabs",
1045
- children: [
1046
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.TabList, { "aria-label": labels.ariaLabel, children: tabs.map((tab) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.Tab, { id: tab.id, children: tab.label }, tab.id)) }),
1047
- activeTab && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.TabPanel, { tabId: activeTab.id, children: activeTab.content })
1048
- ]
1049
- }
1050
- );
1051
- }
1052
-
1053
- // src/shells/faq-accordion.tsx
1054
-
1055
- var defaultLabels8 = {
1056
- ariaLabel: "\uC790\uC8FC \uBB3B\uB294 \uC9C8\uBB38",
1057
- emptyMessage: "\uB4F1\uB85D\uB41C FAQ\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
1058
- };
1059
- function FaqAccordion({
1060
- items,
1061
- labels: customLabels
1062
- }) {
1063
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels8), customLabels);
1064
- if (items.length === 0) {
1065
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1066
- "div",
1067
- {
1068
- className: "text-text-secondary text-sm",
1069
- "data-opt-id": "QRBHV",
1070
- "data-opt-slug": "faq-accordion.FaqAccordion",
1071
- children: labels.emptyMessage
1072
- }
1073
- );
1074
- }
1075
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1076
- _chunkAFF2HPE5cjs.CompositeProvider,
1077
- {
1078
- focusLoop: true,
1079
- orientation: "vertical",
1080
- "data-opt-id": "QRBHV",
1081
- "data-opt-slug": "faq-accordion.FaqAccordion",
1082
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1083
- _chunkAFF2HPE5cjs.Composite,
1084
- {
1085
- role: "region",
1086
- "aria-label": labels.ariaLabel,
1087
- className: "divide-border-subtle border-border divide-y rounded-lg border",
1088
- children: items.map((faq) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.DisclosureRoot, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
1089
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.CompositeItem, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.DisclosureTrigger, {}), children: [
1090
- faq.question,
1091
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1092
- "svg",
1093
- {
1094
- className: "text-text-tertiary h-4 w-4 shrink-0 transition-transform [[data-open]>&]:rotate-180",
1095
- fill: "none",
1096
- viewBox: "0 0 24 24",
1097
- stroke: "currentColor",
1098
- strokeWidth: 2,
1099
- "aria-hidden": "true",
1100
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1101
- "path",
1102
- {
1103
- strokeLinecap: "round",
1104
- strokeLinejoin: "round",
1105
- d: "m19.5 8.25-7.5 7.5-7.5-7.5"
1106
- }
1107
- )
1108
- }
1109
- )
1110
- ] }),
1111
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.DisclosureContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-text-secondary px-4 pt-2 pb-4 text-sm", children: faq.answer }) })
1112
- ] }) }, faq.id))
1113
- }
1114
- )
1115
- }
1116
- );
1117
- }
1118
-
1119
- // src/shells/settings-form.tsx
1120
-
1121
-
1122
- var defaultLabels9 = {
1123
- formAriaLabel: "\uC124\uC815 \uD3FC",
1124
- submitButton: "\uC800\uC7A5",
1125
- successMessage: "\uC124\uC815\uC774 \uC800\uC7A5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."
1126
- };
1127
- function SettingsForm({
1128
- fields,
1129
- onSubmit,
1130
- labels: customLabels
1131
- }) {
1132
- var _a;
1133
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels9), customLabels);
1134
- const [submitted, setSubmitted] = _react.useState.call(void 0, false);
1135
- if (fields.length === 0) {
1136
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1137
- _chunkAFF2HPE5cjs.EmptyState,
1138
- {
1139
- title: "\uC124\uC815 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
1140
- description: "\uD45C\uC2DC\uD560 \uC124\uC815 \uD544\uB4DC\uB97C \uCD94\uAC00\uD558\uBA74 \uC774 \uD3FC\uC774 \uB80C\uB354\uB9C1\uB429\uB2C8\uB2E4.",
1141
- "data-opt-id": "9TEEJ",
1142
- "data-opt-slug": "settings-form.SettingsForm"
1143
- }
1144
- );
1145
- }
1146
- const defaultValues = {};
1147
- for (const field of fields) {
1148
- defaultValues[field.name] = (_a = field.defaultValue) != null ? _a : field.type === "switch" || field.type === "checkbox" ? false : field.type === "tags" ? [] : "";
1149
- }
1150
- const form = _chunkAFF2HPE5cjs.useFormStore.call(void 0, {
1151
- defaultValues,
1152
- validate: (values) => {
1153
- var _a2;
1154
- const errors = {};
1155
- for (const field of fields) {
1156
- if (field.required) {
1157
- const value = values[field.name];
1158
- if (!value || typeof value === "string" && !value.trim()) {
1159
- errors[field.name] = (_a2 = field.requiredMessage) != null ? _a2 : `${field.label}\uC744(\uB97C) \uC785\uB825\uD574\uC8FC\uC138\uC694.`;
1160
- }
1161
- }
1162
- if (field.validate) {
1163
- const value = values[field.name];
1164
- const error = field.validate(value);
1165
- if (error) {
1166
- errors[field.name] = error;
1167
- }
1168
- }
1169
- }
1170
- return errors;
1171
- },
1172
- onSubmit: (values) => {
1173
- setSubmitted(true);
1174
- onSubmit == null ? void 0 : onSubmit(values);
1175
- }
1176
- });
1177
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1178
- "div",
1179
- {
1180
- className: "gap-group flex flex-col",
1181
- "data-opt-id": "9TEEJ",
1182
- "data-opt-slug": "settings-form.SettingsForm",
1183
- children: [
1184
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.FormRoot, { store: form, "aria-label": labels.formAriaLabel, children: [
1185
- fields.map((field) => {
1186
- var _a2, _b, _c, _d, _e;
1187
- if (field.visible !== void 0) {
1188
- const currentValues = form.getValues();
1189
- const isVisible = typeof field.visible === "function" ? field.visible(currentValues) : field.visible;
1190
- if (!isVisible) return null;
1191
- }
1192
- if (field.type === "tags") {
1193
- const rawValue = form.getValue(field.name);
1194
- const tags = Array.isArray(rawValue) ? rawValue : [];
1195
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "gap-element flex flex-col", children: [
1196
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormLabel, { name: field.name, children: field.label }),
1197
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1198
- _chunkAFF2HPE5cjs.TagInput,
1199
- {
1200
- value: tags,
1201
- onChange: (next) => form.setValue(field.name, next),
1202
- placeholder: field.placeholder
1203
- }
1204
- ),
1205
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormError, { name: field.name })
1206
- ] }, field.name);
1207
- }
1208
- if (field.type === "radio") {
1209
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "fieldset", { className: "gap-element flex flex-col", children: [
1210
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "legend", { className: "text-text-primary text-sm font-medium", children: field.label }),
1211
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormRadioGroup, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "gap-group flex", children: (_a2 = field.options) == null ? void 0 : _a2.map((option) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1212
- "label",
1213
- {
1214
- className: "text-text-primary gap-element flex items-center text-sm",
1215
- children: [
1216
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormRadio, { name: field.name, value: option.value }),
1217
- option.label
1218
- ]
1219
- },
1220
- option.value
1221
- )) }) }),
1222
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormError, { name: field.name })
1223
- ] }, field.name);
1224
- }
1225
- if (field.type === "checkbox") {
1226
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "gap-element flex flex-col", children: [
1227
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { className: "text-text-primary gap-element flex items-center text-sm", children: [
1228
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormCheckbox, { name: field.name }),
1229
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: field.label })
1230
- ] }),
1231
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormError, { name: field.name })
1232
- ] }, field.name);
1233
- }
1234
- if (field.type === "textarea") {
1235
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "gap-element flex flex-col", children: [
1236
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormLabel, { name: field.name, children: field.label }),
1237
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1238
- _chunkAFF2HPE5cjs.FormTextarea,
1239
- {
1240
- name: field.name,
1241
- placeholder: field.placeholder,
1242
- rows: (_b = field.rows) != null ? _b : 4,
1243
- resize: (_c = field.resize) != null ? _c : "vertical",
1244
- className: field.font === "mono" ? "font-mono text-sm" : void 0
1245
- }
1246
- ),
1247
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormError, { name: field.name })
1248
- ] }, field.name);
1249
- }
1250
- if (field.type === "select") {
1251
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "gap-element flex flex-col", children: [
1252
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormLabel, { name: field.name, children: field.label }),
1253
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormSelect, { name: field.name, placeholder: field.placeholder, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormSelectPopover, { children: (_d = field.options) == null ? void 0 : _d.map((option) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormSelectItem, { value: option.value, children: option.label }, option.value)) }) }),
1254
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormError, { name: field.name })
1255
- ] }, field.name);
1256
- }
1257
- if (field.type === "switch") {
1258
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { className: "gap-group flex items-center", children: [
1259
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormSwitch, { name: field.name }),
1260
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col", children: [
1261
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-primary text-sm font-medium", children: field.label }),
1262
- field.description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-secondary text-sm", children: field.description })
1263
- ] })
1264
- ] }, field.name);
1265
- }
1266
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "gap-element flex flex-col", children: [
1267
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormLabel, { name: field.name, children: field.label }),
1268
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1269
- _chunkAFF2HPE5cjs.FormInput,
1270
- {
1271
- name: field.name,
1272
- type: (_e = field.type) != null ? _e : "text",
1273
- placeholder: field.placeholder
1274
- }
1275
- ),
1276
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormError, { name: field.name })
1277
- ] }, field.name);
1278
- }),
1279
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.FormSubmit, { children: labels.submitButton })
1280
- ] }),
1281
- submitted && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border-success bg-success-subtle text-success-fg rounded-lg border p-3 text-sm", children: labels.successMessage })
1282
- ]
1283
- }
1284
- );
1285
- }
1286
-
1287
- // src/shells/deployment-timeline.tsx
1288
-
1289
- var statusIcon = {
1290
- success: "\u25CF",
1291
- pending: "\u25CC",
1292
- running: "\u27F3",
1293
- error: "\u2717",
1294
- skipped: "\u25CB"
1295
- };
1296
- var statusColor = {
1297
- success: "text-success-fg",
1298
- pending: _chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY,
1299
- running: "text-accent",
1300
- error: "text-danger-fg",
1301
- skipped: "text-text-tertiary"
1302
- };
1303
- var statusBadge = {
1304
- success: _chunkAFF2HPE5cjs.OPT_BADGE_GREEN,
1305
- pending: _chunkAFF2HPE5cjs.OPT_BADGE_NEUTRAL,
1306
- running: "inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-medium bg-info-subtle text-info-fg",
1307
- error: _chunkAFF2HPE5cjs.OPT_BADGE_RED,
1308
- skipped: _chunkAFF2HPE5cjs.OPT_BADGE_NEUTRAL
1309
- };
1310
- var statusLabel = {
1311
- success: "\uC131\uACF5",
1312
- pending: "\uB300\uAE30",
1313
- running: "\uC2E4\uD589 \uC911",
1314
- error: "\uC5D0\uB7EC",
1315
- skipped: "\uAC74\uB108\uB700"
1316
- };
1317
- function DeploymentTimeline({
1318
- steps,
1319
- title = "\uBC30\uD3EC \uD0C0\uC784\uB77C\uC778"
1320
- }) {
1321
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1322
- "div",
1323
- {
1324
- className: "gap-group flex flex-col",
1325
- "data-opt-id": "XXVQ2",
1326
- "data-opt-slug": "deployment-timeline.DeploymentTimeline",
1327
- children: [
1328
- title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: `text-sm font-semibold ${_chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY}`, children: title }),
1329
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.CompositeProvider, { focusLoop: true, orientation: "vertical", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.Composite, { role: "list", "aria-label": title, className: "relative", children: steps.map((step, i) => {
1330
- const isLast = i === steps.length - 1;
1331
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1332
- _chunkAFF2HPE5cjs.CompositeItem,
1333
- {
1334
- className: `group gap-group relative flex w-full scroll-m-2 rounded-lg px-3 py-2 ${_chunkAFF2HPE5cjs.OPT_FOCUS} data-[active-item]:bg-accent-subtle`,
1335
- role: "listitem",
1336
- children: [
1337
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center", children: [
1338
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1339
- "span",
1340
- {
1341
- className: `text-lg leading-none ${statusColor[step.status]}`,
1342
- "aria-label": statusLabel[step.status],
1343
- children: statusIcon[step.status]
1344
- }
1345
- ),
1346
- !isLast && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-border-subtle mt-1 w-px flex-1" })
1347
- ] }),
1348
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 pb-3", children: [
1349
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "gap-element flex items-center", children: [
1350
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `text-sm font-medium ${_chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY}`, children: step.name }),
1351
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: statusBadge[step.status], children: statusLabel[step.status] }),
1352
- step.duration && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `text-xs ${_chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY}`, children: step.duration })
1353
- ] }),
1354
- step.detail && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: `mt-0.5 text-xs ${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY}`, children: step.detail })
1355
- ] })
1356
- ]
1357
- },
1358
- step.id
1359
- );
1360
- }) }) })
1361
- ]
1362
- }
1363
- );
1364
- }
1365
-
1366
- // src/shells/project-switcher.tsx
1367
-
1368
-
1369
-
1370
- var statusDot = {
1371
- active: _chunkAFF2HPE5cjs.OPT_DOT_GREEN,
1372
- paused: _chunkAFF2HPE5cjs.OPT_DOT_YELLOW,
1373
- error: _chunkAFF2HPE5cjs.OPT_DOT_RED
1374
- };
1375
- function ProjectSwitcher({
1376
- projects,
1377
- value,
1378
- onChange,
1379
- placeholder = "\uD504\uB85C\uC81D\uD2B8 \uAC80\uC0C9..."
1380
- }) {
1381
- const [search, setSearch] = _react.useState.call(void 0, "");
1382
- const matches = _react.useMemo.call(void 0, () => {
1383
- if (!search) return projects;
1384
- return _matchsorter.matchSorter.call(void 0, projects, search, { keys: ["name", "framework"] });
1385
- }, [search, projects]);
1386
- const selected = projects.find((p) => p.id === value);
1387
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1388
- "div",
1389
- {
1390
- className: "gap-element flex flex-col",
1391
- "data-opt-id": "5R3AG",
1392
- "data-opt-slug": "project-switcher.ProjectSwitcher",
1393
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.ComboboxRoot, { onValueChange: setSearch, children: [
1394
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { className: _chunkAFF2HPE5cjs.OPT_TEXT_LABEL, children: "\uD504\uB85C\uC81D\uD2B8" }),
1395
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1396
- _chunkAFF2HPE5cjs.ComboboxInput,
1397
- {
1398
- placeholder: selected ? selected.name : placeholder,
1399
- className: _chunkAFF2HPE5cjs.OPT_INPUT
1400
- }
1401
- ),
1402
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.ComboboxPopover, { className: "max-h-72 overflow-y-auto", children: [
1403
- matches.length === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: `py-6 text-center text-sm ${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY}`, children: "\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }),
1404
- matches.map((project) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1405
- _chunkAFF2HPE5cjs.ComboboxItem,
1406
- {
1407
- value: project.name,
1408
- onClick: () => onChange == null ? void 0 : onChange(project.id),
1409
- className: `gap-element flex scroll-m-2 items-center ${_chunkAFF2HPE5cjs.OPT_ITEM_BASE} ${_chunkAFF2HPE5cjs.OPT_ACTIVE_ITEM}`,
1410
- children: [
1411
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `shrink-0 ${statusDot[project.status]}` }),
1412
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex-1 truncate font-medium", children: project.name }),
1413
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkAFF2HPE5cjs.OPT_BADGE_NEUTRAL, children: project.framework }),
1414
- project.domain && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1415
- "span",
1416
- {
1417
- className: `truncate text-xs ${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY} data-[active-item]:text-accent-fg/70`,
1418
- children: project.domain
1419
- }
1420
- )
1421
- ]
1422
- },
1423
- project.id
1424
- ))
1425
- ] })
1426
- ] })
1427
- }
1428
- );
1429
- }
1430
- ProjectSwitcher.displayName = "ProjectSwitcher";
1431
-
1432
- // src/shells/env-panel.tsx
1433
-
1434
- var defaultLabels10 = {
1435
- varCount: (count) => `${count}\uAC1C \uBCC0\uC218`,
1436
- envVarsLabel: (env) => `${env} \uD658\uACBD \uBCC0\uC218`,
1437
- secretBadge: "secret"
1438
- };
1439
- var envDot = {
1440
- Production: _chunkAFF2HPE5cjs.OPT_DOT_RED,
1441
- Preview: _chunkAFF2HPE5cjs.OPT_DOT_YELLOW,
1442
- Development: _chunkAFF2HPE5cjs.OPT_DOT_GREEN
1443
- };
1444
- function EnvPanel({ groups, labels: customLabels }) {
1445
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels10), customLabels);
1446
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1447
- "div",
1448
- {
1449
- className: `rounded-lg ${_chunkAFF2HPE5cjs.OPT_BORDER} divide-y ${_chunkAFF2HPE5cjs.OPT_DIVIDER} bg-surface`,
1450
- "data-opt-id": "ZBDWK",
1451
- "data-opt-slug": "env-panel.EnvPanel",
1452
- children: groups.map((group) => {
1453
- var _a;
1454
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1455
- _chunkAFF2HPE5cjs.DisclosureRoot,
1456
- {
1457
- defaultOpen: group.env === "Production",
1458
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
1459
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.DisclosureTrigger, { className: _chunkAFF2HPE5cjs.OPT_DISCLOSURE_TRIGGER, children: [
1460
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "gap-element flex items-center", children: [
1461
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1462
- "span",
1463
- {
1464
- className: (_a = envDot[group.env]) != null ? _a : "bg-bg-muted h-2 w-2 rounded-full"
1465
- }
1466
- ),
1467
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium", children: group.env }),
1468
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `text-xs ${_chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY}`, children: labels.varCount(group.vars.length) })
1469
- ] }),
1470
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1471
- "svg",
1472
- {
1473
- className: "text-text-tertiary h-4 w-4 shrink-0 transition-transform [[data-open]>&]:rotate-180",
1474
- fill: "none",
1475
- viewBox: "0 0 24 24",
1476
- stroke: "currentColor",
1477
- strokeWidth: 2,
1478
- "aria-hidden": "true",
1479
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1480
- "path",
1481
- {
1482
- strokeLinecap: "round",
1483
- strokeLinejoin: "round",
1484
- d: "m19.5 8.25-7.5 7.5-7.5-7.5"
1485
- }
1486
- )
1487
- }
1488
- )
1489
- ] }),
1490
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.DisclosureContent, { className: _chunkAFF2HPE5cjs.OPT_DISCLOSURE_CONTENT, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.CompositeProvider, { focusLoop: true, orientation: "vertical", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1491
- _chunkAFF2HPE5cjs.Composite,
1492
- {
1493
- role: "list",
1494
- "aria-label": labels.envVarsLabel(group.env),
1495
- className: "px-4 pb-3",
1496
- children: group.vars.map((v) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1497
- _chunkAFF2HPE5cjs.CompositeItem,
1498
- {
1499
- role: "listitem",
1500
- className: `gap-group flex scroll-m-2 items-center rounded px-2 py-1.5 text-sm ${_chunkAFF2HPE5cjs.OPT_FOCUS} data-[active-item]:bg-accent-subtle`,
1501
- children: [
1502
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1503
- "span",
1504
- {
1505
- className: `w-44 shrink-0 truncate font-mono text-xs font-medium ${_chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY}`,
1506
- children: v.key
1507
- }
1508
- ),
1509
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1510
- "span",
1511
- {
1512
- className: `flex-1 truncate font-mono text-xs ${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY}`,
1513
- children: v.isSecret ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : v.value
1514
- }
1515
- ),
1516
- v.isSecret && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkAFF2HPE5cjs.OPT_BADGE_NEUTRAL, children: labels.secretBadge })
1517
- ]
1518
- },
1519
- v.key
1520
- ))
1521
- }
1522
- ) }) })
1523
- ] })
1524
- },
1525
- group.env
1526
- );
1527
- })
1528
- }
1529
- );
1530
- }
1531
-
1532
- // src/shells/branch-select.tsx
1533
-
1534
-
1535
- var defaultLabels11 = {
1536
- selectLabel: "\uBE0C\uB79C\uCE58",
1537
- emptySelectionLabel: "\uC120\uD0DD...",
1538
- emptyMessage: "\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBE0C\uB79C\uCE58\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
1539
- defaultBadge: "default"
1540
- };
1541
- function BranchSelect({
1542
- branches,
1543
- value: controlledValue,
1544
- onChange,
1545
- label,
1546
- labels: customLabels
1547
- }) {
1548
- var _a, _b, _c, _d;
1549
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels11), customLabels);
1550
- const resolvedLabel = label != null ? label : labels.selectLabel;
1551
- const defaultBranch = branches.find((b) => b.isDefault);
1552
- const [internalValue, setInternalValue] = _react.useState.call(void 0,
1553
- (_c = (_b = defaultBranch == null ? void 0 : defaultBranch.name) != null ? _b : (_a = branches[0]) == null ? void 0 : _a.name) != null ? _c : ""
1554
- );
1555
- const value = controlledValue != null ? controlledValue : internalValue;
1556
- const selected = branches.find((b) => b.name === value);
1557
- if (branches.length === 0) {
1558
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1559
- "div",
1560
- {
1561
- className: "gap-element flex flex-col",
1562
- "data-opt-id": "7EDEP",
1563
- "data-opt-slug": "branch-select.BranchSelect",
1564
- children: [
1565
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkAFF2HPE5cjs.OPT_TEXT_LABEL, children: resolvedLabel }),
1566
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY, children: labels.emptyMessage })
1567
- ]
1568
- }
1569
- );
1570
- }
1571
- const handleChange = (v) => {
1572
- var _a2;
1573
- const next = Array.isArray(v) ? (_a2 = v[0]) != null ? _a2 : "" : v;
1574
- if (onChange) onChange(next);
1575
- else setInternalValue(next);
1576
- };
1577
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1578
- "div",
1579
- {
1580
- className: "gap-element flex flex-col",
1581
- "data-opt-id": "7EDEP",
1582
- "data-opt-slug": "branch-select.BranchSelect",
1583
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.SelectRoot, { value, onValueChange: handleChange, children: [
1584
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.SelectLabel, { className: _chunkAFF2HPE5cjs.OPT_TEXT_LABEL, children: resolvedLabel }),
1585
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1586
- _chunkAFF2HPE5cjs.SelectTrigger,
1587
- {
1588
- className: `${_chunkAFF2HPE5cjs.OPT_INPUT} max-w-xs items-center justify-between gap-1`,
1589
- children: [
1590
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "gap-element flex items-center truncate", children: [
1591
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1592
- "svg",
1593
- {
1594
- className: "text-text-tertiary h-4 w-4 shrink-0",
1595
- fill: "none",
1596
- viewBox: "0 0 24 24",
1597
- stroke: "currentColor",
1598
- strokeWidth: 2,
1599
- "aria-hidden": "true",
1600
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1601
- "path",
1602
- {
1603
- strokeLinecap: "round",
1604
- strokeLinejoin: "round",
1605
- d: "M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"
1606
- }
1607
- )
1608
- }
1609
- ),
1610
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate", children: (_d = selected == null ? void 0 : selected.name) != null ? _d : labels.emptySelectionLabel }),
1611
- (selected == null ? void 0 : selected.isDefault) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: _chunkAFF2HPE5cjs.OPT_BADGE_BLUE, children: labels.defaultBadge })
1612
- ] }),
1613
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1614
- "svg",
1615
- {
1616
- className: "text-text-tertiary h-4 w-4 shrink-0",
1617
- fill: "none",
1618
- viewBox: "0 0 24 24",
1619
- stroke: "currentColor",
1620
- strokeWidth: 2,
1621
- "aria-hidden": "true",
1622
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1623
- "path",
1624
- {
1625
- strokeLinecap: "round",
1626
- strokeLinejoin: "round",
1627
- d: "m19.5 8.25-7.5 7.5-7.5-7.5"
1628
- }
1629
- )
1630
- }
1631
- )
1632
- ]
1633
- }
1634
- ),
1635
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.SelectPopover, { className: "max-w-xs", children: branches.map((branch) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1636
- _chunkAFF2HPE5cjs.SelectItem,
1637
- {
1638
- value: branch.name,
1639
- className: `gap-element flex scroll-m-2 items-center ${_chunkAFF2HPE5cjs.OPT_ITEM_BASE} ${_chunkAFF2HPE5cjs.OPT_ACTIVE_ITEM}`,
1640
- children: [
1641
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex-1 truncate", children: branch.name }),
1642
- branch.isDefault && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "bg-accent-subtle text-accent data-[active-item]:bg-accent-fg/20 data-[active-item]:text-accent-fg rounded-full px-2 py-0.5 text-[11px] font-medium", children: labels.defaultBadge }),
1643
- branch.lastCommit && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1644
- "span",
1645
- {
1646
- className: `font-mono text-xs ${_chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY} data-[active-item]:text-accent-fg/60`,
1647
- children: branch.lastCommit
1648
- }
1649
- ),
1650
- branch.author && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1651
- "span",
1652
- {
1653
- className: `text-xs ${_chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY} data-[active-item]:text-accent-fg/60`,
1654
- children: branch.author
1655
- }
1656
- )
1657
- ]
1658
- },
1659
- branch.name
1660
- )) })
1661
- ] })
1662
- }
1663
- );
1664
- }
1665
- BranchSelect.displayName = "BranchSelect";
1666
-
1667
- // src/shells/domain-table.tsx
1668
-
1669
- var defaultLabels12 = {
1670
- domain: "Domain",
1671
- status: "Status",
1672
- ssl: "SSL",
1673
- redirect: "Redirect",
1674
- added: "Added",
1675
- emptyMessage: "No domains configured"
1676
- };
1677
- var statusBadge2 = {
1678
- active: _chunkAFF2HPE5cjs.OPT_BADGE_GREEN,
1679
- pending: _chunkAFF2HPE5cjs.OPT_BADGE_YELLOW,
1680
- error: _chunkAFF2HPE5cjs.OPT_BADGE_RED
1681
- };
1682
- var sslBadge = {
1683
- valid: _chunkAFF2HPE5cjs.OPT_BADGE_GREEN,
1684
- pending: _chunkAFF2HPE5cjs.OPT_BADGE_YELLOW,
1685
- expired: _chunkAFF2HPE5cjs.OPT_BADGE_RED
1686
- };
1687
- var statusLabel2 = {
1688
- active: "Active",
1689
- pending: "Pending",
1690
- error: "Error"
1691
- };
1692
- var sslLabel = {
1693
- valid: "Valid",
1694
- pending: "Pending",
1695
- expired: "Expired"
1696
- };
1697
- function DomainTable({
1698
- domains,
1699
- title = "\uB3C4\uBA54\uC778",
1700
- labels: customLabels
1701
- }) {
1702
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels12), customLabels);
1703
- if (domains.length === 0) {
1704
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1705
- "div",
1706
- {
1707
- className: "gap-group flex flex-col",
1708
- "data-opt-id": "A7SRM",
1709
- "data-opt-slug": "domain-table.DomainTable",
1710
- children: [
1711
- title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: `text-sm font-semibold ${_chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY}`, children: title }),
1712
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1713
- "div",
1714
- {
1715
- className: `rounded-lg px-4 py-6 text-sm ${_chunkAFF2HPE5cjs.OPT_BORDER} ${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY} bg-surface`,
1716
- children: labels.emptyMessage
1717
- }
1718
- )
1719
- ]
1720
- }
1721
- );
1722
- }
1723
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1724
- "div",
1725
- {
1726
- className: "gap-group flex flex-col",
1727
- "data-opt-id": "A7SRM",
1728
- "data-opt-slug": "domain-table.DomainTable",
1729
- children: [
1730
- title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: `text-sm font-semibold ${_chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY}`, children: title }),
1731
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `overflow-x-auto rounded-lg ${_chunkAFF2HPE5cjs.OPT_BORDER} bg-surface`, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.CompositeProvider, { focusLoop: true, focusWrap: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1732
- _chunkAFF2HPE5cjs.Composite,
1733
- {
1734
- role: "grid",
1735
- "aria-label": title,
1736
- className: "w-full",
1737
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "table", {}),
1738
- children: [
1739
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { className: "border-border-subtle bg-surface-inset border-b", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
1740
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: _chunkAFF2HPE5cjs.OPT_TH, children: labels.domain }),
1741
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: _chunkAFF2HPE5cjs.OPT_TH, children: labels.status }),
1742
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: _chunkAFF2HPE5cjs.OPT_TH, children: labels.ssl }),
1743
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: _chunkAFF2HPE5cjs.OPT_TH, children: labels.redirect }),
1744
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: _chunkAFF2HPE5cjs.OPT_TH, children: labels.added })
1745
- ] }) }),
1746
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tbody", { className: `divide-y ${_chunkAFF2HPE5cjs.OPT_DIVIDER}`, children: domains.map((d) => {
1747
- var _a, _b;
1748
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAFF2HPE5cjs.CompositeRow, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tr", {}), children: [
1749
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1750
- _chunkAFF2HPE5cjs.CompositeItem,
1751
- {
1752
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1753
- "td",
1754
- {
1755
- className: `${_chunkAFF2HPE5cjs.OPT_TD} font-mono font-medium`,
1756
- role: "gridcell"
1757
- }
1758
- ),
1759
- className: _chunkAFF2HPE5cjs.OPT_TABLE_ROW_ACTIVE,
1760
- children: d.domain
1761
- }
1762
- ),
1763
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1764
- _chunkAFF2HPE5cjs.CompositeItem,
1765
- {
1766
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { className: _chunkAFF2HPE5cjs.OPT_TD, role: "gridcell" }),
1767
- className: _chunkAFF2HPE5cjs.OPT_TABLE_ROW_ACTIVE,
1768
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: statusBadge2[d.status], children: statusLabel2[d.status] })
1769
- }
1770
- ),
1771
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1772
- _chunkAFF2HPE5cjs.CompositeItem,
1773
- {
1774
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { className: _chunkAFF2HPE5cjs.OPT_TD, role: "gridcell" }),
1775
- className: _chunkAFF2HPE5cjs.OPT_TABLE_ROW_ACTIVE,
1776
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: sslBadge[d.ssl], children: sslLabel[d.ssl] })
1777
- }
1778
- ),
1779
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1780
- _chunkAFF2HPE5cjs.CompositeItem,
1781
- {
1782
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { className: _chunkAFF2HPE5cjs.OPT_TD, role: "gridcell" }),
1783
- className: _chunkAFF2HPE5cjs.OPT_TABLE_ROW_ACTIVE,
1784
- children: (_a = d.redirect) != null ? _a : "\u2014"
1785
- }
1786
- ),
1787
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1788
- _chunkAFF2HPE5cjs.CompositeItem,
1789
- {
1790
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { className: _chunkAFF2HPE5cjs.OPT_TD_MUTED, role: "gridcell" }),
1791
- className: _chunkAFF2HPE5cjs.OPT_TABLE_ROW_ACTIVE,
1792
- children: (_b = d.addedAt) != null ? _b : "\u2014"
1793
- }
1794
- )
1795
- ] }, d.domain);
1796
- }) })
1797
- ]
1798
- }
1799
- ) }) })
1800
- ]
1801
- }
1802
- );
1803
- }
1804
-
1805
- // src/shells/data-table.tsx
1806
-
1807
-
1808
-
1809
-
1810
-
1811
-
1812
-
1813
- var MIN_COLUMN_WIDTH = 40;
1814
- var DEFAULT_COLUMN_RESIZE_MAX = 1200;
1815
- var alignmentClass = {
1816
- left: "text-left",
1817
- center: "text-center",
1818
- right: "text-right"
1819
- };
1820
- function getCellValue(row, accessor) {
1821
- if (typeof accessor === "function") {
1822
- try {
1823
- return accessor(row);
1824
- } catch (e) {
1825
- return "\u2014";
1826
- }
1827
- }
1828
- const value = row[accessor];
1829
- if (value === null || value === void 0 || typeof value === "number" && !Number.isFinite(value)) {
1830
- return "\u2014";
1831
- }
1832
- return String(value);
1833
- }
1834
- function getRawValue(row, accessor) {
1835
- if (typeof accessor === "function") {
1836
- return accessor(row);
1837
- }
1838
- return row[accessor];
1839
- }
1840
- function isMissingSortValue(value) {
1841
- return value == null || typeof value === "number" && !Number.isFinite(value);
1842
- }
1843
- function compareSortValues(aVal, bVal, dir) {
1844
- const aMissing = isMissingSortValue(aVal);
1845
- const bMissing = isMissingSortValue(bVal);
1846
- if (aMissing && bMissing) return 0;
1847
- if (aMissing) return 1;
1848
- if (bMissing) return -1;
1849
- const cmp = typeof aVal === "number" && typeof bVal === "number" ? aVal - bVal : String(aVal).localeCompare(String(bVal));
1850
- return dir === "desc" ? -cmp : cmp;
1851
- }
1852
- function clampPercent(ratio) {
1853
- if (!Number.isFinite(ratio)) return 0;
1854
- return Math.min(100, Math.max(0, Math.round(ratio * 100)));
1855
- }
1856
- function getResizeHandleValue(currentWidth, configuredWidth) {
1857
- if (typeof currentWidth === "number" && Number.isFinite(currentWidth)) {
1858
- return Math.max(MIN_COLUMN_WIDTH, Math.round(currentWidth));
1859
- }
1860
- const pxWidth = configuredWidth == null ? void 0 : configuredWidth.trim().match(/^(\d+(?:\.\d+)?)px$/);
1861
- if (pxWidth) {
1862
- return Math.max(MIN_COLUMN_WIDTH, Math.round(Number(pxWidth[1])));
1863
- }
1864
- return MIN_COLUMN_WIDTH;
1865
- }
1866
- function DataTableProgressBar({
1867
- value,
1868
- barColor,
1869
- label
1870
- }) {
1871
- const percent = clampPercent(value);
1872
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1873
- "div",
1874
- {
1875
- className: "bg-bg-subtle mt-1 h-1.5 w-full overflow-hidden rounded-full",
1876
- role: "progressbar",
1877
- "aria-valuenow": percent,
1878
- "aria-valuemin": 0,
1879
- "aria-valuemax": 100,
1880
- "aria-valuetext": `${percent}%`,
1881
- "aria-label": label,
1882
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1883
- "div",
1884
- {
1885
- className: _chunkAFF2HPE5cjs.cn.call(void 0, "h-full rounded-full transition-all", barColor),
1886
- style: { width: `${percent}%` }
1887
- }
1888
- )
1889
- }
1890
- );
1891
- }
1892
- function DataTable({
1893
- data,
1894
- columns,
1895
- keyExtractor,
1896
- title = "Data Table",
1897
- onRowClick,
1898
- emptyMessage = "No data available",
1899
- activeRowId,
1900
- sortable = false,
1901
- selectable = false,
1902
- selectedKeys,
1903
- onSelectionChange,
1904
- expandable = false,
1905
- renderExpanded,
1906
- pageSize,
1907
- stickyHeader = false,
1908
- resizableColumns = false,
1909
- onSort: onSortExternal,
1910
- className
1911
- }) {
1912
- const [sortCol, setSortCol] = _react.useState.call(void 0, null);
1913
- const [sortDir, setSortDir] = _react.useState.call(void 0, null);
1914
- const [expandedKeys, setExpandedKeys] = _react.useState.call(void 0, /* @__PURE__ */ new Set());
1915
- const [page, setPage] = _react.useState.call(void 0, 0);
1916
- const [colWidths, setColWidths] = _react.useState.call(void 0, {});
1917
- const sortedData = _react.useMemo.call(void 0, () => {
1918
- if (!sortable || !sortCol || !sortDir) return data;
1919
- const col = columns.find((c) => c.id === sortCol);
1920
- if (!col) return data;
1921
- return [...data].sort((a, b) => {
1922
- const aVal = getRawValue(a, col.accessor);
1923
- const bVal = getRawValue(b, col.accessor);
1924
- return compareSortValues(aVal, bVal, sortDir);
1925
- });
1926
- }, [data, sortable, sortCol, sortDir, columns]);
1927
- const totalPages = pageSize ? Math.ceil(sortedData.length / pageSize) : 1;
1928
- const pagedData = pageSize ? sortedData.slice(page * pageSize, (page + 1) * pageSize) : sortedData;
1929
- const handleSort = _react.useCallback.call(void 0,
1930
- (colId) => {
1931
- if (!sortable) return;
1932
- let nextDir;
1933
- if (sortCol === colId) {
1934
- nextDir = sortDir === "asc" ? "desc" : sortDir === "desc" ? null : "asc";
1935
- setSortDir(nextDir);
1936
- if (nextDir === null) setSortCol(null);
1937
- } else {
1938
- setSortCol(colId);
1939
- setSortDir("asc");
1940
- nextDir = "asc";
1941
- }
1942
- setPage(0);
1943
- if (onSortExternal) {
1944
- onSortExternal(colId, nextDir);
1945
- }
1946
- },
1947
- [sortable, sortCol, sortDir, onSortExternal]
1948
- );
1949
- const toggleExpand = _react.useCallback.call(void 0, (key) => {
1950
- setExpandedKeys((prev) => {
1951
- const next = new Set(prev);
1952
- if (next.has(key)) next.delete(key);
1953
- else next.add(key);
1954
- return next;
1955
- });
1956
- }, []);
1957
- const selected = selectedKeys != null ? selectedKeys : [];
1958
- const selectedSet = _react.useMemo.call(void 0,
1959
- () => new Set(selectedKeys != null ? selectedKeys : []),
1960
- [selectedKeys]
1961
- );
1962
- const allKeys = data.map(keyExtractor);
1963
- const allSelected = allKeys.length > 0 && allKeys.every((k) => selectedSet.has(k));
1964
- const toggleSelectAll = _react.useCallback.call(void 0, () => {
1965
- if (!onSelectionChange) return;
1966
- onSelectionChange(allSelected ? [] : allKeys);
1967
- }, [allSelected, allKeys, onSelectionChange]);
1968
- const toggleSelectRow = _react.useCallback.call(void 0,
1969
- (key) => {
1970
- if (!onSelectionChange) return;
1971
- onSelectionChange(
1972
- selectedSet.has(key) ? selected.filter((k) => k !== key) : [...selected, key]
1973
- );
1974
- },
1975
- [selected, selectedSet, onSelectionChange]
1976
- );
1977
- const sortIndicator = (colId) => {
1978
- if (sortCol !== colId) return null;
1979
- return sortDir === "asc" ? " \u25B2" : sortDir === "desc" ? " \u25BC" : null;
1980
- };
1981
- const colCount = columns.length + (selectable ? 1 : 0) + (expandable ? 1 : 0);
1982
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1983
- "div",
1984
- {
1985
- className: _chunkAFF2HPE5cjs.cn.call(void 0, "gap-group flex flex-col", className),
1986
- "data-opt-id": "J1KN4",
1987
- "data-opt-slug": "data-table.DataTable",
1988
- children: [
1989
- title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: _chunkAFF2HPE5cjs.cn.call(void 0, "text-sm font-semibold", _chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY), children: title }),
1990
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1991
- "div",
1992
- {
1993
- className: _chunkAFF2HPE5cjs.cn.call(void 0, "overflow-x-auto rounded-lg", _chunkAFF2HPE5cjs.OPT_BORDER, "bg-surface"),
1994
- children: data.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1995
- "div",
1996
- {
1997
- className: _chunkAFF2HPE5cjs.cn.call(void 0, "px-4 py-8 text-center text-sm", _chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY),
1998
- children: emptyMessage
1999
- }
2000
- ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.CompositeProvider, { focusLoop: true, focusWrap: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2001
- _chunkAFF2HPE5cjs.Composite,
2002
- {
2003
- role: "grid",
2004
- "aria-label": title,
2005
- className: "w-full",
2006
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "table", {}),
2007
- children: [
2008
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2009
- "thead",
2010
- {
2011
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2012
- "border-border-subtle bg-surface-inset border-b",
2013
- stickyHeader && "sticky top-0 z-10"
2014
- ),
2015
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
2016
- selectable && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_TH, "w-10"), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2017
- _chunkAFF2HPE5cjs.Checkbox,
2018
- {
2019
- checked: allSelected,
2020
- onChange: toggleSelectAll,
2021
- "aria-label": "Select all"
2022
- }
2023
- ) }),
2024
- expandable && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_TH, "w-10") }),
2025
- columns.map((col) => {
2026
- var _a;
2027
- const isSortable = sortable && col.sortable !== false;
2028
- const resizeValue = getResizeHandleValue(
2029
- colWidths[col.id],
2030
- col.width
2031
- );
2032
- const resizeMax = Math.max(
2033
- DEFAULT_COLUMN_RESIZE_MAX,
2034
- resizeValue
2035
- );
2036
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2037
- "th",
2038
- {
2039
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2040
- _chunkAFF2HPE5cjs.OPT_TH,
2041
- "relative",
2042
- alignmentClass[(_a = col.align) != null ? _a : "left"],
2043
- isSortable && "hover:text-text-primary cursor-pointer select-none",
2044
- isSortable && _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE
2045
- ),
2046
- style: {
2047
- width: colWidths[col.id] || col.width || void 0
2048
- },
2049
- onClick: isSortable ? () => handleSort(col.id) : void 0,
2050
- onKeyDown: (event) => {
2051
- if (!isSortable || event.key !== "Enter" && event.key !== " ") {
2052
- return;
2053
- }
2054
- event.preventDefault();
2055
- handleSort(col.id);
2056
- },
2057
- tabIndex: isSortable ? 0 : void 0,
2058
- "aria-sort": sortCol === col.id && sortDir ? sortDir === "asc" ? "ascending" : "descending" : void 0,
2059
- children: [
2060
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "flex items-center", children: [
2061
- col.header,
2062
- sortIndicator(col.id)
2063
- ] }),
2064
- resizableColumns && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2065
- "span",
2066
- {
2067
- role: "separator",
2068
- "aria-orientation": "vertical",
2069
- "aria-label": `Resize ${col.header}`,
2070
- "aria-valuemin": MIN_COLUMN_WIDTH,
2071
- "aria-valuemax": resizeMax,
2072
- "aria-valuenow": resizeValue,
2073
- "aria-valuetext": `${resizeValue} pixels`,
2074
- tabIndex: 0,
2075
- className: "bg-border absolute top-0 right-0 bottom-0 w-1 cursor-col-resize opacity-0 hover:opacity-100",
2076
- onKeyDown: (e) => {
2077
- if (e.key !== "ArrowLeft" && e.key !== "ArrowRight" && e.key !== "Home" && e.key !== "End") {
2078
- return;
2079
- }
2080
- e.preventDefault();
2081
- e.stopPropagation();
2082
- if (e.key === "Home" || e.key === "End") {
2083
- setColWidths((prev) => _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, prev), {
2084
- [col.id]: e.key === "Home" ? MIN_COLUMN_WIDTH : resizeMax
2085
- }));
2086
- return;
2087
- }
2088
- const delta = e.shiftKey ? 40 : 10;
2089
- const direction = e.key === "ArrowRight" ? 1 : -1;
2090
- setColWidths((prev) => {
2091
- const current = getResizeHandleValue(
2092
- prev[col.id],
2093
- col.width
2094
- );
2095
- return _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, prev), {
2096
- [col.id]: Math.max(
2097
- MIN_COLUMN_WIDTH,
2098
- current + direction * delta
2099
- )
2100
- });
2101
- });
2102
- },
2103
- onMouseDown: (e) => {
2104
- e.preventDefault();
2105
- e.stopPropagation();
2106
- const startX = e.clientX;
2107
- const th = e.target.parentElement;
2108
- const startW = th.offsetWidth;
2109
- const onMove = (ev) => {
2110
- const newW = Math.max(
2111
- MIN_COLUMN_WIDTH,
2112
- startW + ev.clientX - startX
2113
- );
2114
- setColWidths((prev) => _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, prev), {
2115
- [col.id]: newW
2116
- }));
2117
- };
2118
- const onUp = () => {
2119
- document.removeEventListener(
2120
- "mousemove",
2121
- onMove
2122
- );
2123
- document.removeEventListener("mouseup", onUp);
2124
- };
2125
- document.addEventListener("mousemove", onMove);
2126
- document.addEventListener("mouseup", onUp);
2127
- }
2128
- }
2129
- )
2130
- ]
2131
- },
2132
- col.id
2133
- );
2134
- })
2135
- ] })
2136
- }
2137
- ),
2138
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tbody", { className: _chunkAFF2HPE5cjs.cn.call(void 0, "divide-y", _chunkAFF2HPE5cjs.OPT_DIVIDER), children: pagedData.map((row) => {
2139
- const key = keyExtractor(row);
2140
- const isExpanded = expandedKeys.has(key);
2141
- const isSelected = selectedSet.has(key);
2142
- const isActive = activeRowId === key;
2143
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _react.Fragment, { children: [
2144
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2145
- _chunkAFF2HPE5cjs.CompositeRow,
2146
- {
2147
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2148
- "tr",
2149
- {
2150
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2151
- onRowClick ? "cursor-pointer" : void 0,
2152
- (isSelected || isActive) && "bg-accent-subtle"
2153
- ),
2154
- onClick: onRowClick ? () => onRowClick(row) : void 0
2155
- }
2156
- ),
2157
- children: [
2158
- selectable && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2159
- _chunkAFF2HPE5cjs.CompositeItem,
2160
- {
2161
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2162
- "td",
2163
- {
2164
- className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_TD, "w-10"),
2165
- role: "gridcell"
2166
- }
2167
- ),
2168
- className: _chunkAFF2HPE5cjs.OPT_TABLE_ROW_ACTIVE,
2169
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2170
- _chunkAFF2HPE5cjs.Checkbox,
2171
- {
2172
- checked: isSelected,
2173
- onChange: () => toggleSelectRow(key),
2174
- "aria-label": `Select row ${key}`
2175
- }
2176
- )
2177
- }
2178
- ),
2179
- expandable && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2180
- _chunkAFF2HPE5cjs.CompositeItem,
2181
- {
2182
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2183
- "td",
2184
- {
2185
- className: _chunkAFF2HPE5cjs.cn.call(void 0, _chunkAFF2HPE5cjs.OPT_TD, "w-10"),
2186
- role: "gridcell"
2187
- }
2188
- ),
2189
- className: _chunkAFF2HPE5cjs.OPT_TABLE_ROW_ACTIVE,
2190
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2191
- "button",
2192
- {
2193
- type: "button",
2194
- onClick: (e) => {
2195
- e.stopPropagation();
2196
- toggleExpand(key);
2197
- },
2198
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2199
- "rounded p-0.5 text-sm transition-transform",
2200
- _chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY,
2201
- _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE,
2202
- isExpanded && "rotate-90"
2203
- ),
2204
- "aria-expanded": isExpanded,
2205
- "aria-label": `${isExpanded ? "Collapse" : "Expand"} row ${key}`,
2206
- children: "\u25B6"
2207
- }
2208
- )
2209
- }
2210
- ),
2211
- columns.map((col, colIndex) => {
2212
- var _a, _b;
2213
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2214
- _chunkAFF2HPE5cjs.CompositeItem,
2215
- {
2216
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2217
- "td",
2218
- {
2219
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2220
- _chunkAFF2HPE5cjs.OPT_TD,
2221
- alignmentClass[(_a = col.align) != null ? _a : "left"],
2222
- colIndex === 0 ? "font-medium" : ""
2223
- ),
2224
- role: "gridcell"
2225
- }
2226
- ),
2227
- className: _chunkAFF2HPE5cjs.OPT_TABLE_ROW_ACTIVE,
2228
- onKeyDown: (event) => {
2229
- if (!onRowClick || event.target !== event.currentTarget || event.key !== "Enter" && event.key !== " ") {
2230
- return;
2231
- }
2232
- event.preventDefault();
2233
- onRowClick(row);
2234
- },
2235
- children: [
2236
- getCellValue(row, col.accessor),
2237
- col.bar && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2238
- DataTableProgressBar,
2239
- {
2240
- value: col.bar(row),
2241
- barColor: (_b = col.barColor) != null ? _b : "bg-accent",
2242
- label: col.header
2243
- }
2244
- )
2245
- ]
2246
- },
2247
- col.id
2248
- );
2249
- })
2250
- ]
2251
- }
2252
- ),
2253
- expandable && isExpanded && renderExpanded && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tr", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2254
- "td",
2255
- {
2256
- colSpan: colCount,
2257
- className: "border-border-subtle bg-surface-inset border-t px-4 py-3",
2258
- children: renderExpanded(row)
2259
- }
2260
- ) })
2261
- ] }, key);
2262
- }) })
2263
- ]
2264
- }
2265
- ) })
2266
- }
2267
- ),
2268
- pageSize && totalPages > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2269
- _chunkAFF2HPE5cjs.Pagination,
2270
- {
2271
- totalItems: sortedData.length,
2272
- pageSize,
2273
- currentPage: page + 1,
2274
- onPageChange: (p) => setPage(p - 1)
2275
- }
2276
- )
2277
- ]
2278
- }
2279
- );
2280
- }
2281
-
2282
- // src/shells/notification-toast.tsx
2283
-
2284
-
2285
-
2286
-
2287
-
2288
-
2289
-
2290
-
2291
-
2292
-
2293
- var toastCounter = 0;
2294
- var toasts = [];
2295
- var listeners = /* @__PURE__ */ new Set();
2296
- function emitChange() {
2297
- for (const l of listeners) l();
2298
- }
2299
- var toastStore = {
2300
- subscribe(listener) {
2301
- listeners.add(listener);
2302
- return () => {
2303
- listeners.delete(listener);
2304
- };
2305
- },
2306
- getSnapshot() {
2307
- return toasts;
2308
- },
2309
- add(input) {
2310
- var _a;
2311
- const id = `toast-${++toastCounter}`;
2312
- toasts = [...toasts, _chunkONE3C5RVcjs.__spreadValues.call(void 0, { id, variant: (_a = input.variant) != null ? _a : "info" }, input)];
2313
- emitChange();
2314
- return id;
2315
- },
2316
- dismiss(id) {
2317
- const next = toasts.filter((t) => t.id !== id);
2318
- if (next.length !== toasts.length) {
2319
- toasts = next;
2320
- emitChange();
2321
- }
2322
- },
2323
- clear() {
2324
- if (toasts.length) {
2325
- toasts = [];
2326
- emitChange();
2327
- }
2328
- }
2329
- };
2330
- function makeVariant(variant) {
2331
- return (message, options) => toastStore.add(_chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, options), { message, variant }));
2332
- }
2333
- var toast = Object.assign(
2334
- (options) => toastStore.add(options),
2335
- {
2336
- info: makeVariant("info"),
2337
- success: makeVariant("success"),
2338
- warning: makeVariant("warning"),
2339
- error: makeVariant("error"),
2340
- dismiss: (id) => toastStore.dismiss(id),
2341
- clear: () => toastStore.clear()
2342
- }
2343
- );
2344
- var ToastContext = _react.createContext.call(void 0, null);
2345
- var positionStyles = {
2346
- "top-right": "top-4 right-4",
2347
- "top-left": "top-4 left-4",
2348
- "bottom-right": "bottom-4 right-4",
2349
- "bottom-left": "bottom-4 left-4"
2350
- };
2351
- function ToastProvider({
2352
- children,
2353
- position = "top-right",
2354
- defaultDuration = 5e3,
2355
- stackLimit = 5
2356
- }) {
2357
- const allToasts = _react.useSyncExternalStore.call(void 0,
2358
- toastStore.subscribe,
2359
- toastStore.getSnapshot,
2360
- toastStore.getSnapshot
2361
- );
2362
- const visibleToasts = allToasts.length > stackLimit ? allToasts.slice(-stackLimit) : allToasts;
2363
- const addToast = _react.useCallback.call(void 0,
2364
- (t) => toastStore.add(t),
2365
- []
2366
- );
2367
- const removeToast = _react.useCallback.call(void 0, (id) => toastStore.dismiss(id), []);
2368
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2369
- ToastContext.Provider,
2370
- {
2371
- value: { toasts: visibleToasts, addToast, removeToast },
2372
- children: [
2373
- children,
2374
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2375
- "div",
2376
- {
2377
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2378
- "gap-element fixed z-50 flex flex-col",
2379
- positionStyles[position]
2380
- ),
2381
- role: "region",
2382
- "aria-label": "Notifications",
2383
- "data-opt-id": "M0KTS",
2384
- "data-opt-slug": "notification-toast.ToastProvider",
2385
- children: visibleToasts.map((t) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2386
- NotificationToast,
2387
- {
2388
- toast: t,
2389
- defaultDuration,
2390
- onDismiss: () => toastStore.dismiss(t.id)
2391
- },
2392
- t.id
2393
- ))
2394
- }
2395
- )
2396
- ]
2397
- }
2398
- );
2399
- }
2400
- function useToast() {
2401
- const context = _react.useContext.call(void 0, ToastContext);
2402
- if (!context) {
2403
- throw new Error("useToast must be used within a ToastProvider");
2404
- }
2405
- return context;
2406
- }
2407
- function NotificationToast({
2408
- toast: toast2,
2409
- onDismiss,
2410
- defaultDuration = 5e3
2411
- }) {
2412
- var _a;
2413
- const duration = (_a = toast2.duration) != null ? _a : defaultDuration;
2414
- const isUrgent = toast2.variant === "error" || toast2.variant === "warning";
2415
- const onDismissRef = _react.useRef.call(void 0, onDismiss);
2416
- const dismissedRef = _react.useRef.call(void 0, false);
2417
- const timerStartedAtRef = _react.useRef.call(void 0, null);
2418
- const remainingDurationRef = _react.useRef.call(void 0, duration);
2419
- const [paused, setPaused] = _react.useState.call(void 0, false);
2420
- _react.useEffect.call(void 0, () => {
2421
- onDismissRef.current = onDismiss;
2422
- }, [onDismiss]);
2423
- const dismissOnce = _react.useCallback.call(void 0, () => {
2424
- if (dismissedRef.current) return;
2425
- dismissedRef.current = true;
2426
- onDismissRef.current();
2427
- }, []);
2428
- _react.useEffect.call(void 0, () => {
2429
- dismissedRef.current = false;
2430
- remainingDurationRef.current = duration;
2431
- }, [toast2.id, duration]);
2432
- _react.useEffect.call(void 0, () => {
2433
- if (!duration || duration <= 0 || paused || dismissedRef.current) {
2434
- return;
2435
- }
2436
- timerStartedAtRef.current = Date.now();
2437
- const timer = setTimeout(() => {
2438
- dismissOnce();
2439
- }, remainingDurationRef.current);
2440
- return () => {
2441
- clearTimeout(timer);
2442
- if (timerStartedAtRef.current !== null) {
2443
- const elapsed = Date.now() - timerStartedAtRef.current;
2444
- remainingDurationRef.current = Math.max(
2445
- 0,
2446
- remainingDurationRef.current - elapsed
2447
- );
2448
- timerStartedAtRef.current = null;
2449
- }
2450
- };
2451
- }, [dismissOnce, duration, paused]);
2452
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2453
- "div",
2454
- {
2455
- className: "animate-in slide-in-from-right-full fade-in w-80 duration-200",
2456
- role: isUrgent ? "alert" : "status",
2457
- "aria-live": isUrgent ? "assertive" : "polite",
2458
- "aria-atomic": "true",
2459
- onMouseEnter: () => setPaused(true),
2460
- onMouseLeave: () => setPaused(false),
2461
- onFocus: () => setPaused(true),
2462
- onBlur: (event) => {
2463
- if (!event.currentTarget.contains(event.relatedTarget)) {
2464
- setPaused(false);
2465
- }
2466
- },
2467
- "data-opt-id": "26YVM",
2468
- "data-opt-slug": "notification-toast.NotificationToast",
2469
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2470
- _chunkAFF2HPE5cjs.Alert,
2471
- {
2472
- variant: toast2.variant,
2473
- title: toast2.title,
2474
- dismissible: true,
2475
- onDismiss: dismissOnce,
2476
- children: [
2477
- toast2.message,
2478
- toast2.actions && toast2.actions.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "gap-element mt-2 flex", children: toast2.actions.map((action) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2479
- "button",
2480
- {
2481
- type: "button",
2482
- onClick: action.onClick,
2483
- className: "text-xs font-medium underline hover:no-underline",
2484
- children: action.label
2485
- },
2486
- action.label
2487
- )) })
2488
- ]
2489
- }
2490
- )
2491
- }
2492
- );
2493
- }
2494
-
2495
- // src/shells/failure-list.tsx
2496
-
2497
- var defaultLabels13 = {
2498
- title: "\uCD5C\uADFC \uC2E4\uD328",
2499
- emptyMessage: "\uC2E4\uD328 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4",
2500
- moreItems: "{count}\uAC1C \uB354 \uBCF4\uAE30",
2501
- severityLabels: {
2502
- critical: "\uC2EC\uAC01",
2503
- error: "\uC624\uB958",
2504
- warning: "\uACBD\uACE0"
2505
- },
2506
- timeAgo: {
2507
- justNow: "\uBC29\uAE08 \uC804",
2508
- minutesAgo: "{minutes}\uBD84 \uC804",
2509
- hoursAgo: "{hours}\uC2DC\uAC04 \uC804",
2510
- daysAgo: "{days}\uC77C \uC804"
2511
- }
2512
- };
2513
- var severityVariant = {
2514
- critical: "error",
2515
- error: "error",
2516
- warning: "warning"
2517
- };
2518
- var severityBorder = {
2519
- critical: "border-l-2 border-l-danger",
2520
- error: "border-l-2 border-l-danger",
2521
- warning: "border-l-2 border-l-warning"
2522
- };
2523
- function formatRelativeTime(timestamp, timeLabels, locale) {
2524
- const now = /* @__PURE__ */ new Date();
2525
- const date = new Date(timestamp);
2526
- const diffMs = now.getTime() - date.getTime();
2527
- const diffMins = Math.floor(diffMs / 6e4);
2528
- const diffHours = Math.floor(diffMs / 36e5);
2529
- const diffDays = Math.floor(diffMs / 864e5);
2530
- if (diffMins < 1) return timeLabels.justNow;
2531
- if (diffMins < 60)
2532
- return timeLabels.minutesAgo.replace("{minutes}", String(diffMins));
2533
- if (diffHours < 24)
2534
- return timeLabels.hoursAgo.replace("{hours}", String(diffHours));
2535
- if (diffDays < 7)
2536
- return timeLabels.daysAgo.replace("{days}", String(diffDays));
2537
- return date.toLocaleDateString(locale);
2538
- }
2539
- function groupBy(items, key) {
2540
- const map = /* @__PURE__ */ new Map();
2541
- for (const item of items) {
2542
- const k = key(item);
2543
- const existing = map.get(k);
2544
- if (existing) {
2545
- existing.push(item);
2546
- } else {
2547
- map.set(k, [item]);
2548
- }
2549
- }
2550
- return map;
2551
- }
2552
- function FailureItemRow({
2553
- failure,
2554
- isLast,
2555
- onFailureClick,
2556
- renderActions,
2557
- mergedSeverityLabels,
2558
- mergedTimeAgo,
2559
- locale
2560
- }) {
2561
- const itemId = `failure-${failure.id}`;
2562
- const handleKeyDown = (event) => {
2563
- if (!onFailureClick) return;
2564
- if (event.key !== "Enter" && event.key !== " ") return;
2565
- event.preventDefault();
2566
- onFailureClick(failure);
2567
- };
2568
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2569
- _chunkAFF2HPE5cjs.CompositeItem,
2570
- {
2571
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "article", {}),
2572
- role: "article",
2573
- "aria-labelledby": itemId,
2574
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2575
- "group gap-group relative flex w-full items-start p-3",
2576
- _chunkAFF2HPE5cjs.OPT_FOCUS_VISIBLE,
2577
- "data-[active-item]:bg-accent-subtle",
2578
- onFailureClick && "cursor-pointer",
2579
- !isLast && "border-border-subtle border-b",
2580
- severityBorder[failure.severity]
2581
- ),
2582
- onClick: () => onFailureClick == null ? void 0 : onFailureClick(failure),
2583
- onKeyDown: handleKeyDown,
2584
- children: [
2585
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "min-w-0 flex-1", children: [
2586
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "gap-element flex items-center", children: [
2587
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.Badge, { variant: severityVariant[failure.severity], size: "sm", children: mergedSeverityLabels[failure.severity] }),
2588
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2589
- "span",
2590
- {
2591
- id: itemId,
2592
- className: `text-sm font-medium ${_chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY} truncate`,
2593
- children: failure.title
2594
- }
2595
- )
2596
- ] }),
2597
- failure.message && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: `mt-1 text-xs ${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY} line-clamp-2`, children: failure.message }),
2598
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2599
- "time",
2600
- {
2601
- dateTime: failure.timestamp,
2602
- className: `mt-1 block text-xs ${_chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY}`,
2603
- children: formatRelativeTime(failure.timestamp, mergedTimeAgo, locale)
2604
- }
2605
- )
2606
- ] }),
2607
- renderActions && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex shrink-0 items-center gap-1", children: renderActions(failure) })
2608
- ]
2609
- },
2610
- failure.id
2611
- );
2612
- }
2613
- function FailureList({
2614
- failures,
2615
- title,
2616
- maxItems,
2617
- grouped = false,
2618
- onFailureClick,
2619
- onShowMore,
2620
- labels: customLabels,
2621
- locale = "ko-KR",
2622
- loading = false,
2623
- renderActions,
2624
- className
2625
- }) {
2626
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
2627
- const mergedTimeAgo = {
2628
- justNow: (_b = (_a = customLabels == null ? void 0 : customLabels.timeAgo) == null ? void 0 : _a.justNow) != null ? _b : defaultLabels13.timeAgo.justNow,
2629
- minutesAgo: (_d = (_c = customLabels == null ? void 0 : customLabels.timeAgo) == null ? void 0 : _c.minutesAgo) != null ? _d : defaultLabels13.timeAgo.minutesAgo,
2630
- hoursAgo: (_f = (_e = customLabels == null ? void 0 : customLabels.timeAgo) == null ? void 0 : _e.hoursAgo) != null ? _f : defaultLabels13.timeAgo.hoursAgo,
2631
- daysAgo: (_h = (_g = customLabels == null ? void 0 : customLabels.timeAgo) == null ? void 0 : _g.daysAgo) != null ? _h : defaultLabels13.timeAgo.daysAgo
2632
- };
2633
- const mergedSeverityLabels = {
2634
- critical: (_j = (_i = customLabels == null ? void 0 : customLabels.severityLabels) == null ? void 0 : _i.critical) != null ? _j : defaultLabels13.severityLabels.critical,
2635
- error: (_l = (_k = customLabels == null ? void 0 : customLabels.severityLabels) == null ? void 0 : _k.error) != null ? _l : defaultLabels13.severityLabels.error,
2636
- warning: (_n = (_m = customLabels == null ? void 0 : customLabels.severityLabels) == null ? void 0 : _m.warning) != null ? _n : defaultLabels13.severityLabels.warning
2637
- };
2638
- const labels = {
2639
- title: (_o = customLabels == null ? void 0 : customLabels.title) != null ? _o : defaultLabels13.title,
2640
- emptyMessage: (_p = customLabels == null ? void 0 : customLabels.emptyMessage) != null ? _p : defaultLabels13.emptyMessage,
2641
- moreItems: (_q = customLabels == null ? void 0 : customLabels.moreItems) != null ? _q : defaultLabels13.moreItems
2642
- };
2643
- const displayTitle = title != null ? title : labels.title;
2644
- const allItems = maxItems ? failures.slice(0, maxItems) : failures;
2645
- const remainingCount = maxItems ? Math.max(0, failures.length - maxItems) : 0;
2646
- const rowProps = {
2647
- onFailureClick,
2648
- renderActions,
2649
- mergedSeverityLabels,
2650
- mergedTimeAgo,
2651
- locale
2652
- };
2653
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2654
- "div",
2655
- {
2656
- className,
2657
- "data-opt-id": "ZAM3R",
2658
- "data-opt-slug": "failure-list.FailureList",
2659
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "gap-group flex flex-col", children: [
2660
- displayTitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: `text-sm font-semibold ${_chunkAFF2HPE5cjs.OPT_TEXT_PRIMARY}`, children: displayTitle }),
2661
- failures.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2662
- "div",
2663
- {
2664
- role: "status",
2665
- className: `py-8 text-center text-sm ${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY}`,
2666
- children: labels.emptyMessage
2667
- }
2668
- ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAFF2HPE5cjs.CompositeProvider, { focusLoop: true, orientation: "vertical", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2669
- _chunkAFF2HPE5cjs.Composite,
2670
- {
2671
- role: "feed",
2672
- "aria-label": displayTitle,
2673
- "aria-busy": loading,
2674
- className: `rounded-lg ${_chunkAFF2HPE5cjs.OPT_BORDER} bg-surface`,
2675
- children: grouped ? renderGrouped(
2676
- allItems,
2677
- remainingCount,
2678
- rowProps,
2679
- labels,
2680
- onShowMore
2681
- ) : renderFlat(
2682
- allItems,
2683
- remainingCount,
2684
- rowProps,
2685
- labels,
2686
- onShowMore
2687
- )
2688
- }
2689
- ) })
2690
- ] })
2691
- }
2692
- );
2693
- }
2694
- function renderFlat(items, remainingCount, rowProps, labels, onShowMore) {
2695
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2696
- items.map((failure, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2697
- FailureItemRow,
2698
- _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
2699
- failure,
2700
- isLast: index === items.length - 1 && remainingCount === 0
2701
- }, rowProps),
2702
- failure.id
2703
- )),
2704
- remainingCount > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2705
- _chunkAFF2HPE5cjs.CompositeItem,
2706
- {
2707
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { type: "button" }),
2708
- onClick: onShowMore,
2709
- className: `border-border-subtle w-full border-t p-3 text-center text-xs font-medium ${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY} ${_chunkAFF2HPE5cjs.OPT_FOCUS} hover:text-accent data-[active-item]:bg-accent-subtle transition-colors`,
2710
- "aria-label": `${remainingCount}\uAC1C\uC758 \uC2E4\uD328 \uB354 \uBCF4\uAE30`,
2711
- children: labels.moreItems.replace("{count}", String(remainingCount))
2712
- }
2713
- )
2714
- ] });
2715
- }
2716
- function renderGrouped(items, remainingCount, rowProps, labels, onShowMore) {
2717
- const groups = groupBy(items, (f) => {
2718
- var _a;
2719
- return (_a = f.group) != null ? _a : "";
2720
- });
2721
- const groupEntries = Array.from(groups.entries());
2722
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2723
- groupEntries.map(([groupName, groupItems], groupIndex) => {
2724
- const isLastGroup = groupIndex === groupEntries.length - 1 && remainingCount === 0;
2725
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
2726
- groupName && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2727
- "div",
2728
- {
2729
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2730
- `px-3 py-2 text-xs font-semibold ${_chunkAFF2HPE5cjs.OPT_TEXT_TERTIARY} tracking-wider uppercase`,
2731
- groupIndex > 0 && "border-border-subtle border-t"
2732
- ),
2733
- children: groupName
2734
- }
2735
- ),
2736
- groupItems.map((failure, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2737
- FailureItemRow,
2738
- _chunkONE3C5RVcjs.__spreadValues.call(void 0, {
2739
- failure,
2740
- isLast: isLastGroup && index === groupItems.length - 1
2741
- }, rowProps),
2742
- failure.id
2743
- ))
2744
- ] }, groupName || "__ungrouped__");
2745
- }),
2746
- remainingCount > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2747
- _chunkAFF2HPE5cjs.CompositeItem,
2748
- {
2749
- render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { type: "button" }),
2750
- onClick: onShowMore,
2751
- className: `border-border-subtle w-full border-t p-3 text-center text-xs font-medium ${_chunkAFF2HPE5cjs.OPT_TEXT_SECONDARY} ${_chunkAFF2HPE5cjs.OPT_FOCUS} hover:text-accent data-[active-item]:bg-accent-subtle transition-colors`,
2752
- "aria-label": `${remainingCount}\uAC1C\uC758 \uC2E4\uD328 \uB354 \uBCF4\uAE30`,
2753
- children: labels.moreItems.replace("{count}", String(remainingCount))
2754
- }
2755
- )
2756
- ] });
2757
- }
2758
-
2759
- // src/shells/key-value-editor.tsx
2760
-
2761
-
2762
- var defaultLabels14 = {
2763
- keyPlaceholder: "\uD0A4",
2764
- valuePlaceholder: "\uAC12",
2765
- addButton: "\uCD94\uAC00",
2766
- removeAriaLabel: "\uD56D\uBAA9 \uC0AD\uC81C",
2767
- toggleSecretAriaLabel: "\uBE44\uBC00\uAC12 \uD1A0\uAE00",
2768
- emptyMessage: "\uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uCD94\uAC00 \uBC84\uD2BC\uC744 \uB20C\uB7EC\uC8FC\uC138\uC694."
2769
- };
2770
- var idCounter = 0;
2771
- function generateId() {
2772
- return `kv-${++idCounter}`;
2773
- }
2774
- function KeyValueEditor({
2775
- value: controlledValue,
2776
- defaultValue,
2777
- onChange,
2778
- showSecretToggle = false,
2779
- maxEntries,
2780
- readOnly = false,
2781
- labels: customLabels,
2782
- renderActions,
2783
- validateKey,
2784
- className
2785
- }) {
2786
- const labels = _chunkONE3C5RVcjs.__spreadValues.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, defaultLabels14), customLabels);
2787
- const [internalEntries, setInternalEntries] = _react.useState.call(void 0,
2788
- () => defaultValue != null ? defaultValue : []
2789
- );
2790
- const entries = controlledValue != null ? controlledValue : internalEntries;
2791
- const keyInputRef = _react.useRef.call(void 0, null);
2792
- const updateEntries = _react.useCallback.call(void 0,
2793
- (next) => {
2794
- if (!controlledValue) {
2795
- setInternalEntries(next);
2796
- }
2797
- onChange == null ? void 0 : onChange(next);
2798
- },
2799
- [controlledValue, onChange]
2800
- );
2801
- const addEntry = _react.useCallback.call(void 0, () => {
2802
- if (maxEntries && entries.length >= maxEntries) return;
2803
- const newEntry = {
2804
- id: generateId(),
2805
- key: "",
2806
- value: "",
2807
- isSecret: false
2808
- };
2809
- updateEntries([...entries, newEntry]);
2810
- requestAnimationFrame(() => {
2811
- var _a, _b, _c;
2812
- (_c = (_b = (_a = keyInputRef.current) == null ? void 0 : _a.closest("[data-kv-list]")) == null ? void 0 : _b.querySelector(
2813
- `[data-kv-id="${newEntry.id}"] [data-kv-key]`
2814
- )) == null ? void 0 : _c.focus();
2815
- });
2816
- }, [entries, maxEntries, updateEntries]);
2817
- const removeEntry = _react.useCallback.call(void 0,
2818
- (id) => {
2819
- updateEntries(entries.filter((e) => e.id !== id));
2820
- },
2821
- [entries, updateEntries]
2822
- );
2823
- const updateEntry = _react.useCallback.call(void 0,
2824
- (id, field, val) => {
2825
- updateEntries(
2826
- entries.map((e) => e.id === id ? _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, e), { [field]: val }) : e)
2827
- );
2828
- },
2829
- [entries, updateEntries]
2830
- );
2831
- const toggleSecret = _react.useCallback.call(void 0,
2832
- (id) => {
2833
- updateEntries(
2834
- entries.map((e) => e.id === id ? _chunkONE3C5RVcjs.__spreadProps.call(void 0, _chunkONE3C5RVcjs.__spreadValues.call(void 0, {}, e), { isSecret: !e.isSecret }) : e)
2835
- );
2836
- },
2837
- [entries, updateEntries]
2838
- );
2839
- const canAdd = !readOnly && (!maxEntries || entries.length < maxEntries);
2840
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2841
- "div",
2842
- {
2843
- className: _chunkAFF2HPE5cjs.cn.call(void 0, "gap-group flex flex-col", className),
2844
- "data-opt-id": "NCBWA",
2845
- "data-opt-slug": "key-value-editor.KeyValueEditor",
2846
- children: [
2847
- entries.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-text-tertiary py-4 text-center text-sm", children: labels.emptyMessage }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "gap-element flex flex-col", "data-kv-list": true, children: entries.map((entry, index) => {
2848
- const keyError = validateKey == null ? void 0 : validateKey(entry.key, entries);
2849
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2850
- "div",
2851
- {
2852
- "data-kv-id": entry.id,
2853
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2854
- "gap-element flex items-start",
2855
- "border-border rounded-lg border p-3",
2856
- "bg-surface"
2857
- ),
2858
- children: [
2859
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
2860
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2861
- "input",
2862
- {
2863
- "data-kv-key": true,
2864
- ref: index === entries.length - 1 ? keyInputRef : void 0,
2865
- type: "text",
2866
- value: entry.key,
2867
- onChange: (e) => updateEntry(entry.id, "key", e.target.value),
2868
- placeholder: labels.keyPlaceholder,
2869
- readOnly,
2870
- "aria-label": `${labels.keyPlaceholder} ${index + 1}`,
2871
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2872
- "border-border bg-bg-subtle text-text-primary placeholder:text-text-tertiary w-full rounded-md border px-3 py-1.5 font-mono text-sm",
2873
- "focus:border-accent focus-visible:ring-ring focus-visible:ring-offset-ring-offset focus-visible:ring-2 focus-visible:ring-offset-1",
2874
- readOnly && "cursor-default opacity-70",
2875
- keyError && "border-error"
2876
- )
2877
- }
2878
- ),
2879
- keyError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-error text-xs", children: keyError })
2880
- ] }),
2881
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-tertiary px-1 py-1.5", children: "=" }),
2882
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2883
- "input",
2884
- {
2885
- type: entry.isSecret ? "password" : "text",
2886
- value: entry.value,
2887
- onChange: (e) => updateEntry(entry.id, "value", e.target.value),
2888
- placeholder: labels.valuePlaceholder,
2889
- readOnly,
2890
- "aria-label": `${labels.valuePlaceholder} ${index + 1}`,
2891
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2892
- "border-border bg-bg-subtle text-text-primary placeholder:text-text-tertiary w-full rounded-md border px-3 py-1.5 font-mono text-sm",
2893
- "focus:border-accent focus-visible:ring-ring focus-visible:ring-offset-ring-offset focus-visible:ring-2 focus-visible:ring-offset-1",
2894
- readOnly && "cursor-default opacity-70"
2895
- )
2896
- }
2897
- ) }),
2898
- showSecretToggle && !readOnly && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2899
- "button",
2900
- {
2901
- type: "button",
2902
- onClick: () => toggleSecret(entry.id),
2903
- "aria-label": labels.toggleSecretAriaLabel,
2904
- "aria-pressed": entry.isSecret,
2905
- className: "text-text-tertiary hover:text-text-primary shrink-0 rounded p-1.5 transition-colors",
2906
- children: entry.isSecret ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2907
- "svg",
2908
- {
2909
- className: "size-4",
2910
- fill: "none",
2911
- viewBox: "0 0 24 24",
2912
- stroke: "currentColor",
2913
- strokeWidth: 2,
2914
- "aria-hidden": "true",
2915
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2916
- "path",
2917
- {
2918
- strokeLinecap: "round",
2919
- strokeLinejoin: "round",
2920
- d: "M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"
2921
- }
2922
- )
2923
- }
2924
- ) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2925
- "svg",
2926
- {
2927
- className: "size-4",
2928
- fill: "none",
2929
- viewBox: "0 0 24 24",
2930
- stroke: "currentColor",
2931
- strokeWidth: 2,
2932
- "aria-hidden": "true",
2933
- children: [
2934
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2935
- "path",
2936
- {
2937
- strokeLinecap: "round",
2938
- strokeLinejoin: "round",
2939
- d: "M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"
2940
- }
2941
- ),
2942
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2943
- "path",
2944
- {
2945
- strokeLinecap: "round",
2946
- strokeLinejoin: "round",
2947
- d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z"
2948
- }
2949
- )
2950
- ]
2951
- }
2952
- )
2953
- }
2954
- ),
2955
- renderActions == null ? void 0 : renderActions(entry, index),
2956
- !readOnly && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2957
- "button",
2958
- {
2959
- type: "button",
2960
- onClick: () => removeEntry(entry.id),
2961
- "aria-label": labels.removeAriaLabel,
2962
- className: "text-text-tertiary hover:text-error shrink-0 rounded p-1.5 transition-colors",
2963
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2964
- "svg",
2965
- {
2966
- className: "size-4",
2967
- fill: "none",
2968
- viewBox: "0 0 24 24",
2969
- stroke: "currentColor",
2970
- strokeWidth: 2,
2971
- "aria-hidden": "true",
2972
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2973
- "path",
2974
- {
2975
- strokeLinecap: "round",
2976
- strokeLinejoin: "round",
2977
- d: "M6 18L18 6M6 6l12 12"
2978
- }
2979
- )
2980
- }
2981
- )
2982
- }
2983
- )
2984
- ]
2985
- },
2986
- entry.id
2987
- );
2988
- }) }),
2989
- canAdd && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2990
- "button",
2991
- {
2992
- type: "button",
2993
- onClick: addEntry,
2994
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
2995
- "border-border text-text-secondary rounded-lg border border-dashed px-4 py-2 text-sm transition-colors",
2996
- "hover:border-accent hover:text-accent"
2997
- ),
2998
- children: labels.addButton
2999
- }
3000
- )
3001
- ]
3002
- }
3003
- );
3004
- }
3005
-
3006
- // src/shells/workflow-canvas.tsx
3007
-
3008
-
3009
- var statusVariant = {
3010
- idle: "default",
3011
- running: "info",
3012
- success: "success",
3013
- error: "error"
3014
- };
3015
- function clamp(value, min, max) {
3016
- return Math.max(min, Math.min(max, value));
3017
- }
3018
- function WorkflowCanvas({
3019
- steps,
3020
- connections = [],
3021
- rows = 9,
3022
- cols = 9,
3023
- cellSize = 72,
3024
- gap = 12,
3025
- title = "Workflow Canvas",
3026
- emptyMessage = "No workflow steps",
3027
- selectedStepId,
3028
- onSelectStep,
3029
- onStepMove,
3030
- renderStep,
3031
- className
3032
- }) {
3033
- const stepMap = React.useMemo(
3034
- () => new Map(steps.map((step) => [step.id, step])),
3035
- [steps]
3036
- );
3037
- const width = cols * cellSize + (cols - 1) * gap;
3038
- const height = rows * cellSize + (rows - 1) * gap;
3039
- const renderDefaultStep = React.useCallback(
3040
- (step, selected) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3041
- "button",
3042
- {
3043
- type: "button",
3044
- onClick: () => onSelectStep == null ? void 0 : onSelectStep(step),
3045
- className: _chunkAFF2HPE5cjs.cn.call(void 0,
3046
- "group absolute flex h-full w-full flex-col justify-between rounded-lg border p-2 text-left transition-colors",
3047
- selected ? "border-accent bg-accent-subtle" : "border-border bg-surface hover:bg-bg-subtle"
3048
- ),
3049
- children: [
3050
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-text-primary truncate text-xs font-medium", children: step.title }),
3051
- step.status && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3052
- _chunkAFF2HPE5cjs.Badge,
3053
- {
3054
- variant: statusVariant[step.status],
3055
- size: "sm",
3056
- className: "w-fit",
3057
- children: step.status
3058
- }
3059
- )
3060
- ]
3061
- }
3062
- ),
3063
- [onSelectStep]
3064
- );
3065
- const handleStepKeyDown = React.useCallback(
3066
- (event, step) => {
3067
- if (!onStepMove) {
3068
- return;
3069
- }
3070
- let nextRow = step.row;
3071
- let nextCol = step.col;
3072
- switch (event.key) {
3073
- case "ArrowUp":
3074
- nextRow -= 1;
3075
- break;
3076
- case "ArrowDown":
3077
- nextRow += 1;
3078
- break;
3079
- case "ArrowLeft":
3080
- nextCol -= 1;
3081
- break;
3082
- case "ArrowRight":
3083
- nextCol += 1;
3084
- break;
3085
- default:
3086
- return;
3087
- }
3088
- event.preventDefault();
3089
- onStepMove(
3090
- step.id,
3091
- clamp(nextRow, 0, rows - 1),
3092
- clamp(nextCol, 0, cols - 1)
3093
- );
3094
- },
3095
- [onStepMove, rows, cols]
3096
- );
3097
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3098
- "div",
3099
- {
3100
- className: _chunkAFF2HPE5cjs.cn.call(void 0, "gap-group flex flex-col", className),
3101
- "data-opt-id": "4TX11",
3102
- "data-opt-slug": "workflow-canvas.WorkflowCanvas",
3103
- children: [
3104
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-text-primary text-sm font-semibold", children: title }),
3105
- steps.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-text-secondary border-border rounded-lg border border-dashed p-8 text-center text-sm", children: emptyMessage }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border-border bg-bg-subtle relative overflow-auto rounded-lg border p-3", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3106
- "div",
3107
- {
3108
- role: "grid",
3109
- "aria-label": title,
3110
- className: "relative",
3111
- style: { width, height },
3112
- children: [
3113
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3114
- "div",
3115
- {
3116
- className: "grid",
3117
- style: {
3118
- gridTemplateColumns: `repeat(${cols}, ${cellSize}px)`,
3119
- gridTemplateRows: `repeat(${rows}, ${cellSize}px)`,
3120
- gap
3121
- },
3122
- children: Array.from({ length: rows * cols }, (_, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3123
- "div",
3124
- {
3125
- "aria-hidden": "true",
3126
- className: "border-border-subtle bg-surface/30 rounded-md border border-dashed"
3127
- },
3128
- i
3129
- ))
3130
- }
3131
- ),
3132
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3133
- "svg",
3134
- {
3135
- className: "pointer-events-none absolute inset-0",
3136
- width,
3137
- height,
3138
- "aria-hidden": "true",
3139
- children: connections.map((connection) => {
3140
- const from = stepMap.get(connection.from);
3141
- const to = stepMap.get(connection.to);
3142
- if (!from || !to) {
3143
- return null;
3144
- }
3145
- const x1 = from.col * (cellSize + gap) + cellSize / 2;
3146
- const y1 = from.row * (cellSize + gap) + cellSize / 2;
3147
- const x2 = to.col * (cellSize + gap) + cellSize / 2;
3148
- const y2 = to.row * (cellSize + gap) + cellSize / 2;
3149
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "g", { children: [
3150
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3151
- "line",
3152
- {
3153
- x1,
3154
- y1,
3155
- x2,
3156
- y2,
3157
- stroke: "currentColor",
3158
- strokeOpacity: "0.35",
3159
- strokeWidth: "2"
3160
- }
3161
- ),
3162
- connection.label && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3163
- "text",
3164
- {
3165
- x: (x1 + x2) / 2,
3166
- y: (y1 + y2) / 2 - 4,
3167
- textAnchor: "middle",
3168
- className: "fill-text-secondary text-[10px]",
3169
- children: connection.label
3170
- }
3171
- )
3172
- ] }, `${connection.from}-${connection.to}`);
3173
- })
3174
- }
3175
- ),
3176
- steps.map((step) => {
3177
- const selected = selectedStepId === step.id;
3178
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3179
- "div",
3180
- {
3181
- role: "gridcell",
3182
- tabIndex: 0,
3183
- "aria-selected": selected,
3184
- "aria-label": `${step.title} (${step.row + 1}, ${step.col + 1})`,
3185
- onKeyDown: (event) => handleStepKeyDown(event, step),
3186
- className: "focus-visible:ring-ring absolute focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-white focus-visible:outline-none",
3187
- style: {
3188
- width: cellSize,
3189
- height: cellSize,
3190
- left: step.col * (cellSize + gap),
3191
- top: step.row * (cellSize + gap)
3192
- },
3193
- children: renderStep ? renderStep(step, selected) : renderDefaultStep(step, selected)
3194
- },
3195
- step.id
3196
- );
3197
- })
3198
- ]
3199
- }
3200
- ) })
3201
- ]
3202
- }
3203
- );
3204
- }
3205
- WorkflowCanvas.displayName = "WorkflowCanvas";
3206
-
3207
-
3208
-
3209
-
3210
-
3211
-
3212
-
3213
-
3214
-
3215
-
3216
-
3217
-
3218
-
3219
-
3220
-
3221
-
3222
-
3223
-
3224
-
3225
-
3226
-
3227
-
3228
-
3229
-
3230
-
3231
-
3232
-
3233
-
3234
-
3235
-
3236
-
3237
-
3238
-
3239
-
3240
-
3241
- exports.Command = Command; exports.CommandDialog = CommandDialog; exports.CommandInput = CommandInput; exports.CommandList = CommandList; exports.CommandEmpty = CommandEmpty; exports.CommandGroup = CommandGroup; exports.CommandSeparator = CommandSeparator; exports.CommandItem = CommandItem; exports.CommandShortcut = CommandShortcut; exports.CommandPalette = CommandPalette; exports.CommandPaletteTrigger = CommandPaletteTrigger; exports.DashboardGrid = DashboardGrid; exports.SearchCombobox = SearchCombobox; exports.StatusSelect = StatusSelect; exports.AppMenubar = AppMenubar; exports.SidebarNav = SidebarNav; exports.EditorToolbar = EditorToolbar; exports.ContentTabs = ContentTabs; exports.FaqAccordion = FaqAccordion; exports.SettingsForm = SettingsForm; exports.DeploymentTimeline = DeploymentTimeline; exports.ProjectSwitcher = ProjectSwitcher; exports.EnvPanel = EnvPanel; exports.BranchSelect = BranchSelect; exports.DomainTable = DomainTable; exports.DataTable = DataTable; exports.toast = toast; exports.ToastProvider = ToastProvider; exports.useToast = useToast; exports.NotificationToast = NotificationToast; exports.FailureList = FailureList; exports.KeyValueEditor = KeyValueEditor; exports.WorkflowCanvas = WorkflowCanvas;