@3w-witim/ui 0.1.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.
- package/README.md +23 -0
- package/dist/calendar/index.css +37 -0
- package/dist/calendar/index.css.map +1 -0
- package/dist/calendar/index.d.mts +55 -0
- package/dist/calendar/index.d.ts +55 -0
- package/dist/calendar/index.js +169 -0
- package/dist/calendar/index.js.map +1 -0
- package/dist/calendar/index.mjs +143 -0
- package/dist/calendar/index.mjs.map +1 -0
- package/dist/icons/index.d.mts +229 -0
- package/dist/icons/index.d.ts +229 -0
- package/dist/icons/index.js +678 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/icons/index.mjs +568 -0
- package/dist/icons/index.mjs.map +1 -0
- package/dist/index.d.mts +971 -0
- package/dist/index.d.ts +971 -0
- package/dist/index.js +3739 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3584 -0
- package/dist/index.mjs.map +1 -0
- package/dist/tailwind-preset.cjs +134 -0
- package/dist/tokens.css +662 -0
- package/package.json +74 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3584 @@
|
|
|
1
|
+
import { clsx } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
import * as React16 from 'react';
|
|
4
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
8
|
+
|
|
9
|
+
// src/utils.ts
|
|
10
|
+
function cn(...inputs) {
|
|
11
|
+
return twMerge(clsx(inputs));
|
|
12
|
+
}
|
|
13
|
+
var buttonVariants = cva(
|
|
14
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded text-base font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-5 [&_svg]:shrink-0",
|
|
15
|
+
{
|
|
16
|
+
variants: {
|
|
17
|
+
variant: {
|
|
18
|
+
primary: "bg-brand-solid text-text-on-brand hover:bg-brand-solid-hover active:bg-brand-solid-pressed",
|
|
19
|
+
neutral: "border border-border-default bg-surface-default text-text-default hover:bg-surface-hover active:bg-surface-pressed",
|
|
20
|
+
ghost: "text-text-default hover:bg-surface-hover active:bg-surface-pressed",
|
|
21
|
+
danger: "bg-danger-solid text-text-on-brand hover:bg-danger-solid-hover",
|
|
22
|
+
"danger-outline": "border border-danger-border bg-transparent text-danger-text hover:bg-danger-subtle active:bg-danger-subtle"
|
|
23
|
+
},
|
|
24
|
+
size: {
|
|
25
|
+
sm: "h-9 px-3",
|
|
26
|
+
// 36px · px 12
|
|
27
|
+
md: "h-10 px-4",
|
|
28
|
+
// 40px · px 16 (기본)
|
|
29
|
+
lg: "h-12 px-5"
|
|
30
|
+
// 48px · px 20
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
defaultVariants: {
|
|
34
|
+
variant: "primary",
|
|
35
|
+
size: "md"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
var Button = React16.forwardRef(
|
|
40
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
41
|
+
const Comp = asChild ? Slot : "button";
|
|
42
|
+
return /* @__PURE__ */ jsx(
|
|
43
|
+
Comp,
|
|
44
|
+
{
|
|
45
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
46
|
+
ref,
|
|
47
|
+
...props
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
Button.displayName = "Button";
|
|
53
|
+
var inputVariants = cva(
|
|
54
|
+
"flex w-full items-center rounded border bg-surface-default text-text-default transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-text-subtle focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base disabled:cursor-not-allowed disabled:bg-surface-sunken disabled:text-text-disabled disabled:placeholder:text-text-disabled",
|
|
55
|
+
{
|
|
56
|
+
variants: {
|
|
57
|
+
state: {
|
|
58
|
+
default: "border-border-default hover:border-border-strong focus-visible:border-border-focus focus-visible:ring-brand-border",
|
|
59
|
+
error: "border-danger-border focus-visible:border-danger-border focus-visible:ring-danger-border"
|
|
60
|
+
},
|
|
61
|
+
inputSize: {
|
|
62
|
+
sm: "h-9 gap-1.5 px-2.5 text-sm",
|
|
63
|
+
md: "h-10 gap-2 px-3 text-base",
|
|
64
|
+
lg: "h-12 gap-2.5 px-3.5 text-base"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
defaultVariants: {
|
|
68
|
+
state: "default",
|
|
69
|
+
inputSize: "md"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
var Input = React16.forwardRef(
|
|
74
|
+
({
|
|
75
|
+
className,
|
|
76
|
+
type = "text",
|
|
77
|
+
state,
|
|
78
|
+
inputSize,
|
|
79
|
+
startIcon,
|
|
80
|
+
endIcon,
|
|
81
|
+
helperText,
|
|
82
|
+
id,
|
|
83
|
+
"aria-describedby": ariaDescribedby,
|
|
84
|
+
...props
|
|
85
|
+
}, ref) => {
|
|
86
|
+
const isError = state === "error";
|
|
87
|
+
const reactId = React16.useId();
|
|
88
|
+
const helperId = helperText ? `${id ?? reactId}-helper` : void 0;
|
|
89
|
+
const describedBy = [ariaDescribedby, helperId].filter(Boolean).join(" ") || void 0;
|
|
90
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-1.5", children: [
|
|
91
|
+
/* @__PURE__ */ jsxs(
|
|
92
|
+
"div",
|
|
93
|
+
{
|
|
94
|
+
className: cn(
|
|
95
|
+
inputVariants({ state, inputSize }),
|
|
96
|
+
(startIcon || endIcon) && "cursor-text",
|
|
97
|
+
className
|
|
98
|
+
),
|
|
99
|
+
children: [
|
|
100
|
+
startIcon ? /* @__PURE__ */ jsx(
|
|
101
|
+
"span",
|
|
102
|
+
{
|
|
103
|
+
"aria-hidden": "true",
|
|
104
|
+
className: cn(
|
|
105
|
+
"flex size-5 shrink-0 items-center justify-center [&_svg]:size-5",
|
|
106
|
+
isError ? "text-danger-text" : "text-text-subtle"
|
|
107
|
+
),
|
|
108
|
+
children: startIcon
|
|
109
|
+
}
|
|
110
|
+
) : null,
|
|
111
|
+
/* @__PURE__ */ jsx(
|
|
112
|
+
"input",
|
|
113
|
+
{
|
|
114
|
+
id: id ?? reactId,
|
|
115
|
+
type,
|
|
116
|
+
ref,
|
|
117
|
+
"aria-invalid": isError || void 0,
|
|
118
|
+
"aria-describedby": describedBy,
|
|
119
|
+
className: "h-full w-full min-w-0 bg-transparent outline-none placeholder:text-text-subtle disabled:cursor-not-allowed disabled:text-text-disabled",
|
|
120
|
+
...props
|
|
121
|
+
}
|
|
122
|
+
),
|
|
123
|
+
endIcon ? /* @__PURE__ */ jsx(
|
|
124
|
+
"span",
|
|
125
|
+
{
|
|
126
|
+
"aria-hidden": "true",
|
|
127
|
+
className: cn(
|
|
128
|
+
"flex size-5 shrink-0 items-center justify-center [&_svg]:size-5",
|
|
129
|
+
isError ? "text-danger-text" : "text-text-subtle"
|
|
130
|
+
),
|
|
131
|
+
children: endIcon
|
|
132
|
+
}
|
|
133
|
+
) : null
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
),
|
|
137
|
+
helperText ? /* @__PURE__ */ jsxs(
|
|
138
|
+
"p",
|
|
139
|
+
{
|
|
140
|
+
id: helperId,
|
|
141
|
+
className: cn(
|
|
142
|
+
"flex items-center gap-1 text-sm [&_svg]:size-4",
|
|
143
|
+
isError ? "text-danger-text" : "text-text-subtle"
|
|
144
|
+
),
|
|
145
|
+
children: [
|
|
146
|
+
isError ? /* @__PURE__ */ jsx(
|
|
147
|
+
"svg",
|
|
148
|
+
{
|
|
149
|
+
"aria-hidden": "true",
|
|
150
|
+
viewBox: "0 0 20 20",
|
|
151
|
+
fill: "currentColor",
|
|
152
|
+
className: "shrink-0",
|
|
153
|
+
children: /* @__PURE__ */ jsx(
|
|
154
|
+
"path",
|
|
155
|
+
{
|
|
156
|
+
fillRule: "evenodd",
|
|
157
|
+
d: "M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16Zm-.75-11.5a.75.75 0 0 1 1.5 0v4a.75.75 0 0 1-1.5 0v-4ZM10 14.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z",
|
|
158
|
+
clipRule: "evenodd"
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
) : null,
|
|
163
|
+
helperText
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
) : null
|
|
167
|
+
] });
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
Input.displayName = "Input";
|
|
171
|
+
var textareaVariants = cva(
|
|
172
|
+
"flex w-full resize-none rounded border bg-surface-default text-base text-text-default transition-colors placeholder:text-text-subtle focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base disabled:cursor-not-allowed disabled:opacity-50",
|
|
173
|
+
{
|
|
174
|
+
variants: {
|
|
175
|
+
state: {
|
|
176
|
+
default: "border-border-default focus-visible:border-border-focus focus-visible:ring-brand-border",
|
|
177
|
+
error: "border-danger-border focus-visible:border-danger-border focus-visible:ring-danger-border"
|
|
178
|
+
},
|
|
179
|
+
size: {
|
|
180
|
+
sm: "min-h-[64px] p-2 text-sm",
|
|
181
|
+
md: "min-h-[80px] p-3 text-base",
|
|
182
|
+
lg: "min-h-[120px] p-4 text-base"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
defaultVariants: {
|
|
186
|
+
state: "default",
|
|
187
|
+
size: "md"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
var Textarea = React16.forwardRef(
|
|
192
|
+
({ className, state, size, "aria-invalid": ariaInvalid, ...props }, ref) => {
|
|
193
|
+
return /* @__PURE__ */ jsx(
|
|
194
|
+
"textarea",
|
|
195
|
+
{
|
|
196
|
+
ref,
|
|
197
|
+
"aria-invalid": ariaInvalid ?? (state === "error" ? true : void 0),
|
|
198
|
+
className: cn(textareaVariants({ state, size, className })),
|
|
199
|
+
...props
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
Textarea.displayName = "Textarea";
|
|
205
|
+
var cardVariants = cva("rounded-lg text-text-default transition-colors", {
|
|
206
|
+
variants: {
|
|
207
|
+
variant: {
|
|
208
|
+
default: "border border-border-subtle bg-surface-default shadow-card",
|
|
209
|
+
raised: "border border-border-subtle bg-surface-raised shadow-md",
|
|
210
|
+
outline: "border border-border-default bg-transparent"
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
defaultVariants: {
|
|
214
|
+
variant: "default"
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
var Card = React16.forwardRef(
|
|
218
|
+
({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
219
|
+
"div",
|
|
220
|
+
{
|
|
221
|
+
ref,
|
|
222
|
+
className: cn(cardVariants({ variant, className })),
|
|
223
|
+
...props
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
);
|
|
227
|
+
Card.displayName = "Card";
|
|
228
|
+
var CardHeader = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
229
|
+
"div",
|
|
230
|
+
{
|
|
231
|
+
ref,
|
|
232
|
+
className: cn("flex flex-col gap-3 p-5", className),
|
|
233
|
+
...props
|
|
234
|
+
}
|
|
235
|
+
));
|
|
236
|
+
CardHeader.displayName = "CardHeader";
|
|
237
|
+
var CardTitle = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
238
|
+
"div",
|
|
239
|
+
{
|
|
240
|
+
ref,
|
|
241
|
+
className: cn(
|
|
242
|
+
"font-semibold leading-none tracking-tight text-text-strong",
|
|
243
|
+
className
|
|
244
|
+
),
|
|
245
|
+
...props
|
|
246
|
+
}
|
|
247
|
+
));
|
|
248
|
+
CardTitle.displayName = "CardTitle";
|
|
249
|
+
var CardDescription = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
250
|
+
"div",
|
|
251
|
+
{
|
|
252
|
+
ref,
|
|
253
|
+
className: cn("text-sm text-text-subtle", className),
|
|
254
|
+
...props
|
|
255
|
+
}
|
|
256
|
+
));
|
|
257
|
+
CardDescription.displayName = "CardDescription";
|
|
258
|
+
var CardContent = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-5 pt-0", className), ...props }));
|
|
259
|
+
CardContent.displayName = "CardContent";
|
|
260
|
+
var CardFooter = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
261
|
+
"div",
|
|
262
|
+
{
|
|
263
|
+
ref,
|
|
264
|
+
className: cn("flex items-center gap-3 p-5 pt-0", className),
|
|
265
|
+
...props
|
|
266
|
+
}
|
|
267
|
+
));
|
|
268
|
+
CardFooter.displayName = "CardFooter";
|
|
269
|
+
var ScrollArea = React16.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
270
|
+
ScrollAreaPrimitive.Root,
|
|
271
|
+
{
|
|
272
|
+
ref,
|
|
273
|
+
className: cn("relative overflow-hidden", className),
|
|
274
|
+
...props,
|
|
275
|
+
children: [
|
|
276
|
+
/* @__PURE__ */ jsx(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
|
|
277
|
+
/* @__PURE__ */ jsx(ScrollBar, {}),
|
|
278
|
+
/* @__PURE__ */ jsx(ScrollAreaPrimitive.Corner, {})
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
));
|
|
282
|
+
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
283
|
+
var ScrollBar = React16.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
|
|
284
|
+
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
285
|
+
{
|
|
286
|
+
ref,
|
|
287
|
+
orientation,
|
|
288
|
+
className: cn(
|
|
289
|
+
"flex touch-none select-none transition-colors",
|
|
290
|
+
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
|
|
291
|
+
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
|
292
|
+
className
|
|
293
|
+
),
|
|
294
|
+
...props,
|
|
295
|
+
children: /* @__PURE__ */ jsx(ScrollAreaPrimitive.ScrollAreaThumb, { className: "relative flex-1 rounded-full bg-slate-300 hover:bg-slate-400" })
|
|
296
|
+
}
|
|
297
|
+
));
|
|
298
|
+
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
299
|
+
var labelVariants = cva(
|
|
300
|
+
"inline-flex items-center justify-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium whitespace-nowrap [&_svg]:pointer-events-none [&_svg]:size-3 [&_svg]:shrink-0",
|
|
301
|
+
{
|
|
302
|
+
variants: {
|
|
303
|
+
variant: {
|
|
304
|
+
brand: "bg-brand-subtle text-brand-text",
|
|
305
|
+
danger: "bg-danger-subtle text-danger-text",
|
|
306
|
+
neutral: "bg-[var(--comp-label-neutral-bg)] text-[var(--comp-label-neutral-text)]"
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
defaultVariants: {
|
|
310
|
+
variant: "neutral"
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
);
|
|
314
|
+
var Label = React16.forwardRef(
|
|
315
|
+
({ className, variant, ...props }, ref) => {
|
|
316
|
+
return /* @__PURE__ */ jsx(
|
|
317
|
+
"span",
|
|
318
|
+
{
|
|
319
|
+
ref,
|
|
320
|
+
className: cn(labelVariants({ variant, className })),
|
|
321
|
+
...props
|
|
322
|
+
}
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
);
|
|
326
|
+
Label.displayName = "Label";
|
|
327
|
+
var skeletonVariants = cva("animate-pulse bg-border-subtle", {
|
|
328
|
+
variants: {
|
|
329
|
+
variant: {
|
|
330
|
+
text: "rounded-lg h-4 w-full",
|
|
331
|
+
circle: "rounded-full",
|
|
332
|
+
rect: "rounded-lg"
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
defaultVariants: {
|
|
336
|
+
variant: "rect"
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
var Skeleton = React16.forwardRef(
|
|
340
|
+
({ className, variant, ...props }, ref) => {
|
|
341
|
+
return /* @__PURE__ */ jsx(
|
|
342
|
+
"div",
|
|
343
|
+
{
|
|
344
|
+
ref,
|
|
345
|
+
role: "status",
|
|
346
|
+
"aria-busy": "true",
|
|
347
|
+
"aria-live": "polite",
|
|
348
|
+
"aria-label": "\uB85C\uB529 \uC911",
|
|
349
|
+
className: cn(skeletonVariants({ variant, className })),
|
|
350
|
+
...props,
|
|
351
|
+
children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "\uB85C\uB529 \uC911" })
|
|
352
|
+
}
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
);
|
|
356
|
+
Skeleton.displayName = "Skeleton";
|
|
357
|
+
var progressTrackVariants = cva(
|
|
358
|
+
"relative w-full overflow-hidden rounded-full bg-border-subtle",
|
|
359
|
+
{
|
|
360
|
+
variants: {
|
|
361
|
+
size: {
|
|
362
|
+
md: "h-1.5"
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
defaultVariants: {
|
|
366
|
+
size: "md"
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
);
|
|
370
|
+
var progressFillVariants = cva(
|
|
371
|
+
"h-full rounded-full bg-brand-solid transition-[width] duration-300 ease-out",
|
|
372
|
+
{
|
|
373
|
+
variants: {
|
|
374
|
+
indeterminate: {
|
|
375
|
+
true: "w-full animate-pulse rounded-full",
|
|
376
|
+
false: ""
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
defaultVariants: {
|
|
380
|
+
indeterminate: false
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
function clamp(value) {
|
|
385
|
+
if (Number.isNaN(value)) return 0;
|
|
386
|
+
return Math.min(100, Math.max(0, value));
|
|
387
|
+
}
|
|
388
|
+
var Progress = React16.forwardRef(
|
|
389
|
+
({
|
|
390
|
+
className,
|
|
391
|
+
size,
|
|
392
|
+
value = 0,
|
|
393
|
+
indeterminate = false,
|
|
394
|
+
label = "Loading",
|
|
395
|
+
...props
|
|
396
|
+
}, ref) => {
|
|
397
|
+
const pct = clamp(value);
|
|
398
|
+
return /* @__PURE__ */ jsx(
|
|
399
|
+
"div",
|
|
400
|
+
{
|
|
401
|
+
ref,
|
|
402
|
+
role: "progressbar",
|
|
403
|
+
"aria-label": label,
|
|
404
|
+
"aria-valuemin": indeterminate ? void 0 : 0,
|
|
405
|
+
"aria-valuemax": indeterminate ? void 0 : 100,
|
|
406
|
+
"aria-valuenow": indeterminate ? void 0 : pct,
|
|
407
|
+
"aria-valuetext": indeterminate ? "Loading" : `${pct}%`,
|
|
408
|
+
className: cn(progressTrackVariants({ size, className })),
|
|
409
|
+
...props,
|
|
410
|
+
children: /* @__PURE__ */ jsx(
|
|
411
|
+
"div",
|
|
412
|
+
{
|
|
413
|
+
className: cn(progressFillVariants({ indeterminate })),
|
|
414
|
+
style: indeterminate ? void 0 : { width: `${pct}%` }
|
|
415
|
+
}
|
|
416
|
+
)
|
|
417
|
+
}
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
);
|
|
421
|
+
Progress.displayName = "Progress";
|
|
422
|
+
var checkboxVariants = cva(
|
|
423
|
+
"relative flex size-5 shrink-0 items-center justify-center rounded border-2 transition-colors peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-bg-base peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
424
|
+
{
|
|
425
|
+
variants: {
|
|
426
|
+
state: {
|
|
427
|
+
default: "border-border-strong bg-surface-default peer-focus-visible:ring-border-focus peer-checked:border-brand-solid peer-checked:bg-brand-solid",
|
|
428
|
+
error: "border-danger-border bg-surface-default peer-focus-visible:ring-danger-solid peer-checked:border-danger-border peer-checked:bg-danger-solid"
|
|
429
|
+
}
|
|
430
|
+
},
|
|
431
|
+
defaultVariants: {
|
|
432
|
+
state: "default"
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
);
|
|
436
|
+
var CheckIcon = ({ className }) => /* @__PURE__ */ jsx(
|
|
437
|
+
"svg",
|
|
438
|
+
{
|
|
439
|
+
viewBox: "0 0 12 12",
|
|
440
|
+
fill: "none",
|
|
441
|
+
"aria-hidden": "true",
|
|
442
|
+
className: cn("size-3", className),
|
|
443
|
+
children: /* @__PURE__ */ jsx(
|
|
444
|
+
"path",
|
|
445
|
+
{
|
|
446
|
+
d: "M2.5 6.2 5 8.7l4.5-5",
|
|
447
|
+
stroke: "currentColor",
|
|
448
|
+
strokeWidth: 2,
|
|
449
|
+
strokeLinecap: "round",
|
|
450
|
+
strokeLinejoin: "round"
|
|
451
|
+
}
|
|
452
|
+
)
|
|
453
|
+
}
|
|
454
|
+
);
|
|
455
|
+
var Checkbox = React16.forwardRef(
|
|
456
|
+
({ className, state, error, label, id, disabled, "aria-invalid": ariaInvalid, ...props }, ref) => {
|
|
457
|
+
const reactId = React16.useId();
|
|
458
|
+
const inputId = id ?? reactId;
|
|
459
|
+
const resolvedState = error ? "error" : state ?? "default";
|
|
460
|
+
const isInvalid = resolvedState === "error";
|
|
461
|
+
return /* @__PURE__ */ jsxs(
|
|
462
|
+
"label",
|
|
463
|
+
{
|
|
464
|
+
htmlFor: inputId,
|
|
465
|
+
className: cn(
|
|
466
|
+
"group inline-flex items-start gap-2 text-sm text-text-default",
|
|
467
|
+
disabled ? "cursor-not-allowed text-text-disabled" : "cursor-pointer"
|
|
468
|
+
),
|
|
469
|
+
children: [
|
|
470
|
+
/* @__PURE__ */ jsx(
|
|
471
|
+
"input",
|
|
472
|
+
{
|
|
473
|
+
ref,
|
|
474
|
+
id: inputId,
|
|
475
|
+
type: "checkbox",
|
|
476
|
+
disabled,
|
|
477
|
+
"aria-invalid": ariaInvalid ?? (isInvalid || void 0),
|
|
478
|
+
className: "peer sr-only",
|
|
479
|
+
...props
|
|
480
|
+
}
|
|
481
|
+
),
|
|
482
|
+
/* @__PURE__ */ jsx(
|
|
483
|
+
"span",
|
|
484
|
+
{
|
|
485
|
+
className: cn(
|
|
486
|
+
checkboxVariants({ state: resolvedState }),
|
|
487
|
+
// 여러 줄 라벨에서 첫 줄 글자와 광학적으로 맞추기 위한 미세 보정(2px)
|
|
488
|
+
"mt-0.5 peer-checked:[&>svg]:opacity-100",
|
|
489
|
+
className
|
|
490
|
+
),
|
|
491
|
+
children: /* @__PURE__ */ jsx(CheckIcon, { className: "text-text-on-brand opacity-0 transition-opacity" })
|
|
492
|
+
}
|
|
493
|
+
),
|
|
494
|
+
label != null && /* @__PURE__ */ jsx("span", { className: "select-none", children: label })
|
|
495
|
+
]
|
|
496
|
+
}
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
);
|
|
500
|
+
Checkbox.displayName = "Checkbox";
|
|
501
|
+
var RadioGroupContext = React16.createContext(
|
|
502
|
+
null
|
|
503
|
+
);
|
|
504
|
+
var RadioGroup = React16.forwardRef(
|
|
505
|
+
({
|
|
506
|
+
className,
|
|
507
|
+
name,
|
|
508
|
+
value,
|
|
509
|
+
defaultValue,
|
|
510
|
+
onValueChange,
|
|
511
|
+
disabled,
|
|
512
|
+
error,
|
|
513
|
+
children,
|
|
514
|
+
...props
|
|
515
|
+
}, ref) => {
|
|
516
|
+
const [internalValue, setInternalValue] = React16.useState(defaultValue);
|
|
517
|
+
const isControlled = value !== void 0;
|
|
518
|
+
const currentValue = isControlled ? value : internalValue;
|
|
519
|
+
const handleValueChange = React16.useCallback(
|
|
520
|
+
(next) => {
|
|
521
|
+
if (!isControlled) setInternalValue(next);
|
|
522
|
+
onValueChange?.(next);
|
|
523
|
+
},
|
|
524
|
+
[isControlled, onValueChange]
|
|
525
|
+
);
|
|
526
|
+
const ctx = React16.useMemo(
|
|
527
|
+
() => ({
|
|
528
|
+
name,
|
|
529
|
+
value: currentValue,
|
|
530
|
+
onValueChange: handleValueChange,
|
|
531
|
+
disabled,
|
|
532
|
+
error
|
|
533
|
+
}),
|
|
534
|
+
[name, currentValue, handleValueChange, disabled, error]
|
|
535
|
+
);
|
|
536
|
+
return /* @__PURE__ */ jsx(RadioGroupContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
|
|
537
|
+
"div",
|
|
538
|
+
{
|
|
539
|
+
ref,
|
|
540
|
+
role: "radiogroup",
|
|
541
|
+
"aria-invalid": error || void 0,
|
|
542
|
+
className: cn("flex flex-col gap-3", className),
|
|
543
|
+
...props,
|
|
544
|
+
children
|
|
545
|
+
}
|
|
546
|
+
) });
|
|
547
|
+
}
|
|
548
|
+
);
|
|
549
|
+
RadioGroup.displayName = "RadioGroup";
|
|
550
|
+
var radioVariants = cva(
|
|
551
|
+
"relative grid h-5 w-5 shrink-0 place-items-center rounded-full border-2 bg-surface-default transition-colors peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-bg-base disabled:cursor-not-allowed",
|
|
552
|
+
{
|
|
553
|
+
variants: {
|
|
554
|
+
state: {
|
|
555
|
+
default: "border-border-strong peer-focus-visible:ring-border-focus peer-checked:border-brand-border",
|
|
556
|
+
error: "border-danger-border peer-focus-visible:ring-danger-solid peer-checked:border-danger-border"
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
defaultVariants: {
|
|
560
|
+
state: "default"
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
);
|
|
564
|
+
var radioDotVariants = cva(
|
|
565
|
+
"h-2 w-2 rounded-full scale-0 transition-transform peer-checked:scale-100",
|
|
566
|
+
{
|
|
567
|
+
variants: {
|
|
568
|
+
state: {
|
|
569
|
+
default: "bg-brand-solid",
|
|
570
|
+
error: "bg-danger-solid"
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
defaultVariants: {
|
|
574
|
+
state: "default"
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
);
|
|
578
|
+
var Radio = React16.forwardRef(
|
|
579
|
+
({
|
|
580
|
+
className,
|
|
581
|
+
id,
|
|
582
|
+
value,
|
|
583
|
+
label,
|
|
584
|
+
description,
|
|
585
|
+
name: nameProp,
|
|
586
|
+
checked: checkedProp,
|
|
587
|
+
disabled: disabledProp,
|
|
588
|
+
error: errorProp,
|
|
589
|
+
onValueChange,
|
|
590
|
+
onChange,
|
|
591
|
+
onClick,
|
|
592
|
+
...props
|
|
593
|
+
}, ref) => {
|
|
594
|
+
const group = React16.useContext(RadioGroupContext);
|
|
595
|
+
const reactId = React16.useId();
|
|
596
|
+
const inputId = id ?? reactId;
|
|
597
|
+
const isGroup = group != null;
|
|
598
|
+
const isControlled = checkedProp !== void 0;
|
|
599
|
+
const [internalChecked, setInternalChecked] = React16.useState(false);
|
|
600
|
+
const name = nameProp ?? group?.name;
|
|
601
|
+
const disabled = disabledProp ?? group?.disabled ?? false;
|
|
602
|
+
const error = errorProp ?? group?.error ?? false;
|
|
603
|
+
const checked = isControlled ? checkedProp : isGroup ? group.value === value : internalChecked;
|
|
604
|
+
const state = error ? "error" : "default";
|
|
605
|
+
const handleChange = (event) => {
|
|
606
|
+
onChange?.(event);
|
|
607
|
+
if (event.target.checked) {
|
|
608
|
+
onValueChange?.(value);
|
|
609
|
+
group?.onValueChange?.(value);
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
const handleClick = (event) => {
|
|
613
|
+
onClick?.(event);
|
|
614
|
+
if (!isControlled && !isGroup) {
|
|
615
|
+
setInternalChecked((prev) => !prev);
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
const control = /* @__PURE__ */ jsxs("span", { className: "relative inline-flex", children: [
|
|
619
|
+
/* @__PURE__ */ jsx(
|
|
620
|
+
"input",
|
|
621
|
+
{
|
|
622
|
+
ref,
|
|
623
|
+
id: inputId,
|
|
624
|
+
type: "radio",
|
|
625
|
+
name,
|
|
626
|
+
value,
|
|
627
|
+
checked,
|
|
628
|
+
disabled,
|
|
629
|
+
"aria-invalid": error || void 0,
|
|
630
|
+
onChange: handleChange,
|
|
631
|
+
onClick: handleClick,
|
|
632
|
+
className: "peer sr-only",
|
|
633
|
+
...props
|
|
634
|
+
}
|
|
635
|
+
),
|
|
636
|
+
/* @__PURE__ */ jsx(
|
|
637
|
+
"span",
|
|
638
|
+
{
|
|
639
|
+
"aria-hidden": "true",
|
|
640
|
+
className: cn(
|
|
641
|
+
radioVariants({ state }),
|
|
642
|
+
disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
|
|
643
|
+
)
|
|
644
|
+
}
|
|
645
|
+
),
|
|
646
|
+
/* @__PURE__ */ jsx(
|
|
647
|
+
"span",
|
|
648
|
+
{
|
|
649
|
+
"aria-hidden": "true",
|
|
650
|
+
className: cn(
|
|
651
|
+
radioDotVariants({ state }),
|
|
652
|
+
"pointer-events-none absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
|
|
653
|
+
disabled && "opacity-50"
|
|
654
|
+
)
|
|
655
|
+
}
|
|
656
|
+
)
|
|
657
|
+
] });
|
|
658
|
+
if (!label && !description) {
|
|
659
|
+
return control;
|
|
660
|
+
}
|
|
661
|
+
return /* @__PURE__ */ jsxs(
|
|
662
|
+
"label",
|
|
663
|
+
{
|
|
664
|
+
htmlFor: inputId,
|
|
665
|
+
className: cn(
|
|
666
|
+
"flex items-start gap-2",
|
|
667
|
+
disabled ? "cursor-not-allowed" : "cursor-pointer",
|
|
668
|
+
className
|
|
669
|
+
),
|
|
670
|
+
children: [
|
|
671
|
+
control,
|
|
672
|
+
/* @__PURE__ */ jsxs("span", { className: "flex flex-col gap-0.5", children: [
|
|
673
|
+
label ? /* @__PURE__ */ jsx(
|
|
674
|
+
"span",
|
|
675
|
+
{
|
|
676
|
+
className: cn(
|
|
677
|
+
"text-sm leading-5",
|
|
678
|
+
disabled ? "text-text-disabled" : "text-text-default"
|
|
679
|
+
),
|
|
680
|
+
children: label
|
|
681
|
+
}
|
|
682
|
+
) : null,
|
|
683
|
+
description ? /* @__PURE__ */ jsx(
|
|
684
|
+
"span",
|
|
685
|
+
{
|
|
686
|
+
className: cn(
|
|
687
|
+
"text-xs leading-4",
|
|
688
|
+
error ? "text-danger-text" : "text-text-subtle"
|
|
689
|
+
),
|
|
690
|
+
children: description
|
|
691
|
+
}
|
|
692
|
+
) : null
|
|
693
|
+
] })
|
|
694
|
+
]
|
|
695
|
+
}
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
);
|
|
699
|
+
Radio.displayName = "Radio";
|
|
700
|
+
var toggleTrackVariants = cva(
|
|
701
|
+
"relative inline-flex shrink-0 cursor-pointer items-center rounded-full p-0.5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base disabled:cursor-not-allowed disabled:opacity-50 data-[state=off]:bg-surface-sunken data-[state=on]:bg-brand-solid",
|
|
702
|
+
{
|
|
703
|
+
variants: {
|
|
704
|
+
size: {
|
|
705
|
+
sm: "h-5 w-9",
|
|
706
|
+
md: "h-6 w-11"
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
defaultVariants: {
|
|
710
|
+
size: "md"
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
);
|
|
714
|
+
var toggleThumbVariants = cva(
|
|
715
|
+
"pointer-events-none block rounded-full bg-surface-default shadow-sm transition-transform data-[state=off]:translate-x-0",
|
|
716
|
+
{
|
|
717
|
+
variants: {
|
|
718
|
+
size: {
|
|
719
|
+
sm: "h-4 w-4 data-[state=on]:translate-x-4",
|
|
720
|
+
md: "h-5 w-5 data-[state=on]:translate-x-5"
|
|
721
|
+
}
|
|
722
|
+
},
|
|
723
|
+
defaultVariants: {
|
|
724
|
+
size: "md"
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
);
|
|
728
|
+
var Toggle = React16.forwardRef(
|
|
729
|
+
({
|
|
730
|
+
className,
|
|
731
|
+
size,
|
|
732
|
+
checked,
|
|
733
|
+
defaultChecked = false,
|
|
734
|
+
onCheckedChange,
|
|
735
|
+
disabled,
|
|
736
|
+
onClick,
|
|
737
|
+
...props
|
|
738
|
+
}, ref) => {
|
|
739
|
+
const isControlled = checked !== void 0;
|
|
740
|
+
const [internalChecked, setInternalChecked] = React16.useState(defaultChecked);
|
|
741
|
+
const isOn = isControlled ? checked : internalChecked;
|
|
742
|
+
const state = isOn ? "on" : "off";
|
|
743
|
+
const handleClick = (event) => {
|
|
744
|
+
onClick?.(event);
|
|
745
|
+
if (event.defaultPrevented || disabled) return;
|
|
746
|
+
const next = !isOn;
|
|
747
|
+
if (!isControlled) setInternalChecked(next);
|
|
748
|
+
onCheckedChange?.(next);
|
|
749
|
+
};
|
|
750
|
+
return /* @__PURE__ */ jsx(
|
|
751
|
+
"button",
|
|
752
|
+
{
|
|
753
|
+
ref,
|
|
754
|
+
type: "button",
|
|
755
|
+
role: "switch",
|
|
756
|
+
"aria-checked": isOn,
|
|
757
|
+
"data-state": state,
|
|
758
|
+
disabled,
|
|
759
|
+
onClick: handleClick,
|
|
760
|
+
className: cn(toggleTrackVariants({ size, className })),
|
|
761
|
+
...props,
|
|
762
|
+
children: /* @__PURE__ */ jsx("span", { "data-state": state, className: cn(toggleThumbVariants({ size })) })
|
|
763
|
+
}
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
);
|
|
767
|
+
Toggle.displayName = "Toggle";
|
|
768
|
+
var chipVariants = cva(
|
|
769
|
+
"inline-flex h-8 items-center gap-1 rounded border px-3 text-sm font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
770
|
+
{
|
|
771
|
+
variants: {
|
|
772
|
+
variant: {
|
|
773
|
+
default: "border-border-default bg-surface-default text-text-default hover:bg-surface-hover active:bg-surface-pressed",
|
|
774
|
+
selected: "border-brand-border bg-brand-subtle text-brand-text font-bold hover:bg-brand-subtle active:bg-brand-subtle"
|
|
775
|
+
}
|
|
776
|
+
},
|
|
777
|
+
defaultVariants: {
|
|
778
|
+
variant: "default"
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
);
|
|
782
|
+
var CheckIcon2 = () => /* @__PURE__ */ jsx(
|
|
783
|
+
"svg",
|
|
784
|
+
{
|
|
785
|
+
viewBox: "0 0 16 16",
|
|
786
|
+
fill: "none",
|
|
787
|
+
stroke: "currentColor",
|
|
788
|
+
strokeWidth: "2",
|
|
789
|
+
strokeLinecap: "round",
|
|
790
|
+
strokeLinejoin: "round",
|
|
791
|
+
"aria-hidden": "true",
|
|
792
|
+
children: /* @__PURE__ */ jsx("path", { d: "M13 4.5 6.5 11.5 3 8" })
|
|
793
|
+
}
|
|
794
|
+
);
|
|
795
|
+
var CloseIcon = () => /* @__PURE__ */ jsx(
|
|
796
|
+
"svg",
|
|
797
|
+
{
|
|
798
|
+
viewBox: "0 0 16 16",
|
|
799
|
+
fill: "none",
|
|
800
|
+
stroke: "currentColor",
|
|
801
|
+
strokeWidth: "2",
|
|
802
|
+
strokeLinecap: "round",
|
|
803
|
+
strokeLinejoin: "round",
|
|
804
|
+
"aria-hidden": "true",
|
|
805
|
+
children: /* @__PURE__ */ jsx("path", { d: "M4 4l8 8M12 4l-8 8" })
|
|
806
|
+
}
|
|
807
|
+
);
|
|
808
|
+
var Chip = React16.forwardRef(
|
|
809
|
+
({
|
|
810
|
+
className,
|
|
811
|
+
variant,
|
|
812
|
+
showSelectedIcon = false,
|
|
813
|
+
removable = false,
|
|
814
|
+
onRemove,
|
|
815
|
+
removeLabel = "Remove",
|
|
816
|
+
children,
|
|
817
|
+
disabled,
|
|
818
|
+
...props
|
|
819
|
+
}, ref) => {
|
|
820
|
+
return /* @__PURE__ */ jsxs(
|
|
821
|
+
"button",
|
|
822
|
+
{
|
|
823
|
+
type: "button",
|
|
824
|
+
ref,
|
|
825
|
+
disabled,
|
|
826
|
+
"aria-pressed": variant === "selected",
|
|
827
|
+
className: cn(chipVariants({ variant }), removable && "pr-2", className),
|
|
828
|
+
...props,
|
|
829
|
+
children: [
|
|
830
|
+
showSelectedIcon && variant === "selected" ? /* @__PURE__ */ jsx(CheckIcon2, {}) : null,
|
|
831
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children }),
|
|
832
|
+
removable ? /* @__PURE__ */ jsx(
|
|
833
|
+
"span",
|
|
834
|
+
{
|
|
835
|
+
role: "button",
|
|
836
|
+
"aria-label": removeLabel,
|
|
837
|
+
tabIndex: disabled ? -1 : 0,
|
|
838
|
+
onClick: (e) => {
|
|
839
|
+
e.stopPropagation();
|
|
840
|
+
if (!disabled) onRemove?.();
|
|
841
|
+
},
|
|
842
|
+
onKeyDown: (e) => {
|
|
843
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
844
|
+
e.preventDefault();
|
|
845
|
+
e.stopPropagation();
|
|
846
|
+
if (!disabled) onRemove?.();
|
|
847
|
+
}
|
|
848
|
+
},
|
|
849
|
+
className: "-mr-1 ml-0.5 inline-flex size-4 items-center justify-center rounded-full text-text-subtle transition-colors hover:bg-surface-hover hover:text-text-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base",
|
|
850
|
+
children: /* @__PURE__ */ jsx(CloseIcon, {})
|
|
851
|
+
}
|
|
852
|
+
) : null
|
|
853
|
+
]
|
|
854
|
+
}
|
|
855
|
+
);
|
|
856
|
+
}
|
|
857
|
+
);
|
|
858
|
+
Chip.displayName = "Chip";
|
|
859
|
+
var alertVariants = cva(
|
|
860
|
+
"relative flex gap-3 rounded-lg border p-3 [&>svg]:size-5 [&>svg]:shrink-0 [&>svg]:mt-0.5",
|
|
861
|
+
{
|
|
862
|
+
variants: {
|
|
863
|
+
variant: {
|
|
864
|
+
info: "bg-surface-sunken border-border-default text-text-default [&>svg]:text-text-subtle",
|
|
865
|
+
danger: "bg-danger-subtle border-danger-border text-danger-text [&>svg]:text-danger-text"
|
|
866
|
+
}
|
|
867
|
+
},
|
|
868
|
+
defaultVariants: {
|
|
869
|
+
variant: "info"
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
);
|
|
873
|
+
var Alert = React16.forwardRef(
|
|
874
|
+
({ className, variant, role = "alert", ...props }, ref) => /* @__PURE__ */ jsx(
|
|
875
|
+
"div",
|
|
876
|
+
{
|
|
877
|
+
ref,
|
|
878
|
+
role,
|
|
879
|
+
className: cn(alertVariants({ variant, className })),
|
|
880
|
+
...props
|
|
881
|
+
}
|
|
882
|
+
)
|
|
883
|
+
);
|
|
884
|
+
Alert.displayName = "Alert";
|
|
885
|
+
var AlertTitle = React16.forwardRef(
|
|
886
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
887
|
+
"p",
|
|
888
|
+
{
|
|
889
|
+
ref,
|
|
890
|
+
className: cn(
|
|
891
|
+
"text-sm font-semibold leading-5 text-text-strong",
|
|
892
|
+
className
|
|
893
|
+
),
|
|
894
|
+
...props
|
|
895
|
+
}
|
|
896
|
+
)
|
|
897
|
+
);
|
|
898
|
+
AlertTitle.displayName = "AlertTitle";
|
|
899
|
+
var AlertDescription = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
900
|
+
"p",
|
|
901
|
+
{
|
|
902
|
+
ref,
|
|
903
|
+
className: cn("mt-1 text-sm leading-5 [&_p]:leading-5", className),
|
|
904
|
+
...props
|
|
905
|
+
}
|
|
906
|
+
));
|
|
907
|
+
AlertDescription.displayName = "AlertDescription";
|
|
908
|
+
var SIZE_PX = { sm: 12, md: 16, lg: 20 };
|
|
909
|
+
var PRESENCE_LABEL = {
|
|
910
|
+
online: "\uC628\uB77C\uC778",
|
|
911
|
+
away: "\uC790\uB9AC\uBE44\uC6C0",
|
|
912
|
+
offline: "\uC624\uD504\uB77C\uC778",
|
|
913
|
+
remote: "\uC7AC\uD0DD"
|
|
914
|
+
};
|
|
915
|
+
function HouseMark({ px }) {
|
|
916
|
+
const s = Math.round(px * 0.64);
|
|
917
|
+
return /* @__PURE__ */ jsx(
|
|
918
|
+
"svg",
|
|
919
|
+
{
|
|
920
|
+
width: s,
|
|
921
|
+
height: s,
|
|
922
|
+
viewBox: "0 0 24 24",
|
|
923
|
+
fill: "currentColor",
|
|
924
|
+
"aria-hidden": true,
|
|
925
|
+
children: /* @__PURE__ */ jsx("path", { d: "M12 3 4 9v12h5v-7h6v7h5V9z" })
|
|
926
|
+
}
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
function Presence({
|
|
930
|
+
status = "online",
|
|
931
|
+
size = "md",
|
|
932
|
+
className,
|
|
933
|
+
...props
|
|
934
|
+
}) {
|
|
935
|
+
const px = SIZE_PX[size];
|
|
936
|
+
const label = PRESENCE_LABEL[status];
|
|
937
|
+
const base = "inline-flex shrink-0 items-center justify-center rounded-full font-extrabold leading-none";
|
|
938
|
+
const STATUS_STYLE = {
|
|
939
|
+
online: "bg-brand-solid text-text-on-brand",
|
|
940
|
+
away: "bg-presence-away-bg text-presence-away-fg",
|
|
941
|
+
offline: "bg-presence-offline",
|
|
942
|
+
remote: "bg-brand-solid text-text-on-brand"
|
|
943
|
+
};
|
|
944
|
+
return /* @__PURE__ */ jsxs(
|
|
945
|
+
"span",
|
|
946
|
+
{
|
|
947
|
+
role: "img",
|
|
948
|
+
"aria-label": label,
|
|
949
|
+
title: label,
|
|
950
|
+
className: cn(base, STATUS_STYLE[status], className),
|
|
951
|
+
style: { width: px, height: px, fontSize: Math.round(px * 0.58) },
|
|
952
|
+
...props,
|
|
953
|
+
children: [
|
|
954
|
+
status === "away" && "Z",
|
|
955
|
+
status === "remote" && /* @__PURE__ */ jsx(HouseMark, { px })
|
|
956
|
+
]
|
|
957
|
+
}
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
var avatarVariants = cva(
|
|
961
|
+
"relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-surface-sunken align-middle ring-2 ring-border-subtle select-none",
|
|
962
|
+
{
|
|
963
|
+
variants: {
|
|
964
|
+
size: {
|
|
965
|
+
xs: "h-6 w-6 text-[10px]",
|
|
966
|
+
// 24px
|
|
967
|
+
sm: "h-8 w-8 text-sm",
|
|
968
|
+
// 32px · font14 기본
|
|
969
|
+
md: "h-10 w-10 text-base",
|
|
970
|
+
// 40px
|
|
971
|
+
lg: "h-12 w-12 text-lg",
|
|
972
|
+
// 48px
|
|
973
|
+
xl: "h-16 w-16 text-2xl"
|
|
974
|
+
// 64px
|
|
975
|
+
}
|
|
976
|
+
},
|
|
977
|
+
defaultVariants: {
|
|
978
|
+
size: "sm"
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
);
|
|
982
|
+
var presenceSizeForAvatar = {
|
|
983
|
+
xs: "sm",
|
|
984
|
+
sm: "sm",
|
|
985
|
+
md: "md",
|
|
986
|
+
lg: "md",
|
|
987
|
+
xl: "lg"
|
|
988
|
+
};
|
|
989
|
+
var MASCOTS = {};
|
|
990
|
+
try {
|
|
991
|
+
MASCOTS = import.meta.glob(
|
|
992
|
+
"../../design-system/avatars/avatar-mascot-*.svg",
|
|
993
|
+
{ query: "?url", import: "default", eager: true }
|
|
994
|
+
);
|
|
995
|
+
} catch {
|
|
996
|
+
MASCOTS = {};
|
|
997
|
+
}
|
|
998
|
+
var MASCOT_BY_COLOR = {};
|
|
999
|
+
for (const [path, url] of Object.entries(MASCOTS)) {
|
|
1000
|
+
const m = path.match(/avatar-mascot-([a-z]+)\.svg$/);
|
|
1001
|
+
if (m) MASCOT_BY_COLOR[m[1]] = url;
|
|
1002
|
+
}
|
|
1003
|
+
var AVATAR_COLORS = Object.keys(
|
|
1004
|
+
MASCOT_BY_COLOR
|
|
1005
|
+
).sort();
|
|
1006
|
+
function defaultColor(seed) {
|
|
1007
|
+
if (AVATAR_COLORS.length === 0) return "gray";
|
|
1008
|
+
const s = seed ?? "";
|
|
1009
|
+
let h = 0;
|
|
1010
|
+
for (let i = 0; i < s.length; i++) h = h * 31 + s.charCodeAt(i) >>> 0;
|
|
1011
|
+
return AVATAR_COLORS[h % AVATAR_COLORS.length];
|
|
1012
|
+
}
|
|
1013
|
+
function mascotUrl(color, seed) {
|
|
1014
|
+
const c = color ?? defaultColor(seed);
|
|
1015
|
+
return MASCOT_BY_COLOR[c] ?? MASCOT_BY_COLOR[AVATAR_COLORS[0]] ?? "";
|
|
1016
|
+
}
|
|
1017
|
+
function MascotImage({
|
|
1018
|
+
color,
|
|
1019
|
+
seed,
|
|
1020
|
+
alt
|
|
1021
|
+
}) {
|
|
1022
|
+
return /* @__PURE__ */ jsx(
|
|
1023
|
+
"img",
|
|
1024
|
+
{
|
|
1025
|
+
src: mascotUrl(color, seed),
|
|
1026
|
+
alt: alt ?? "",
|
|
1027
|
+
"aria-hidden": alt ? void 0 : true,
|
|
1028
|
+
className: "h-full w-full object-cover"
|
|
1029
|
+
}
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
var Avatar = React16.forwardRef(
|
|
1033
|
+
({ className, size = "sm", src, alt, color, presence, children, ...props }, ref) => {
|
|
1034
|
+
const resolvedSize = size ?? "sm";
|
|
1035
|
+
return (
|
|
1036
|
+
// presence badge가 원 밖으로 걸치도록 wrapper(relative)에 이미지 원 + badge를 형제로 배치.
|
|
1037
|
+
/* @__PURE__ */ jsxs(
|
|
1038
|
+
"span",
|
|
1039
|
+
{
|
|
1040
|
+
ref,
|
|
1041
|
+
className: cn("relative inline-flex shrink-0 align-middle", className),
|
|
1042
|
+
...props,
|
|
1043
|
+
children: [
|
|
1044
|
+
/* @__PURE__ */ jsx(
|
|
1045
|
+
"span",
|
|
1046
|
+
{
|
|
1047
|
+
className: cn(
|
|
1048
|
+
avatarVariants({ size }),
|
|
1049
|
+
// 가이드: 오프라인이면 아바타를 흐리게(opacity .55)
|
|
1050
|
+
presence === "offline" && "opacity-[.55]"
|
|
1051
|
+
),
|
|
1052
|
+
children: children ?? (src ? /* @__PURE__ */ jsx(AvatarImage, { src, alt, color, seed: alt }) : (
|
|
1053
|
+
// 기본: 무조건 마스코트 이미지. color 선택 시 그 색, 없으면 이름 기반 기본값.
|
|
1054
|
+
/* @__PURE__ */ jsx(MascotImage, { color, seed: alt, alt })
|
|
1055
|
+
))
|
|
1056
|
+
}
|
|
1057
|
+
),
|
|
1058
|
+
presence ? /* @__PURE__ */ jsx(
|
|
1059
|
+
Presence,
|
|
1060
|
+
{
|
|
1061
|
+
status: presence,
|
|
1062
|
+
size: presenceSizeForAvatar[resolvedSize],
|
|
1063
|
+
className: "absolute -bottom-0.5 -right-0.5 ring-2 ring-bg-base"
|
|
1064
|
+
}
|
|
1065
|
+
) : null
|
|
1066
|
+
]
|
|
1067
|
+
}
|
|
1068
|
+
)
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
);
|
|
1072
|
+
Avatar.displayName = "Avatar";
|
|
1073
|
+
var AvatarImage = React16.forwardRef(
|
|
1074
|
+
({ className, alt = "", color, seed, ...props }, ref) => {
|
|
1075
|
+
const [errored, setErrored] = React16.useState(false);
|
|
1076
|
+
if (errored) {
|
|
1077
|
+
return /* @__PURE__ */ jsx(MascotImage, { color, seed: seed ?? alt, alt });
|
|
1078
|
+
}
|
|
1079
|
+
return /* @__PURE__ */ jsx(
|
|
1080
|
+
"img",
|
|
1081
|
+
{
|
|
1082
|
+
ref,
|
|
1083
|
+
alt,
|
|
1084
|
+
className: cn("h-full w-full object-cover", className),
|
|
1085
|
+
onError: () => setErrored(true),
|
|
1086
|
+
...props
|
|
1087
|
+
}
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
);
|
|
1091
|
+
AvatarImage.displayName = "AvatarImage";
|
|
1092
|
+
var AvatarFallback = React16.forwardRef(
|
|
1093
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1094
|
+
"span",
|
|
1095
|
+
{
|
|
1096
|
+
ref,
|
|
1097
|
+
className: cn(
|
|
1098
|
+
"flex h-full w-full items-center justify-center bg-surface-sunken font-medium text-text-subtle",
|
|
1099
|
+
className
|
|
1100
|
+
),
|
|
1101
|
+
...props
|
|
1102
|
+
}
|
|
1103
|
+
)
|
|
1104
|
+
);
|
|
1105
|
+
AvatarFallback.displayName = "AvatarFallback";
|
|
1106
|
+
var AvatarGroup = React16.forwardRef(
|
|
1107
|
+
({ className, children, max, size = "sm", ...props }, ref) => {
|
|
1108
|
+
const items = React16.Children.toArray(children).filter(React16.isValidElement);
|
|
1109
|
+
const visible = typeof max === "number" ? items.slice(0, max) : items;
|
|
1110
|
+
const overflow = items.length - visible.length;
|
|
1111
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: cn("flex items-center", className), ...props, children: [
|
|
1112
|
+
visible.map((child, i) => /* @__PURE__ */ jsx("span", { className: i === 0 ? "" : "-ml-2", children: child }, i)),
|
|
1113
|
+
overflow > 0 ? /* @__PURE__ */ jsxs(
|
|
1114
|
+
"span",
|
|
1115
|
+
{
|
|
1116
|
+
className: cn(
|
|
1117
|
+
avatarVariants({ size }),
|
|
1118
|
+
"-ml-2 font-medium text-text-subtle"
|
|
1119
|
+
),
|
|
1120
|
+
"aria-label": `\uC678 ${overflow}\uBA85`,
|
|
1121
|
+
title: `\uC678 ${overflow}\uBA85`,
|
|
1122
|
+
children: [
|
|
1123
|
+
"+",
|
|
1124
|
+
overflow
|
|
1125
|
+
]
|
|
1126
|
+
}
|
|
1127
|
+
) : null
|
|
1128
|
+
] });
|
|
1129
|
+
}
|
|
1130
|
+
);
|
|
1131
|
+
AvatarGroup.displayName = "AvatarGroup";
|
|
1132
|
+
var tooltipContentVariants = cva(
|
|
1133
|
+
"pointer-events-none absolute z-50 w-max max-w-xs whitespace-normal rounded bg-[var(--comp-tooltip-bg)] px-2 py-1 text-xs font-medium text-[var(--comp-tooltip-text)] shadow-popover",
|
|
1134
|
+
{
|
|
1135
|
+
variants: {
|
|
1136
|
+
placement: {
|
|
1137
|
+
top: "bottom-full left-1/2 mb-2 -translate-x-1/2",
|
|
1138
|
+
"top-left": "bottom-full left-0 mb-2",
|
|
1139
|
+
"top-right": "bottom-full right-0 mb-2",
|
|
1140
|
+
right: "left-full top-1/2 ml-2 -translate-y-1/2",
|
|
1141
|
+
bottom: "top-full left-1/2 mt-2 -translate-x-1/2",
|
|
1142
|
+
"bottom-left": "top-full left-0 mt-2",
|
|
1143
|
+
"bottom-right": "top-full right-0 mt-2",
|
|
1144
|
+
left: "right-full top-1/2 mr-2 -translate-y-1/2"
|
|
1145
|
+
}
|
|
1146
|
+
},
|
|
1147
|
+
defaultVariants: {
|
|
1148
|
+
placement: "top"
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
);
|
|
1152
|
+
var tooltipArrowVariants = cva(
|
|
1153
|
+
"pointer-events-none absolute z-50 h-2 w-2 rotate-45 bg-[var(--comp-tooltip-bg)]",
|
|
1154
|
+
{
|
|
1155
|
+
variants: {
|
|
1156
|
+
placement: {
|
|
1157
|
+
top: "bottom-full left-1/2 -translate-x-1/2 mb-[5px]",
|
|
1158
|
+
"top-left": "bottom-full left-1/2 -translate-x-1/2 mb-[5px]",
|
|
1159
|
+
"top-right": "bottom-full left-1/2 -translate-x-1/2 mb-[5px]",
|
|
1160
|
+
right: "left-full top-1/2 -translate-y-1/2 ml-[5px]",
|
|
1161
|
+
bottom: "top-full left-1/2 -translate-x-1/2 mt-[5px]",
|
|
1162
|
+
"bottom-left": "top-full left-1/2 -translate-x-1/2 mt-[5px]",
|
|
1163
|
+
"bottom-right": "top-full left-1/2 -translate-x-1/2 mt-[5px]",
|
|
1164
|
+
left: "right-full top-1/2 -translate-y-1/2 mr-[5px]"
|
|
1165
|
+
}
|
|
1166
|
+
},
|
|
1167
|
+
defaultVariants: {
|
|
1168
|
+
placement: "top"
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
);
|
|
1172
|
+
var Tooltip = React16.forwardRef(
|
|
1173
|
+
({
|
|
1174
|
+
className,
|
|
1175
|
+
content,
|
|
1176
|
+
children,
|
|
1177
|
+
placement = "top",
|
|
1178
|
+
open,
|
|
1179
|
+
arrow = true,
|
|
1180
|
+
disabled = false,
|
|
1181
|
+
...props
|
|
1182
|
+
}, ref) => {
|
|
1183
|
+
const [hovered, setHovered] = React16.useState(false);
|
|
1184
|
+
const isControlled = open !== void 0;
|
|
1185
|
+
const visible = !disabled && (isControlled ? open : hovered);
|
|
1186
|
+
const tooltipId = React16.useId();
|
|
1187
|
+
return /* @__PURE__ */ jsxs(
|
|
1188
|
+
"div",
|
|
1189
|
+
{
|
|
1190
|
+
ref,
|
|
1191
|
+
className: cn("relative inline-flex", className),
|
|
1192
|
+
onMouseEnter: isControlled ? void 0 : () => setHovered(true),
|
|
1193
|
+
onMouseLeave: isControlled ? void 0 : () => setHovered(false),
|
|
1194
|
+
onFocus: isControlled ? void 0 : () => setHovered(true),
|
|
1195
|
+
onBlur: isControlled ? void 0 : () => setHovered(false),
|
|
1196
|
+
...props,
|
|
1197
|
+
children: [
|
|
1198
|
+
/* @__PURE__ */ jsx("span", { "aria-describedby": visible ? tooltipId : void 0, children }),
|
|
1199
|
+
/* @__PURE__ */ jsx(
|
|
1200
|
+
"div",
|
|
1201
|
+
{
|
|
1202
|
+
id: tooltipId,
|
|
1203
|
+
role: "tooltip",
|
|
1204
|
+
"aria-hidden": !visible,
|
|
1205
|
+
className: cn(
|
|
1206
|
+
tooltipContentVariants({ placement }),
|
|
1207
|
+
"transition-opacity duration-150",
|
|
1208
|
+
visible ? "opacity-100" : "opacity-0"
|
|
1209
|
+
),
|
|
1210
|
+
children: content
|
|
1211
|
+
}
|
|
1212
|
+
),
|
|
1213
|
+
arrow ? /* @__PURE__ */ jsx(
|
|
1214
|
+
"span",
|
|
1215
|
+
{
|
|
1216
|
+
"aria-hidden": true,
|
|
1217
|
+
className: cn(
|
|
1218
|
+
tooltipArrowVariants({ placement }),
|
|
1219
|
+
"transition-opacity duration-150",
|
|
1220
|
+
visible ? "opacity-100" : "opacity-0"
|
|
1221
|
+
)
|
|
1222
|
+
}
|
|
1223
|
+
) : null
|
|
1224
|
+
]
|
|
1225
|
+
}
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
);
|
|
1229
|
+
Tooltip.displayName = "Tooltip";
|
|
1230
|
+
var DropdownMenuContext = React16.createContext(null);
|
|
1231
|
+
function useDropdownMenuContext(component) {
|
|
1232
|
+
const ctx = React16.useContext(DropdownMenuContext);
|
|
1233
|
+
if (!ctx) {
|
|
1234
|
+
throw new Error(`${component} must be used within <DropdownMenu>`);
|
|
1235
|
+
}
|
|
1236
|
+
return ctx;
|
|
1237
|
+
}
|
|
1238
|
+
var DropdownMenu = React16.forwardRef(
|
|
1239
|
+
({ className, open: openProp, defaultOpen = false, onOpenChange, ...props }, ref) => {
|
|
1240
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React16.useState(defaultOpen);
|
|
1241
|
+
const isControlled = openProp !== void 0;
|
|
1242
|
+
const open = isControlled ? openProp : uncontrolledOpen;
|
|
1243
|
+
const setOpen = React16.useCallback(
|
|
1244
|
+
(value) => {
|
|
1245
|
+
const next = typeof value === "function" ? value(open) : value;
|
|
1246
|
+
if (!isControlled) setUncontrolledOpen(next);
|
|
1247
|
+
onOpenChange?.(next);
|
|
1248
|
+
},
|
|
1249
|
+
[isControlled, onOpenChange, open]
|
|
1250
|
+
);
|
|
1251
|
+
const ctx = React16.useMemo(() => ({ open, setOpen }), [open, setOpen]);
|
|
1252
|
+
return /* @__PURE__ */ jsx(DropdownMenuContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
|
|
1253
|
+
"div",
|
|
1254
|
+
{
|
|
1255
|
+
ref,
|
|
1256
|
+
className: cn("relative inline-block text-left", className),
|
|
1257
|
+
...props
|
|
1258
|
+
}
|
|
1259
|
+
) });
|
|
1260
|
+
}
|
|
1261
|
+
);
|
|
1262
|
+
DropdownMenu.displayName = "DropdownMenu";
|
|
1263
|
+
var DropdownMenuTrigger = React16.forwardRef(({ className, onClick, disabled, ...props }, ref) => {
|
|
1264
|
+
const { open, setOpen } = useDropdownMenuContext("DropdownMenuTrigger");
|
|
1265
|
+
return /* @__PURE__ */ jsx(
|
|
1266
|
+
"button",
|
|
1267
|
+
{
|
|
1268
|
+
ref,
|
|
1269
|
+
type: "button",
|
|
1270
|
+
"aria-haspopup": "menu",
|
|
1271
|
+
"aria-expanded": open,
|
|
1272
|
+
disabled,
|
|
1273
|
+
onClick: (event) => {
|
|
1274
|
+
onClick?.(event);
|
|
1275
|
+
if (!event.defaultPrevented) setOpen((prev) => !prev);
|
|
1276
|
+
},
|
|
1277
|
+
className: cn(
|
|
1278
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded border border-border-default bg-surface-default px-4 py-2 text-sm font-medium text-text-default transition-colors hover:bg-surface-hover active:bg-surface-pressed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
1279
|
+
className
|
|
1280
|
+
),
|
|
1281
|
+
...props
|
|
1282
|
+
}
|
|
1283
|
+
);
|
|
1284
|
+
});
|
|
1285
|
+
DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
|
|
1286
|
+
var dropdownMenuContentVariants = cva(
|
|
1287
|
+
// panel padding 4 · radius sm(8) · min-w 180 · shadow-dropdown
|
|
1288
|
+
"z-50 min-w-[180px] rounded-lg border border-border-subtle bg-surface-raised p-1 shadow-dropdown outline-none",
|
|
1289
|
+
{
|
|
1290
|
+
variants: {
|
|
1291
|
+
align: {
|
|
1292
|
+
start: "left-0",
|
|
1293
|
+
end: "right-0"
|
|
1294
|
+
}
|
|
1295
|
+
},
|
|
1296
|
+
defaultVariants: {
|
|
1297
|
+
align: "start"
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
);
|
|
1301
|
+
var DropdownMenuContent = React16.forwardRef(({ className, align, forceMount = false, ...props }, ref) => {
|
|
1302
|
+
const { open } = useDropdownMenuContext("DropdownMenuContent");
|
|
1303
|
+
if (!open && !forceMount) return null;
|
|
1304
|
+
return /* @__PURE__ */ jsx(
|
|
1305
|
+
"div",
|
|
1306
|
+
{
|
|
1307
|
+
ref,
|
|
1308
|
+
role: "menu",
|
|
1309
|
+
"aria-orientation": "vertical",
|
|
1310
|
+
className: cn(
|
|
1311
|
+
"absolute top-[calc(100%+4px)]",
|
|
1312
|
+
dropdownMenuContentVariants({ align, className })
|
|
1313
|
+
),
|
|
1314
|
+
...props
|
|
1315
|
+
}
|
|
1316
|
+
);
|
|
1317
|
+
});
|
|
1318
|
+
DropdownMenuContent.displayName = "DropdownMenuContent";
|
|
1319
|
+
var dropdownMenuItemVariants = cva(
|
|
1320
|
+
// item px12 py8 · item radius xs(4) · hover bg-surface-hover
|
|
1321
|
+
"relative flex w-full cursor-pointer select-none items-center gap-2 rounded px-3 py-2 text-sm text-text-default outline-none transition-colors hover:bg-surface-hover focus-visible:bg-surface-hover focus-visible:outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:text-text-disabled data-[disabled=true]:opacity-60 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
1322
|
+
{
|
|
1323
|
+
variants: {
|
|
1324
|
+
variant: {
|
|
1325
|
+
default: "",
|
|
1326
|
+
danger: "text-danger-text hover:bg-danger-subtle focus-visible:bg-danger-subtle"
|
|
1327
|
+
}
|
|
1328
|
+
},
|
|
1329
|
+
defaultVariants: {
|
|
1330
|
+
variant: "default"
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
);
|
|
1334
|
+
var DropdownMenuItem = React16.forwardRef(
|
|
1335
|
+
({
|
|
1336
|
+
className,
|
|
1337
|
+
variant,
|
|
1338
|
+
disabled = false,
|
|
1339
|
+
icon,
|
|
1340
|
+
trailing,
|
|
1341
|
+
children,
|
|
1342
|
+
...props
|
|
1343
|
+
}, ref) => {
|
|
1344
|
+
return /* @__PURE__ */ jsxs(
|
|
1345
|
+
"button",
|
|
1346
|
+
{
|
|
1347
|
+
ref,
|
|
1348
|
+
type: "button",
|
|
1349
|
+
role: "menuitem",
|
|
1350
|
+
"aria-disabled": disabled || void 0,
|
|
1351
|
+
"data-disabled": disabled,
|
|
1352
|
+
tabIndex: disabled ? -1 : 0,
|
|
1353
|
+
className: cn(dropdownMenuItemVariants({ variant, className })),
|
|
1354
|
+
...props,
|
|
1355
|
+
children: [
|
|
1356
|
+
icon ? /* @__PURE__ */ jsx("span", { className: "shrink-0", children: icon }) : null,
|
|
1357
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-left", children }),
|
|
1358
|
+
trailing ? /* @__PURE__ */ jsx("span", { className: "ml-auto shrink-0 text-xs text-text-subtle", children: trailing }) : null
|
|
1359
|
+
]
|
|
1360
|
+
}
|
|
1361
|
+
);
|
|
1362
|
+
}
|
|
1363
|
+
);
|
|
1364
|
+
DropdownMenuItem.displayName = "DropdownMenuItem";
|
|
1365
|
+
var DropdownMenuLabel = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1366
|
+
"div",
|
|
1367
|
+
{
|
|
1368
|
+
ref,
|
|
1369
|
+
className: cn(
|
|
1370
|
+
"px-3 py-2 text-xs font-semibold uppercase tracking-wide text-text-subtle",
|
|
1371
|
+
className
|
|
1372
|
+
),
|
|
1373
|
+
...props
|
|
1374
|
+
}
|
|
1375
|
+
));
|
|
1376
|
+
DropdownMenuLabel.displayName = "DropdownMenuLabel";
|
|
1377
|
+
var DropdownMenuSeparator = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1378
|
+
"div",
|
|
1379
|
+
{
|
|
1380
|
+
ref,
|
|
1381
|
+
role: "separator",
|
|
1382
|
+
"aria-orientation": "horizontal",
|
|
1383
|
+
className: cn("my-1 h-px bg-border-subtle", className),
|
|
1384
|
+
...props
|
|
1385
|
+
}
|
|
1386
|
+
));
|
|
1387
|
+
DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
|
|
1388
|
+
var DropdownMenuEmpty = React16.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1389
|
+
"div",
|
|
1390
|
+
{
|
|
1391
|
+
ref,
|
|
1392
|
+
className: cn("px-3 py-6 text-center text-sm text-text-subtle", className),
|
|
1393
|
+
...props,
|
|
1394
|
+
children: children ?? "No items"
|
|
1395
|
+
}
|
|
1396
|
+
));
|
|
1397
|
+
DropdownMenuEmpty.displayName = "DropdownMenuEmpty";
|
|
1398
|
+
var selectTriggerVariants = cva(
|
|
1399
|
+
"flex h-10 w-full items-center justify-between gap-2 rounded border bg-surface-default px-3 text-sm text-text-default transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base disabled:cursor-not-allowed disabled:bg-surface-sunken disabled:text-text-disabled",
|
|
1400
|
+
{
|
|
1401
|
+
variants: {
|
|
1402
|
+
state: {
|
|
1403
|
+
default: "border-border-default hover:border-border-strong focus-visible:ring-brand-border",
|
|
1404
|
+
error: "border-danger-border focus-visible:ring-danger-border"
|
|
1405
|
+
}
|
|
1406
|
+
},
|
|
1407
|
+
defaultVariants: {
|
|
1408
|
+
state: "default"
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
);
|
|
1412
|
+
var ChevronIcon = ({ className }) => /* @__PURE__ */ jsx(
|
|
1413
|
+
"svg",
|
|
1414
|
+
{
|
|
1415
|
+
width: 20,
|
|
1416
|
+
height: 20,
|
|
1417
|
+
viewBox: "0 0 20 20",
|
|
1418
|
+
fill: "none",
|
|
1419
|
+
stroke: "currentColor",
|
|
1420
|
+
strokeWidth: 1.5,
|
|
1421
|
+
strokeLinecap: "round",
|
|
1422
|
+
strokeLinejoin: "round",
|
|
1423
|
+
"aria-hidden": "true",
|
|
1424
|
+
className,
|
|
1425
|
+
children: /* @__PURE__ */ jsx("path", { d: "M5 7.5 10 12.5 15 7.5" })
|
|
1426
|
+
}
|
|
1427
|
+
);
|
|
1428
|
+
var CheckIcon3 = ({ className }) => /* @__PURE__ */ jsx(
|
|
1429
|
+
"svg",
|
|
1430
|
+
{
|
|
1431
|
+
width: 20,
|
|
1432
|
+
height: 20,
|
|
1433
|
+
viewBox: "0 0 20 20",
|
|
1434
|
+
fill: "none",
|
|
1435
|
+
stroke: "currentColor",
|
|
1436
|
+
strokeWidth: 1.5,
|
|
1437
|
+
strokeLinecap: "round",
|
|
1438
|
+
strokeLinejoin: "round",
|
|
1439
|
+
"aria-hidden": "true",
|
|
1440
|
+
className,
|
|
1441
|
+
children: /* @__PURE__ */ jsx("path", { d: "m4.5 10.5 3.5 3.5 7.5-8" })
|
|
1442
|
+
}
|
|
1443
|
+
);
|
|
1444
|
+
var Select = React16.forwardRef(
|
|
1445
|
+
({
|
|
1446
|
+
className,
|
|
1447
|
+
state,
|
|
1448
|
+
options,
|
|
1449
|
+
value,
|
|
1450
|
+
placeholder = "\uC120\uD0DD\uD558\uC138\uC694",
|
|
1451
|
+
onValueChange,
|
|
1452
|
+
disabled = false,
|
|
1453
|
+
defaultOpen = false,
|
|
1454
|
+
errorMessageId,
|
|
1455
|
+
"aria-label": ariaLabel,
|
|
1456
|
+
...props
|
|
1457
|
+
}, ref) => {
|
|
1458
|
+
const [open, setOpen] = React16.useState(defaultOpen);
|
|
1459
|
+
const selected = React16.useMemo(
|
|
1460
|
+
() => options.find((o) => o.value === value),
|
|
1461
|
+
[options, value]
|
|
1462
|
+
);
|
|
1463
|
+
const isError = state === "error";
|
|
1464
|
+
const handleSelect = (option) => {
|
|
1465
|
+
if (option.disabled) return;
|
|
1466
|
+
onValueChange?.(option.value);
|
|
1467
|
+
setOpen(false);
|
|
1468
|
+
};
|
|
1469
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: cn("relative w-full", className), ...props, children: [
|
|
1470
|
+
/* @__PURE__ */ jsxs(
|
|
1471
|
+
"button",
|
|
1472
|
+
{
|
|
1473
|
+
type: "button",
|
|
1474
|
+
disabled,
|
|
1475
|
+
"aria-haspopup": "listbox",
|
|
1476
|
+
"aria-expanded": open,
|
|
1477
|
+
"aria-invalid": isError || void 0,
|
|
1478
|
+
"aria-describedby": isError ? errorMessageId : void 0,
|
|
1479
|
+
"aria-label": ariaLabel,
|
|
1480
|
+
onClick: () => setOpen((o) => !o),
|
|
1481
|
+
className: cn(selectTriggerVariants({ state })),
|
|
1482
|
+
children: [
|
|
1483
|
+
/* @__PURE__ */ jsx(
|
|
1484
|
+
"span",
|
|
1485
|
+
{
|
|
1486
|
+
className: cn(
|
|
1487
|
+
"truncate",
|
|
1488
|
+
!selected && "text-text-subtle"
|
|
1489
|
+
),
|
|
1490
|
+
children: selected ? selected.label : placeholder
|
|
1491
|
+
}
|
|
1492
|
+
),
|
|
1493
|
+
/* @__PURE__ */ jsx(
|
|
1494
|
+
ChevronIcon,
|
|
1495
|
+
{
|
|
1496
|
+
className: cn(
|
|
1497
|
+
"shrink-0 text-text-subtle transition-transform",
|
|
1498
|
+
open && "rotate-180"
|
|
1499
|
+
)
|
|
1500
|
+
}
|
|
1501
|
+
)
|
|
1502
|
+
]
|
|
1503
|
+
}
|
|
1504
|
+
),
|
|
1505
|
+
open && !disabled && /* @__PURE__ */ jsxs(
|
|
1506
|
+
"ul",
|
|
1507
|
+
{
|
|
1508
|
+
role: "listbox",
|
|
1509
|
+
"aria-label": ariaLabel,
|
|
1510
|
+
className: "absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded border border-border-subtle bg-surface-raised p-1 shadow-dropdown",
|
|
1511
|
+
children: [
|
|
1512
|
+
options.length === 0 && /* @__PURE__ */ jsx("li", { className: "px-3 py-2 text-sm text-text-subtle", children: "\uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" }),
|
|
1513
|
+
options.map((option) => {
|
|
1514
|
+
const isSelected = option.value === value;
|
|
1515
|
+
return /* @__PURE__ */ jsxs(
|
|
1516
|
+
"li",
|
|
1517
|
+
{
|
|
1518
|
+
role: "option",
|
|
1519
|
+
"aria-selected": isSelected,
|
|
1520
|
+
"aria-disabled": option.disabled || void 0,
|
|
1521
|
+
onClick: () => handleSelect(option),
|
|
1522
|
+
className: cn(
|
|
1523
|
+
"flex items-center justify-between gap-2 rounded px-3 py-2 text-sm text-text-default",
|
|
1524
|
+
option.disabled ? "cursor-not-allowed text-text-disabled" : "cursor-pointer hover:bg-surface-hover active:bg-surface-pressed",
|
|
1525
|
+
isSelected && "bg-brand-subtle text-brand-text"
|
|
1526
|
+
),
|
|
1527
|
+
children: [
|
|
1528
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: option.label }),
|
|
1529
|
+
isSelected && /* @__PURE__ */ jsx(CheckIcon3, { className: "shrink-0 text-brand-text" })
|
|
1530
|
+
]
|
|
1531
|
+
},
|
|
1532
|
+
option.value
|
|
1533
|
+
);
|
|
1534
|
+
})
|
|
1535
|
+
]
|
|
1536
|
+
}
|
|
1537
|
+
)
|
|
1538
|
+
] });
|
|
1539
|
+
}
|
|
1540
|
+
);
|
|
1541
|
+
Select.displayName = "Select";
|
|
1542
|
+
var DialogOverlay = React16.forwardRef(
|
|
1543
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1544
|
+
"div",
|
|
1545
|
+
{
|
|
1546
|
+
ref,
|
|
1547
|
+
className: cn(
|
|
1548
|
+
"absolute inset-0 bg-bg-emphasis/60 backdrop-blur-sm",
|
|
1549
|
+
className
|
|
1550
|
+
),
|
|
1551
|
+
...props
|
|
1552
|
+
}
|
|
1553
|
+
)
|
|
1554
|
+
);
|
|
1555
|
+
DialogOverlay.displayName = "DialogOverlay";
|
|
1556
|
+
var dialogPanelVariants = cva(
|
|
1557
|
+
"relative flex w-full flex-col gap-4 border border-border-subtle bg-surface-raised p-6 pb-4 text-text-default shadow-modal rounded-lg focus-visible:outline-none",
|
|
1558
|
+
{
|
|
1559
|
+
variants: {
|
|
1560
|
+
size: {
|
|
1561
|
+
sm: "min-w-[280px] max-w-[360px]",
|
|
1562
|
+
md: "min-w-[280px] max-w-[480px]",
|
|
1563
|
+
lg: "min-w-[280px] max-w-[640px]"
|
|
1564
|
+
}
|
|
1565
|
+
},
|
|
1566
|
+
defaultVariants: {
|
|
1567
|
+
size: "md"
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
);
|
|
1571
|
+
var Dialog = React16.forwardRef(
|
|
1572
|
+
({
|
|
1573
|
+
open = true,
|
|
1574
|
+
onOpenChange,
|
|
1575
|
+
size,
|
|
1576
|
+
className,
|
|
1577
|
+
overlayClassName,
|
|
1578
|
+
children,
|
|
1579
|
+
...props
|
|
1580
|
+
}, ref) => {
|
|
1581
|
+
if (!open) return null;
|
|
1582
|
+
const handleKeyDown = (event) => {
|
|
1583
|
+
if (event.key === "Escape") onOpenChange?.(false);
|
|
1584
|
+
};
|
|
1585
|
+
return /* @__PURE__ */ jsxs(
|
|
1586
|
+
"div",
|
|
1587
|
+
{
|
|
1588
|
+
className: "absolute inset-0 z-50 flex items-center justify-center p-4",
|
|
1589
|
+
onKeyDown: handleKeyDown,
|
|
1590
|
+
children: [
|
|
1591
|
+
/* @__PURE__ */ jsx(
|
|
1592
|
+
DialogOverlay,
|
|
1593
|
+
{
|
|
1594
|
+
className: overlayClassName,
|
|
1595
|
+
onClick: () => onOpenChange?.(false)
|
|
1596
|
+
}
|
|
1597
|
+
),
|
|
1598
|
+
/* @__PURE__ */ jsx(
|
|
1599
|
+
"div",
|
|
1600
|
+
{
|
|
1601
|
+
ref,
|
|
1602
|
+
role: "dialog",
|
|
1603
|
+
"aria-modal": "true",
|
|
1604
|
+
className: cn(dialogPanelVariants({ size }), className),
|
|
1605
|
+
...props,
|
|
1606
|
+
children
|
|
1607
|
+
}
|
|
1608
|
+
)
|
|
1609
|
+
]
|
|
1610
|
+
}
|
|
1611
|
+
);
|
|
1612
|
+
}
|
|
1613
|
+
);
|
|
1614
|
+
Dialog.displayName = "Dialog";
|
|
1615
|
+
var DialogHeader = React16.forwardRef(
|
|
1616
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1617
|
+
"div",
|
|
1618
|
+
{
|
|
1619
|
+
ref,
|
|
1620
|
+
className: cn("flex flex-col gap-1.5 text-left", className),
|
|
1621
|
+
...props
|
|
1622
|
+
}
|
|
1623
|
+
)
|
|
1624
|
+
);
|
|
1625
|
+
DialogHeader.displayName = "DialogHeader";
|
|
1626
|
+
var DialogTitle = React16.forwardRef(
|
|
1627
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1628
|
+
"h2",
|
|
1629
|
+
{
|
|
1630
|
+
ref,
|
|
1631
|
+
className: cn(
|
|
1632
|
+
"text-base font-semibold leading-tight text-text-strong",
|
|
1633
|
+
className
|
|
1634
|
+
),
|
|
1635
|
+
...props
|
|
1636
|
+
}
|
|
1637
|
+
)
|
|
1638
|
+
);
|
|
1639
|
+
DialogTitle.displayName = "DialogTitle";
|
|
1640
|
+
var DialogDescription = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1641
|
+
"p",
|
|
1642
|
+
{
|
|
1643
|
+
ref,
|
|
1644
|
+
className: cn("text-sm leading-relaxed text-text-subtle", className),
|
|
1645
|
+
...props
|
|
1646
|
+
}
|
|
1647
|
+
));
|
|
1648
|
+
DialogDescription.displayName = "DialogDescription";
|
|
1649
|
+
var DialogBody = React16.forwardRef(
|
|
1650
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1651
|
+
"div",
|
|
1652
|
+
{
|
|
1653
|
+
ref,
|
|
1654
|
+
className: cn("text-sm text-text-default", className),
|
|
1655
|
+
...props
|
|
1656
|
+
}
|
|
1657
|
+
)
|
|
1658
|
+
);
|
|
1659
|
+
DialogBody.displayName = "DialogBody";
|
|
1660
|
+
var DialogFooter = React16.forwardRef(
|
|
1661
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1662
|
+
"div",
|
|
1663
|
+
{
|
|
1664
|
+
ref,
|
|
1665
|
+
className: cn(
|
|
1666
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
1667
|
+
className
|
|
1668
|
+
),
|
|
1669
|
+
...props
|
|
1670
|
+
}
|
|
1671
|
+
)
|
|
1672
|
+
);
|
|
1673
|
+
DialogFooter.displayName = "DialogFooter";
|
|
1674
|
+
var sheetOverlayVariants = cva(
|
|
1675
|
+
"absolute inset-0 bg-[var(--color-overlay-scrim)] transition-opacity duration-200",
|
|
1676
|
+
{
|
|
1677
|
+
variants: {
|
|
1678
|
+
open: {
|
|
1679
|
+
true: "opacity-100",
|
|
1680
|
+
false: "pointer-events-none opacity-0"
|
|
1681
|
+
}
|
|
1682
|
+
},
|
|
1683
|
+
defaultVariants: { open: false }
|
|
1684
|
+
}
|
|
1685
|
+
);
|
|
1686
|
+
var sheetPanelVariants = cva(
|
|
1687
|
+
"absolute flex flex-col gap-4 bg-surface-raised px-5 pb-6 pt-4 text-text-default shadow-modal transition-transform duration-300 ease-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-border focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base",
|
|
1688
|
+
{
|
|
1689
|
+
variants: {
|
|
1690
|
+
side: {
|
|
1691
|
+
bottom: "inset-x-0 bottom-0 rounded-b-none rounded-t-[var(--radius-lg)] data-[state=closed]:translate-y-full",
|
|
1692
|
+
top: "inset-x-0 top-0 rounded-b-[var(--radius-lg)] data-[state=closed]:-translate-y-full",
|
|
1693
|
+
left: "inset-y-0 left-0 h-full w-80 max-w-[85%] rounded-r-[var(--radius-lg)] data-[state=closed]:-translate-x-full",
|
|
1694
|
+
right: "inset-y-0 right-0 h-full w-80 max-w-[85%] rounded-l-[var(--radius-lg)] data-[state=closed]:translate-x-full"
|
|
1695
|
+
}
|
|
1696
|
+
},
|
|
1697
|
+
defaultVariants: { side: "bottom" }
|
|
1698
|
+
}
|
|
1699
|
+
);
|
|
1700
|
+
var Sheet = React16.forwardRef(
|
|
1701
|
+
({
|
|
1702
|
+
className,
|
|
1703
|
+
side = "bottom",
|
|
1704
|
+
open = false,
|
|
1705
|
+
onOpenChange,
|
|
1706
|
+
showHandle = true,
|
|
1707
|
+
children,
|
|
1708
|
+
...props
|
|
1709
|
+
}, ref) => {
|
|
1710
|
+
const state = open ? "open" : "closed";
|
|
1711
|
+
const handleVisible = showHandle && (side === "bottom" || side === "top");
|
|
1712
|
+
return /* @__PURE__ */ jsxs(
|
|
1713
|
+
"div",
|
|
1714
|
+
{
|
|
1715
|
+
className: cn(
|
|
1716
|
+
"pointer-events-none absolute inset-0 overflow-hidden",
|
|
1717
|
+
open && "pointer-events-auto"
|
|
1718
|
+
),
|
|
1719
|
+
"data-state": state,
|
|
1720
|
+
children: [
|
|
1721
|
+
/* @__PURE__ */ jsx(
|
|
1722
|
+
"div",
|
|
1723
|
+
{
|
|
1724
|
+
"aria-hidden": "true",
|
|
1725
|
+
className: sheetOverlayVariants({ open }),
|
|
1726
|
+
onClick: () => onOpenChange?.(false)
|
|
1727
|
+
}
|
|
1728
|
+
),
|
|
1729
|
+
/* @__PURE__ */ jsxs(
|
|
1730
|
+
"div",
|
|
1731
|
+
{
|
|
1732
|
+
ref,
|
|
1733
|
+
role: "dialog",
|
|
1734
|
+
"aria-modal": "true",
|
|
1735
|
+
"aria-hidden": !open,
|
|
1736
|
+
"data-state": state,
|
|
1737
|
+
tabIndex: -1,
|
|
1738
|
+
className: cn(sheetPanelVariants({ side }), className),
|
|
1739
|
+
...props,
|
|
1740
|
+
children: [
|
|
1741
|
+
handleVisible ? /* @__PURE__ */ jsx(SheetHandle, {}) : null,
|
|
1742
|
+
children
|
|
1743
|
+
]
|
|
1744
|
+
}
|
|
1745
|
+
)
|
|
1746
|
+
]
|
|
1747
|
+
}
|
|
1748
|
+
);
|
|
1749
|
+
}
|
|
1750
|
+
);
|
|
1751
|
+
Sheet.displayName = "Sheet";
|
|
1752
|
+
var SheetHandle = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1753
|
+
"div",
|
|
1754
|
+
{
|
|
1755
|
+
ref,
|
|
1756
|
+
"aria-hidden": "true",
|
|
1757
|
+
className: cn(
|
|
1758
|
+
"mx-auto mb-1 h-1 w-10 shrink-0 rounded-full bg-bg-emphasis",
|
|
1759
|
+
className
|
|
1760
|
+
),
|
|
1761
|
+
...props
|
|
1762
|
+
}
|
|
1763
|
+
));
|
|
1764
|
+
SheetHandle.displayName = "SheetHandle";
|
|
1765
|
+
var SheetHeader = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1766
|
+
"div",
|
|
1767
|
+
{
|
|
1768
|
+
ref,
|
|
1769
|
+
className: cn("flex flex-col gap-0.5", className),
|
|
1770
|
+
...props
|
|
1771
|
+
}
|
|
1772
|
+
));
|
|
1773
|
+
SheetHeader.displayName = "SheetHeader";
|
|
1774
|
+
var SheetTitle = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1775
|
+
"h2",
|
|
1776
|
+
{
|
|
1777
|
+
ref,
|
|
1778
|
+
className: cn("text-lg font-semibold text-text-strong", className),
|
|
1779
|
+
...props
|
|
1780
|
+
}
|
|
1781
|
+
));
|
|
1782
|
+
SheetTitle.displayName = "SheetTitle";
|
|
1783
|
+
var SheetDescription = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1784
|
+
"p",
|
|
1785
|
+
{
|
|
1786
|
+
ref,
|
|
1787
|
+
className: cn("text-sm text-text-subtle", className),
|
|
1788
|
+
...props
|
|
1789
|
+
}
|
|
1790
|
+
));
|
|
1791
|
+
SheetDescription.displayName = "SheetDescription";
|
|
1792
|
+
var SheetBody = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1793
|
+
"div",
|
|
1794
|
+
{
|
|
1795
|
+
ref,
|
|
1796
|
+
className: cn("flex flex-1 flex-col gap-4 overflow-y-auto", className),
|
|
1797
|
+
...props
|
|
1798
|
+
}
|
|
1799
|
+
));
|
|
1800
|
+
SheetBody.displayName = "SheetBody";
|
|
1801
|
+
var SheetFooter = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1802
|
+
"div",
|
|
1803
|
+
{
|
|
1804
|
+
ref,
|
|
1805
|
+
className: cn(
|
|
1806
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
1807
|
+
className
|
|
1808
|
+
),
|
|
1809
|
+
...props
|
|
1810
|
+
}
|
|
1811
|
+
));
|
|
1812
|
+
SheetFooter.displayName = "SheetFooter";
|
|
1813
|
+
var TabsContext = React16.createContext(null);
|
|
1814
|
+
function useTabsContext(component) {
|
|
1815
|
+
const ctx = React16.useContext(TabsContext);
|
|
1816
|
+
if (!ctx) {
|
|
1817
|
+
throw new Error(`<${component}> must be used within <Tabs>`);
|
|
1818
|
+
}
|
|
1819
|
+
return ctx;
|
|
1820
|
+
}
|
|
1821
|
+
var Tabs = React16.forwardRef(
|
|
1822
|
+
({ className, value, defaultValue, onValueChange, children, ...props }, ref) => {
|
|
1823
|
+
const baseId = React16.useId();
|
|
1824
|
+
const [internalValue, setInternalValue] = React16.useState(
|
|
1825
|
+
defaultValue ?? ""
|
|
1826
|
+
);
|
|
1827
|
+
const isControlled = value !== void 0;
|
|
1828
|
+
const activeValue = isControlled ? value : internalValue;
|
|
1829
|
+
const setValue = React16.useCallback(
|
|
1830
|
+
(next) => {
|
|
1831
|
+
if (!isControlled) setInternalValue(next);
|
|
1832
|
+
onValueChange?.(next);
|
|
1833
|
+
},
|
|
1834
|
+
[isControlled, onValueChange]
|
|
1835
|
+
);
|
|
1836
|
+
const ctx = React16.useMemo(
|
|
1837
|
+
() => ({ value: activeValue, setValue, baseId }),
|
|
1838
|
+
[activeValue, setValue, baseId]
|
|
1839
|
+
);
|
|
1840
|
+
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col gap-4", className), ...props, children }) });
|
|
1841
|
+
}
|
|
1842
|
+
);
|
|
1843
|
+
Tabs.displayName = "Tabs";
|
|
1844
|
+
var tabsListVariants = cva(
|
|
1845
|
+
"relative flex items-center border-b border-border-subtle",
|
|
1846
|
+
{
|
|
1847
|
+
variants: {
|
|
1848
|
+
fullWidth: {
|
|
1849
|
+
true: "w-full",
|
|
1850
|
+
false: "w-fit"
|
|
1851
|
+
}
|
|
1852
|
+
},
|
|
1853
|
+
defaultVariants: {
|
|
1854
|
+
fullWidth: false
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
);
|
|
1858
|
+
var TabsList = React16.forwardRef(
|
|
1859
|
+
({ className, fullWidth, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1860
|
+
"div",
|
|
1861
|
+
{
|
|
1862
|
+
ref,
|
|
1863
|
+
role: "tablist",
|
|
1864
|
+
className: cn(tabsListVariants({ fullWidth }), "gap-1", className),
|
|
1865
|
+
...props
|
|
1866
|
+
}
|
|
1867
|
+
)
|
|
1868
|
+
);
|
|
1869
|
+
TabsList.displayName = "TabsList";
|
|
1870
|
+
var tabsTriggerVariants = cva(
|
|
1871
|
+
[
|
|
1872
|
+
"relative inline-flex items-center justify-center gap-2 whitespace-nowrap px-3 py-2 text-sm font-medium",
|
|
1873
|
+
"transition-colors focus-visible:outline-none",
|
|
1874
|
+
"focus-visible:ring-2 focus-visible:ring-brand-border focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base",
|
|
1875
|
+
"disabled:pointer-events-none disabled:text-text-disabled",
|
|
1876
|
+
"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
1877
|
+
// bottom indicator element (2px)
|
|
1878
|
+
"after:absolute after:inset-x-0 after:-bottom-px after:h-0.5 after:rounded-full after:transition-colors"
|
|
1879
|
+
],
|
|
1880
|
+
{
|
|
1881
|
+
variants: {
|
|
1882
|
+
active: {
|
|
1883
|
+
true: "text-text-strong after:bg-brand-solid",
|
|
1884
|
+
false: "text-text-subtle hover:text-text-default after:bg-transparent"
|
|
1885
|
+
}
|
|
1886
|
+
},
|
|
1887
|
+
defaultVariants: {
|
|
1888
|
+
active: false
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
);
|
|
1892
|
+
var TabsTrigger = React16.forwardRef(
|
|
1893
|
+
({ className, value, disabled, ...props }, ref) => {
|
|
1894
|
+
const { value: activeValue, setValue, baseId } = useTabsContext("TabsTrigger");
|
|
1895
|
+
const isActive = activeValue === value;
|
|
1896
|
+
return /* @__PURE__ */ jsx(
|
|
1897
|
+
"button",
|
|
1898
|
+
{
|
|
1899
|
+
ref,
|
|
1900
|
+
type: "button",
|
|
1901
|
+
role: "tab",
|
|
1902
|
+
id: `${baseId}-trigger-${value}`,
|
|
1903
|
+
"aria-selected": isActive,
|
|
1904
|
+
"aria-controls": `${baseId}-content-${value}`,
|
|
1905
|
+
tabIndex: isActive ? 0 : -1,
|
|
1906
|
+
disabled,
|
|
1907
|
+
"data-state": isActive ? "active" : "inactive",
|
|
1908
|
+
onClick: () => setValue(value),
|
|
1909
|
+
className: cn(tabsTriggerVariants({ active: isActive }), className),
|
|
1910
|
+
...props
|
|
1911
|
+
}
|
|
1912
|
+
);
|
|
1913
|
+
}
|
|
1914
|
+
);
|
|
1915
|
+
TabsTrigger.displayName = "TabsTrigger";
|
|
1916
|
+
var TabsContent = React16.forwardRef(
|
|
1917
|
+
({ className, value, forceMount, children, ...props }, ref) => {
|
|
1918
|
+
const { value: activeValue, baseId } = useTabsContext("TabsContent");
|
|
1919
|
+
const isActive = activeValue === value;
|
|
1920
|
+
if (!isActive && !forceMount) return null;
|
|
1921
|
+
return /* @__PURE__ */ jsx(
|
|
1922
|
+
"div",
|
|
1923
|
+
{
|
|
1924
|
+
ref,
|
|
1925
|
+
role: "tabpanel",
|
|
1926
|
+
id: `${baseId}-content-${value}`,
|
|
1927
|
+
"aria-labelledby": `${baseId}-trigger-${value}`,
|
|
1928
|
+
hidden: !isActive,
|
|
1929
|
+
tabIndex: 0,
|
|
1930
|
+
"data-state": isActive ? "active" : "inactive",
|
|
1931
|
+
className: cn(
|
|
1932
|
+
"text-sm text-text-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-border focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base",
|
|
1933
|
+
className
|
|
1934
|
+
),
|
|
1935
|
+
...props,
|
|
1936
|
+
children
|
|
1937
|
+
}
|
|
1938
|
+
);
|
|
1939
|
+
}
|
|
1940
|
+
);
|
|
1941
|
+
TabsContent.displayName = "TabsContent";
|
|
1942
|
+
var tableVariants = cva(
|
|
1943
|
+
"w-full caption-bottom border-separate border-spacing-0 overflow-hidden rounded-lg border border-border-default text-sm text-text-default",
|
|
1944
|
+
{
|
|
1945
|
+
variants: {
|
|
1946
|
+
density: {
|
|
1947
|
+
comfortable: "[&_td]:py-2 [&_th]:py-2",
|
|
1948
|
+
compact: "[&_td]:py-1 [&_th]:py-1"
|
|
1949
|
+
}
|
|
1950
|
+
},
|
|
1951
|
+
defaultVariants: {
|
|
1952
|
+
density: "comfortable"
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
);
|
|
1956
|
+
var Table = React16.forwardRef(
|
|
1957
|
+
({ className, density, containerProps, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1958
|
+
"div",
|
|
1959
|
+
{
|
|
1960
|
+
...containerProps,
|
|
1961
|
+
className: cn("relative w-full overflow-x-auto", containerProps?.className),
|
|
1962
|
+
children: /* @__PURE__ */ jsx(
|
|
1963
|
+
"table",
|
|
1964
|
+
{
|
|
1965
|
+
ref,
|
|
1966
|
+
className: cn(tableVariants({ density, className })),
|
|
1967
|
+
...props
|
|
1968
|
+
}
|
|
1969
|
+
)
|
|
1970
|
+
}
|
|
1971
|
+
)
|
|
1972
|
+
);
|
|
1973
|
+
Table.displayName = "Table";
|
|
1974
|
+
var TableHeader = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1975
|
+
"thead",
|
|
1976
|
+
{
|
|
1977
|
+
ref,
|
|
1978
|
+
className: cn("bg-surface-sunken text-text-subtle", className),
|
|
1979
|
+
...props
|
|
1980
|
+
}
|
|
1981
|
+
));
|
|
1982
|
+
TableHeader.displayName = "TableHeader";
|
|
1983
|
+
var TableBody = React16.forwardRef(
|
|
1984
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("", className), ...props })
|
|
1985
|
+
);
|
|
1986
|
+
TableBody.displayName = "TableBody";
|
|
1987
|
+
var tableRowVariants = cva(
|
|
1988
|
+
"border-b border-border-default transition-colors [&>*]:border-b [&>*]:border-border-default last:[&>*]:border-b-0",
|
|
1989
|
+
{
|
|
1990
|
+
variants: {
|
|
1991
|
+
interactive: {
|
|
1992
|
+
true: "cursor-pointer hover:bg-surface-hover data-[selected=true]:bg-brand-subtle",
|
|
1993
|
+
false: "hover:bg-surface-hover"
|
|
1994
|
+
}
|
|
1995
|
+
},
|
|
1996
|
+
defaultVariants: {
|
|
1997
|
+
interactive: false
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
);
|
|
2001
|
+
var TableRow = React16.forwardRef(
|
|
2002
|
+
({ className, interactive, selected, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2003
|
+
"tr",
|
|
2004
|
+
{
|
|
2005
|
+
ref,
|
|
2006
|
+
"data-selected": selected ? "true" : void 0,
|
|
2007
|
+
"aria-selected": selected,
|
|
2008
|
+
className: cn(tableRowVariants({ interactive, className })),
|
|
2009
|
+
...props
|
|
2010
|
+
}
|
|
2011
|
+
)
|
|
2012
|
+
);
|
|
2013
|
+
TableRow.displayName = "TableRow";
|
|
2014
|
+
var TableHead = React16.forwardRef(
|
|
2015
|
+
({ className, sort, children, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2016
|
+
"th",
|
|
2017
|
+
{
|
|
2018
|
+
ref,
|
|
2019
|
+
scope: "col",
|
|
2020
|
+
"aria-sort": sort === "asc" ? "ascending" : sort === "desc" ? "descending" : sort === "none" ? "none" : void 0,
|
|
2021
|
+
className: cn(
|
|
2022
|
+
"h-9 px-3 py-2 text-left align-middle text-xs font-medium text-text-subtle",
|
|
2023
|
+
"[&:has([role=checkbox])]:pr-0",
|
|
2024
|
+
className
|
|
2025
|
+
),
|
|
2026
|
+
...props,
|
|
2027
|
+
children: sort && sort !== "none" ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
2028
|
+
children,
|
|
2029
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-text-subtle", children: sort === "asc" ? "\u2191" : "\u2193" })
|
|
2030
|
+
] }) : children
|
|
2031
|
+
}
|
|
2032
|
+
)
|
|
2033
|
+
);
|
|
2034
|
+
TableHead.displayName = "TableHead";
|
|
2035
|
+
var TableCell = React16.forwardRef(
|
|
2036
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2037
|
+
"td",
|
|
2038
|
+
{
|
|
2039
|
+
ref,
|
|
2040
|
+
className: cn(
|
|
2041
|
+
"px-3 py-2 align-middle text-sm text-text-default [&:has([role=checkbox])]:pr-0",
|
|
2042
|
+
className
|
|
2043
|
+
),
|
|
2044
|
+
...props
|
|
2045
|
+
}
|
|
2046
|
+
)
|
|
2047
|
+
);
|
|
2048
|
+
TableCell.displayName = "TableCell";
|
|
2049
|
+
var TableCaption = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2050
|
+
"caption",
|
|
2051
|
+
{
|
|
2052
|
+
ref,
|
|
2053
|
+
className: cn("mt-3 text-xs text-text-subtle", className),
|
|
2054
|
+
...props
|
|
2055
|
+
}
|
|
2056
|
+
));
|
|
2057
|
+
TableCaption.displayName = "TableCaption";
|
|
2058
|
+
var paginationItemVariants = cva(
|
|
2059
|
+
"inline-flex h-8 min-w-8 items-center justify-center rounded-lg px-2 text-sm font-medium transition-colors select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base disabled:pointer-events-none disabled:text-text-disabled [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
2060
|
+
{
|
|
2061
|
+
variants: {
|
|
2062
|
+
active: {
|
|
2063
|
+
true: "bg-brand-solid text-text-on-brand hover:bg-brand-solid-hover",
|
|
2064
|
+
false: "text-text-default hover:bg-surface-hover active:bg-surface-pressed"
|
|
2065
|
+
}
|
|
2066
|
+
},
|
|
2067
|
+
defaultVariants: {
|
|
2068
|
+
active: false
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
);
|
|
2072
|
+
var ChevronLeftIcon = (props) => /* @__PURE__ */ jsx(
|
|
2073
|
+
"svg",
|
|
2074
|
+
{
|
|
2075
|
+
viewBox: "0 0 24 24",
|
|
2076
|
+
fill: "none",
|
|
2077
|
+
stroke: "currentColor",
|
|
2078
|
+
strokeWidth: 2,
|
|
2079
|
+
strokeLinecap: "round",
|
|
2080
|
+
strokeLinejoin: "round",
|
|
2081
|
+
"aria-hidden": "true",
|
|
2082
|
+
...props,
|
|
2083
|
+
children: /* @__PURE__ */ jsx("path", { d: "m15 18-6-6 6-6" })
|
|
2084
|
+
}
|
|
2085
|
+
);
|
|
2086
|
+
var ChevronRightIcon = (props) => /* @__PURE__ */ jsx(
|
|
2087
|
+
"svg",
|
|
2088
|
+
{
|
|
2089
|
+
viewBox: "0 0 24 24",
|
|
2090
|
+
fill: "none",
|
|
2091
|
+
stroke: "currentColor",
|
|
2092
|
+
strokeWidth: 2,
|
|
2093
|
+
strokeLinecap: "round",
|
|
2094
|
+
strokeLinejoin: "round",
|
|
2095
|
+
"aria-hidden": "true",
|
|
2096
|
+
...props,
|
|
2097
|
+
children: /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" })
|
|
2098
|
+
}
|
|
2099
|
+
);
|
|
2100
|
+
var EllipsisIcon = (props) => /* @__PURE__ */ jsxs(
|
|
2101
|
+
"svg",
|
|
2102
|
+
{
|
|
2103
|
+
viewBox: "0 0 24 24",
|
|
2104
|
+
fill: "currentColor",
|
|
2105
|
+
stroke: "none",
|
|
2106
|
+
"aria-hidden": "true",
|
|
2107
|
+
...props,
|
|
2108
|
+
children: [
|
|
2109
|
+
/* @__PURE__ */ jsx("circle", { cx: "5", cy: "12", r: "1.5" }),
|
|
2110
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
2111
|
+
/* @__PURE__ */ jsx("circle", { cx: "19", cy: "12", r: "1.5" })
|
|
2112
|
+
]
|
|
2113
|
+
}
|
|
2114
|
+
);
|
|
2115
|
+
var PaginationItem = React16.forwardRef(
|
|
2116
|
+
({ className, active, page, ...props }, ref) => {
|
|
2117
|
+
return /* @__PURE__ */ jsx(
|
|
2118
|
+
"button",
|
|
2119
|
+
{
|
|
2120
|
+
ref,
|
|
2121
|
+
type: "button",
|
|
2122
|
+
"aria-current": active ? "page" : void 0,
|
|
2123
|
+
"aria-label": `Go to page ${page}`,
|
|
2124
|
+
className: cn(paginationItemVariants({ active, className })),
|
|
2125
|
+
...props,
|
|
2126
|
+
children: page
|
|
2127
|
+
}
|
|
2128
|
+
);
|
|
2129
|
+
}
|
|
2130
|
+
);
|
|
2131
|
+
PaginationItem.displayName = "PaginationItem";
|
|
2132
|
+
var PaginationEllipsis = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
2133
|
+
"span",
|
|
2134
|
+
{
|
|
2135
|
+
ref,
|
|
2136
|
+
"aria-hidden": "true",
|
|
2137
|
+
className: cn(
|
|
2138
|
+
"inline-flex h-8 min-w-8 items-center justify-center px-1 text-sm text-text-subtle",
|
|
2139
|
+
className
|
|
2140
|
+
),
|
|
2141
|
+
...props,
|
|
2142
|
+
children: [
|
|
2143
|
+
/* @__PURE__ */ jsx(EllipsisIcon, {}),
|
|
2144
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "More pages" })
|
|
2145
|
+
]
|
|
2146
|
+
}
|
|
2147
|
+
));
|
|
2148
|
+
PaginationEllipsis.displayName = "PaginationEllipsis";
|
|
2149
|
+
var PaginationPrevious = React16.forwardRef(({ className, disabled, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2150
|
+
"button",
|
|
2151
|
+
{
|
|
2152
|
+
ref,
|
|
2153
|
+
type: "button",
|
|
2154
|
+
disabled,
|
|
2155
|
+
"aria-label": "Go to previous page",
|
|
2156
|
+
className: cn(paginationItemVariants({ active: false, className })),
|
|
2157
|
+
...props,
|
|
2158
|
+
children: /* @__PURE__ */ jsx(ChevronLeftIcon, {})
|
|
2159
|
+
}
|
|
2160
|
+
));
|
|
2161
|
+
PaginationPrevious.displayName = "PaginationPrevious";
|
|
2162
|
+
var PaginationNext = React16.forwardRef(
|
|
2163
|
+
({ className, disabled, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2164
|
+
"button",
|
|
2165
|
+
{
|
|
2166
|
+
ref,
|
|
2167
|
+
type: "button",
|
|
2168
|
+
disabled,
|
|
2169
|
+
"aria-label": "Go to next page",
|
|
2170
|
+
className: cn(paginationItemVariants({ active: false, className })),
|
|
2171
|
+
...props,
|
|
2172
|
+
children: /* @__PURE__ */ jsx(ChevronRightIcon, {})
|
|
2173
|
+
}
|
|
2174
|
+
)
|
|
2175
|
+
);
|
|
2176
|
+
PaginationNext.displayName = "PaginationNext";
|
|
2177
|
+
function buildPageRange(current, total, siblingCount = 1) {
|
|
2178
|
+
const totalSlots = siblingCount * 2 + 5;
|
|
2179
|
+
if (total <= totalSlots) {
|
|
2180
|
+
return Array.from({ length: total }, (_, i) => i + 1);
|
|
2181
|
+
}
|
|
2182
|
+
const leftSibling = Math.max(current - siblingCount, 1);
|
|
2183
|
+
const rightSibling = Math.min(current + siblingCount, total);
|
|
2184
|
+
const showLeftEllipsis = leftSibling > 2;
|
|
2185
|
+
const showRightEllipsis = rightSibling < total - 1;
|
|
2186
|
+
const range = [];
|
|
2187
|
+
if (!showLeftEllipsis && showRightEllipsis) {
|
|
2188
|
+
const leftItemCount = siblingCount * 2 + 3;
|
|
2189
|
+
for (let i = 1; i <= leftItemCount; i++) range.push(i);
|
|
2190
|
+
range.push("ellipsis", total);
|
|
2191
|
+
} else if (showLeftEllipsis && !showRightEllipsis) {
|
|
2192
|
+
const rightItemCount = siblingCount * 2 + 3;
|
|
2193
|
+
range.push(1, "ellipsis");
|
|
2194
|
+
for (let i = total - rightItemCount + 1; i <= total; i++) range.push(i);
|
|
2195
|
+
} else {
|
|
2196
|
+
range.push(1, "ellipsis");
|
|
2197
|
+
for (let i = leftSibling; i <= rightSibling; i++) range.push(i);
|
|
2198
|
+
range.push("ellipsis", total);
|
|
2199
|
+
}
|
|
2200
|
+
return range;
|
|
2201
|
+
}
|
|
2202
|
+
var Pagination = React16.forwardRef(
|
|
2203
|
+
({
|
|
2204
|
+
className,
|
|
2205
|
+
totalPages,
|
|
2206
|
+
page,
|
|
2207
|
+
onPageChange,
|
|
2208
|
+
siblingCount = 1,
|
|
2209
|
+
label = "Pagination",
|
|
2210
|
+
...props
|
|
2211
|
+
}, ref) => {
|
|
2212
|
+
const safeTotal = Math.max(totalPages, 1);
|
|
2213
|
+
const current = Math.min(Math.max(page, 1), safeTotal);
|
|
2214
|
+
const items = buildPageRange(current, safeTotal, siblingCount);
|
|
2215
|
+
const goTo = (target) => {
|
|
2216
|
+
if (target < 1 || target > safeTotal || target === current) return;
|
|
2217
|
+
onPageChange?.(target);
|
|
2218
|
+
};
|
|
2219
|
+
return /* @__PURE__ */ jsxs(
|
|
2220
|
+
"nav",
|
|
2221
|
+
{
|
|
2222
|
+
ref,
|
|
2223
|
+
role: "navigation",
|
|
2224
|
+
"aria-label": label,
|
|
2225
|
+
className: cn("flex items-center gap-1", className),
|
|
2226
|
+
...props,
|
|
2227
|
+
children: [
|
|
2228
|
+
/* @__PURE__ */ jsx(
|
|
2229
|
+
PaginationPrevious,
|
|
2230
|
+
{
|
|
2231
|
+
disabled: current <= 1,
|
|
2232
|
+
onClick: () => goTo(current - 1)
|
|
2233
|
+
}
|
|
2234
|
+
),
|
|
2235
|
+
items.map(
|
|
2236
|
+
(item, index) => item === "ellipsis" ? /* @__PURE__ */ jsx(PaginationEllipsis, {}, `ellipsis-${index}`) : /* @__PURE__ */ jsx(
|
|
2237
|
+
PaginationItem,
|
|
2238
|
+
{
|
|
2239
|
+
page: item,
|
|
2240
|
+
active: item === current,
|
|
2241
|
+
onClick: () => goTo(item)
|
|
2242
|
+
},
|
|
2243
|
+
item
|
|
2244
|
+
)
|
|
2245
|
+
),
|
|
2246
|
+
/* @__PURE__ */ jsx(
|
|
2247
|
+
PaginationNext,
|
|
2248
|
+
{
|
|
2249
|
+
disabled: current >= safeTotal,
|
|
2250
|
+
onClick: () => goTo(current + 1)
|
|
2251
|
+
}
|
|
2252
|
+
)
|
|
2253
|
+
]
|
|
2254
|
+
}
|
|
2255
|
+
);
|
|
2256
|
+
}
|
|
2257
|
+
);
|
|
2258
|
+
Pagination.displayName = "Pagination";
|
|
2259
|
+
var segmentContainerVariants = cva(
|
|
2260
|
+
"relative inline-grid h-8 auto-cols-fr grid-flow-col items-center rounded-lg bg-surface-sunken p-0.5 text-sm",
|
|
2261
|
+
{
|
|
2262
|
+
variants: {
|
|
2263
|
+
fullWidth: {
|
|
2264
|
+
true: "flex w-full",
|
|
2265
|
+
false: "inline-grid w-auto"
|
|
2266
|
+
}
|
|
2267
|
+
},
|
|
2268
|
+
defaultVariants: {
|
|
2269
|
+
fullWidth: false
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
);
|
|
2273
|
+
var segmentItemVariants = cva(
|
|
2274
|
+
"relative z-10 inline-flex h-full w-full items-center justify-center gap-1.5 whitespace-nowrap rounded-lg px-3 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
2275
|
+
{
|
|
2276
|
+
variants: {
|
|
2277
|
+
// 활성=label1 굵기(semibold/600) · 비활성=body-sm 굵기(regular/400), 둘 다 14px.
|
|
2278
|
+
// NOTE: text-label1/body-sm 클래스는 twMerge가 text-* 색상과 같은 충돌군으로
|
|
2279
|
+
// 보고 제거하므로, 색상과 충돌 안 하는 font-weight 유틸로 굵기를 지정한다.
|
|
2280
|
+
active: {
|
|
2281
|
+
true: "font-semibold text-text-strong",
|
|
2282
|
+
false: "font-normal text-text-subtle hover:text-text-default"
|
|
2283
|
+
}
|
|
2284
|
+
},
|
|
2285
|
+
defaultVariants: {
|
|
2286
|
+
active: false
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
);
|
|
2290
|
+
var SegmentedControl = React16.forwardRef(
|
|
2291
|
+
({
|
|
2292
|
+
className,
|
|
2293
|
+
items,
|
|
2294
|
+
value,
|
|
2295
|
+
defaultValue,
|
|
2296
|
+
onValueChange,
|
|
2297
|
+
disabled = false,
|
|
2298
|
+
fullWidth,
|
|
2299
|
+
"aria-label": ariaLabel,
|
|
2300
|
+
...props
|
|
2301
|
+
}, ref) => {
|
|
2302
|
+
const isControlled = value !== void 0;
|
|
2303
|
+
const [internalValue, setInternalValue] = React16.useState(
|
|
2304
|
+
defaultValue ?? items[0]?.value ?? ""
|
|
2305
|
+
);
|
|
2306
|
+
const currentValue = isControlled ? value : internalValue;
|
|
2307
|
+
const activeIndex = Math.max(
|
|
2308
|
+
0,
|
|
2309
|
+
items.findIndex((item) => item.value === currentValue)
|
|
2310
|
+
);
|
|
2311
|
+
const count = items.length || 1;
|
|
2312
|
+
const handleSelect = (next) => {
|
|
2313
|
+
if (!isControlled) setInternalValue(next);
|
|
2314
|
+
onValueChange?.(next);
|
|
2315
|
+
};
|
|
2316
|
+
return /* @__PURE__ */ jsxs(
|
|
2317
|
+
"div",
|
|
2318
|
+
{
|
|
2319
|
+
ref,
|
|
2320
|
+
role: "tablist",
|
|
2321
|
+
"aria-label": ariaLabel,
|
|
2322
|
+
"aria-disabled": disabled || void 0,
|
|
2323
|
+
className: cn(segmentContainerVariants({ fullWidth }), className),
|
|
2324
|
+
...props,
|
|
2325
|
+
children: [
|
|
2326
|
+
items.length > 0 && /* @__PURE__ */ jsx(
|
|
2327
|
+
"span",
|
|
2328
|
+
{
|
|
2329
|
+
"aria-hidden": "true",
|
|
2330
|
+
className: "pointer-events-none absolute bottom-0.5 left-0.5 top-0.5 z-0 rounded-lg bg-surface-default shadow-sm transition-transform duration-200 ease-out",
|
|
2331
|
+
style: {
|
|
2332
|
+
width: `calc((100% - 0.25rem) / ${count})`,
|
|
2333
|
+
transform: `translateX(calc(${activeIndex} * 100%))`
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
),
|
|
2337
|
+
items.map((item) => {
|
|
2338
|
+
const isActive = item.value === currentValue;
|
|
2339
|
+
const isDisabled = disabled || item.disabled;
|
|
2340
|
+
return /* @__PURE__ */ jsxs(
|
|
2341
|
+
"button",
|
|
2342
|
+
{
|
|
2343
|
+
type: "button",
|
|
2344
|
+
role: "tab",
|
|
2345
|
+
"aria-selected": isActive,
|
|
2346
|
+
disabled: isDisabled,
|
|
2347
|
+
tabIndex: isActive ? 0 : -1,
|
|
2348
|
+
onClick: () => handleSelect(item.value),
|
|
2349
|
+
className: cn(segmentItemVariants({ active: isActive })),
|
|
2350
|
+
children: [
|
|
2351
|
+
item.icon,
|
|
2352
|
+
item.label
|
|
2353
|
+
]
|
|
2354
|
+
},
|
|
2355
|
+
item.value
|
|
2356
|
+
);
|
|
2357
|
+
})
|
|
2358
|
+
]
|
|
2359
|
+
}
|
|
2360
|
+
);
|
|
2361
|
+
}
|
|
2362
|
+
);
|
|
2363
|
+
SegmentedControl.displayName = "SegmentedControl";
|
|
2364
|
+
var toastVariants = cva(
|
|
2365
|
+
"pointer-events-auto flex w-full max-w-sm gap-3 rounded-lg border px-4 py-4 shadow-toast focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base",
|
|
2366
|
+
{
|
|
2367
|
+
variants: {
|
|
2368
|
+
variant: {
|
|
2369
|
+
default: "border-border-default bg-surface-raised text-text-default focus-visible:ring-border-focus",
|
|
2370
|
+
danger: "border-danger-border bg-danger-subtle text-danger-text focus-visible:ring-danger-border"
|
|
2371
|
+
}
|
|
2372
|
+
},
|
|
2373
|
+
defaultVariants: {
|
|
2374
|
+
variant: "default"
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
);
|
|
2378
|
+
function InfoIcon(props) {
|
|
2379
|
+
return /* @__PURE__ */ jsxs(
|
|
2380
|
+
"svg",
|
|
2381
|
+
{
|
|
2382
|
+
viewBox: "0 0 20 20",
|
|
2383
|
+
fill: "none",
|
|
2384
|
+
stroke: "currentColor",
|
|
2385
|
+
strokeWidth: 1.6,
|
|
2386
|
+
strokeLinecap: "round",
|
|
2387
|
+
strokeLinejoin: "round",
|
|
2388
|
+
"aria-hidden": "true",
|
|
2389
|
+
...props,
|
|
2390
|
+
children: [
|
|
2391
|
+
/* @__PURE__ */ jsx("circle", { cx: "10", cy: "10", r: "7.5" }),
|
|
2392
|
+
/* @__PURE__ */ jsx("path", { d: "M10 9v4.5" }),
|
|
2393
|
+
/* @__PURE__ */ jsx("path", { d: "M10 6.5h.01" })
|
|
2394
|
+
]
|
|
2395
|
+
}
|
|
2396
|
+
);
|
|
2397
|
+
}
|
|
2398
|
+
function AlertIcon(props) {
|
|
2399
|
+
return /* @__PURE__ */ jsxs(
|
|
2400
|
+
"svg",
|
|
2401
|
+
{
|
|
2402
|
+
viewBox: "0 0 20 20",
|
|
2403
|
+
fill: "none",
|
|
2404
|
+
stroke: "currentColor",
|
|
2405
|
+
strokeWidth: 1.6,
|
|
2406
|
+
strokeLinecap: "round",
|
|
2407
|
+
strokeLinejoin: "round",
|
|
2408
|
+
"aria-hidden": "true",
|
|
2409
|
+
...props,
|
|
2410
|
+
children: [
|
|
2411
|
+
/* @__PURE__ */ jsx("path", { d: "M10 2.5 18 16.5H2z" }),
|
|
2412
|
+
/* @__PURE__ */ jsx("path", { d: "M10 8v3.5" }),
|
|
2413
|
+
/* @__PURE__ */ jsx("path", { d: "M10 14h.01" })
|
|
2414
|
+
]
|
|
2415
|
+
}
|
|
2416
|
+
);
|
|
2417
|
+
}
|
|
2418
|
+
function CloseIcon2(props) {
|
|
2419
|
+
return /* @__PURE__ */ jsx(
|
|
2420
|
+
"svg",
|
|
2421
|
+
{
|
|
2422
|
+
viewBox: "0 0 20 20",
|
|
2423
|
+
fill: "none",
|
|
2424
|
+
stroke: "currentColor",
|
|
2425
|
+
strokeWidth: 1.6,
|
|
2426
|
+
strokeLinecap: "round",
|
|
2427
|
+
strokeLinejoin: "round",
|
|
2428
|
+
"aria-hidden": "true",
|
|
2429
|
+
...props,
|
|
2430
|
+
children: /* @__PURE__ */ jsx("path", { d: "M5 5l10 10M15 5L5 15" })
|
|
2431
|
+
}
|
|
2432
|
+
);
|
|
2433
|
+
}
|
|
2434
|
+
var Toast = React16.forwardRef(
|
|
2435
|
+
({
|
|
2436
|
+
className,
|
|
2437
|
+
variant,
|
|
2438
|
+
message,
|
|
2439
|
+
title,
|
|
2440
|
+
icon = true,
|
|
2441
|
+
dismissible = true,
|
|
2442
|
+
onClose,
|
|
2443
|
+
closeLabel = "Close",
|
|
2444
|
+
...props
|
|
2445
|
+
}, ref) => {
|
|
2446
|
+
const StatusIcon = variant === "danger" ? AlertIcon : InfoIcon;
|
|
2447
|
+
return /* @__PURE__ */ jsxs(
|
|
2448
|
+
"div",
|
|
2449
|
+
{
|
|
2450
|
+
ref,
|
|
2451
|
+
role: variant === "danger" ? "alert" : "status",
|
|
2452
|
+
"aria-live": variant === "danger" ? "assertive" : "polite",
|
|
2453
|
+
className: cn(
|
|
2454
|
+
toastVariants({ variant, className }),
|
|
2455
|
+
title ? "items-start" : "items-center"
|
|
2456
|
+
),
|
|
2457
|
+
...props,
|
|
2458
|
+
children: [
|
|
2459
|
+
/* @__PURE__ */ jsxs(
|
|
2460
|
+
"div",
|
|
2461
|
+
{
|
|
2462
|
+
className: cn(
|
|
2463
|
+
"flex min-w-0 flex-1 gap-2",
|
|
2464
|
+
title ? "items-start" : "items-center"
|
|
2465
|
+
),
|
|
2466
|
+
children: [
|
|
2467
|
+
icon ? /* @__PURE__ */ jsx(
|
|
2468
|
+
StatusIcon,
|
|
2469
|
+
{
|
|
2470
|
+
className: cn(
|
|
2471
|
+
"size-5 shrink-0",
|
|
2472
|
+
variant === "danger" ? "text-danger-text" : "text-text-subtle"
|
|
2473
|
+
)
|
|
2474
|
+
}
|
|
2475
|
+
) : null,
|
|
2476
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
2477
|
+
title ? /* @__PURE__ */ jsx(
|
|
2478
|
+
"p",
|
|
2479
|
+
{
|
|
2480
|
+
className: cn(
|
|
2481
|
+
"text-label1",
|
|
2482
|
+
variant === "danger" ? "text-danger-text" : "text-text-strong"
|
|
2483
|
+
),
|
|
2484
|
+
children: title
|
|
2485
|
+
}
|
|
2486
|
+
) : null,
|
|
2487
|
+
/* @__PURE__ */ jsx("p", { className: cn("text-body-sm break-words", title && "mt-0.5"), children: message })
|
|
2488
|
+
] })
|
|
2489
|
+
]
|
|
2490
|
+
}
|
|
2491
|
+
),
|
|
2492
|
+
dismissible ? /* @__PURE__ */ jsx(
|
|
2493
|
+
"button",
|
|
2494
|
+
{
|
|
2495
|
+
type: "button",
|
|
2496
|
+
onClick: onClose,
|
|
2497
|
+
"aria-label": closeLabel,
|
|
2498
|
+
className: cn(
|
|
2499
|
+
"-mr-1 inline-flex size-6 shrink-0 items-center justify-center rounded text-text-subtle transition-colors hover:bg-surface-hover hover:text-text-default active:bg-surface-pressed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base",
|
|
2500
|
+
title && "-mt-0.5"
|
|
2501
|
+
),
|
|
2502
|
+
children: /* @__PURE__ */ jsx(CloseIcon2, { className: "size-4" })
|
|
2503
|
+
}
|
|
2504
|
+
) : null
|
|
2505
|
+
]
|
|
2506
|
+
}
|
|
2507
|
+
);
|
|
2508
|
+
}
|
|
2509
|
+
);
|
|
2510
|
+
Toast.displayName = "Toast";
|
|
2511
|
+
var SIZES = {
|
|
2512
|
+
lg: {
|
|
2513
|
+
plate: 180,
|
|
2514
|
+
art: 120,
|
|
2515
|
+
pad: "px-6 py-12",
|
|
2516
|
+
plateMb: "mb-4",
|
|
2517
|
+
title: "text-xl",
|
|
2518
|
+
desc: "text-base max-w-[360px]",
|
|
2519
|
+
gap: "mt-1",
|
|
2520
|
+
act: "mt-5"
|
|
2521
|
+
},
|
|
2522
|
+
md: {
|
|
2523
|
+
plate: 144,
|
|
2524
|
+
art: 96,
|
|
2525
|
+
pad: "px-5 py-10",
|
|
2526
|
+
plateMb: "mb-3",
|
|
2527
|
+
title: "text-lg",
|
|
2528
|
+
desc: "text-base max-w-[300px]",
|
|
2529
|
+
gap: "mt-0.5",
|
|
2530
|
+
act: "mt-4"
|
|
2531
|
+
},
|
|
2532
|
+
sm: {
|
|
2533
|
+
plate: 108,
|
|
2534
|
+
art: 72,
|
|
2535
|
+
pad: "px-4 py-8",
|
|
2536
|
+
plateMb: "mb-3",
|
|
2537
|
+
title: "text-lg",
|
|
2538
|
+
desc: "text-sm max-w-[240px]",
|
|
2539
|
+
gap: "mt-0.5",
|
|
2540
|
+
act: "mt-4"
|
|
2541
|
+
}
|
|
2542
|
+
};
|
|
2543
|
+
function EmptyState({
|
|
2544
|
+
size = "lg",
|
|
2545
|
+
illustration,
|
|
2546
|
+
title,
|
|
2547
|
+
description,
|
|
2548
|
+
action,
|
|
2549
|
+
className,
|
|
2550
|
+
...props
|
|
2551
|
+
}) {
|
|
2552
|
+
const s = SIZES[size];
|
|
2553
|
+
return /* @__PURE__ */ jsxs(
|
|
2554
|
+
"div",
|
|
2555
|
+
{
|
|
2556
|
+
className: cn("flex flex-col items-center text-center", s.pad, className),
|
|
2557
|
+
...props,
|
|
2558
|
+
children: [
|
|
2559
|
+
illustration && // 플레이트: border-subtle = 라이트 gray-20(sunken) · 다크 gray-60(카드 gray-80보다 밝아 떠 보임)
|
|
2560
|
+
/* @__PURE__ */ jsx(
|
|
2561
|
+
"div",
|
|
2562
|
+
{
|
|
2563
|
+
className: cn(
|
|
2564
|
+
"flex items-center justify-center rounded-full bg-border-subtle",
|
|
2565
|
+
s.plateMb
|
|
2566
|
+
),
|
|
2567
|
+
style: { width: s.plate, height: s.plate },
|
|
2568
|
+
children: /* @__PURE__ */ jsx(
|
|
2569
|
+
"span",
|
|
2570
|
+
{
|
|
2571
|
+
className: "inline-flex [&>img]:h-full [&>img]:w-full [&>img]:object-contain [&>svg]:h-full [&>svg]:w-full",
|
|
2572
|
+
style: { width: s.art, height: s.art },
|
|
2573
|
+
children: illustration
|
|
2574
|
+
}
|
|
2575
|
+
)
|
|
2576
|
+
}
|
|
2577
|
+
),
|
|
2578
|
+
/* @__PURE__ */ jsx("h3", { className: cn("font-bold leading-snug text-text-strong", s.title), children: title }),
|
|
2579
|
+
description && /* @__PURE__ */ jsx("p", { className: cn("leading-relaxed text-text-subtle", s.desc, s.gap), children: description }),
|
|
2580
|
+
action && /* @__PURE__ */ jsx("div", { className: cn("flex gap-2", s.act), children: action })
|
|
2581
|
+
]
|
|
2582
|
+
}
|
|
2583
|
+
);
|
|
2584
|
+
}
|
|
2585
|
+
function IconBase({
|
|
2586
|
+
size = 20,
|
|
2587
|
+
children,
|
|
2588
|
+
...props
|
|
2589
|
+
}) {
|
|
2590
|
+
return /* @__PURE__ */ jsx(
|
|
2591
|
+
"svg",
|
|
2592
|
+
{
|
|
2593
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2594
|
+
width: size,
|
|
2595
|
+
height: size,
|
|
2596
|
+
viewBox: "0 0 24 24",
|
|
2597
|
+
fill: "none",
|
|
2598
|
+
stroke: "currentColor",
|
|
2599
|
+
strokeWidth: 1.5,
|
|
2600
|
+
strokeLinecap: "round",
|
|
2601
|
+
strokeLinejoin: "round",
|
|
2602
|
+
"aria-hidden": "true",
|
|
2603
|
+
...props,
|
|
2604
|
+
children
|
|
2605
|
+
}
|
|
2606
|
+
);
|
|
2607
|
+
}
|
|
2608
|
+
var CheckIcon4 = (props) => /* @__PURE__ */ jsx(IconBase, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) });
|
|
2609
|
+
var ChevronDownIcon = (props) => /* @__PURE__ */ jsx(IconBase, { ...props, children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" }) });
|
|
2610
|
+
var ChevronLeftIcon2 = (props) => /* @__PURE__ */ jsx(IconBase, { ...props, children: /* @__PURE__ */ jsx("path", { d: "m15 6-6 6 6 6" }) });
|
|
2611
|
+
var ChevronRightIcon2 = (props) => /* @__PURE__ */ jsx(IconBase, { ...props, children: /* @__PURE__ */ jsx("path", { d: "m9 6 6 6-6 6" }) });
|
|
2612
|
+
var HashIcon = (props) => /* @__PURE__ */ jsx(IconBase, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M4 9h16M4 15h16M10 3 8 21M16 3 14 21" }) });
|
|
2613
|
+
var LockIcon = (props) => /* @__PURE__ */ jsxs(IconBase, { ...props, children: [
|
|
2614
|
+
/* @__PURE__ */ jsx("rect", { width: "18", height: "11", x: "3", y: "11", rx: "3", ry: "3" }),
|
|
2615
|
+
/* @__PURE__ */ jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
|
|
2616
|
+
] });
|
|
2617
|
+
var PinIcon = (props) => /* @__PURE__ */ jsxs(IconBase, { ...props, children: [
|
|
2618
|
+
/* @__PURE__ */ jsx("path", { d: "M12 17v5" }),
|
|
2619
|
+
/* @__PURE__ */ jsx("path", { d: "M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z" })
|
|
2620
|
+
] });
|
|
2621
|
+
var PlusIcon = (props) => /* @__PURE__ */ jsx(IconBase, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M12 5v14M5 12h14" }) });
|
|
2622
|
+
var SearchIcon = (props) => /* @__PURE__ */ jsxs(IconBase, { ...props, children: [
|
|
2623
|
+
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "7" }),
|
|
2624
|
+
/* @__PURE__ */ jsx("path", { d: "m20 20-3.4-3.4" })
|
|
2625
|
+
] });
|
|
2626
|
+
var XIcon = (props) => /* @__PURE__ */ jsx(IconBase, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) });
|
|
2627
|
+
var AccordionItem = React16.forwardRef(
|
|
2628
|
+
({ className, title, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
2629
|
+
"details",
|
|
2630
|
+
{
|
|
2631
|
+
ref,
|
|
2632
|
+
className: cn(
|
|
2633
|
+
"group border-t border-border-subtle first:border-t-0",
|
|
2634
|
+
className
|
|
2635
|
+
),
|
|
2636
|
+
...props,
|
|
2637
|
+
children: [
|
|
2638
|
+
/* @__PURE__ */ jsxs("summary", { className: "flex cursor-pointer select-none list-none items-center justify-between gap-2.5 px-4 py-3.5 text-sm font-semibold text-text-default group-open:text-brand-text [&::-webkit-details-marker]:hidden", children: [
|
|
2639
|
+
title,
|
|
2640
|
+
/* @__PURE__ */ jsx(
|
|
2641
|
+
ChevronDownIcon,
|
|
2642
|
+
{
|
|
2643
|
+
size: 18,
|
|
2644
|
+
className: "shrink-0 text-text-subtle transition-transform duration-200 group-open:rotate-180"
|
|
2645
|
+
}
|
|
2646
|
+
)
|
|
2647
|
+
] }),
|
|
2648
|
+
/* @__PURE__ */ jsx("div", { className: "px-4 pb-3.5 text-sm leading-relaxed text-text-subtle", children })
|
|
2649
|
+
]
|
|
2650
|
+
}
|
|
2651
|
+
)
|
|
2652
|
+
);
|
|
2653
|
+
AccordionItem.displayName = "AccordionItem";
|
|
2654
|
+
var Accordion = React16.forwardRef(
|
|
2655
|
+
({ className, items, children, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2656
|
+
"div",
|
|
2657
|
+
{
|
|
2658
|
+
ref,
|
|
2659
|
+
className: cn(
|
|
2660
|
+
"overflow-hidden rounded-lg border border-border-subtle bg-surface-default",
|
|
2661
|
+
className
|
|
2662
|
+
),
|
|
2663
|
+
...props,
|
|
2664
|
+
children: items ? items.map((it) => /* @__PURE__ */ jsx(
|
|
2665
|
+
AccordionItem,
|
|
2666
|
+
{
|
|
2667
|
+
title: it.title,
|
|
2668
|
+
open: it.defaultOpen,
|
|
2669
|
+
children: it.content
|
|
2670
|
+
},
|
|
2671
|
+
it.id ?? String(it.title)
|
|
2672
|
+
)) : children
|
|
2673
|
+
}
|
|
2674
|
+
)
|
|
2675
|
+
);
|
|
2676
|
+
Accordion.displayName = "Accordion";
|
|
2677
|
+
var KpiRow = React16.forwardRef(
|
|
2678
|
+
({ items, className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex w-[360px] gap-2", className), ...props, children: items.map((k) => /* @__PURE__ */ jsxs(
|
|
2679
|
+
"div",
|
|
2680
|
+
{
|
|
2681
|
+
className: "flex-1 rounded-lg border border-border-subtle bg-surface-default p-3",
|
|
2682
|
+
children: [
|
|
2683
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
2684
|
+
k.dot != null && /* @__PURE__ */ jsx(
|
|
2685
|
+
"span",
|
|
2686
|
+
{
|
|
2687
|
+
className: cn("h-2 w-2 shrink-0 rounded-full", k.dot),
|
|
2688
|
+
"aria-hidden": true
|
|
2689
|
+
}
|
|
2690
|
+
),
|
|
2691
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-text-subtle", children: k.label })
|
|
2692
|
+
] }),
|
|
2693
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 text-2xl font-bold text-text-strong", children: k.value })
|
|
2694
|
+
]
|
|
2695
|
+
},
|
|
2696
|
+
k.label
|
|
2697
|
+
)) })
|
|
2698
|
+
);
|
|
2699
|
+
KpiRow.displayName = "KpiRow";
|
|
2700
|
+
var ProgressList = React16.forwardRef(
|
|
2701
|
+
({ items, className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2702
|
+
"div",
|
|
2703
|
+
{
|
|
2704
|
+
ref,
|
|
2705
|
+
className: cn("flex w-[320px] flex-col gap-3", className),
|
|
2706
|
+
...props,
|
|
2707
|
+
children: items.map((r) => /* @__PURE__ */ jsxs("div", { children: [
|
|
2708
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-1 flex justify-between text-sm", children: [
|
|
2709
|
+
/* @__PURE__ */ jsx("span", { className: "text-text-default", children: r.label }),
|
|
2710
|
+
/* @__PURE__ */ jsxs("span", { className: r.danger ? "text-danger-text" : "text-brand-text", children: [
|
|
2711
|
+
r.pct,
|
|
2712
|
+
"%"
|
|
2713
|
+
] })
|
|
2714
|
+
] }),
|
|
2715
|
+
/* @__PURE__ */ jsx("div", { className: "h-2 overflow-hidden rounded-full bg-surface-sunken", children: /* @__PURE__ */ jsx(
|
|
2716
|
+
"div",
|
|
2717
|
+
{
|
|
2718
|
+
className: cn(
|
|
2719
|
+
"h-full rounded-full",
|
|
2720
|
+
r.danger ? "bg-danger-solid" : "bg-brand-solid"
|
|
2721
|
+
),
|
|
2722
|
+
style: { width: `${r.pct}%` }
|
|
2723
|
+
}
|
|
2724
|
+
) })
|
|
2725
|
+
] }, r.label))
|
|
2726
|
+
}
|
|
2727
|
+
)
|
|
2728
|
+
);
|
|
2729
|
+
ProgressList.displayName = "ProgressList";
|
|
2730
|
+
var Ring = React16.forwardRef(
|
|
2731
|
+
({ pct, size = 84, label, className, style, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
2732
|
+
"div",
|
|
2733
|
+
{
|
|
2734
|
+
ref,
|
|
2735
|
+
className: cn("relative grid place-items-center", className),
|
|
2736
|
+
style: { height: size, width: size, ...style },
|
|
2737
|
+
...props,
|
|
2738
|
+
children: [
|
|
2739
|
+
/* @__PURE__ */ jsxs("svg", { viewBox: "0 0 36 36", className: "h-full w-full -rotate-90", children: [
|
|
2740
|
+
/* @__PURE__ */ jsx(
|
|
2741
|
+
"circle",
|
|
2742
|
+
{
|
|
2743
|
+
cx: "18",
|
|
2744
|
+
cy: "18",
|
|
2745
|
+
r: "15.5",
|
|
2746
|
+
fill: "none",
|
|
2747
|
+
strokeWidth: "3",
|
|
2748
|
+
className: "stroke-surface-sunken"
|
|
2749
|
+
}
|
|
2750
|
+
),
|
|
2751
|
+
/* @__PURE__ */ jsx(
|
|
2752
|
+
"circle",
|
|
2753
|
+
{
|
|
2754
|
+
cx: "18",
|
|
2755
|
+
cy: "18",
|
|
2756
|
+
r: "15.5",
|
|
2757
|
+
fill: "none",
|
|
2758
|
+
strokeWidth: "3",
|
|
2759
|
+
strokeLinecap: "round",
|
|
2760
|
+
pathLength: 100,
|
|
2761
|
+
strokeDasharray: `${pct} 100`,
|
|
2762
|
+
className: "stroke-brand-solid"
|
|
2763
|
+
}
|
|
2764
|
+
)
|
|
2765
|
+
] }),
|
|
2766
|
+
/* @__PURE__ */ jsx("b", { className: "absolute text-sm font-bold text-text-strong", children: label ?? `${pct}%` })
|
|
2767
|
+
]
|
|
2768
|
+
}
|
|
2769
|
+
)
|
|
2770
|
+
);
|
|
2771
|
+
Ring.displayName = "Ring";
|
|
2772
|
+
var StackBar = React16.forwardRef(
|
|
2773
|
+
({ segments, showLegend = true, className, ...props }, ref) => /* @__PURE__ */ jsxs("div", { ref, className: cn("w-[360px]", className), ...props, children: [
|
|
2774
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-6 gap-0.5", children: segments.map((s, i) => /* @__PURE__ */ jsx(
|
|
2775
|
+
"div",
|
|
2776
|
+
{
|
|
2777
|
+
className: cn(
|
|
2778
|
+
s.className ?? "bg-brand-solid",
|
|
2779
|
+
i === 0 && "rounded-l-full",
|
|
2780
|
+
i === segments.length - 1 && "rounded-r-full"
|
|
2781
|
+
),
|
|
2782
|
+
style: { width: `${s.pct}%` }
|
|
2783
|
+
},
|
|
2784
|
+
s.label
|
|
2785
|
+
)) }),
|
|
2786
|
+
showLegend && /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-x-4 gap-y-1", children: segments.map((s) => /* @__PURE__ */ jsxs(
|
|
2787
|
+
"div",
|
|
2788
|
+
{
|
|
2789
|
+
className: "flex items-center gap-1.5 text-xs text-text-subtle",
|
|
2790
|
+
children: [
|
|
2791
|
+
/* @__PURE__ */ jsx(
|
|
2792
|
+
"span",
|
|
2793
|
+
{
|
|
2794
|
+
className: cn(
|
|
2795
|
+
"h-2.5 w-2.5 rounded-full",
|
|
2796
|
+
s.className ?? "bg-brand-solid"
|
|
2797
|
+
)
|
|
2798
|
+
}
|
|
2799
|
+
),
|
|
2800
|
+
s.label,
|
|
2801
|
+
" ",
|
|
2802
|
+
/* @__PURE__ */ jsxs("span", { className: "text-text-default", children: [
|
|
2803
|
+
s.pct,
|
|
2804
|
+
"%"
|
|
2805
|
+
] })
|
|
2806
|
+
]
|
|
2807
|
+
},
|
|
2808
|
+
s.label
|
|
2809
|
+
)) })
|
|
2810
|
+
] })
|
|
2811
|
+
);
|
|
2812
|
+
StackBar.displayName = "StackBar";
|
|
2813
|
+
var BAR_BY_STATE = {
|
|
2814
|
+
reached: "bg-brand-solid",
|
|
2815
|
+
unreached: "bg-brand-subtle",
|
|
2816
|
+
pending: "bg-surface-sunken"
|
|
2817
|
+
};
|
|
2818
|
+
var WorkHoursBar = React16.forwardRef(
|
|
2819
|
+
({ data, max = 12, height = 120, caption, className, ...props }, ref) => /* @__PURE__ */ jsxs("div", { ref, className, ...props, children: [
|
|
2820
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-end gap-3", children: data.map((d) => {
|
|
2821
|
+
const barH = d.state === "pending" ? 4 : d.hours / max * height;
|
|
2822
|
+
const labelCls = d.today ? "text-brand-text font-semibold" : d.future ? "text-text-disabled" : "text-text-subtle";
|
|
2823
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
2824
|
+
/* @__PURE__ */ jsx("div", { className: "flex w-8 items-end", style: { height }, children: /* @__PURE__ */ jsx(
|
|
2825
|
+
"div",
|
|
2826
|
+
{
|
|
2827
|
+
className: cn("w-full rounded-t", BAR_BY_STATE[d.state]),
|
|
2828
|
+
style: { height: barH }
|
|
2829
|
+
}
|
|
2830
|
+
) }),
|
|
2831
|
+
/* @__PURE__ */ jsx("div", { className: cn("text-xs", labelCls), children: d.day })
|
|
2832
|
+
] }, d.day);
|
|
2833
|
+
}) }),
|
|
2834
|
+
caption != null && /* @__PURE__ */ jsx("div", { className: "mt-2 text-xs text-text-subtle", children: caption })
|
|
2835
|
+
] })
|
|
2836
|
+
);
|
|
2837
|
+
WorkHoursBar.displayName = "WorkHoursBar";
|
|
2838
|
+
var Kbd = React16.forwardRef(
|
|
2839
|
+
({ active, className, children, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2840
|
+
"kbd",
|
|
2841
|
+
{
|
|
2842
|
+
ref,
|
|
2843
|
+
className: cn(
|
|
2844
|
+
"rounded border px-1.5 py-px font-mono text-xs",
|
|
2845
|
+
active ? "border-current bg-transparent text-brand-text" : "border-border-subtle bg-bg-base text-text-subtle",
|
|
2846
|
+
className
|
|
2847
|
+
),
|
|
2848
|
+
...props,
|
|
2849
|
+
children
|
|
2850
|
+
}
|
|
2851
|
+
)
|
|
2852
|
+
);
|
|
2853
|
+
Kbd.displayName = "Kbd";
|
|
2854
|
+
var CommandPalette = React16.forwardRef(
|
|
2855
|
+
({
|
|
2856
|
+
groups,
|
|
2857
|
+
onSelect,
|
|
2858
|
+
activeId,
|
|
2859
|
+
placeholder = "\uBA85\uB839 \uB610\uB294 \uAC80\uC0C9\u2026",
|
|
2860
|
+
searchKbd = "\u2318K",
|
|
2861
|
+
open = true,
|
|
2862
|
+
className,
|
|
2863
|
+
...props
|
|
2864
|
+
}, ref) => {
|
|
2865
|
+
if (!open) return null;
|
|
2866
|
+
return /* @__PURE__ */ jsxs(
|
|
2867
|
+
"div",
|
|
2868
|
+
{
|
|
2869
|
+
ref,
|
|
2870
|
+
role: "dialog",
|
|
2871
|
+
"aria-label": "\uCEE4\uB9E8\uB4DC \uD314\uB808\uD2B8",
|
|
2872
|
+
className: cn(
|
|
2873
|
+
"w-[420px] max-w-full overflow-hidden rounded-lg border border-border-subtle bg-surface-default shadow-lg",
|
|
2874
|
+
className
|
|
2875
|
+
),
|
|
2876
|
+
...props,
|
|
2877
|
+
children: [
|
|
2878
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 border-b border-border-subtle px-4 py-3.5", children: [
|
|
2879
|
+
/* @__PURE__ */ jsx(SearchIcon, { size: 18, className: "text-text-subtle" }),
|
|
2880
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm text-text-subtle", children: placeholder }),
|
|
2881
|
+
searchKbd ? /* @__PURE__ */ jsx(Kbd, { children: searchKbd }) : null
|
|
2882
|
+
] }),
|
|
2883
|
+
/* @__PURE__ */ jsx("div", { className: "p-1.5", children: groups.map((group, gi) => /* @__PURE__ */ jsxs("div", { children: [
|
|
2884
|
+
group.heading ? /* @__PURE__ */ jsx("div", { className: "px-2.5 pb-1 pt-2 text-xs font-bold uppercase tracking-wide text-text-subtle", children: group.heading }) : null,
|
|
2885
|
+
group.items.map((item) => {
|
|
2886
|
+
const active = item.id === activeId;
|
|
2887
|
+
return /* @__PURE__ */ jsxs(
|
|
2888
|
+
"button",
|
|
2889
|
+
{
|
|
2890
|
+
type: "button",
|
|
2891
|
+
onClick: () => onSelect?.(item),
|
|
2892
|
+
className: cn(
|
|
2893
|
+
"flex w-full items-center gap-2.5 rounded px-2.5 py-2 text-left text-sm [&>svg]:h-[17px] [&>svg]:w-[17px]",
|
|
2894
|
+
active ? "bg-brand-subtle text-brand-text" : "text-text-default hover:bg-surface-hover"
|
|
2895
|
+
),
|
|
2896
|
+
children: [
|
|
2897
|
+
item.icon,
|
|
2898
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1", children: item.label }),
|
|
2899
|
+
item.kbd ? /* @__PURE__ */ jsx(Kbd, { active, children: item.kbd }) : null
|
|
2900
|
+
]
|
|
2901
|
+
},
|
|
2902
|
+
item.id
|
|
2903
|
+
);
|
|
2904
|
+
})
|
|
2905
|
+
] }, group.heading ?? gi)) })
|
|
2906
|
+
]
|
|
2907
|
+
}
|
|
2908
|
+
);
|
|
2909
|
+
}
|
|
2910
|
+
);
|
|
2911
|
+
CommandPalette.displayName = "CommandPalette";
|
|
2912
|
+
var AvatarWithPresence = React16.forwardRef(
|
|
2913
|
+
({
|
|
2914
|
+
name,
|
|
2915
|
+
status = "online",
|
|
2916
|
+
color,
|
|
2917
|
+
src,
|
|
2918
|
+
size,
|
|
2919
|
+
ringClassName = "ring-surface-default",
|
|
2920
|
+
className
|
|
2921
|
+
}, ref) => /* @__PURE__ */ jsxs("span", { ref, className: cn("relative inline-flex shrink-0", className), children: [
|
|
2922
|
+
/* @__PURE__ */ jsx(
|
|
2923
|
+
Avatar,
|
|
2924
|
+
{
|
|
2925
|
+
size,
|
|
2926
|
+
color,
|
|
2927
|
+
src,
|
|
2928
|
+
alt: name,
|
|
2929
|
+
className: cn("ring-0", status === "offline" && "opacity-[.55]")
|
|
2930
|
+
}
|
|
2931
|
+
),
|
|
2932
|
+
/* @__PURE__ */ jsx(
|
|
2933
|
+
Presence,
|
|
2934
|
+
{
|
|
2935
|
+
status,
|
|
2936
|
+
size: "sm",
|
|
2937
|
+
className: cn("absolute -bottom-0.5 -right-0.5 ring-2", ringClassName)
|
|
2938
|
+
}
|
|
2939
|
+
)
|
|
2940
|
+
] })
|
|
2941
|
+
);
|
|
2942
|
+
AvatarWithPresence.displayName = "AvatarWithPresence";
|
|
2943
|
+
var SidebarSection = React16.forwardRef(({ title, addable, onAdd, addLabel, className, children, ...props }, ref) => /* @__PURE__ */ jsxs("div", { ref, className, ...props, children: [
|
|
2944
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 px-2 pb-1.5 pt-2.5 text-xs font-semibold text-text-subtle", children: [
|
|
2945
|
+
title,
|
|
2946
|
+
addable && /* @__PURE__ */ jsx(
|
|
2947
|
+
Button,
|
|
2948
|
+
{
|
|
2949
|
+
type: "button",
|
|
2950
|
+
variant: "ghost",
|
|
2951
|
+
size: "sm",
|
|
2952
|
+
onClick: onAdd,
|
|
2953
|
+
"aria-label": addLabel ?? `${title} \uCD94\uAC00`,
|
|
2954
|
+
className: "ml-auto h-6 w-6 rounded p-0 text-brand-solid",
|
|
2955
|
+
children: /* @__PURE__ */ jsx(PlusIcon, { size: 16 })
|
|
2956
|
+
}
|
|
2957
|
+
)
|
|
2958
|
+
] }),
|
|
2959
|
+
children
|
|
2960
|
+
] }));
|
|
2961
|
+
SidebarSection.displayName = "SidebarSection";
|
|
2962
|
+
var SidebarChannel = React16.forwardRef(({ name, icon, locked, active, badge, className, ...props }, ref) => {
|
|
2963
|
+
const resolvedIcon = icon ?? (locked ? /* @__PURE__ */ jsx(LockIcon, { size: 17 }) : /* @__PURE__ */ jsx(HashIcon, { size: 17 }));
|
|
2964
|
+
return /* @__PURE__ */ jsxs(
|
|
2965
|
+
"button",
|
|
2966
|
+
{
|
|
2967
|
+
ref,
|
|
2968
|
+
type: "button",
|
|
2969
|
+
"aria-current": active ? "page" : void 0,
|
|
2970
|
+
className: cn(
|
|
2971
|
+
"flex h-9 w-full cursor-pointer items-center gap-2.5 rounded-lg px-2.5 text-left text-sm hover:bg-sidebar-accent",
|
|
2972
|
+
active ? "bg-sidebar-accent font-semibold text-sidebar-accent-fg" : "text-sidebar-fg",
|
|
2973
|
+
className
|
|
2974
|
+
),
|
|
2975
|
+
...props,
|
|
2976
|
+
children: [
|
|
2977
|
+
/* @__PURE__ */ jsx(
|
|
2978
|
+
"span",
|
|
2979
|
+
{
|
|
2980
|
+
className: cn(
|
|
2981
|
+
"inline-flex shrink-0",
|
|
2982
|
+
active ? "text-sidebar-accent-fg" : "text-sidebar-fg"
|
|
2983
|
+
),
|
|
2984
|
+
children: resolvedIcon
|
|
2985
|
+
}
|
|
2986
|
+
),
|
|
2987
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: name }),
|
|
2988
|
+
badge != null && badge !== "" && /* @__PURE__ */ jsx("span", { className: "ml-auto inline-flex h-[18px] min-w-[18px] shrink-0 items-center justify-center rounded-full bg-brand-solid px-1.5 text-[11px] font-semibold leading-none text-text-on-brand", children: badge })
|
|
2989
|
+
]
|
|
2990
|
+
}
|
|
2991
|
+
);
|
|
2992
|
+
});
|
|
2993
|
+
SidebarChannel.displayName = "SidebarChannel";
|
|
2994
|
+
var SidebarDm = React16.forwardRef(
|
|
2995
|
+
({ name, status = "online", color, avatarSrc, pinned, className, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
2996
|
+
"button",
|
|
2997
|
+
{
|
|
2998
|
+
ref,
|
|
2999
|
+
type: "button",
|
|
3000
|
+
className: cn(
|
|
3001
|
+
"flex h-9 w-full cursor-pointer items-center gap-2.5 rounded-lg px-2.5 text-left text-sm text-sidebar-fg hover:bg-sidebar-accent",
|
|
3002
|
+
className
|
|
3003
|
+
),
|
|
3004
|
+
...props,
|
|
3005
|
+
children: [
|
|
3006
|
+
/* @__PURE__ */ jsx(
|
|
3007
|
+
AvatarWithPresence,
|
|
3008
|
+
{
|
|
3009
|
+
name,
|
|
3010
|
+
status,
|
|
3011
|
+
color,
|
|
3012
|
+
src: avatarSrc,
|
|
3013
|
+
size: "xs",
|
|
3014
|
+
ringClassName: "ring-sidebar-bg"
|
|
3015
|
+
}
|
|
3016
|
+
),
|
|
3017
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: name }),
|
|
3018
|
+
pinned && /* @__PURE__ */ jsx(
|
|
3019
|
+
PinIcon,
|
|
3020
|
+
{
|
|
3021
|
+
size: 14,
|
|
3022
|
+
className: "ml-auto shrink-0 text-text-subtle",
|
|
3023
|
+
"aria-label": "\uACE0\uC815\uB428"
|
|
3024
|
+
}
|
|
3025
|
+
)
|
|
3026
|
+
]
|
|
3027
|
+
}
|
|
3028
|
+
)
|
|
3029
|
+
);
|
|
3030
|
+
SidebarDm.displayName = "SidebarDm";
|
|
3031
|
+
var sidebarContainerVariants = cva(
|
|
3032
|
+
"border-border-subtle bg-sidebar-bg p-2",
|
|
3033
|
+
{
|
|
3034
|
+
variants: {
|
|
3035
|
+
variant: {
|
|
3036
|
+
panel: "w-[260px] max-w-full rounded-lg border",
|
|
3037
|
+
shell: "h-full border-r"
|
|
3038
|
+
}
|
|
3039
|
+
},
|
|
3040
|
+
defaultVariants: { variant: "panel" }
|
|
3041
|
+
}
|
|
3042
|
+
);
|
|
3043
|
+
var SidebarPanel = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
3044
|
+
"div",
|
|
3045
|
+
{
|
|
3046
|
+
ref,
|
|
3047
|
+
className: cn(sidebarContainerVariants({ variant: "panel" }), className),
|
|
3048
|
+
...props
|
|
3049
|
+
}
|
|
3050
|
+
));
|
|
3051
|
+
SidebarPanel.displayName = "SidebarPanel";
|
|
3052
|
+
var Sidebar = React16.forwardRef(
|
|
3053
|
+
({ sections, variant = "panel", className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
3054
|
+
"nav",
|
|
3055
|
+
{
|
|
3056
|
+
ref,
|
|
3057
|
+
className: cn(sidebarContainerVariants({ variant }), className),
|
|
3058
|
+
...props,
|
|
3059
|
+
children: sections.map((section, si) => /* @__PURE__ */ jsx(
|
|
3060
|
+
SidebarSection,
|
|
3061
|
+
{
|
|
3062
|
+
title: section.title,
|
|
3063
|
+
addable: section.addable,
|
|
3064
|
+
onAdd: section.onAdd,
|
|
3065
|
+
children: section.items.map((item, ii) => {
|
|
3066
|
+
const key = item.id ?? item.name + ii;
|
|
3067
|
+
if (item.kind === "dm") {
|
|
3068
|
+
const { kind: kind2, id: id2, ...rest2 } = item;
|
|
3069
|
+
return /* @__PURE__ */ jsx(SidebarDm, { ...rest2 }, key);
|
|
3070
|
+
}
|
|
3071
|
+
const { kind, id, ...rest } = item;
|
|
3072
|
+
return /* @__PURE__ */ jsx(SidebarChannel, { ...rest }, key);
|
|
3073
|
+
})
|
|
3074
|
+
},
|
|
3075
|
+
section.title + si
|
|
3076
|
+
))
|
|
3077
|
+
}
|
|
3078
|
+
)
|
|
3079
|
+
);
|
|
3080
|
+
Sidebar.displayName = "Sidebar";
|
|
3081
|
+
var List = React16.forwardRef(
|
|
3082
|
+
({ className, bordered = true, divided = true, ...props }, ref) => {
|
|
3083
|
+
return /* @__PURE__ */ jsx(
|
|
3084
|
+
"ul",
|
|
3085
|
+
{
|
|
3086
|
+
ref,
|
|
3087
|
+
className: cn(
|
|
3088
|
+
"bg-surface-default px-4",
|
|
3089
|
+
bordered && "rounded-lg border border-border-subtle",
|
|
3090
|
+
divided && "[&>li+li]:border-t [&>li+li]:border-border-subtle",
|
|
3091
|
+
className
|
|
3092
|
+
),
|
|
3093
|
+
...props
|
|
3094
|
+
}
|
|
3095
|
+
);
|
|
3096
|
+
}
|
|
3097
|
+
);
|
|
3098
|
+
List.displayName = "List";
|
|
3099
|
+
var ListItem = React16.forwardRef(
|
|
3100
|
+
({ className, leading, title, description, trailing, ...props }, ref) => {
|
|
3101
|
+
return /* @__PURE__ */ jsxs(
|
|
3102
|
+
"li",
|
|
3103
|
+
{
|
|
3104
|
+
ref,
|
|
3105
|
+
className: cn("flex items-center gap-3 py-2.5", className),
|
|
3106
|
+
...props,
|
|
3107
|
+
children: [
|
|
3108
|
+
leading != null ? /* @__PURE__ */ jsx("div", { className: "relative shrink-0", children: leading }) : null,
|
|
3109
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
3110
|
+
/* @__PURE__ */ jsx("div", { className: "truncate text-sm font-semibold text-text-default", children: title }),
|
|
3111
|
+
description != null ? /* @__PURE__ */ jsx("div", { className: "truncate text-xs text-text-subtle", children: description }) : null
|
|
3112
|
+
] }),
|
|
3113
|
+
trailing != null ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children: trailing }) : null
|
|
3114
|
+
]
|
|
3115
|
+
}
|
|
3116
|
+
);
|
|
3117
|
+
}
|
|
3118
|
+
);
|
|
3119
|
+
ListItem.displayName = "ListItem";
|
|
3120
|
+
var SuccessCheck = React16.forwardRef(
|
|
3121
|
+
({ size = 22, className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
3122
|
+
"span",
|
|
3123
|
+
{
|
|
3124
|
+
ref,
|
|
3125
|
+
className: cn(
|
|
3126
|
+
"inline-flex shrink-0 items-center justify-center rounded-full bg-brand-solid text-text-on-brand",
|
|
3127
|
+
className
|
|
3128
|
+
),
|
|
3129
|
+
style: { width: size, height: size },
|
|
3130
|
+
...props,
|
|
3131
|
+
children: /* @__PURE__ */ jsx(CheckIcon4, { size: Math.round(size * 0.6), strokeWidth: 3 })
|
|
3132
|
+
}
|
|
3133
|
+
)
|
|
3134
|
+
);
|
|
3135
|
+
SuccessCheck.displayName = "SuccessCheck";
|
|
3136
|
+
var separatorVariants = cva("shrink-0 border-border-default", {
|
|
3137
|
+
variants: {
|
|
3138
|
+
orientation: {
|
|
3139
|
+
horizontal: "w-full border-t",
|
|
3140
|
+
vertical: "h-full self-stretch border-l"
|
|
3141
|
+
}
|
|
3142
|
+
},
|
|
3143
|
+
defaultVariants: {
|
|
3144
|
+
orientation: "horizontal"
|
|
3145
|
+
}
|
|
3146
|
+
});
|
|
3147
|
+
var Separator = React16.forwardRef(
|
|
3148
|
+
({ className, orientation = "horizontal", label, decorative = false, ...props }, ref) => {
|
|
3149
|
+
const resolvedOrientation = orientation === "vertical" ? "vertical" : "horizontal";
|
|
3150
|
+
const ariaOrientation = label != null ? "horizontal" : resolvedOrientation;
|
|
3151
|
+
const a11yProps = decorative ? { role: "none" } : { role: "separator", "aria-orientation": ariaOrientation };
|
|
3152
|
+
if (label != null) {
|
|
3153
|
+
return /* @__PURE__ */ jsxs(
|
|
3154
|
+
"div",
|
|
3155
|
+
{
|
|
3156
|
+
ref,
|
|
3157
|
+
...a11yProps,
|
|
3158
|
+
className: cn(
|
|
3159
|
+
"flex w-full items-center gap-3 text-sm text-text-subtle",
|
|
3160
|
+
className
|
|
3161
|
+
),
|
|
3162
|
+
...props,
|
|
3163
|
+
children: [
|
|
3164
|
+
/* @__PURE__ */ jsx(
|
|
3165
|
+
"span",
|
|
3166
|
+
{
|
|
3167
|
+
"aria-hidden": "true",
|
|
3168
|
+
className: "flex-1 border-t border-border-default"
|
|
3169
|
+
}
|
|
3170
|
+
),
|
|
3171
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0", children: label }),
|
|
3172
|
+
/* @__PURE__ */ jsx(
|
|
3173
|
+
"span",
|
|
3174
|
+
{
|
|
3175
|
+
"aria-hidden": "true",
|
|
3176
|
+
className: "flex-1 border-t border-border-default"
|
|
3177
|
+
}
|
|
3178
|
+
)
|
|
3179
|
+
]
|
|
3180
|
+
}
|
|
3181
|
+
);
|
|
3182
|
+
}
|
|
3183
|
+
return /* @__PURE__ */ jsx(
|
|
3184
|
+
"div",
|
|
3185
|
+
{
|
|
3186
|
+
ref,
|
|
3187
|
+
...a11yProps,
|
|
3188
|
+
className: cn(
|
|
3189
|
+
separatorVariants({ orientation: resolvedOrientation }),
|
|
3190
|
+
className
|
|
3191
|
+
),
|
|
3192
|
+
...props
|
|
3193
|
+
}
|
|
3194
|
+
);
|
|
3195
|
+
}
|
|
3196
|
+
);
|
|
3197
|
+
Separator.displayName = "Separator";
|
|
3198
|
+
var popoverContentVariants = cva(
|
|
3199
|
+
// content shell: raised surface · border · radius lg(8) · shadow-popover · padding
|
|
3200
|
+
"absolute z-50 w-max min-w-[220px] max-w-xs rounded-lg border border-border-default bg-surface-default p-4 text-sm text-text-default shadow-popover outline-none",
|
|
3201
|
+
{
|
|
3202
|
+
variants: {
|
|
3203
|
+
placement: {
|
|
3204
|
+
top: "bottom-full mb-2",
|
|
3205
|
+
bottom: "top-full mt-2",
|
|
3206
|
+
left: "right-full mr-2",
|
|
3207
|
+
right: "left-full ml-2"
|
|
3208
|
+
},
|
|
3209
|
+
align: {
|
|
3210
|
+
start: "",
|
|
3211
|
+
center: "",
|
|
3212
|
+
end: ""
|
|
3213
|
+
}
|
|
3214
|
+
},
|
|
3215
|
+
compoundVariants: [
|
|
3216
|
+
// vertical placements (top/bottom) → align along the X axis
|
|
3217
|
+
{ placement: ["top", "bottom"], align: "start", class: "left-0" },
|
|
3218
|
+
{
|
|
3219
|
+
placement: ["top", "bottom"],
|
|
3220
|
+
align: "center",
|
|
3221
|
+
class: "left-1/2 -translate-x-1/2"
|
|
3222
|
+
},
|
|
3223
|
+
{ placement: ["top", "bottom"], align: "end", class: "right-0" },
|
|
3224
|
+
// horizontal placements (left/right) → align along the Y axis
|
|
3225
|
+
{ placement: ["left", "right"], align: "start", class: "top-0" },
|
|
3226
|
+
{
|
|
3227
|
+
placement: ["left", "right"],
|
|
3228
|
+
align: "center",
|
|
3229
|
+
class: "top-1/2 -translate-y-1/2"
|
|
3230
|
+
},
|
|
3231
|
+
{ placement: ["left", "right"], align: "end", class: "bottom-0" }
|
|
3232
|
+
],
|
|
3233
|
+
defaultVariants: {
|
|
3234
|
+
placement: "bottom",
|
|
3235
|
+
align: "center"
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
);
|
|
3239
|
+
var Popover = React16.forwardRef(
|
|
3240
|
+
({
|
|
3241
|
+
className,
|
|
3242
|
+
content,
|
|
3243
|
+
children,
|
|
3244
|
+
placement = "bottom",
|
|
3245
|
+
align = "center",
|
|
3246
|
+
open: openProp,
|
|
3247
|
+
defaultOpen = false,
|
|
3248
|
+
onOpenChange,
|
|
3249
|
+
...props
|
|
3250
|
+
}, ref) => {
|
|
3251
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React16.useState(defaultOpen);
|
|
3252
|
+
const isControlled = openProp !== void 0;
|
|
3253
|
+
const open = isControlled ? openProp : uncontrolledOpen;
|
|
3254
|
+
const innerRef = React16.useRef(null);
|
|
3255
|
+
React16.useImperativeHandle(ref, () => innerRef.current, []);
|
|
3256
|
+
const contentId = React16.useId();
|
|
3257
|
+
const setOpen = React16.useCallback(
|
|
3258
|
+
(next) => {
|
|
3259
|
+
if (!isControlled) setUncontrolledOpen(next);
|
|
3260
|
+
onOpenChange?.(next);
|
|
3261
|
+
},
|
|
3262
|
+
[isControlled, onOpenChange]
|
|
3263
|
+
);
|
|
3264
|
+
React16.useEffect(() => {
|
|
3265
|
+
if (!open) return;
|
|
3266
|
+
const onPointerDown = (event) => {
|
|
3267
|
+
const node = innerRef.current;
|
|
3268
|
+
if (node && !node.contains(event.target)) setOpen(false);
|
|
3269
|
+
};
|
|
3270
|
+
const onKeyDown = (event) => {
|
|
3271
|
+
if (event.key === "Escape") setOpen(false);
|
|
3272
|
+
};
|
|
3273
|
+
document.addEventListener("pointerdown", onPointerDown);
|
|
3274
|
+
document.addEventListener("keydown", onKeyDown);
|
|
3275
|
+
return () => {
|
|
3276
|
+
document.removeEventListener("pointerdown", onPointerDown);
|
|
3277
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
3278
|
+
};
|
|
3279
|
+
}, [open, setOpen]);
|
|
3280
|
+
return /* @__PURE__ */ jsxs(
|
|
3281
|
+
"div",
|
|
3282
|
+
{
|
|
3283
|
+
ref: innerRef,
|
|
3284
|
+
className: cn("relative inline-flex", className),
|
|
3285
|
+
...props,
|
|
3286
|
+
children: [
|
|
3287
|
+
/* @__PURE__ */ jsx(
|
|
3288
|
+
"span",
|
|
3289
|
+
{
|
|
3290
|
+
className: "inline-flex",
|
|
3291
|
+
"aria-haspopup": "dialog",
|
|
3292
|
+
"aria-expanded": open,
|
|
3293
|
+
"aria-controls": open ? contentId : void 0,
|
|
3294
|
+
onClick: (event) => {
|
|
3295
|
+
if (!event.defaultPrevented) setOpen(!open);
|
|
3296
|
+
},
|
|
3297
|
+
children
|
|
3298
|
+
}
|
|
3299
|
+
),
|
|
3300
|
+
open ? /* @__PURE__ */ jsx(
|
|
3301
|
+
"div",
|
|
3302
|
+
{
|
|
3303
|
+
id: contentId,
|
|
3304
|
+
role: "dialog",
|
|
3305
|
+
"aria-modal": "false",
|
|
3306
|
+
className: cn(popoverContentVariants({ placement, align })),
|
|
3307
|
+
children: content
|
|
3308
|
+
}
|
|
3309
|
+
) : null
|
|
3310
|
+
]
|
|
3311
|
+
}
|
|
3312
|
+
);
|
|
3313
|
+
}
|
|
3314
|
+
);
|
|
3315
|
+
Popover.displayName = "Popover";
|
|
3316
|
+
var fieldVariants = cva("flex gap-1.5", {
|
|
3317
|
+
variants: {
|
|
3318
|
+
orientation: {
|
|
3319
|
+
vertical: "flex-col",
|
|
3320
|
+
horizontal: "flex-row items-start gap-4"
|
|
3321
|
+
}
|
|
3322
|
+
},
|
|
3323
|
+
defaultVariants: {
|
|
3324
|
+
orientation: "vertical"
|
|
3325
|
+
}
|
|
3326
|
+
});
|
|
3327
|
+
var Field = React16.forwardRef(
|
|
3328
|
+
({
|
|
3329
|
+
className,
|
|
3330
|
+
orientation = "vertical",
|
|
3331
|
+
label,
|
|
3332
|
+
htmlFor,
|
|
3333
|
+
required = false,
|
|
3334
|
+
optional = false,
|
|
3335
|
+
hint,
|
|
3336
|
+
error,
|
|
3337
|
+
children,
|
|
3338
|
+
...props
|
|
3339
|
+
}, ref) => {
|
|
3340
|
+
const reactId = React16.useId();
|
|
3341
|
+
const controlId = htmlFor ?? reactId;
|
|
3342
|
+
const isHorizontal = orientation === "horizontal";
|
|
3343
|
+
const messageId = error ? `${controlId}-error` : hint ? `${controlId}-hint` : void 0;
|
|
3344
|
+
const control = React16.isValidElement(children) ? React16.cloneElement(children, {
|
|
3345
|
+
id: children.props.id ?? controlId,
|
|
3346
|
+
"aria-invalid": error ? true : children.props["aria-invalid"],
|
|
3347
|
+
"aria-describedby": [children.props["aria-describedby"], messageId].filter(Boolean).join(" ") || void 0
|
|
3348
|
+
}) : children;
|
|
3349
|
+
return /* @__PURE__ */ jsxs(
|
|
3350
|
+
"div",
|
|
3351
|
+
{
|
|
3352
|
+
ref,
|
|
3353
|
+
className: cn(fieldVariants({ orientation }), className),
|
|
3354
|
+
...props,
|
|
3355
|
+
children: [
|
|
3356
|
+
label ? /* @__PURE__ */ jsx("div", { className: cn(isHorizontal && "w-40 shrink-0 pt-2"), children: /* @__PURE__ */ jsxs(
|
|
3357
|
+
"label",
|
|
3358
|
+
{
|
|
3359
|
+
htmlFor: controlId,
|
|
3360
|
+
className: "inline-flex items-center gap-1.5 text-sm font-medium text-text-default",
|
|
3361
|
+
children: [
|
|
3362
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
3363
|
+
label,
|
|
3364
|
+
required ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-danger-text", children: "*" }) : null
|
|
3365
|
+
] }),
|
|
3366
|
+
optional && !required ? /* @__PURE__ */ jsx(Label, { variant: "neutral", children: "\uC120\uD0DD" }) : null
|
|
3367
|
+
]
|
|
3368
|
+
}
|
|
3369
|
+
) }) : null,
|
|
3370
|
+
/* @__PURE__ */ jsxs(
|
|
3371
|
+
"div",
|
|
3372
|
+
{
|
|
3373
|
+
className: cn(
|
|
3374
|
+
"flex min-w-0 flex-col gap-1.5",
|
|
3375
|
+
isHorizontal && "flex-1"
|
|
3376
|
+
),
|
|
3377
|
+
children: [
|
|
3378
|
+
control,
|
|
3379
|
+
error ? /* @__PURE__ */ jsx(
|
|
3380
|
+
"p",
|
|
3381
|
+
{
|
|
3382
|
+
id: `${controlId}-error`,
|
|
3383
|
+
className: "flex items-center gap-1 text-sm text-danger-text",
|
|
3384
|
+
children: error
|
|
3385
|
+
}
|
|
3386
|
+
) : hint ? /* @__PURE__ */ jsx(
|
|
3387
|
+
"p",
|
|
3388
|
+
{
|
|
3389
|
+
id: `${controlId}-hint`,
|
|
3390
|
+
className: "flex items-center gap-1 text-sm text-text-subtle",
|
|
3391
|
+
children: hint
|
|
3392
|
+
}
|
|
3393
|
+
) : null
|
|
3394
|
+
]
|
|
3395
|
+
}
|
|
3396
|
+
)
|
|
3397
|
+
]
|
|
3398
|
+
}
|
|
3399
|
+
);
|
|
3400
|
+
}
|
|
3401
|
+
);
|
|
3402
|
+
Field.displayName = "Field";
|
|
3403
|
+
var accessoryButtonClass = "inline-flex size-6 shrink-0 items-center justify-center rounded text-text-subtle transition-colors hover:bg-surface-hover hover:text-text-default active:bg-surface-pressed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-border disabled:pointer-events-none disabled:text-text-disabled";
|
|
3404
|
+
var SearchField = React16.forwardRef(
|
|
3405
|
+
({
|
|
3406
|
+
className,
|
|
3407
|
+
value,
|
|
3408
|
+
defaultValue,
|
|
3409
|
+
onValueChange,
|
|
3410
|
+
placeholder = "\uAC80\uC0C9",
|
|
3411
|
+
resultCount,
|
|
3412
|
+
onPrev,
|
|
3413
|
+
onNext,
|
|
3414
|
+
onClear,
|
|
3415
|
+
size,
|
|
3416
|
+
disabled,
|
|
3417
|
+
...props
|
|
3418
|
+
}, ref) => {
|
|
3419
|
+
const isControlled = value !== void 0;
|
|
3420
|
+
const [internalValue, setInternalValue] = React16.useState(
|
|
3421
|
+
defaultValue ?? ""
|
|
3422
|
+
);
|
|
3423
|
+
const currentValue = isControlled ? value : internalValue;
|
|
3424
|
+
const innerRef = React16.useRef(null);
|
|
3425
|
+
React16.useImperativeHandle(ref, () => innerRef.current);
|
|
3426
|
+
const commit = (next) => {
|
|
3427
|
+
if (!isControlled) setInternalValue(next);
|
|
3428
|
+
onValueChange?.(next);
|
|
3429
|
+
};
|
|
3430
|
+
const handleClear = () => {
|
|
3431
|
+
commit("");
|
|
3432
|
+
onClear?.();
|
|
3433
|
+
innerRef.current?.focus();
|
|
3434
|
+
};
|
|
3435
|
+
const hasCount = typeof resultCount === "number";
|
|
3436
|
+
const hasNav = Boolean(onPrev || onNext);
|
|
3437
|
+
const showClear = Boolean(onClear) && currentValue.length > 0;
|
|
3438
|
+
const showAccessories = hasCount || hasNav || showClear;
|
|
3439
|
+
const showDivider = hasCount && (hasNav || showClear);
|
|
3440
|
+
return /* @__PURE__ */ jsxs(
|
|
3441
|
+
"div",
|
|
3442
|
+
{
|
|
3443
|
+
className: cn(
|
|
3444
|
+
inputVariants({ inputSize: size }),
|
|
3445
|
+
"cursor-text focus-within:border-border-focus focus-within:ring-2 focus-within:ring-brand-border focus-within:ring-offset-2 focus-within:ring-offset-bg-base",
|
|
3446
|
+
disabled && "cursor-not-allowed bg-surface-sunken text-text-disabled",
|
|
3447
|
+
className
|
|
3448
|
+
),
|
|
3449
|
+
children: [
|
|
3450
|
+
/* @__PURE__ */ jsx(
|
|
3451
|
+
"span",
|
|
3452
|
+
{
|
|
3453
|
+
"aria-hidden": "true",
|
|
3454
|
+
className: "flex size-5 shrink-0 items-center justify-center text-text-subtle [&_svg]:size-5",
|
|
3455
|
+
children: /* @__PURE__ */ jsx(SearchIcon, {})
|
|
3456
|
+
}
|
|
3457
|
+
),
|
|
3458
|
+
/* @__PURE__ */ jsx(
|
|
3459
|
+
"input",
|
|
3460
|
+
{
|
|
3461
|
+
ref: innerRef,
|
|
3462
|
+
type: "search",
|
|
3463
|
+
role: "searchbox",
|
|
3464
|
+
value: currentValue,
|
|
3465
|
+
placeholder,
|
|
3466
|
+
disabled,
|
|
3467
|
+
onChange: (event) => commit(event.target.value),
|
|
3468
|
+
className: "h-full w-full min-w-0 bg-transparent text-text-default outline-none placeholder:text-text-subtle disabled:cursor-not-allowed disabled:text-text-disabled [&::-webkit-search-cancel-button]:hidden",
|
|
3469
|
+
...props
|
|
3470
|
+
}
|
|
3471
|
+
),
|
|
3472
|
+
showAccessories ? /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
3473
|
+
hasCount ? /* @__PURE__ */ jsxs("span", { className: "shrink-0 whitespace-nowrap text-sm tabular-nums text-text-subtle", children: [
|
|
3474
|
+
resultCount,
|
|
3475
|
+
"\uAC74"
|
|
3476
|
+
] }) : null,
|
|
3477
|
+
showDivider ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "h-4 w-px bg-border-subtle" }) : null,
|
|
3478
|
+
onPrev ? /* @__PURE__ */ jsx(
|
|
3479
|
+
"button",
|
|
3480
|
+
{
|
|
3481
|
+
type: "button",
|
|
3482
|
+
"aria-label": "\uC774\uC804 \uACB0\uACFC",
|
|
3483
|
+
disabled,
|
|
3484
|
+
onClick: onPrev,
|
|
3485
|
+
className: accessoryButtonClass,
|
|
3486
|
+
children: /* @__PURE__ */ jsx(ChevronLeftIcon2, { size: 16 })
|
|
3487
|
+
}
|
|
3488
|
+
) : null,
|
|
3489
|
+
onNext ? /* @__PURE__ */ jsx(
|
|
3490
|
+
"button",
|
|
3491
|
+
{
|
|
3492
|
+
type: "button",
|
|
3493
|
+
"aria-label": "\uB2E4\uC74C \uACB0\uACFC",
|
|
3494
|
+
disabled,
|
|
3495
|
+
onClick: onNext,
|
|
3496
|
+
className: accessoryButtonClass,
|
|
3497
|
+
children: /* @__PURE__ */ jsx(ChevronRightIcon2, { size: 16 })
|
|
3498
|
+
}
|
|
3499
|
+
) : null,
|
|
3500
|
+
showClear ? /* @__PURE__ */ jsx(
|
|
3501
|
+
"button",
|
|
3502
|
+
{
|
|
3503
|
+
type: "button",
|
|
3504
|
+
"aria-label": "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30",
|
|
3505
|
+
disabled,
|
|
3506
|
+
onClick: handleClear,
|
|
3507
|
+
className: accessoryButtonClass,
|
|
3508
|
+
children: /* @__PURE__ */ jsx(XIcon, { size: 16 })
|
|
3509
|
+
}
|
|
3510
|
+
) : null
|
|
3511
|
+
] }) : null
|
|
3512
|
+
]
|
|
3513
|
+
}
|
|
3514
|
+
);
|
|
3515
|
+
}
|
|
3516
|
+
);
|
|
3517
|
+
SearchField.displayName = "SearchField";
|
|
3518
|
+
var bannerVariants = cva(
|
|
3519
|
+
"flex w-full items-start gap-3 rounded-lg border p-4 text-sm",
|
|
3520
|
+
{
|
|
3521
|
+
variants: {
|
|
3522
|
+
variant: {
|
|
3523
|
+
neutral: "border-border-default bg-surface-sunken text-text-default",
|
|
3524
|
+
brand: "border-brand-border bg-brand-subtle text-brand-text",
|
|
3525
|
+
danger: "border-danger-border bg-danger-subtle text-danger-text"
|
|
3526
|
+
}
|
|
3527
|
+
},
|
|
3528
|
+
defaultVariants: {
|
|
3529
|
+
variant: "neutral"
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
);
|
|
3533
|
+
var Banner = React16.forwardRef(
|
|
3534
|
+
({
|
|
3535
|
+
className,
|
|
3536
|
+
variant,
|
|
3537
|
+
icon,
|
|
3538
|
+
title,
|
|
3539
|
+
dismissible = false,
|
|
3540
|
+
onDismiss,
|
|
3541
|
+
children,
|
|
3542
|
+
role = "status",
|
|
3543
|
+
...props
|
|
3544
|
+
}, ref) => {
|
|
3545
|
+
return /* @__PURE__ */ jsxs(
|
|
3546
|
+
"div",
|
|
3547
|
+
{
|
|
3548
|
+
ref,
|
|
3549
|
+
role,
|
|
3550
|
+
className: cn(bannerVariants({ variant }), className),
|
|
3551
|
+
...props,
|
|
3552
|
+
children: [
|
|
3553
|
+
icon ? /* @__PURE__ */ jsx(
|
|
3554
|
+
"span",
|
|
3555
|
+
{
|
|
3556
|
+
"aria-hidden": "true",
|
|
3557
|
+
className: "mt-0.5 flex size-5 shrink-0 items-center justify-center [&_svg]:size-5",
|
|
3558
|
+
children: icon
|
|
3559
|
+
}
|
|
3560
|
+
) : null,
|
|
3561
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
3562
|
+
title ? /* @__PURE__ */ jsx("p", { className: "font-semibold leading-5", children: title }) : null,
|
|
3563
|
+
children ? /* @__PURE__ */ jsx("div", { className: cn("leading-5", title && "mt-1"), children }) : null
|
|
3564
|
+
] }),
|
|
3565
|
+
dismissible ? /* @__PURE__ */ jsx(
|
|
3566
|
+
"button",
|
|
3567
|
+
{
|
|
3568
|
+
type: "button",
|
|
3569
|
+
"aria-label": "\uB2EB\uAE30",
|
|
3570
|
+
onClick: onDismiss,
|
|
3571
|
+
className: "-m-1 inline-flex size-6 shrink-0 items-center justify-center rounded text-current opacity-70 transition-opacity hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-border focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base",
|
|
3572
|
+
children: /* @__PURE__ */ jsx(XIcon, { className: "size-4" })
|
|
3573
|
+
}
|
|
3574
|
+
) : null
|
|
3575
|
+
]
|
|
3576
|
+
}
|
|
3577
|
+
);
|
|
3578
|
+
}
|
|
3579
|
+
);
|
|
3580
|
+
Banner.displayName = "Banner";
|
|
3581
|
+
|
|
3582
|
+
export { AVATAR_COLORS, Accordion, AccordionItem, Alert, AlertDescription, AlertTitle, Avatar, AvatarFallback, AvatarGroup, AvatarImage, AvatarWithPresence, Banner, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Chip, CommandPalette, Dialog, Button as DialogAction, DialogBody, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogTitle, DropdownMenu, DropdownMenuContent, DropdownMenuEmpty, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, EmptyState, Field, Input, Kbd, KpiRow, Label, List, ListItem, PRESENCE_LABEL, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, Popover, Presence, Progress, ProgressList, Radio, RadioGroup, Ring, ScrollArea, ScrollBar, SearchField, SegmentedControl, Select, Separator, Sheet, SheetBody, SheetDescription, SheetFooter, SheetHandle, SheetHeader, SheetTitle, Sidebar, SidebarChannel, SidebarDm, SidebarPanel, SidebarSection, Skeleton, StackBar, SuccessCheck, Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toast, Toggle, Tooltip, WorkHoursBar, alertVariants, avatarVariants, bannerVariants, buildPageRange, buttonVariants, cardVariants, checkboxVariants, chipVariants, cn, dialogPanelVariants, dropdownMenuContentVariants, dropdownMenuItemVariants, fieldVariants, inputVariants, labelVariants, paginationItemVariants, popoverContentVariants, progressFillVariants, progressTrackVariants, radioVariants, segmentContainerVariants, segmentItemVariants, selectTriggerVariants, separatorVariants, sheetOverlayVariants, sheetPanelVariants, sidebarContainerVariants, skeletonVariants, tableRowVariants, tableVariants, tabsListVariants, tabsTriggerVariants, textareaVariants, toastVariants, toggleThumbVariants, toggleTrackVariants, tooltipArrowVariants, tooltipContentVariants };
|
|
3583
|
+
//# sourceMappingURL=index.mjs.map
|
|
3584
|
+
//# sourceMappingURL=index.mjs.map
|