@olundot/ui 0.20.0-next.4 → 0.20.0-next.5
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/CHANGELOG.md +38 -0
- package/dist/index.d.ts +202 -190
- package/dist/index.js +621 -599
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -184,7 +184,7 @@ function useOlunTheme() {
|
|
|
184
184
|
// src/components/ui/button.tsx
|
|
185
185
|
import * as React from "react";
|
|
186
186
|
import { cva } from "class-variance-authority";
|
|
187
|
-
import { Loader2 } from "lucide-react";
|
|
187
|
+
import { ChevronDown, Loader2 } from "lucide-react";
|
|
188
188
|
import { Slot } from "radix-ui";
|
|
189
189
|
|
|
190
190
|
// src/components/ui/action-variants.ts
|
|
@@ -197,8 +197,14 @@ var actionPaint = {
|
|
|
197
197
|
filledDanger: "border-[var(--error)] bg-[var(--error)] text-[var(--error-contrast)] hover:bg-[var(--error-hover)] hover:border-[var(--error-hover)]",
|
|
198
198
|
// = Button `secondary`
|
|
199
199
|
outlineNeutral: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-foreground hover:border-[var(--border)] hover:bg-[var(--action-hover)]",
|
|
200
|
+
// Destructive action that is not the main one: outline neutral's surface, error border and
|
|
201
|
+
// label, error wash on hover.
|
|
202
|
+
outlineDanger: "border-[var(--error)] bg-[var(--bg-surface)] text-[var(--error)] hover:bg-[var(--error-bg)]",
|
|
200
203
|
// = Button and IconButton `ghost`
|
|
201
|
-
ghostNeutral: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground"
|
|
204
|
+
ghostNeutral: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
|
|
205
|
+
// Button `appearance="link"` only: the label color; the box and underline live in button.tsx.
|
|
206
|
+
linkPrimary: "text-[var(--accent)]",
|
|
207
|
+
linkDanger: "text-[var(--error)]"
|
|
202
208
|
};
|
|
203
209
|
var actionAxisVariants = {
|
|
204
210
|
appearance: { filled: "", outline: "", ghost: "" },
|
|
@@ -209,6 +215,7 @@ var actionCompoundVariants = [
|
|
|
209
215
|
{ appearance: "filled", tone: "neutral", className: actionPaint.filledNeutral },
|
|
210
216
|
{ appearance: "filled", tone: "danger", className: actionPaint.filledDanger },
|
|
211
217
|
{ appearance: "outline", tone: "neutral", className: actionPaint.outlineNeutral },
|
|
218
|
+
{ appearance: "outline", tone: "danger", className: actionPaint.outlineDanger },
|
|
212
219
|
{ appearance: "ghost", tone: "neutral", className: actionPaint.ghostNeutral }
|
|
213
220
|
];
|
|
214
221
|
function resolveActionStyle(appearance, tone, fallback) {
|
|
@@ -228,17 +235,13 @@ var buttonSizes = {
|
|
|
228
235
|
// xs/sm: invisible ::before stretches the hit area to 44px tall (#69), vertically only so
|
|
229
236
|
// side-by-side buttons never overlap. Its inset is measured from the padding box, inside
|
|
230
237
|
// the 1px border every variant carries: inset = (44 - (height - 2 × 1px)) / 2.
|
|
231
|
-
// IconButton with text
|
|
238
|
+
// IconButton with text renders through `buttonVariants`, so it takes these too.
|
|
232
239
|
xs: "relative h-[28px] gap-[6px] px-[var(--space-3)] text-[12px] leading-[14px] before:absolute before:inset-x-0 before:-inset-y-[9px] before:content-[''] [&_svg]:size-[14px] [&_svg]:stroke-[1.75]",
|
|
233
240
|
sm: "relative h-[30px] gap-[6px] px-[var(--space-3)] text-body-sm leading-[16px] before:absolute before:inset-x-0 before:-inset-y-[8px] before:content-[''] [&_svg]:size-[16px]",
|
|
234
241
|
md: buttonSizeMd,
|
|
235
242
|
lg: "h-[36px] gap-[var(--space-2)] px-[var(--space-4)] text-[15px] leading-[18px] [&_svg]:size-[18px]",
|
|
236
243
|
xl: "h-[40px] gap-[var(--space-2)] px-5 text-[15px] leading-[18px] [&_svg]:size-[18px]",
|
|
237
|
-
default: buttonSizeMd
|
|
238
|
-
/** @deprecated Use IconButton `size="lg"`. */
|
|
239
|
-
icon: "size-[36px] p-0 [&_svg]:size-[18px]",
|
|
240
|
-
/** @deprecated Use IconButton `size="md"`. */
|
|
241
|
-
"icon-xs": "size-[32px] p-0 [&_svg]:size-[14px] [&_svg]:stroke-[1.75]"
|
|
244
|
+
default: buttonSizeMd
|
|
242
245
|
};
|
|
243
246
|
var buttonCva = cva(
|
|
244
247
|
[
|
|
@@ -252,70 +255,62 @@ var buttonCva = cva(
|
|
|
252
255
|
].join(" "),
|
|
253
256
|
{
|
|
254
257
|
variants: {
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
primary: "border-[var(--primary)] bg-[var(--primary)] text-[var(--primary-fg)] hover:bg-[var(--primary-hover)] hover:border-[var(--primary-hover)]",
|
|
260
|
-
/** @deprecated Use `appearance="outline" tone="neutral"`. */
|
|
261
|
-
outline: "border-[var(--border)] bg-transparent text-foreground hover:border-[var(--border-strong)] hover:bg-[var(--action-hover)]",
|
|
262
|
-
/** @deprecated Use `appearance="ghost" tone="neutral"`. */
|
|
263
|
-
ghost: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
|
|
264
|
-
/** @deprecated Use `appearance="filled" tone="danger"`. */
|
|
265
|
-
danger: "border-[var(--error)] bg-[var(--error)] text-[var(--error-contrast)] hover:bg-[var(--error-hover)] hover:border-[var(--error-hover)]",
|
|
266
|
-
/** @deprecated Use `appearance="filled" tone="danger"`. */
|
|
267
|
-
emergency: "border-[var(--error)] bg-[var(--error)] text-[var(--error-contrast)] hover:bg-[var(--error-hover)] hover:border-[var(--error-hover)]",
|
|
268
|
-
/** @deprecated Use `appearance="outline" tone="neutral"`. */
|
|
269
|
-
subtle: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-foreground hover:border-[var(--border)] hover:bg-[var(--action-hover)]",
|
|
270
|
-
/** @deprecated Use `appearance="filled" tone="primary"`. */
|
|
271
|
-
default: "border-[var(--primary)] bg-[var(--primary)] text-[var(--primary-fg)] hover:bg-[var(--primary-hover)] hover:border-[var(--primary-hover)]",
|
|
272
|
-
/** @deprecated Use `appearance="filled" tone="danger"`. */
|
|
273
|
-
destructive: "border-[var(--error)] bg-[var(--error)] text-[var(--error-contrast)] hover:bg-[var(--error-hover)] hover:border-[var(--error-hover)]",
|
|
274
|
-
/** @deprecated Use `appearance="outline" tone="neutral"`. */
|
|
275
|
-
secondary: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-foreground hover:border-[var(--border)] hover:bg-[var(--action-hover)]",
|
|
276
|
-
/** @deprecated No replacement on Button; a link component is planned. */
|
|
277
|
-
link: "border-transparent bg-transparent px-0 text-[var(--accent)] underline-offset-4 hover:underline"
|
|
278
|
-
},
|
|
279
|
-
...actionAxisVariants,
|
|
258
|
+
// `link` is Button's own appearance (IconButton has no link); its box comes after the
|
|
259
|
+
// size in the compounds below.
|
|
260
|
+
appearance: { ...actionAxisVariants.appearance, link: "" },
|
|
261
|
+
tone: actionAxisVariants.tone,
|
|
280
262
|
size: buttonSizes
|
|
281
263
|
},
|
|
282
|
-
compoundVariants: [
|
|
264
|
+
compoundVariants: [
|
|
265
|
+
...actionCompoundVariants,
|
|
266
|
+
// Compounds render after the size, so px-0 beats the size's px-*. The height and the xs/sm
|
|
267
|
+
// 44px band stay. Underline on hover only, no visited look; disabled keeps the transparent
|
|
268
|
+
// box with Button's disabled text color.
|
|
269
|
+
{
|
|
270
|
+
appearance: "link",
|
|
271
|
+
className: [
|
|
272
|
+
"border-transparent bg-transparent px-0 underline-offset-4 hover:underline",
|
|
273
|
+
"disabled:border-transparent disabled:bg-transparent disabled:no-underline",
|
|
274
|
+
"aria-disabled:border-transparent aria-disabled:bg-transparent aria-disabled:no-underline"
|
|
275
|
+
].join(" ")
|
|
276
|
+
},
|
|
277
|
+
{ appearance: "link", tone: "primary", className: actionPaint.linkPrimary },
|
|
278
|
+
{ appearance: "link", tone: "danger", className: actionPaint.linkDanger }
|
|
279
|
+
],
|
|
283
280
|
defaultVariants: {
|
|
284
|
-
variant: "primary",
|
|
285
281
|
size: "md"
|
|
286
282
|
}
|
|
287
283
|
}
|
|
288
284
|
);
|
|
285
|
+
function resolveButtonStyle(appearance, tone) {
|
|
286
|
+
if (appearance === "link") return { appearance, tone: tone ?? "primary" };
|
|
287
|
+
return resolveActionStyle(appearance, tone, "filled");
|
|
288
|
+
}
|
|
289
289
|
function buttonVariants(options) {
|
|
290
|
-
|
|
291
|
-
return buttonCva({
|
|
292
|
-
...options,
|
|
293
|
-
...resolveActionStyle(options.appearance, options.tone, "filled"),
|
|
294
|
-
variant: null
|
|
295
|
-
});
|
|
290
|
+
return cn(buttonCva({ ...options, ...resolveButtonStyle(options?.appearance, options?.tone) }));
|
|
296
291
|
}
|
|
297
|
-
var buttonSizeClassName = (size) => buttonSizes[size];
|
|
298
292
|
var footerButtonHitAreaClassName = "relative before:absolute before:inset-x-0 before:-inset-y-[5px] before:content-['']";
|
|
293
|
+
function preventActivation(event) {
|
|
294
|
+
event.preventDefault();
|
|
295
|
+
event.stopPropagation();
|
|
296
|
+
}
|
|
299
297
|
var Button = React.forwardRef(
|
|
300
298
|
({
|
|
301
299
|
asChild = false,
|
|
302
300
|
className,
|
|
303
301
|
children,
|
|
304
302
|
disabled,
|
|
305
|
-
leadingIcon: LeadingIcon,
|
|
306
303
|
loading,
|
|
307
|
-
trailingIcon: TrailingIcon,
|
|
308
304
|
type = "button",
|
|
309
|
-
variant,
|
|
310
305
|
appearance,
|
|
311
306
|
tone,
|
|
312
307
|
size,
|
|
313
308
|
style,
|
|
309
|
+
menuIndicator,
|
|
314
310
|
...props
|
|
315
311
|
}, ref) => {
|
|
316
312
|
const Comp = asChild ? Slot.Root : "button";
|
|
317
313
|
const isDisabled = disabled || loading;
|
|
318
|
-
const IconBefore = loading ? Loader2 : LeadingIcon;
|
|
319
314
|
const internalRef = React.useRef(null);
|
|
320
315
|
const frozenWidthRef = React.useRef(null);
|
|
321
316
|
if (loading && internalRef.current && frozenWidthRef.current === null) {
|
|
@@ -343,20 +338,14 @@ var Button = React.forwardRef(
|
|
|
343
338
|
"aria-disabled": isDisabled ? true : void 0,
|
|
344
339
|
disabled: !asChild ? isDisabled : void 0,
|
|
345
340
|
type: !asChild ? type : void 0,
|
|
346
|
-
className: cn(buttonVariants({
|
|
341
|
+
className: cn(buttonVariants({ appearance, tone, size, className })),
|
|
347
342
|
style: frozenStyle ? { ...frozenStyle, ...style } : style,
|
|
348
343
|
...props,
|
|
344
|
+
...asChild && isDisabled ? { tabIndex: -1, onClickCapture: preventActivation, onAuxClickCapture: preventActivation } : null,
|
|
349
345
|
children: [
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
"aria-hidden": "true",
|
|
354
|
-
"data-slot": loading ? "button-spinner" : "button-leading-icon",
|
|
355
|
-
className: loading ? "animate-spin" : void 0
|
|
356
|
-
}
|
|
357
|
-
) : null,
|
|
358
|
-
children,
|
|
359
|
-
!loading && TrailingIcon ? /* @__PURE__ */ jsx(TrailingIcon, { "aria-hidden": "true", "data-slot": "button-trailing-icon" }) : null
|
|
346
|
+
loading ? /* @__PURE__ */ jsx(Loader2, { "aria-hidden": "true", "data-slot": "button-spinner", className: "animate-spin" }) : null,
|
|
347
|
+
asChild ? /* @__PURE__ */ jsx(Slot.Slottable, { children }) : children,
|
|
348
|
+
menuIndicator ? /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true", "data-slot": "button-menu-indicator" }) : null
|
|
360
349
|
]
|
|
361
350
|
}
|
|
362
351
|
);
|
|
@@ -393,7 +382,8 @@ var CopyButton = React2.forwardRef(
|
|
|
393
382
|
onCopied,
|
|
394
383
|
size = "sm",
|
|
395
384
|
value,
|
|
396
|
-
|
|
385
|
+
appearance = "outline",
|
|
386
|
+
tone,
|
|
397
387
|
...props
|
|
398
388
|
}, ref) => {
|
|
399
389
|
const [copied, setCopied] = React2.useState(false);
|
|
@@ -424,7 +414,7 @@ var CopyButton = React2.forwardRef(
|
|
|
424
414
|
"aria-label": ariaLabel ?? getCopyButtonAriaLabel(label, value),
|
|
425
415
|
"data-slot": "copy-button",
|
|
426
416
|
size,
|
|
427
|
-
|
|
417
|
+
...{ appearance, tone },
|
|
428
418
|
onClick: handleClick,
|
|
429
419
|
...props,
|
|
430
420
|
children: [
|
|
@@ -1420,7 +1410,7 @@ import { cva as cva5 } from "class-variance-authority";
|
|
|
1420
1410
|
import {
|
|
1421
1411
|
AlertCircle as AlertCircle3,
|
|
1422
1412
|
CheckCircle2 as CheckCircle23,
|
|
1423
|
-
ChevronDown,
|
|
1413
|
+
ChevronDown as ChevronDown2,
|
|
1424
1414
|
ChevronUp
|
|
1425
1415
|
} from "lucide-react";
|
|
1426
1416
|
import { Select as SelectPrimitive } from "radix-ui";
|
|
@@ -1631,7 +1621,7 @@ var Select = React7.forwardRef(
|
|
|
1631
1621
|
{
|
|
1632
1622
|
"data-slot": "select-scroll-down",
|
|
1633
1623
|
className: "flex items-center justify-center border-t border-[var(--border)] bg-[var(--bg-surface)] py-[var(--space-1)] text-text-tertiary",
|
|
1634
|
-
children: /* @__PURE__ */ jsx7(
|
|
1624
|
+
children: /* @__PURE__ */ jsx7(ChevronDown2, { "aria-hidden": "true", className: "size-[16px]" })
|
|
1635
1625
|
}
|
|
1636
1626
|
)
|
|
1637
1627
|
]
|
|
@@ -1674,7 +1664,7 @@ var Select = React7.forwardRef(
|
|
|
1674
1664
|
"data-slot": "select-icon",
|
|
1675
1665
|
className: "ml-[var(--space-2)] inline-flex size-[14px] shrink-0 items-center justify-center text-text-tertiary group-disabled:text-text-disabled",
|
|
1676
1666
|
children: /* @__PURE__ */ jsx7(
|
|
1677
|
-
|
|
1667
|
+
ChevronDown2,
|
|
1678
1668
|
{
|
|
1679
1669
|
"aria-hidden": "true",
|
|
1680
1670
|
className: "size-[14px]",
|
|
@@ -3468,7 +3458,7 @@ DetailLayout.displayName = "DetailLayout";
|
|
|
3468
3458
|
|
|
3469
3459
|
// src/components/ui/form-layout.tsx
|
|
3470
3460
|
import * as React19 from "react";
|
|
3471
|
-
import { ChevronDown as
|
|
3461
|
+
import { ChevronDown as ChevronDown3 } from "lucide-react";
|
|
3472
3462
|
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3473
3463
|
function FormLayoutSectionBlock({
|
|
3474
3464
|
section,
|
|
@@ -3537,7 +3527,7 @@ function FormLayoutSectionBlock({
|
|
|
3537
3527
|
children: /* @__PURE__ */ jsxs19("div", { className: "flex min-w-0 items-start gap-[var(--space-2)]", children: [
|
|
3538
3528
|
/* @__PURE__ */ jsx20("div", { className: "min-w-0 flex-1", children: sectionHeader }),
|
|
3539
3529
|
/* @__PURE__ */ jsx20(
|
|
3540
|
-
|
|
3530
|
+
ChevronDown3,
|
|
3541
3531
|
{
|
|
3542
3532
|
"aria-hidden": "true",
|
|
3543
3533
|
className: cn(
|
|
@@ -3885,7 +3875,9 @@ import { Dialog as DialogPrimitive } from "radix-ui";
|
|
|
3885
3875
|
// src/components/ui/icon-button.tsx
|
|
3886
3876
|
import * as React23 from "react";
|
|
3887
3877
|
import { cva as cva9 } from "class-variance-authority";
|
|
3878
|
+
import { ChevronDown as ChevronDown4, Loader2 as Loader23 } from "lucide-react";
|
|
3888
3879
|
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3880
|
+
var pressedNeutralClassName = "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground";
|
|
3889
3881
|
var iconButtonCva = cva9(
|
|
3890
3882
|
[
|
|
3891
3883
|
"olun-icon-button relative inline-flex cursor-pointer shrink-0 items-center justify-center before:absolute before:content-['']",
|
|
@@ -3897,28 +3889,17 @@ var iconButtonCva = cva9(
|
|
|
3897
3889
|
].join(" "),
|
|
3898
3890
|
{
|
|
3899
3891
|
variants: {
|
|
3900
|
-
// Legacy single axis, deprecated in 0.19 for `appearance` × `tone` and removed in 0.20.
|
|
3901
|
-
// Frozen at 0.18; button-appearance.test.tsx keeps ghost and subtle equal to their new
|
|
3902
|
-
// pair. `outline` and `danger` differ from the pair they migrate to (outline + neutral =
|
|
3903
|
-
// Button secondary, filled + danger = solid red).
|
|
3904
|
-
variant: {
|
|
3905
|
-
/** @deprecated Use `appearance="ghost" tone="neutral"` (the default). */
|
|
3906
|
-
ghost: "border-transparent bg-transparent text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
|
|
3907
|
-
/** @deprecated Use `appearance="outline" tone="neutral"`. */
|
|
3908
|
-
outline: "border-[var(--border-subtle)] bg-[var(--bg-surface)] text-text-secondary hover:border-[var(--border-strong)] hover:bg-[var(--action-hover)] hover:text-foreground",
|
|
3909
|
-
/** @deprecated Use `appearance="filled" tone="neutral"`. */
|
|
3910
|
-
subtle: "border-transparent bg-[var(--bg-inset)] text-text-secondary hover:bg-[var(--action-hover)] hover:text-foreground",
|
|
3911
|
-
/** @deprecated Use `appearance="filled" tone="danger"` (solid red, like Button). */
|
|
3912
|
-
danger: "border-transparent bg-[var(--error-bg)] text-[var(--error)] hover:bg-[var(--action-hover)]"
|
|
3913
|
-
},
|
|
3914
3892
|
...actionAxisVariants,
|
|
3915
|
-
//
|
|
3916
|
-
//
|
|
3917
|
-
//
|
|
3893
|
+
// Button's five heights, so one size is one height with or without text. Icon only is
|
|
3894
|
+
// square with a 44px hit area: the ::before is absolutely positioned, so its inset is
|
|
3895
|
+
// measured from the padding box — inside the 1px border every pair carries (transparent
|
|
3896
|
+
// or not). Inset = (44 - (size - 2 × 1px border)) / 2. With text the box is Button's.
|
|
3918
3897
|
size: {
|
|
3919
|
-
|
|
3898
|
+
xs: "size-[28px] before:-inset-[9px]",
|
|
3899
|
+
sm: "size-[30px] before:-inset-[8px]",
|
|
3920
3900
|
md: "size-[32px] before:-inset-[7px]",
|
|
3921
|
-
lg: "size-[
|
|
3901
|
+
lg: "size-[36px] before:-inset-[5px]",
|
|
3902
|
+
xl: "size-[40px] before:-inset-[3px]"
|
|
3922
3903
|
},
|
|
3923
3904
|
pressed: {
|
|
3924
3905
|
true: "",
|
|
@@ -3927,39 +3908,17 @@ var iconButtonCva = cva9(
|
|
|
3927
3908
|
},
|
|
3928
3909
|
compoundVariants: [
|
|
3929
3910
|
...actionCompoundVariants,
|
|
3930
|
-
{
|
|
3931
|
-
pressed: true,
|
|
3932
|
-
variant: ["ghost", "outline", "subtle"],
|
|
3933
|
-
className: "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground"
|
|
3934
|
-
},
|
|
3935
|
-
{
|
|
3936
|
-
pressed: true,
|
|
3937
|
-
variant: "danger",
|
|
3938
|
-
className: "border-[var(--error)] bg-[var(--error-bg)] text-[var(--error)]"
|
|
3939
|
-
},
|
|
3940
|
-
{
|
|
3941
|
-
pressed: true,
|
|
3942
|
-
tone: "neutral",
|
|
3943
|
-
className: "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground"
|
|
3944
|
-
}
|
|
3911
|
+
{ pressed: true, tone: "neutral", className: pressedNeutralClassName }
|
|
3945
3912
|
],
|
|
3946
3913
|
// ghost is the intended default, not a fallback: ghost is reserved for icon-only
|
|
3947
3914
|
// actions repeated in rows or chrome (toolbars, headers, table rows), and
|
|
3948
3915
|
// IconButton is its canonical entry point (#58). Text actions use Button.
|
|
3949
3916
|
defaultVariants: {
|
|
3950
|
-
variant: "ghost",
|
|
3951
3917
|
size: "md",
|
|
3952
3918
|
pressed: false
|
|
3953
3919
|
}
|
|
3954
3920
|
}
|
|
3955
3921
|
);
|
|
3956
|
-
var axisSizeClassName = {
|
|
3957
|
-
xs: "size-[28px] before:-inset-[9px]",
|
|
3958
|
-
sm: "size-[30px] before:-inset-[8px]",
|
|
3959
|
-
md: "size-[32px] before:-inset-[7px]",
|
|
3960
|
-
lg: "size-[36px] before:-inset-[5px]",
|
|
3961
|
-
xl: "size-[40px] before:-inset-[3px]"
|
|
3962
|
-
};
|
|
3963
3922
|
var axisIcon = {
|
|
3964
3923
|
xs: { size: 14, strokeWidth: 1.75 },
|
|
3965
3924
|
sm: { size: 16, strokeWidth: 2 },
|
|
@@ -3968,17 +3927,10 @@ var axisIcon = {
|
|
|
3968
3927
|
xl: { size: 18, strokeWidth: 2 }
|
|
3969
3928
|
};
|
|
3970
3929
|
function iconButtonVariants(options) {
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
const { size, ...rest } = options;
|
|
3975
|
-
const paint = iconButtonCva({
|
|
3976
|
-
...rest,
|
|
3977
|
-
...resolveActionStyle(options.appearance, options.tone, "ghost"),
|
|
3978
|
-
variant: null,
|
|
3979
|
-
size: null
|
|
3930
|
+
return iconButtonCva({
|
|
3931
|
+
...options,
|
|
3932
|
+
...resolveActionStyle(options?.appearance, options?.tone, "ghost")
|
|
3980
3933
|
});
|
|
3981
|
-
return size === null ? paint : `${paint} ${axisSizeClassName[size ?? "md"]}`;
|
|
3982
3934
|
}
|
|
3983
3935
|
var iconButtonBadgeVariants = cva9(
|
|
3984
3936
|
[
|
|
@@ -4001,25 +3953,9 @@ var iconButtonBadgeVariants = cva9(
|
|
|
4001
3953
|
}
|
|
4002
3954
|
}
|
|
4003
3955
|
);
|
|
4004
|
-
var iconSize2 = {
|
|
4005
|
-
sm: 14,
|
|
4006
|
-
md: 16,
|
|
4007
|
-
lg: 18
|
|
4008
|
-
};
|
|
4009
|
-
var textButtonSize = {
|
|
4010
|
-
sm: "xs",
|
|
4011
|
-
md: "md",
|
|
4012
|
-
lg: "xl"
|
|
4013
|
-
};
|
|
4014
|
-
var iconStrokeWidth = {
|
|
4015
|
-
sm: 2.25,
|
|
4016
|
-
md: 2.25,
|
|
4017
|
-
lg: 1.75
|
|
4018
|
-
};
|
|
4019
3956
|
var IconButton = React23.forwardRef(
|
|
4020
3957
|
({
|
|
4021
3958
|
className,
|
|
4022
|
-
variant = "ghost",
|
|
4023
3959
|
appearance,
|
|
4024
3960
|
tone,
|
|
4025
3961
|
size = "md",
|
|
@@ -4032,28 +3968,37 @@ var IconButton = React23.forwardRef(
|
|
|
4032
3968
|
"aria-label": ariaLabel,
|
|
4033
3969
|
"aria-labelledby": ariaLabelledBy,
|
|
4034
3970
|
iconPosition = "start",
|
|
3971
|
+
loading,
|
|
3972
|
+
menuIndicator,
|
|
3973
|
+
disabled,
|
|
4035
3974
|
label,
|
|
4036
3975
|
children,
|
|
4037
3976
|
...props
|
|
4038
3977
|
}, ref) => {
|
|
4039
3978
|
const resolvedSize = size ?? "md";
|
|
4040
|
-
const usesAxes = appearance != null || tone != null;
|
|
4041
3979
|
const isToggle = pressed !== void 0;
|
|
4042
3980
|
const isPressed = pressed === true;
|
|
4043
3981
|
const hoverTitle = title ?? (typeof ariaLabel === "string" ? ariaLabel : void 0);
|
|
4044
3982
|
const text = label ?? children;
|
|
4045
3983
|
const hasText = text !== void 0 && text !== null && text !== false;
|
|
4046
|
-
const
|
|
4047
|
-
const
|
|
4048
|
-
const
|
|
4049
|
-
|
|
4050
|
-
|
|
3984
|
+
const isDisabled = disabled || loading;
|
|
3985
|
+
const style = resolveActionStyle(appearance, tone, "ghost");
|
|
3986
|
+
const icon = loading ? /* @__PURE__ */ jsx22(
|
|
3987
|
+
Loader23,
|
|
3988
|
+
{
|
|
3989
|
+
"aria-hidden": "true",
|
|
3990
|
+
"data-slot": "icon-button-spinner",
|
|
3991
|
+
className: "animate-spin",
|
|
3992
|
+
size: axisIcon[resolvedSize].size,
|
|
3993
|
+
strokeWidth: axisIcon[resolvedSize].strokeWidth
|
|
3994
|
+
}
|
|
3995
|
+
) : /* @__PURE__ */ jsx22(
|
|
4051
3996
|
Icon,
|
|
4052
3997
|
{
|
|
4053
3998
|
"aria-hidden": "true",
|
|
4054
3999
|
"data-slot": "icon-button-icon",
|
|
4055
|
-
size:
|
|
4056
|
-
strokeWidth:
|
|
4000
|
+
size: axisIcon[resolvedSize].size,
|
|
4001
|
+
strokeWidth: axisIcon[resolvedSize].strokeWidth
|
|
4057
4002
|
}
|
|
4058
4003
|
);
|
|
4059
4004
|
return /* @__PURE__ */ jsxs20(
|
|
@@ -4062,25 +4007,27 @@ var IconButton = React23.forwardRef(
|
|
|
4062
4007
|
ref,
|
|
4063
4008
|
...props,
|
|
4064
4009
|
"data-slot": "icon-button",
|
|
4065
|
-
"data-
|
|
4066
|
-
"data-
|
|
4067
|
-
"data-tone": style?.tone,
|
|
4010
|
+
"data-appearance": style.appearance,
|
|
4011
|
+
"data-tone": style.tone,
|
|
4068
4012
|
"data-size": resolvedSize,
|
|
4069
4013
|
"data-icon-position": hasText ? iconPosition : void 0,
|
|
4070
4014
|
"data-pressed": isToggle ? String(isPressed) : void 0,
|
|
4015
|
+
"data-loading": loading ? "true" : void 0,
|
|
4016
|
+
"aria-busy": loading ? true : void 0,
|
|
4017
|
+
"aria-disabled": isDisabled ? true : void 0,
|
|
4018
|
+
disabled: isDisabled,
|
|
4071
4019
|
"aria-label": ariaLabel,
|
|
4072
4020
|
"aria-labelledby": ariaLabelledBy,
|
|
4073
4021
|
"aria-pressed": isToggle ? isPressed : void 0,
|
|
4074
4022
|
title: hoverTitle,
|
|
4075
4023
|
className: cn(
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
tone,
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
}),
|
|
4083
|
-
hasText && ["whitespace-nowrap", buttonSizeClassName(textBoxSize)],
|
|
4024
|
+
hasText ? [
|
|
4025
|
+
"olun-icon-button",
|
|
4026
|
+
buttonVariants({ ...style, size: resolvedSize }),
|
|
4027
|
+
isPressed && style.tone === "neutral" && pressedNeutralClassName,
|
|
4028
|
+
// The badge sits on the corner; Button xs/sm are already relative.
|
|
4029
|
+
badge !== void 0 && "relative"
|
|
4030
|
+
] : iconButtonVariants({ appearance, tone, size: resolvedSize, pressed: isPressed }),
|
|
4084
4031
|
className
|
|
4085
4032
|
),
|
|
4086
4033
|
type: type ?? "button",
|
|
@@ -4088,6 +4035,15 @@ var IconButton = React23.forwardRef(
|
|
|
4088
4035
|
hasText && iconPosition === "end" ? null : icon,
|
|
4089
4036
|
hasText ? text : null,
|
|
4090
4037
|
hasText && iconPosition === "end" ? icon : null,
|
|
4038
|
+
hasText && menuIndicator ? /* @__PURE__ */ jsx22(
|
|
4039
|
+
ChevronDown4,
|
|
4040
|
+
{
|
|
4041
|
+
"aria-hidden": "true",
|
|
4042
|
+
"data-slot": "icon-button-menu-indicator",
|
|
4043
|
+
size: axisIcon[resolvedSize].size,
|
|
4044
|
+
strokeWidth: axisIcon[resolvedSize].strokeWidth
|
|
4045
|
+
}
|
|
4046
|
+
) : null,
|
|
4091
4047
|
badge !== void 0 ? /* @__PURE__ */ jsx22(
|
|
4092
4048
|
"span",
|
|
4093
4049
|
{
|
|
@@ -5482,7 +5438,8 @@ var FilterToolbar = React29.forwardRef(
|
|
|
5482
5438
|
"aria-label": collapseTriggerLabel,
|
|
5483
5439
|
icon: SlidersHorizontal,
|
|
5484
5440
|
size: "md",
|
|
5485
|
-
|
|
5441
|
+
appearance: "outline",
|
|
5442
|
+
tone: "neutral",
|
|
5486
5443
|
onClick: () => handleOverlayOpenChange(true)
|
|
5487
5444
|
}
|
|
5488
5445
|
),
|
|
@@ -5637,8 +5594,8 @@ var FilterToolbar = React29.forwardRef(
|
|
|
5637
5594
|
FilterToolbar.displayName = "FilterToolbar";
|
|
5638
5595
|
|
|
5639
5596
|
// src/components/ui/data-table.tsx
|
|
5640
|
-
import * as
|
|
5641
|
-
import { ChevronDown as
|
|
5597
|
+
import * as React33 from "react";
|
|
5598
|
+
import { ChevronDown as ChevronDown5, ChevronUp as ChevronUp2, ChevronsUpDown } from "lucide-react";
|
|
5642
5599
|
import { cva as cva12 } from "class-variance-authority";
|
|
5643
5600
|
|
|
5644
5601
|
// src/components/ui/checkbox.tsx
|
|
@@ -6225,32 +6182,252 @@ function DropdownMenuSubContent({
|
|
|
6225
6182
|
}
|
|
6226
6183
|
|
|
6227
6184
|
// src/components/ui/list-card.tsx
|
|
6185
|
+
import * as React32 from "react";
|
|
6186
|
+
import { ChevronRight as ChevronRight2, MoreVertical } from "lucide-react";
|
|
6187
|
+
|
|
6188
|
+
// src/components/ui/action-menu.tsx
|
|
6228
6189
|
import * as React31 from "react";
|
|
6229
|
-
import {
|
|
6190
|
+
import { Dialog as DialogPrimitive4, Slot as Slot3 } from "radix-ui";
|
|
6230
6191
|
import { Fragment as Fragment11, jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
6231
|
-
|
|
6232
|
-
|
|
6192
|
+
var sheetRowClassName = cn(
|
|
6193
|
+
"group flex min-h-12 w-full cursor-pointer items-center gap-[var(--space-3)] px-[var(--space-4)] py-[var(--space-2)] text-left",
|
|
6194
|
+
"border-t border-[var(--border-subtle)] text-[13px] font-medium leading-normal text-text-primary",
|
|
6195
|
+
"transition-colors motion-reduce:transition-none hover:bg-[var(--action-hover)]",
|
|
6196
|
+
"focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[var(--focus-ring)]",
|
|
6197
|
+
"enabled:data-[destructive]:text-[var(--semantic-error-fg)]",
|
|
6198
|
+
"disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled"
|
|
6199
|
+
);
|
|
6200
|
+
var sheetRowDescriptionClassName = "block text-[12px] font-normal text-text-secondary group-disabled:text-text-disabled";
|
|
6201
|
+
var sheetGroupLabelClassName = "px-[var(--space-4)] pt-[var(--space-3)] pb-[var(--space-2)] text-[12px] font-semibold leading-normal text-text-tertiary";
|
|
6202
|
+
var sheetGroupSeparatorClassName = "h-[var(--space-2)] bg-[var(--bg-inset)]";
|
|
6203
|
+
function ActionMenuSheet({
|
|
6204
|
+
open,
|
|
6205
|
+
onOpenChange,
|
|
6206
|
+
title,
|
|
6207
|
+
description,
|
|
6208
|
+
closeLabel,
|
|
6209
|
+
groups,
|
|
6210
|
+
onOpenAutoFocus,
|
|
6211
|
+
onCloseAutoFocus
|
|
6212
|
+
}) {
|
|
6213
|
+
const pendingRef = React31.useRef(null);
|
|
6214
|
+
const surfaceRef = React31.useRef(null);
|
|
6215
|
+
const labelId = React31.useId();
|
|
6216
|
+
const handleOpenChange = (nextOpen) => {
|
|
6217
|
+
pendingRef.current = null;
|
|
6218
|
+
onOpenChange(nextOpen);
|
|
6219
|
+
};
|
|
6220
|
+
const swipe = useSwipeDismiss({
|
|
6221
|
+
enabled: OVERLAY_POLICY.menu.swipe,
|
|
6222
|
+
onDismiss: () => handleOpenChange(false),
|
|
6223
|
+
surfaceRef,
|
|
6224
|
+
always: true
|
|
6225
|
+
});
|
|
6226
|
+
const handleSelect = (item) => {
|
|
6227
|
+
onOpenChange(false);
|
|
6228
|
+
pendingRef.current = item;
|
|
6229
|
+
};
|
|
6230
|
+
const handleOpenAutoFocus = (event) => {
|
|
6231
|
+
onOpenAutoFocus?.(event);
|
|
6232
|
+
const firstRow = surfaceRef.current?.querySelector('[data-slot="action-menu-item"]:enabled');
|
|
6233
|
+
if (!firstRow) return;
|
|
6234
|
+
event.preventDefault();
|
|
6235
|
+
firstRow.focus();
|
|
6236
|
+
};
|
|
6237
|
+
const handleCloseAutoFocus = (event) => {
|
|
6238
|
+
onCloseAutoFocus(event);
|
|
6239
|
+
const item = pendingRef.current;
|
|
6240
|
+
pendingRef.current = null;
|
|
6241
|
+
item?.onSelect();
|
|
6242
|
+
};
|
|
6243
|
+
return /* @__PURE__ */ jsx35(DialogPrimitive4.Root, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs31(DialogPrimitive4.Portal, { children: [
|
|
6244
|
+
/* @__PURE__ */ jsx35(OverlayScrimLayer, { kind: "menu" }),
|
|
6245
|
+
/* @__PURE__ */ jsxs31(
|
|
6246
|
+
DialogPrimitive4.Content,
|
|
6247
|
+
{
|
|
6248
|
+
ref: surfaceRef,
|
|
6249
|
+
"data-slot": "action-menu-sheet",
|
|
6250
|
+
className: overlayBoxClassName("menu"),
|
|
6251
|
+
onOpenAutoFocus: handleOpenAutoFocus,
|
|
6252
|
+
onCloseAutoFocus: handleCloseAutoFocus,
|
|
6253
|
+
...description ? {} : { "aria-describedby": void 0 },
|
|
6254
|
+
children: [
|
|
6255
|
+
/* @__PURE__ */ jsx35(OverlayGrabber, { always: true, ...swipe.handleProps }),
|
|
6256
|
+
/* @__PURE__ */ jsx35(
|
|
6257
|
+
OverlayHeader,
|
|
6258
|
+
{
|
|
6259
|
+
kind: "menu",
|
|
6260
|
+
title,
|
|
6261
|
+
description,
|
|
6262
|
+
closeLabel,
|
|
6263
|
+
dragHandleProps: swipe.handleProps
|
|
6264
|
+
}
|
|
6265
|
+
),
|
|
6266
|
+
/* @__PURE__ */ jsx35(OverlayBody, { kind: "menu", children: groups.map((group, index) => /* @__PURE__ */ jsxs31(React31.Fragment, { children: [
|
|
6267
|
+
index > 0 ? /* @__PURE__ */ jsx35("div", { role: "separator", className: sheetGroupSeparatorClassName }) : null,
|
|
6268
|
+
/* @__PURE__ */ jsxs31("div", { role: "group", "aria-labelledby": group.label ? `${labelId}-${index}` : void 0, children: [
|
|
6269
|
+
group.label ? /* @__PURE__ */ jsx35("div", { id: `${labelId}-${index}`, className: sheetGroupLabelClassName, children: group.label }) : null,
|
|
6270
|
+
group.items.map((item) => {
|
|
6271
|
+
const Icon = item.icon;
|
|
6272
|
+
return /* @__PURE__ */ jsxs31(
|
|
6273
|
+
"button",
|
|
6274
|
+
{
|
|
6275
|
+
type: "button",
|
|
6276
|
+
"data-slot": "action-menu-item",
|
|
6277
|
+
"data-destructive": item.destructive ? "" : void 0,
|
|
6278
|
+
className: sheetRowClassName,
|
|
6279
|
+
disabled: item.disabled,
|
|
6280
|
+
onClick: () => handleSelect(item),
|
|
6281
|
+
children: [
|
|
6282
|
+
Icon ? /* @__PURE__ */ jsx35(Icon, { "aria-hidden": true, size: 17, strokeWidth: 1.75, className: "shrink-0" }) : null,
|
|
6283
|
+
/* @__PURE__ */ jsxs31("span", { className: "min-w-0 flex-1 break-keep", children: [
|
|
6284
|
+
item.label,
|
|
6285
|
+
item.description ? /* @__PURE__ */ jsx35("span", { className: sheetRowDescriptionClassName, children: item.description }) : null
|
|
6286
|
+
] })
|
|
6287
|
+
]
|
|
6288
|
+
},
|
|
6289
|
+
item.id
|
|
6290
|
+
);
|
|
6291
|
+
})
|
|
6292
|
+
] })
|
|
6293
|
+
] }, group.id)) })
|
|
6294
|
+
]
|
|
6295
|
+
}
|
|
6296
|
+
)
|
|
6297
|
+
] }) });
|
|
6233
6298
|
}
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6299
|
+
var readPresentation = () => window.matchMedia?.(OVERLAY_DESKTOP_QUERY).matches ?? true ? "dropdown" : "sheet";
|
|
6300
|
+
var subscribeNothing = () => () => void 0;
|
|
6301
|
+
var useHydrated = () => React31.useSyncExternalStore(
|
|
6302
|
+
subscribeNothing,
|
|
6303
|
+
() => true,
|
|
6304
|
+
() => false
|
|
6305
|
+
);
|
|
6306
|
+
function ActionMenu({
|
|
6307
|
+
trigger,
|
|
6308
|
+
title,
|
|
6309
|
+
description,
|
|
6310
|
+
open: openProp,
|
|
6311
|
+
onOpenChange,
|
|
6312
|
+
closeLabel,
|
|
6313
|
+
items,
|
|
6314
|
+
groups
|
|
6315
|
+
}) {
|
|
6316
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React31.useState(false);
|
|
6317
|
+
const hydrated = useHydrated();
|
|
6318
|
+
const open = (openProp ?? uncontrolledOpen) && hydrated;
|
|
6319
|
+
const [shown, setShown] = React31.useState({
|
|
6320
|
+
open: false,
|
|
6321
|
+
presentation: "dropdown"
|
|
6322
|
+
});
|
|
6323
|
+
let presentation = shown.presentation;
|
|
6324
|
+
if (shown.open !== open) {
|
|
6325
|
+
if (open) presentation = readPresentation();
|
|
6326
|
+
setShown({ open, presentation });
|
|
6237
6327
|
}
|
|
6238
|
-
|
|
6328
|
+
const triggerRef = React31.useRef(null);
|
|
6329
|
+
const pendingRef = React31.useRef(null);
|
|
6330
|
+
const setOpen = (nextOpen) => {
|
|
6331
|
+
if (nextOpen) pendingRef.current = null;
|
|
6332
|
+
if (openProp === void 0) setUncontrolledOpen(nextOpen);
|
|
6333
|
+
onOpenChange?.(nextOpen);
|
|
6334
|
+
};
|
|
6335
|
+
const menuGroups = groups ?? [{ id: "items", items: items ?? [] }];
|
|
6336
|
+
const handleDropdownCloseAutoFocus = (event) => {
|
|
6337
|
+
const item = pendingRef.current;
|
|
6338
|
+
pendingRef.current = null;
|
|
6339
|
+
if (!item) return;
|
|
6340
|
+
event.preventDefault();
|
|
6341
|
+
triggerRef.current?.focus();
|
|
6342
|
+
item.onSelect();
|
|
6343
|
+
};
|
|
6344
|
+
const handleSheetCloseAutoFocus = (event) => {
|
|
6345
|
+
event.preventDefault();
|
|
6346
|
+
triggerRef.current?.focus();
|
|
6347
|
+
};
|
|
6348
|
+
const triggerLabel = trigger.props["aria-label"];
|
|
6349
|
+
return /* @__PURE__ */ jsxs31(Fragment11, { children: [
|
|
6350
|
+
/* @__PURE__ */ jsxs31(DropdownMenu, { open: open && presentation === "dropdown", onOpenChange: setOpen, children: [
|
|
6351
|
+
/* @__PURE__ */ jsx35(DropdownMenuTrigger, { asChild: true, "aria-expanded": open, children: /* @__PURE__ */ jsx35(Slot3.Root, { ref: triggerRef, children: trigger }) }),
|
|
6352
|
+
/* @__PURE__ */ jsx35(DropdownMenuContent, { align: "end", onCloseAutoFocus: handleDropdownCloseAutoFocus, children: menuGroups.map((group, index) => /* @__PURE__ */ jsxs31(React31.Fragment, { children: [
|
|
6353
|
+
index > 0 ? /* @__PURE__ */ jsx35(DropdownMenuSeparator, {}) : null,
|
|
6354
|
+
/* @__PURE__ */ jsxs31(DropdownMenuGroup, { children: [
|
|
6355
|
+
group.label ? /* @__PURE__ */ jsx35(DropdownMenuLabel, { children: group.label }) : null,
|
|
6356
|
+
group.items.map((item) => {
|
|
6357
|
+
const Icon = item.icon;
|
|
6358
|
+
return /* @__PURE__ */ jsxs31(
|
|
6359
|
+
DropdownMenuItem,
|
|
6360
|
+
{
|
|
6361
|
+
variant: item.destructive ? "destructive" : "default",
|
|
6362
|
+
disabled: item.disabled,
|
|
6363
|
+
onSelect: () => {
|
|
6364
|
+
pendingRef.current = item;
|
|
6365
|
+
},
|
|
6366
|
+
children: [
|
|
6367
|
+
Icon ? /* @__PURE__ */ jsx35(Icon, { "aria-hidden": true, size: 16, strokeWidth: 1.75 }) : null,
|
|
6368
|
+
item.label
|
|
6369
|
+
]
|
|
6370
|
+
},
|
|
6371
|
+
item.id
|
|
6372
|
+
);
|
|
6373
|
+
})
|
|
6374
|
+
] })
|
|
6375
|
+
] }, group.id)) })
|
|
6376
|
+
] }),
|
|
6377
|
+
/* @__PURE__ */ jsx35(
|
|
6378
|
+
ActionMenuSheet,
|
|
6379
|
+
{
|
|
6380
|
+
open: open && presentation === "sheet",
|
|
6381
|
+
onOpenChange: setOpen,
|
|
6382
|
+
title: title ?? /* @__PURE__ */ jsx35("span", { className: "sr-only", children: triggerLabel }),
|
|
6383
|
+
description,
|
|
6384
|
+
closeLabel,
|
|
6385
|
+
groups: menuGroups,
|
|
6386
|
+
onCloseAutoFocus: handleSheetCloseAutoFocus
|
|
6387
|
+
}
|
|
6388
|
+
)
|
|
6389
|
+
] });
|
|
6239
6390
|
}
|
|
6240
|
-
|
|
6241
|
-
|
|
6391
|
+
|
|
6392
|
+
// src/components/ui/list-card.tsx
|
|
6393
|
+
import { Fragment as Fragment12, jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
6394
|
+
function lineTokens(value) {
|
|
6395
|
+
return React32.Children.toArray(value).filter((token) => token !== "");
|
|
6396
|
+
}
|
|
6397
|
+
function MetaLine({
|
|
6398
|
+
tokens,
|
|
6399
|
+
slot,
|
|
6400
|
+
first,
|
|
6401
|
+
last
|
|
6402
|
+
}) {
|
|
6403
|
+
return /* @__PURE__ */ jsx36(
|
|
6242
6404
|
"span",
|
|
6243
6405
|
{
|
|
6244
6406
|
"data-slot": slot,
|
|
6245
|
-
className:
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6407
|
+
className: cn(
|
|
6408
|
+
"flex flex-wrap gap-x-[var(--space-3)] gap-y-[2px] text-[12px] leading-[16px] text-text-secondary",
|
|
6409
|
+
first ? "mt-[var(--space-1)]" : "mt-[2px]"
|
|
6410
|
+
),
|
|
6411
|
+
children: tokens.map((token, index) => /* @__PURE__ */ jsxs32(
|
|
6412
|
+
"span",
|
|
6413
|
+
{
|
|
6414
|
+
className: "max-w-full truncate whitespace-nowrap",
|
|
6415
|
+
title: typeof token === "string" || typeof token === "number" ? String(token) : void 0,
|
|
6416
|
+
children: [
|
|
6417
|
+
token,
|
|
6418
|
+
index < tokens.length - 1 || !last ? /* @__PURE__ */ jsx36("span", { className: "sr-only", children: ", " }) : null
|
|
6419
|
+
]
|
|
6420
|
+
},
|
|
6421
|
+
index
|
|
6422
|
+
))
|
|
6251
6423
|
}
|
|
6252
6424
|
);
|
|
6253
6425
|
}
|
|
6426
|
+
var titleClassName = "line-clamp-2 text-[13px] font-medium leading-[18px] text-text-primary [overflow-wrap:anywhere] [word-break:keep-all]";
|
|
6427
|
+
var overlayClassName = cn(
|
|
6428
|
+
"text-inherit no-underline outline-none after:absolute after:inset-0 after:content-['']",
|
|
6429
|
+
"focus-visible:after:ring-2 focus-visible:after:ring-inset focus-visible:after:ring-[var(--focus-ring)]"
|
|
6430
|
+
);
|
|
6254
6431
|
function ListCard({
|
|
6255
6432
|
title,
|
|
6256
6433
|
meta,
|
|
@@ -6259,6 +6436,7 @@ function ListCard({
|
|
|
6259
6436
|
leading,
|
|
6260
6437
|
value,
|
|
6261
6438
|
trailing = "chevron",
|
|
6439
|
+
actions,
|
|
6262
6440
|
href,
|
|
6263
6441
|
linkComponent,
|
|
6264
6442
|
linkProps,
|
|
@@ -6269,40 +6447,48 @@ function ListCard({
|
|
|
6269
6447
|
const meta1 = lineTokens(meta?.[0]);
|
|
6270
6448
|
const meta2 = lineTokens(meta?.[1]);
|
|
6271
6449
|
const hasValue = value != null;
|
|
6272
|
-
const
|
|
6450
|
+
const overlay = actions != null && (href != null || onClick != null);
|
|
6451
|
+
const trailingNode = trailing === "chevron" ? /* @__PURE__ */ jsx36(
|
|
6273
6452
|
ChevronRight2,
|
|
6274
6453
|
{
|
|
6275
6454
|
"data-slot": `${slot}-suffix`,
|
|
6276
6455
|
"aria-hidden": true,
|
|
6277
6456
|
className: "size-[var(--space-4)] shrink-0 text-text-tertiary"
|
|
6278
6457
|
}
|
|
6279
|
-
);
|
|
6280
|
-
const
|
|
6458
|
+
) : trailing === "none" ? null : /* @__PURE__ */ jsx36("span", { "data-slot": `${slot}-suffix`, children: trailing });
|
|
6459
|
+
const bottomIcon = actions != null && trailingNode != null;
|
|
6460
|
+
const hasEnd = hasValue || actions != null || trailingNode != null;
|
|
6281
6461
|
const rootClassName = cn(
|
|
6282
|
-
"relative grid w-full min-w-0 items-
|
|
6462
|
+
"relative grid w-full min-w-0 items-start gap-x-[var(--space-2)] whitespace-normal text-left outline-none",
|
|
6283
6463
|
"focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--focus-ring)]",
|
|
6284
|
-
//
|
|
6285
|
-
leading ?
|
|
6286
|
-
|
|
6464
|
+
// An empty end keeps the 16px chevron track.
|
|
6465
|
+
leading ? hasEnd ? "grid-cols-[auto_minmax(0,1fr)_auto]" : "grid-cols-[auto_minmax(0,1fr)_16px]" : hasEnd ? "grid-cols-[minmax(0,1fr)_auto]" : "grid-cols-[minmax(0,1fr)_16px]",
|
|
6466
|
+
// 84 = the ⋮ hit area (2 above the top to 42 below) meets the chevron's (42 above the bottom to 2 below).
|
|
6467
|
+
bottomIcon ? "min-h-[calc(var(--space-20)+var(--space-1))]" : null,
|
|
6468
|
+
href && !overlay && "after:absolute after:inset-0 after:content-['']",
|
|
6287
6469
|
className
|
|
6288
6470
|
);
|
|
6289
|
-
const
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6471
|
+
const titleNode = /* @__PURE__ */ jsx36(
|
|
6472
|
+
"span",
|
|
6473
|
+
{
|
|
6474
|
+
"data-slot": `${slot}-title`,
|
|
6475
|
+
className: titleClassName,
|
|
6476
|
+
title: typeof title === "string" || typeof title === "number" ? String(title) : void 0,
|
|
6477
|
+
children: overlay && href != null ? React32.createElement(linkComponent ?? "a", { ...linkProps, href, className: overlayClassName }, title) : title
|
|
6478
|
+
}
|
|
6479
|
+
);
|
|
6480
|
+
const content = /* @__PURE__ */ jsxs32(Fragment12, { children: [
|
|
6481
|
+
leading != null ? /* @__PURE__ */ jsx36("span", { className: "flex min-h-[18px] items-center", children: leading }) : null,
|
|
6482
|
+
/* @__PURE__ */ jsxs32("span", { className: "min-w-0", children: [
|
|
6483
|
+
overlay && href == null ? (
|
|
6484
|
+
// A block button keeps the title's two-line clamp inside it.
|
|
6485
|
+
/* @__PURE__ */ jsx36("button", { type: "button", onClick, className: cn(overlayClassName, "block w-full text-left"), children: titleNode })
|
|
6486
|
+
) : titleNode,
|
|
6487
|
+
meta1.length > 0 ? /* @__PURE__ */ jsx36(MetaLine, { tokens: meta1, slot: `${slot}-meta1`, first: true, last: meta2.length === 0 }) : null,
|
|
6488
|
+
meta2.length > 0 ? /* @__PURE__ */ jsx36(MetaLine, { tokens: meta2, slot: `${slot}-meta2`, first: meta1.length === 0, last: true }) : null,
|
|
6489
|
+
status != null || caption != null ? /* @__PURE__ */ jsxs32("span", { "data-slot": `${slot}-bottom`, className: "mt-[var(--space-2)] flex min-h-[18px] items-center gap-[var(--space-2)]", children: [
|
|
6490
|
+
status != null ? /* @__PURE__ */ jsx36("span", { "data-slot": `${slot}-badge`, className: "flex items-center", children: status }) : null,
|
|
6491
|
+
caption != null ? /* @__PURE__ */ jsx36(
|
|
6306
6492
|
"span",
|
|
6307
6493
|
{
|
|
6308
6494
|
"data-slot": `${slot}-caption`,
|
|
@@ -6312,30 +6498,51 @@ function ListCard({
|
|
|
6312
6498
|
) : null
|
|
6313
6499
|
] }) : null
|
|
6314
6500
|
] }),
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6501
|
+
hasEnd ? /* @__PURE__ */ jsxs32("span", { "data-slot": `${slot}-trailing`, className: "flex flex-col items-end justify-between self-stretch", children: [
|
|
6502
|
+
/* @__PURE__ */ jsxs32(
|
|
6503
|
+
"span",
|
|
6504
|
+
{
|
|
6505
|
+
className: cn(
|
|
6506
|
+
"-mt-[var(--space-2)] flex min-h-[var(--space-8)] items-center",
|
|
6507
|
+
actions != null ? "-mr-[var(--space-2)] gap-[var(--space-1)]" : "gap-[var(--space-2)]"
|
|
6508
|
+
),
|
|
6509
|
+
children: [
|
|
6510
|
+
hasValue ? /* @__PURE__ */ jsx36("span", { "data-slot": `${slot}-value`, className: "text-[13px] leading-[20px] text-text-secondary tabular-nums", children: value }) : null,
|
|
6511
|
+
actions != null ? /* @__PURE__ */ jsx36("span", { className: "relative z-[1] flex", children: /* @__PURE__ */ jsx36(
|
|
6512
|
+
ActionMenu,
|
|
6513
|
+
{
|
|
6514
|
+
title: typeof title === "string" ? title : void 0,
|
|
6515
|
+
items: [...actions.items],
|
|
6516
|
+
trigger: /* @__PURE__ */ jsx36(
|
|
6517
|
+
IconButton,
|
|
6518
|
+
{
|
|
6519
|
+
icon: MoreVertical,
|
|
6520
|
+
"aria-label": actions.label,
|
|
6521
|
+
appearance: "ghost",
|
|
6522
|
+
tone: "neutral",
|
|
6523
|
+
size: "md"
|
|
6524
|
+
}
|
|
6525
|
+
)
|
|
6526
|
+
}
|
|
6527
|
+
) }) : trailingNode
|
|
6528
|
+
]
|
|
6529
|
+
}
|
|
6530
|
+
),
|
|
6531
|
+
bottomIcon ? trailingNode : null
|
|
6532
|
+
] }) : null
|
|
6326
6533
|
] });
|
|
6327
|
-
if (href) {
|
|
6534
|
+
if (href && !overlay) {
|
|
6328
6535
|
const LinkComponent = linkComponent ?? "a";
|
|
6329
|
-
return /* @__PURE__ */
|
|
6536
|
+
return /* @__PURE__ */ jsx36(LinkComponent, { ...linkProps, href, className: rootClassName, children: content });
|
|
6330
6537
|
}
|
|
6331
|
-
if (onClick) {
|
|
6332
|
-
return /* @__PURE__ */
|
|
6538
|
+
if (onClick && !overlay) {
|
|
6539
|
+
return /* @__PURE__ */ jsx36("button", { type: "button", onClick, className: rootClassName, children: content });
|
|
6333
6540
|
}
|
|
6334
|
-
return /* @__PURE__ */
|
|
6541
|
+
return /* @__PURE__ */ jsx36("div", { className: rootClassName, children: content });
|
|
6335
6542
|
}
|
|
6336
6543
|
|
|
6337
6544
|
// src/components/ui/data-table.tsx
|
|
6338
|
-
import { Fragment as
|
|
6545
|
+
import { Fragment as Fragment13, jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
6339
6546
|
var dataTableVariants = cva12(
|
|
6340
6547
|
[
|
|
6341
6548
|
"relative overflow-hidden rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
|
|
@@ -6398,7 +6605,7 @@ function getRenderedCell(row, column) {
|
|
|
6398
6605
|
if (value === null || value === void 0) {
|
|
6399
6606
|
return null;
|
|
6400
6607
|
}
|
|
6401
|
-
if (
|
|
6608
|
+
if (React33.isValidElement(value)) {
|
|
6402
6609
|
return value;
|
|
6403
6610
|
}
|
|
6404
6611
|
return String(value);
|
|
@@ -6418,7 +6625,7 @@ function isInteractiveTarget(target) {
|
|
|
6418
6625
|
function SortIcon({ sort, columnKey }) {
|
|
6419
6626
|
const isActive = sort?.key === columnKey;
|
|
6420
6627
|
if (!isActive) {
|
|
6421
|
-
return /* @__PURE__ */
|
|
6628
|
+
return /* @__PURE__ */ jsx37(
|
|
6422
6629
|
ChevronsUpDown,
|
|
6423
6630
|
{
|
|
6424
6631
|
"aria-hidden": "true",
|
|
@@ -6429,8 +6636,8 @@ function SortIcon({ sort, columnKey }) {
|
|
|
6429
6636
|
}
|
|
6430
6637
|
);
|
|
6431
6638
|
}
|
|
6432
|
-
const Icon = sort.dir === "asc" ? ChevronUp2 :
|
|
6433
|
-
return /* @__PURE__ */
|
|
6639
|
+
const Icon = sort.dir === "asc" ? ChevronUp2 : ChevronDown5;
|
|
6640
|
+
return /* @__PURE__ */ jsx37(
|
|
6434
6641
|
Icon,
|
|
6435
6642
|
{
|
|
6436
6643
|
"aria-hidden": "true",
|
|
@@ -6448,8 +6655,8 @@ function MobileSortMenu({
|
|
|
6448
6655
|
onSortChange
|
|
6449
6656
|
}) {
|
|
6450
6657
|
const active = sortBy ? columns.find((column) => column.key === sortBy.key) : void 0;
|
|
6451
|
-
return /* @__PURE__ */
|
|
6452
|
-
/* @__PURE__ */
|
|
6658
|
+
return /* @__PURE__ */ jsxs33(DropdownMenu, { children: [
|
|
6659
|
+
/* @__PURE__ */ jsx37(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs33(
|
|
6453
6660
|
Button,
|
|
6454
6661
|
{
|
|
6455
6662
|
"data-slot": "data-table-mobile-sort-button",
|
|
@@ -6458,26 +6665,26 @@ function MobileSortMenu({
|
|
|
6458
6665
|
size: "sm",
|
|
6459
6666
|
className: "ml-auto min-w-0",
|
|
6460
6667
|
children: [
|
|
6461
|
-
active && sortBy ? /* @__PURE__ */
|
|
6462
|
-
/* @__PURE__ */
|
|
6463
|
-
/* @__PURE__ */
|
|
6464
|
-
/* @__PURE__ */
|
|
6668
|
+
active && sortBy ? /* @__PURE__ */ jsxs33(Fragment13, { children: [
|
|
6669
|
+
/* @__PURE__ */ jsx37("span", { className: "sr-only", children: "\uC815\uB82C " }),
|
|
6670
|
+
/* @__PURE__ */ jsx37("span", { className: "truncate", children: active.header }),
|
|
6671
|
+
/* @__PURE__ */ jsxs33("span", { className: "sr-only", children: [
|
|
6465
6672
|
", ",
|
|
6466
6673
|
sortBy.dir === "asc" ? "\uC624\uB984\uCC28\uC21C" : "\uB0B4\uB9BC\uCC28\uC21C"
|
|
6467
6674
|
] })
|
|
6468
6675
|
] }) : "\uC815\uB82C",
|
|
6469
|
-
/* @__PURE__ */
|
|
6676
|
+
/* @__PURE__ */ jsx37(SortIcon, { sort: sortBy, columnKey: active?.key ?? "" })
|
|
6470
6677
|
]
|
|
6471
6678
|
}
|
|
6472
6679
|
) }),
|
|
6473
|
-
/* @__PURE__ */
|
|
6680
|
+
/* @__PURE__ */ jsx37(DropdownMenuContent, { align: "end", children: /* @__PURE__ */ jsx37(DropdownMenuRadioGroup, { value: active?.key ?? "", children: columns.map((column) => /* @__PURE__ */ jsxs33(
|
|
6474
6681
|
DropdownMenuRadioItem,
|
|
6475
6682
|
{
|
|
6476
6683
|
value: column.key,
|
|
6477
6684
|
onSelect: () => onSortChange?.(column.key, getNextSort(sortBy, column.key)),
|
|
6478
6685
|
children: [
|
|
6479
|
-
/* @__PURE__ */
|
|
6480
|
-
column.key === active?.key ? /* @__PURE__ */
|
|
6686
|
+
/* @__PURE__ */ jsx37("span", { className: "truncate", children: column.header }),
|
|
6687
|
+
column.key === active?.key ? /* @__PURE__ */ jsx37("span", { className: "ml-auto pl-[var(--space-4)]", children: /* @__PURE__ */ jsx37(SortIcon, { sort: sortBy, columnKey: column.key }) }) : null
|
|
6481
6688
|
]
|
|
6482
6689
|
},
|
|
6483
6690
|
column.key
|
|
@@ -6496,14 +6703,14 @@ function MobileToolbar({
|
|
|
6496
6703
|
if (!selectable && sortableColumns.length === 0) {
|
|
6497
6704
|
return null;
|
|
6498
6705
|
}
|
|
6499
|
-
return /* @__PURE__ */
|
|
6706
|
+
return /* @__PURE__ */ jsxs33(
|
|
6500
6707
|
"div",
|
|
6501
6708
|
{
|
|
6502
6709
|
"data-slot": "data-table-mobile-toolbar",
|
|
6503
6710
|
className: "flex min-w-0 items-center gap-[var(--space-2)] px-[var(--space-4)] py-[var(--space-2)]",
|
|
6504
6711
|
children: [
|
|
6505
|
-
selectable ? /* @__PURE__ */
|
|
6506
|
-
sortableColumns.length > 0 ? /* @__PURE__ */
|
|
6712
|
+
selectable ? /* @__PURE__ */ jsx37(SelectAllCheckbox, { checked: selectAllChecked, onToggleAll }) : null,
|
|
6713
|
+
sortableColumns.length > 0 ? /* @__PURE__ */ jsx37(MobileSortMenu, { columns: sortableColumns, sortBy, onSortChange }) : null
|
|
6507
6714
|
]
|
|
6508
6715
|
}
|
|
6509
6716
|
);
|
|
@@ -6512,13 +6719,13 @@ function SelectAllCheckbox({
|
|
|
6512
6719
|
checked,
|
|
6513
6720
|
onToggleAll
|
|
6514
6721
|
}) {
|
|
6515
|
-
return /* @__PURE__ */
|
|
6722
|
+
return /* @__PURE__ */ jsx37(
|
|
6516
6723
|
Checkbox,
|
|
6517
6724
|
{
|
|
6518
6725
|
"aria-label": "\uC804\uCCB4 \uD589 \uC120\uD0DD",
|
|
6519
6726
|
checked,
|
|
6520
6727
|
onCheckedChange: (nextChecked) => onToggleAll(nextChecked === true),
|
|
6521
|
-
children: /* @__PURE__ */
|
|
6728
|
+
children: /* @__PURE__ */ jsx37("span", { className: "sr-only", children: "\uC804\uCCB4 \uD589 \uC120\uD0DD" })
|
|
6522
6729
|
}
|
|
6523
6730
|
);
|
|
6524
6731
|
}
|
|
@@ -6529,13 +6736,13 @@ function RowCheckbox({
|
|
|
6529
6736
|
selected,
|
|
6530
6737
|
onToggle
|
|
6531
6738
|
}) {
|
|
6532
|
-
return /* @__PURE__ */
|
|
6739
|
+
return /* @__PURE__ */ jsx37(
|
|
6533
6740
|
Checkbox,
|
|
6534
6741
|
{
|
|
6535
6742
|
"aria-label": `${String(row[columns[0]?.key] ?? rowId)} \uD589 \uC120\uD0DD`,
|
|
6536
6743
|
checked: selected,
|
|
6537
6744
|
onCheckedChange: (nextChecked) => onToggle(rowId, nextChecked === true),
|
|
6538
|
-
children: /* @__PURE__ */
|
|
6745
|
+
children: /* @__PURE__ */ jsxs33("span", { className: "sr-only", children: [
|
|
6539
6746
|
rowId,
|
|
6540
6747
|
" \uD589 \uC120\uD0DD"
|
|
6541
6748
|
] })
|
|
@@ -6552,17 +6759,17 @@ function SkeletonRows({
|
|
|
6552
6759
|
// role="table"의 허용 자식은 row/rowgroup뿐이라 컨테이너는 rowgroup이어야 한다.
|
|
6553
6760
|
// 로딩 알림은 그 안의 row/cell 안에 둔다 — 종전에는 컨테이너가 role="status"라
|
|
6554
6761
|
// aria-required-children(Critical)이 났다.
|
|
6555
|
-
/* @__PURE__ */
|
|
6556
|
-
/* @__PURE__ */
|
|
6557
|
-
Array.from({ length: count }, (_, rowIndex) => /* @__PURE__ */
|
|
6762
|
+
/* @__PURE__ */ jsxs33("div", { role: "rowgroup", children: [
|
|
6763
|
+
/* @__PURE__ */ jsx37("div", { role: "row", children: /* @__PURE__ */ jsx37("div", { role: "cell", "aria-colindex": 1, "aria-label": "\uB370\uC774\uD130 \uB85C\uB4DC \uC911", children: /* @__PURE__ */ jsx37("span", { role: "status", className: "sr-only", children: "\uB370\uC774\uD130 \uB85C\uB4DC \uC911" }) }) }),
|
|
6764
|
+
Array.from({ length: count }, (_, rowIndex) => /* @__PURE__ */ jsxs33(
|
|
6558
6765
|
"div",
|
|
6559
6766
|
{
|
|
6560
6767
|
"data-slot": "data-table-skeleton-row",
|
|
6561
6768
|
className: "grid min-h-[48px] items-center border-t border-[var(--border-subtle)]",
|
|
6562
6769
|
style: { gridTemplateColumns },
|
|
6563
6770
|
children: [
|
|
6564
|
-
selectable ? /* @__PURE__ */
|
|
6565
|
-
columns.map((column, columnIndex) => /* @__PURE__ */
|
|
6771
|
+
selectable ? /* @__PURE__ */ jsx37("div", { "aria-hidden": "true", className: "px-[var(--space-4)]" }) : null,
|
|
6772
|
+
columns.map((column, columnIndex) => /* @__PURE__ */ jsx37("div", { className: "px-[var(--space-4)] py-[var(--space-2)]", children: /* @__PURE__ */ jsx37(
|
|
6566
6773
|
"div",
|
|
6567
6774
|
{
|
|
6568
6775
|
className: cn(
|
|
@@ -6579,15 +6786,15 @@ function SkeletonRows({
|
|
|
6579
6786
|
);
|
|
6580
6787
|
}
|
|
6581
6788
|
function MobileSkeletonCards({ count }) {
|
|
6582
|
-
return /* @__PURE__ */
|
|
6789
|
+
return /* @__PURE__ */ jsx37("div", { "data-slot": "data-table-mobile-skeleton", "aria-label": "\uB370\uC774\uD130 \uB85C\uB4DC \uC911", role: "status", children: Array.from({ length: count }, (_, rowIndex) => /* @__PURE__ */ jsxs33(
|
|
6583
6790
|
"div",
|
|
6584
6791
|
{
|
|
6585
6792
|
"data-slot": "data-table-mobile-skeleton-card",
|
|
6586
6793
|
className: "flex flex-col gap-[var(--space-2)] border-t border-[var(--border-subtle)] px-[var(--space-4)] py-[var(--space-4)]",
|
|
6587
6794
|
children: [
|
|
6588
|
-
/* @__PURE__ */
|
|
6589
|
-
/* @__PURE__ */
|
|
6590
|
-
/* @__PURE__ */
|
|
6795
|
+
/* @__PURE__ */ jsx37("div", { className: "h-[14px] w-[72%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-inset)]" }),
|
|
6796
|
+
/* @__PURE__ */ jsx37("div", { className: "h-[12px] w-[56%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-inset)]" }),
|
|
6797
|
+
/* @__PURE__ */ jsx37("div", { className: "h-[12px] w-[64%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-inset)]" })
|
|
6591
6798
|
]
|
|
6592
6799
|
},
|
|
6593
6800
|
rowIndex
|
|
@@ -6635,7 +6842,7 @@ function DataTableRowView({
|
|
|
6635
6842
|
}) {
|
|
6636
6843
|
const linked = Boolean(LinkComponent && href);
|
|
6637
6844
|
const handlers = useActivationHandlers({ row, href, activatable, onActivate });
|
|
6638
|
-
return /* @__PURE__ */
|
|
6845
|
+
return /* @__PURE__ */ jsxs33(
|
|
6639
6846
|
"div",
|
|
6640
6847
|
{
|
|
6641
6848
|
"data-slot": "data-table-row",
|
|
@@ -6653,11 +6860,11 @@ function DataTableRowView({
|
|
|
6653
6860
|
onClick: handlers.onClick,
|
|
6654
6861
|
onKeyDown: handlers.onKeyDown,
|
|
6655
6862
|
children: [
|
|
6656
|
-
selectable ? /* @__PURE__ */
|
|
6863
|
+
selectable ? /* @__PURE__ */ jsx37("div", { role: "cell", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx37(RowCheckbox, { row, rowId, columns, selected, onToggle }) }) : null,
|
|
6657
6864
|
columns.map((column, columnIndex) => {
|
|
6658
6865
|
const align = column.align ?? "left";
|
|
6659
6866
|
const content = getRenderedCell(row, column);
|
|
6660
|
-
return /* @__PURE__ */
|
|
6867
|
+
return /* @__PURE__ */ jsx37(
|
|
6661
6868
|
"div",
|
|
6662
6869
|
{
|
|
6663
6870
|
"data-slot": "data-table-cell",
|
|
@@ -6667,7 +6874,7 @@ function DataTableRowView({
|
|
|
6667
6874
|
alignmentClass[align],
|
|
6668
6875
|
column.tabular ? "font-[family-name:var(--font-display)] tabular-nums" : null
|
|
6669
6876
|
),
|
|
6670
|
-
children: /* @__PURE__ */
|
|
6877
|
+
children: /* @__PURE__ */ jsx37("span", { className: "min-w-0 truncate", children: linked && columnIndex === 0 && LinkComponent ? /* @__PURE__ */ jsx37(LinkComponent, { href, "data-slot": "data-table-row-link", className: rowLinkClass, children: content }) : content })
|
|
6671
6878
|
},
|
|
6672
6879
|
column.key
|
|
6673
6880
|
);
|
|
@@ -6695,14 +6902,28 @@ function DataTableMobileCardView({
|
|
|
6695
6902
|
first
|
|
6696
6903
|
}) {
|
|
6697
6904
|
const linked = Boolean(LinkComponent && href);
|
|
6698
|
-
const handlers = useActivationHandlers({ row, href, activatable, onActivate });
|
|
6699
6905
|
const content = getMobileCardContent(row);
|
|
6700
6906
|
const navigable = linked || activatable;
|
|
6701
|
-
const leading = selectable || content.leading != null ? /* @__PURE__ */
|
|
6702
|
-
selectable ? /* @__PURE__ */
|
|
6907
|
+
const leading = selectable || content.leading != null ? /* @__PURE__ */ jsxs33("span", { className: "flex items-center gap-[var(--space-2)]", children: [
|
|
6908
|
+
selectable ? /* @__PURE__ */ jsx37(RowCheckbox, { row, rowId, columns, selected, onToggle }) : null,
|
|
6703
6909
|
content.leading
|
|
6704
6910
|
] }) : void 0;
|
|
6705
|
-
|
|
6911
|
+
let title = content.title;
|
|
6912
|
+
if (linked && LinkComponent) {
|
|
6913
|
+
title = /* @__PURE__ */ jsx37(LinkComponent, { href, "data-slot": "data-table-row-link", className: rowLinkClass, children: content.title });
|
|
6914
|
+
} else if (activatable) {
|
|
6915
|
+
title = /* @__PURE__ */ jsx37(
|
|
6916
|
+
"button",
|
|
6917
|
+
{
|
|
6918
|
+
type: "button",
|
|
6919
|
+
"data-slot": "data-table-row-link",
|
|
6920
|
+
className: cn(rowLinkClass, "block w-full text-left"),
|
|
6921
|
+
onClick: (event) => onActivate(row, href, event),
|
|
6922
|
+
children: /* @__PURE__ */ jsx37("span", { className: "line-clamp-2", children: content.title })
|
|
6923
|
+
}
|
|
6924
|
+
);
|
|
6925
|
+
}
|
|
6926
|
+
return /* @__PURE__ */ jsx37(
|
|
6706
6927
|
"div",
|
|
6707
6928
|
{
|
|
6708
6929
|
"data-slot": "data-table-mobile-card",
|
|
@@ -6711,37 +6932,35 @@ function DataTableMobileCardView({
|
|
|
6711
6932
|
role: "listitem",
|
|
6712
6933
|
"aria-posinset": ariaPosInSet,
|
|
6713
6934
|
"aria-setsize": ariaSetSize,
|
|
6714
|
-
"aria-label": content.ariaLabel,
|
|
6715
|
-
tabIndex: activatable ? 0 : void 0,
|
|
6935
|
+
"aria-label": content.ariaLabel ?? String(content.title),
|
|
6716
6936
|
className: cn(
|
|
6717
6937
|
"min-w-0 border-t border-[var(--border-subtle)] transition-colors motion-reduce:transition-none",
|
|
6718
6938
|
first ? "border-t-0" : null,
|
|
6719
|
-
navigable ? "cursor-pointer hover:bg-[var(--action-hover)]
|
|
6939
|
+
navigable ? "cursor-pointer hover:bg-[var(--action-hover)]" : null,
|
|
6720
6940
|
visuallySelected ? "bg-[var(--action-selected)]" : null,
|
|
6721
|
-
|
|
6941
|
+
navigable ? rowLinkHostClass : null
|
|
6722
6942
|
),
|
|
6723
6943
|
onContextMenu: (event) => onRowContextMenu?.(rowId, event),
|
|
6724
|
-
|
|
6725
|
-
onKeyDown: handlers.onKeyDown,
|
|
6726
|
-
children: /* @__PURE__ */ jsx36(
|
|
6944
|
+
children: /* @__PURE__ */ jsx37(
|
|
6727
6945
|
ListCard,
|
|
6728
6946
|
{
|
|
6729
6947
|
className: "px-[var(--space-4)] py-[var(--space-3)]",
|
|
6730
|
-
title
|
|
6948
|
+
title,
|
|
6731
6949
|
meta: content.meta ? [content.meta[0], content.meta[1]] : void 0,
|
|
6732
6950
|
status: content.status,
|
|
6733
6951
|
caption: content.date,
|
|
6734
6952
|
value: content.value,
|
|
6735
6953
|
leading,
|
|
6736
|
-
trailing: navigable ? "chevron" : "none"
|
|
6954
|
+
trailing: navigable ? "chevron" : "none",
|
|
6955
|
+
actions: content.actions
|
|
6737
6956
|
}
|
|
6738
6957
|
)
|
|
6739
6958
|
}
|
|
6740
6959
|
);
|
|
6741
6960
|
}
|
|
6742
|
-
var MemoDataTableRow =
|
|
6743
|
-
var MemoDataTableMobileCard =
|
|
6744
|
-
var useIsomorphicLayoutEffect = typeof window === "undefined" ?
|
|
6961
|
+
var MemoDataTableRow = React33.memo(DataTableRowView);
|
|
6962
|
+
var MemoDataTableMobileCard = React33.memo(DataTableMobileCardView);
|
|
6963
|
+
var useIsomorphicLayoutEffect = typeof window === "undefined" ? React33.useEffect : React33.useLayoutEffect;
|
|
6745
6964
|
var VIRTUAL_DEFAULT_OVERSCAN = 8;
|
|
6746
6965
|
var VIRTUAL_INITIAL_ROWS = 24;
|
|
6747
6966
|
var VIRTUAL_FALLBACK_SIZE = { desktop: 48, mobile: 120 };
|
|
@@ -6821,7 +7040,7 @@ function useVirtualWindow({
|
|
|
6821
7040
|
mobileListRef
|
|
6822
7041
|
}) {
|
|
6823
7042
|
const count = rowIds.length;
|
|
6824
|
-
const [win, setWin] =
|
|
7043
|
+
const [win, setWin] = React33.useState({
|
|
6825
7044
|
layout: null,
|
|
6826
7045
|
start: 0,
|
|
6827
7046
|
end: VIRTUAL_INITIAL_ROWS,
|
|
@@ -6829,12 +7048,12 @@ function useVirtualWindow({
|
|
|
6829
7048
|
padTop: 0,
|
|
6830
7049
|
padBottom: 0
|
|
6831
7050
|
});
|
|
6832
|
-
const desktopSize =
|
|
6833
|
-
const cardHeights =
|
|
7051
|
+
const desktopSize = React33.useRef(0);
|
|
7052
|
+
const cardHeights = React33.useRef(null);
|
|
6834
7053
|
cardHeights.current ??= new CardHeights();
|
|
6835
|
-
const update =
|
|
6836
|
-
const reported =
|
|
6837
|
-
const latest =
|
|
7054
|
+
const update = React33.useRef(() => void 0);
|
|
7055
|
+
const reported = React33.useRef("");
|
|
7056
|
+
const latest = React33.useRef({
|
|
6838
7057
|
count,
|
|
6839
7058
|
layout: "desktop",
|
|
6840
7059
|
extent: uniformExtent(VIRTUAL_FALLBACK_SIZE.desktop)
|
|
@@ -6897,7 +7116,7 @@ function useVirtualWindow({
|
|
|
6897
7116
|
useIsomorphicLayoutEffect(() => {
|
|
6898
7117
|
update.current();
|
|
6899
7118
|
});
|
|
6900
|
-
|
|
7119
|
+
React33.useEffect(() => {
|
|
6901
7120
|
if (!enabled) {
|
|
6902
7121
|
return;
|
|
6903
7122
|
}
|
|
@@ -6919,7 +7138,7 @@ function useVirtualWindow({
|
|
|
6919
7138
|
window.cancelAnimationFrame(frame);
|
|
6920
7139
|
};
|
|
6921
7140
|
}, [enabled]);
|
|
6922
|
-
const scrollToIndex =
|
|
7141
|
+
const scrollToIndex = React33.useCallback(
|
|
6923
7142
|
(index) => {
|
|
6924
7143
|
const { count: rowCount, layout, extent } = latest.current;
|
|
6925
7144
|
const list = (layout === "desktop" ? desktopListRef : mobileListRef).current;
|
|
@@ -6952,7 +7171,7 @@ function useVisibleLayout({
|
|
|
6952
7171
|
desktopRef,
|
|
6953
7172
|
mobileRef
|
|
6954
7173
|
}) {
|
|
6955
|
-
const [layout, setLayout] =
|
|
7174
|
+
const [layout, setLayout] = React33.useState(null);
|
|
6956
7175
|
useIsomorphicLayoutEffect(() => {
|
|
6957
7176
|
if (!enabled) {
|
|
6958
7177
|
return;
|
|
@@ -6989,9 +7208,9 @@ function useLayoutFocusHandoff({
|
|
|
6989
7208
|
layout,
|
|
6990
7209
|
containers
|
|
6991
7210
|
}) {
|
|
6992
|
-
const lastFocus =
|
|
6993
|
-
const previousLayout =
|
|
6994
|
-
|
|
7211
|
+
const lastFocus = React33.useRef(null);
|
|
7212
|
+
const previousLayout = React33.useRef(layout);
|
|
7213
|
+
React33.useEffect(() => {
|
|
6995
7214
|
const root = rootRef.current;
|
|
6996
7215
|
if (!root) {
|
|
6997
7216
|
return;
|
|
@@ -7043,7 +7262,7 @@ function useLayoutFocusHandoff({
|
|
|
7043
7262
|
const item = record.rowId ? Array.from(container.querySelectorAll("[data-row-id]")).find(
|
|
7044
7263
|
(node) => node.getAttribute("data-row-id") === record.rowId
|
|
7045
7264
|
) : void 0;
|
|
7046
|
-
const target = (item && (record.checkbox ? item.querySelector('[role="checkbox"]') : item.hasAttribute("tabindex") ? item : item.querySelector("
|
|
7265
|
+
const target = (item && (record.checkbox ? item.querySelector('[role="checkbox"]') : item.hasAttribute("tabindex") ? item : item.querySelector('[data-slot="data-table-row-link"]'))) ?? item ?? container;
|
|
7047
7266
|
if (target instanceof HTMLElement) {
|
|
7048
7267
|
if (!target.hasAttribute("tabindex") && !target.matches("a[href],button,input")) {
|
|
7049
7268
|
target.tabIndex = -1;
|
|
@@ -7081,13 +7300,13 @@ function DataTableInner({
|
|
|
7081
7300
|
}, ref) {
|
|
7082
7301
|
const virtualOptions = virtual ? virtual === true ? {} : virtual : null;
|
|
7083
7302
|
const isVirtual = virtualOptions !== null;
|
|
7084
|
-
const rootRef =
|
|
7085
|
-
const desktopRef =
|
|
7086
|
-
const headerRef =
|
|
7087
|
-
const desktopListRef =
|
|
7088
|
-
const mobileRef =
|
|
7089
|
-
const mobileListRef =
|
|
7090
|
-
const setRootRef =
|
|
7303
|
+
const rootRef = React33.useRef(null);
|
|
7304
|
+
const desktopRef = React33.useRef(null);
|
|
7305
|
+
const headerRef = React33.useRef(null);
|
|
7306
|
+
const desktopListRef = React33.useRef(null);
|
|
7307
|
+
const mobileRef = React33.useRef(null);
|
|
7308
|
+
const mobileListRef = React33.useRef(null);
|
|
7309
|
+
const setRootRef = React33.useCallback(
|
|
7091
7310
|
(node) => {
|
|
7092
7311
|
rootRef.current = node;
|
|
7093
7312
|
if (typeof ref === "function") ref(node);
|
|
@@ -7106,7 +7325,7 @@ function DataTableInner({
|
|
|
7106
7325
|
desktopListRef,
|
|
7107
7326
|
mobileListRef
|
|
7108
7327
|
});
|
|
7109
|
-
|
|
7328
|
+
React33.useImperativeHandle(virtualOptions?.handleRef, () => ({ scrollToIndex }), [scrollToIndex]);
|
|
7110
7329
|
const visibleLayout = useVisibleLayout({ enabled: !isVirtual, desktopRef, mobileRef });
|
|
7111
7330
|
const activeLayout = isVirtual ? virtualWindow.layout : visibleLayout;
|
|
7112
7331
|
useLayoutFocusHandoff({
|
|
@@ -7151,19 +7370,19 @@ function DataTableInner({
|
|
|
7151
7370
|
window.location.assign(href);
|
|
7152
7371
|
}
|
|
7153
7372
|
};
|
|
7154
|
-
const latestHandlers =
|
|
7373
|
+
const latestHandlers = React33.useRef({ toggleRow, activateRow, onRowContextMenu });
|
|
7155
7374
|
useIsomorphicLayoutEffect(() => {
|
|
7156
7375
|
latestHandlers.current = { toggleRow, activateRow, onRowContextMenu };
|
|
7157
7376
|
});
|
|
7158
|
-
const stableToggleRow =
|
|
7377
|
+
const stableToggleRow = React33.useCallback(
|
|
7159
7378
|
(id, checked) => latestHandlers.current.toggleRow(id, checked),
|
|
7160
7379
|
[]
|
|
7161
7380
|
);
|
|
7162
|
-
const stableActivateRow =
|
|
7381
|
+
const stableActivateRow = React33.useCallback(
|
|
7163
7382
|
(row, href, event) => latestHandlers.current.activateRow(row, href, event),
|
|
7164
7383
|
[]
|
|
7165
7384
|
);
|
|
7166
|
-
const stableRowContextMenu =
|
|
7385
|
+
const stableRowContextMenu = React33.useCallback(
|
|
7167
7386
|
(rowId, event) => latestHandlers.current.onRowContextMenu?.(rowId, event),
|
|
7168
7387
|
[]
|
|
7169
7388
|
);
|
|
@@ -7215,7 +7434,7 @@ function DataTableInner({
|
|
|
7215
7434
|
const mobileSlice = sliceFor("mobile");
|
|
7216
7435
|
const RowComponent = isVirtual ? MemoDataTableRow : DataTableRowView;
|
|
7217
7436
|
const CardComponent = isVirtual ? MemoDataTableMobileCard : DataTableMobileCardView;
|
|
7218
|
-
return /* @__PURE__ */
|
|
7437
|
+
return /* @__PURE__ */ jsxs33(
|
|
7219
7438
|
"div",
|
|
7220
7439
|
{
|
|
7221
7440
|
ref: setRootRef,
|
|
@@ -7229,7 +7448,7 @@ function DataTableInner({
|
|
|
7229
7448
|
),
|
|
7230
7449
|
...props,
|
|
7231
7450
|
children: [
|
|
7232
|
-
selectable && announceSelection ? /* @__PURE__ */
|
|
7451
|
+
selectable && announceSelection ? /* @__PURE__ */ jsx37(
|
|
7233
7452
|
"div",
|
|
7234
7453
|
{
|
|
7235
7454
|
"data-slot": "data-table-selection-status",
|
|
@@ -7238,23 +7457,23 @@ function DataTableInner({
|
|
|
7238
7457
|
children: selectedCount > 0 ? `${selectedCount.toLocaleString("ko-KR")}${selectionUnit} \uC120\uD0DD\uB428` : ""
|
|
7239
7458
|
}
|
|
7240
7459
|
) : null,
|
|
7241
|
-
loading && data.length > 0 ? /* @__PURE__ */
|
|
7460
|
+
loading && data.length > 0 ? /* @__PURE__ */ jsx37(
|
|
7242
7461
|
"div",
|
|
7243
7462
|
{
|
|
7244
7463
|
"data-slot": "data-table-progress",
|
|
7245
7464
|
"aria-hidden": "true",
|
|
7246
7465
|
className: "absolute left-0 right-0 top-0 z-10 h-[2px] overflow-hidden bg-[var(--action-selected)]",
|
|
7247
|
-
children: /* @__PURE__ */
|
|
7466
|
+
children: /* @__PURE__ */ jsx37("div", { className: "h-full w-1/3 animate-pulse bg-[var(--primary)]" })
|
|
7248
7467
|
}
|
|
7249
7468
|
) : null,
|
|
7250
|
-
/* @__PURE__ */
|
|
7469
|
+
/* @__PURE__ */ jsx37("div", { ref: desktopRef, "data-slot": "data-table-desktop", className: "max-lg:hidden lg:block", children: /* @__PURE__ */ jsxs33(
|
|
7251
7470
|
"div",
|
|
7252
7471
|
{
|
|
7253
7472
|
role: "table",
|
|
7254
7473
|
"aria-label": ariaLabel,
|
|
7255
7474
|
"aria-rowcount": isVirtual && data.length > 0 ? data.length + 1 : void 0,
|
|
7256
7475
|
children: [
|
|
7257
|
-
/* @__PURE__ */
|
|
7476
|
+
/* @__PURE__ */ jsxs33(
|
|
7258
7477
|
"div",
|
|
7259
7478
|
{
|
|
7260
7479
|
ref: headerRef,
|
|
@@ -7269,12 +7488,12 @@ function DataTableInner({
|
|
|
7269
7488
|
),
|
|
7270
7489
|
style: { gridTemplateColumns },
|
|
7271
7490
|
children: [
|
|
7272
|
-
selectable ? /* @__PURE__ */
|
|
7491
|
+
selectable ? /* @__PURE__ */ jsx37("div", { role: "columnheader", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx37(SelectAllCheckbox, { checked: selectAllChecked, onToggleAll: toggleAllRows }) }) : null,
|
|
7273
7492
|
columns.map((column) => {
|
|
7274
7493
|
const align = column.align ?? "left";
|
|
7275
7494
|
const nextSort = getNextSort(sortBy, column.key);
|
|
7276
7495
|
const ariaSort = sortBy?.key === column.key ? sortBy.dir === "asc" ? "ascending" : "descending" : void 0;
|
|
7277
|
-
return /* @__PURE__ */
|
|
7496
|
+
return /* @__PURE__ */ jsx37(
|
|
7278
7497
|
"div",
|
|
7279
7498
|
{
|
|
7280
7499
|
role: "columnheader",
|
|
@@ -7283,7 +7502,7 @@ function DataTableInner({
|
|
|
7283
7502
|
"flex min-w-0 items-center gap-[var(--space-1)] px-[var(--space-4)] py-[var(--space-2)]",
|
|
7284
7503
|
alignmentClass[align]
|
|
7285
7504
|
),
|
|
7286
|
-
children: column.sortable ? /* @__PURE__ */
|
|
7505
|
+
children: column.sortable ? /* @__PURE__ */ jsxs33(
|
|
7287
7506
|
"button",
|
|
7288
7507
|
{
|
|
7289
7508
|
type: "button",
|
|
@@ -7294,11 +7513,11 @@ function DataTableInner({
|
|
|
7294
7513
|
),
|
|
7295
7514
|
onClick: () => onSortChange?.(column.key, nextSort),
|
|
7296
7515
|
children: [
|
|
7297
|
-
/* @__PURE__ */
|
|
7298
|
-
/* @__PURE__ */
|
|
7516
|
+
/* @__PURE__ */ jsx37("span", { className: "truncate", children: column.header }),
|
|
7517
|
+
/* @__PURE__ */ jsx37(SortIcon, { sort: sortBy, columnKey: column.key })
|
|
7299
7518
|
]
|
|
7300
7519
|
}
|
|
7301
|
-
) : /* @__PURE__ */
|
|
7520
|
+
) : /* @__PURE__ */ jsx37("span", { className: "truncate", children: column.header })
|
|
7302
7521
|
},
|
|
7303
7522
|
column.key
|
|
7304
7523
|
);
|
|
@@ -7306,7 +7525,7 @@ function DataTableInner({
|
|
|
7306
7525
|
]
|
|
7307
7526
|
}
|
|
7308
7527
|
),
|
|
7309
|
-
loading && data.length === 0 ? /* @__PURE__ */
|
|
7528
|
+
loading && data.length === 0 ? /* @__PURE__ */ jsx37(
|
|
7310
7529
|
SkeletonRows,
|
|
7311
7530
|
{
|
|
7312
7531
|
columns,
|
|
@@ -7317,7 +7536,7 @@ function DataTableInner({
|
|
|
7317
7536
|
) : data.length === 0 ? (
|
|
7318
7537
|
/* role="table" 직계 자식은 row/rowgroup이어야 한다. data-slot과 테두리는
|
|
7319
7538
|
그대로 유지해 시각 계약을 깨지 않는다(빈 상태에서도 표가 테두리를 그린다). */
|
|
7320
|
-
/* @__PURE__ */
|
|
7539
|
+
/* @__PURE__ */ jsx37("div", { role: "rowgroup", children: /* @__PURE__ */ jsx37("div", { role: "row", children: /* @__PURE__ */ jsx37(
|
|
7321
7540
|
"div",
|
|
7322
7541
|
{
|
|
7323
7542
|
role: "cell",
|
|
@@ -7327,9 +7546,9 @@ function DataTableInner({
|
|
|
7327
7546
|
children: emptyState
|
|
7328
7547
|
}
|
|
7329
7548
|
) }) })
|
|
7330
|
-
) : /* @__PURE__ */
|
|
7549
|
+
) : /* @__PURE__ */ jsx37("div", { ref: desktopListRef, role: "rowgroup", style: desktopSlice.style, children: desktopSlice.rows.map((row, index) => {
|
|
7331
7550
|
const itemProps = getItemProps(row);
|
|
7332
|
-
return /* @__PURE__ */
|
|
7551
|
+
return /* @__PURE__ */ jsx37(
|
|
7333
7552
|
RowComponent,
|
|
7334
7553
|
{
|
|
7335
7554
|
...itemProps,
|
|
@@ -7342,8 +7561,8 @@ function DataTableInner({
|
|
|
7342
7561
|
]
|
|
7343
7562
|
}
|
|
7344
7563
|
) }),
|
|
7345
|
-
/* @__PURE__ */
|
|
7346
|
-
/* @__PURE__ */
|
|
7564
|
+
/* @__PURE__ */ jsxs33("div", { ref: mobileRef, "data-slot": "data-table-mobile", className: "lg:hidden", children: [
|
|
7565
|
+
/* @__PURE__ */ jsx37(
|
|
7347
7566
|
MobileToolbar,
|
|
7348
7567
|
{
|
|
7349
7568
|
columns,
|
|
@@ -7354,7 +7573,7 @@ function DataTableInner({
|
|
|
7354
7573
|
onToggleAll: toggleAllRows
|
|
7355
7574
|
}
|
|
7356
7575
|
),
|
|
7357
|
-
loading && data.length === 0 ? /* @__PURE__ */
|
|
7576
|
+
loading && data.length === 0 ? /* @__PURE__ */ jsx37(MobileSkeletonCards, { count: skeletonRowCount }) : data.length === 0 ? /* @__PURE__ */ jsx37("div", { "data-slot": "data-table-mobile-empty", className: "border-t border-[var(--border-subtle)] p-[var(--space-4)]", children: emptyState }) : /* @__PURE__ */ jsx37(
|
|
7358
7577
|
"div",
|
|
7359
7578
|
{
|
|
7360
7579
|
ref: mobileListRef,
|
|
@@ -7365,7 +7584,7 @@ function DataTableInner({
|
|
|
7365
7584
|
children: mobileSlice.rows.map((row, index) => {
|
|
7366
7585
|
const itemProps = getItemProps(row);
|
|
7367
7586
|
const rowIndex = mobileSlice.start + index;
|
|
7368
|
-
return /* @__PURE__ */
|
|
7587
|
+
return /* @__PURE__ */ jsx37(
|
|
7369
7588
|
CardComponent,
|
|
7370
7589
|
{
|
|
7371
7590
|
...itemProps,
|
|
@@ -7384,11 +7603,11 @@ function DataTableInner({
|
|
|
7384
7603
|
}
|
|
7385
7604
|
);
|
|
7386
7605
|
}
|
|
7387
|
-
var DataTable =
|
|
7606
|
+
var DataTable = React33.forwardRef(DataTableInner);
|
|
7388
7607
|
DataTable.displayName = "DataTable";
|
|
7389
7608
|
|
|
7390
7609
|
// src/components/ui/context-menu.tsx
|
|
7391
|
-
import { jsx as
|
|
7610
|
+
import { jsx as jsx38, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
7392
7611
|
function ContextMenu({
|
|
7393
7612
|
open,
|
|
7394
7613
|
onOpenChange,
|
|
@@ -7399,8 +7618,8 @@ function ContextMenu({
|
|
|
7399
7618
|
if (!position) {
|
|
7400
7619
|
return null;
|
|
7401
7620
|
}
|
|
7402
|
-
return /* @__PURE__ */
|
|
7403
|
-
/* @__PURE__ */
|
|
7621
|
+
return /* @__PURE__ */ jsxs34(DropdownMenu, { open, onOpenChange, modal: false, children: [
|
|
7622
|
+
/* @__PURE__ */ jsx38(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(
|
|
7404
7623
|
"span",
|
|
7405
7624
|
{
|
|
7406
7625
|
"aria-hidden": "true",
|
|
@@ -7414,19 +7633,19 @@ function ContextMenu({
|
|
|
7414
7633
|
}
|
|
7415
7634
|
}
|
|
7416
7635
|
) }),
|
|
7417
|
-
/* @__PURE__ */
|
|
7636
|
+
/* @__PURE__ */ jsx38(DropdownMenuContent, { ...contentProps, children })
|
|
7418
7637
|
] });
|
|
7419
7638
|
}
|
|
7420
7639
|
|
|
7421
7640
|
// src/components/ui/bulk-action-bar.tsx
|
|
7422
|
-
import * as
|
|
7641
|
+
import * as React34 from "react";
|
|
7423
7642
|
import { X as X3 } from "lucide-react";
|
|
7424
|
-
import { jsx as
|
|
7643
|
+
import { jsx as jsx39, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
7425
7644
|
function ActionButton({ action }) {
|
|
7426
7645
|
const danger = action.variant === "destructive";
|
|
7427
7646
|
const off = action.disabled;
|
|
7428
7647
|
const Icon = action.icon;
|
|
7429
|
-
return /* @__PURE__ */
|
|
7648
|
+
return /* @__PURE__ */ jsxs35(
|
|
7430
7649
|
"button",
|
|
7431
7650
|
{
|
|
7432
7651
|
type: "button",
|
|
@@ -7453,7 +7672,7 @@ function ActionButton({ action }) {
|
|
|
7453
7672
|
whiteSpace: "nowrap"
|
|
7454
7673
|
},
|
|
7455
7674
|
children: [
|
|
7456
|
-
Icon ? /* @__PURE__ */
|
|
7675
|
+
Icon ? /* @__PURE__ */ jsx39(
|
|
7457
7676
|
Icon,
|
|
7458
7677
|
{
|
|
7459
7678
|
"aria-hidden": "true",
|
|
@@ -7468,7 +7687,7 @@ function ActionButton({ action }) {
|
|
|
7468
7687
|
);
|
|
7469
7688
|
}
|
|
7470
7689
|
function Divider() {
|
|
7471
|
-
return /* @__PURE__ */
|
|
7690
|
+
return /* @__PURE__ */ jsx39(
|
|
7472
7691
|
"span",
|
|
7473
7692
|
{
|
|
7474
7693
|
"aria-hidden": "true",
|
|
@@ -7483,7 +7702,7 @@ function Divider() {
|
|
|
7483
7702
|
);
|
|
7484
7703
|
}
|
|
7485
7704
|
function ClearButton({ onClear }) {
|
|
7486
|
-
return /* @__PURE__ */
|
|
7705
|
+
return /* @__PURE__ */ jsx39(
|
|
7487
7706
|
"button",
|
|
7488
7707
|
{
|
|
7489
7708
|
type: "button",
|
|
@@ -7505,7 +7724,7 @@ function ClearButton({ onClear }) {
|
|
|
7505
7724
|
justifyContent: "center",
|
|
7506
7725
|
borderRadius: "var(--radius-md)"
|
|
7507
7726
|
},
|
|
7508
|
-
children: /* @__PURE__ */
|
|
7727
|
+
children: /* @__PURE__ */ jsx39(X3, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" })
|
|
7509
7728
|
}
|
|
7510
7729
|
);
|
|
7511
7730
|
}
|
|
@@ -7560,10 +7779,10 @@ var idleLineStyle = {
|
|
|
7560
7779
|
fontVariantNumeric: "tabular-nums",
|
|
7561
7780
|
color: "var(--text-secondary)"
|
|
7562
7781
|
};
|
|
7563
|
-
var useIsomorphicLayoutEffect2 = typeof window === "undefined" ?
|
|
7782
|
+
var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React34.useEffect : React34.useLayoutEffect;
|
|
7564
7783
|
function useCompactSummary(slot, enabled) {
|
|
7565
|
-
const [fullWidth, setFullWidth] =
|
|
7566
|
-
const measure =
|
|
7784
|
+
const [fullWidth, setFullWidth] = React34.useState(null);
|
|
7785
|
+
const measure = React34.useCallback(() => {
|
|
7567
7786
|
if (!slot) return;
|
|
7568
7787
|
setFullWidth((prev) => {
|
|
7569
7788
|
if (prev === null) return slot.scrollWidth > slot.clientWidth ? slot.scrollWidth : null;
|
|
@@ -7573,7 +7792,7 @@ function useCompactSummary(slot, enabled) {
|
|
|
7573
7792
|
useIsomorphicLayoutEffect2(() => {
|
|
7574
7793
|
if (enabled) measure();
|
|
7575
7794
|
});
|
|
7576
|
-
|
|
7795
|
+
React34.useEffect(() => {
|
|
7577
7796
|
if (!enabled || !slot || typeof ResizeObserver === "undefined") return;
|
|
7578
7797
|
const observer = new ResizeObserver(measure);
|
|
7579
7798
|
observer.observe(slot);
|
|
@@ -7597,7 +7816,7 @@ function BulkActionBar({
|
|
|
7597
7816
|
...props
|
|
7598
7817
|
}) {
|
|
7599
7818
|
const inline = placement === "inline";
|
|
7600
|
-
const trailingSlot = trailing !== void 0 && trailing !== null ? /* @__PURE__ */
|
|
7819
|
+
const trailingSlot = trailing !== void 0 && trailing !== null ? /* @__PURE__ */ jsx39(
|
|
7601
7820
|
"div",
|
|
7602
7821
|
{
|
|
7603
7822
|
"data-slot": "bulk-action-bar-trailing",
|
|
@@ -7610,13 +7829,13 @@ function BulkActionBar({
|
|
|
7610
7829
|
children: trailing
|
|
7611
7830
|
}
|
|
7612
7831
|
) : null;
|
|
7613
|
-
const [summaryElement, setSummaryElement] =
|
|
7832
|
+
const [summaryElement, setSummaryElement] = React34.useState(null);
|
|
7614
7833
|
const compact = useCompactSummary(
|
|
7615
7834
|
summaryElement,
|
|
7616
7835
|
inline && compactSummary !== void 0 && compactSummary !== null
|
|
7617
7836
|
);
|
|
7618
7837
|
if (count === 0 && idleContent !== void 0 && trailingSlot) {
|
|
7619
|
-
return /* @__PURE__ */
|
|
7838
|
+
return /* @__PURE__ */ jsxs35(
|
|
7620
7839
|
"div",
|
|
7621
7840
|
{
|
|
7622
7841
|
"data-slot": "bulk-action-bar",
|
|
@@ -7626,7 +7845,7 @@ function BulkActionBar({
|
|
|
7626
7845
|
style: { ...idleLineStyle, overflow: "visible", ...style },
|
|
7627
7846
|
...props,
|
|
7628
7847
|
children: [
|
|
7629
|
-
/* @__PURE__ */
|
|
7848
|
+
/* @__PURE__ */ jsx39(
|
|
7630
7849
|
"div",
|
|
7631
7850
|
{
|
|
7632
7851
|
role: "status",
|
|
@@ -7648,7 +7867,7 @@ function BulkActionBar({
|
|
|
7648
7867
|
);
|
|
7649
7868
|
}
|
|
7650
7869
|
if (count === 0 && idleContent !== void 0) {
|
|
7651
|
-
return /* @__PURE__ */
|
|
7870
|
+
return /* @__PURE__ */ jsx39(
|
|
7652
7871
|
"div",
|
|
7653
7872
|
{
|
|
7654
7873
|
role: "status",
|
|
@@ -7665,7 +7884,7 @@ function BulkActionBar({
|
|
|
7665
7884
|
if (count === 0 && emptyHint === void 0) {
|
|
7666
7885
|
return null;
|
|
7667
7886
|
}
|
|
7668
|
-
const countLabel = /* @__PURE__ */
|
|
7887
|
+
const countLabel = /* @__PURE__ */ jsx39(
|
|
7669
7888
|
"span",
|
|
7670
7889
|
{
|
|
7671
7890
|
"data-slot": "bulk-action-bar-count",
|
|
@@ -7682,7 +7901,7 @@ function BulkActionBar({
|
|
|
7682
7901
|
children: count > 0 ? `${count.toLocaleString("ko-KR")}${unit} \uC120\uD0DD\uB428` : emptyHint
|
|
7683
7902
|
}
|
|
7684
7903
|
);
|
|
7685
|
-
const summarySlot = summary !== void 0 && summary !== null ? /* @__PURE__ */
|
|
7904
|
+
const summarySlot = summary !== void 0 && summary !== null ? /* @__PURE__ */ jsx39(
|
|
7686
7905
|
"span",
|
|
7687
7906
|
{
|
|
7688
7907
|
ref: setSummaryElement,
|
|
@@ -7716,7 +7935,7 @@ function BulkActionBar({
|
|
|
7716
7935
|
children: compact ? compactSummary : summary
|
|
7717
7936
|
}
|
|
7718
7937
|
) : null;
|
|
7719
|
-
const actionGroup = /* @__PURE__ */
|
|
7938
|
+
const actionGroup = /* @__PURE__ */ jsx39(
|
|
7720
7939
|
"div",
|
|
7721
7940
|
{
|
|
7722
7941
|
"data-slot": "bulk-action-bar-actions",
|
|
@@ -7728,11 +7947,11 @@ function BulkActionBar({
|
|
|
7728
7947
|
justifyContent: "flex-end",
|
|
7729
7948
|
gap: 2
|
|
7730
7949
|
},
|
|
7731
|
-
children: actions.map((action) => /* @__PURE__ */
|
|
7950
|
+
children: actions.map((action) => /* @__PURE__ */ jsx39(ActionButton, { action }, action.key))
|
|
7732
7951
|
}
|
|
7733
7952
|
);
|
|
7734
7953
|
if (inline) {
|
|
7735
|
-
return /* @__PURE__ */
|
|
7954
|
+
return /* @__PURE__ */ jsxs35(
|
|
7736
7955
|
"div",
|
|
7737
7956
|
{
|
|
7738
7957
|
role: "toolbar",
|
|
@@ -7743,7 +7962,7 @@ function BulkActionBar({
|
|
|
7743
7962
|
style: { ...inlineStyle, ...style },
|
|
7744
7963
|
...props,
|
|
7745
7964
|
children: [
|
|
7746
|
-
/* @__PURE__ */
|
|
7965
|
+
/* @__PURE__ */ jsxs35(
|
|
7747
7966
|
"div",
|
|
7748
7967
|
{
|
|
7749
7968
|
role: "status",
|
|
@@ -7761,7 +7980,7 @@ function BulkActionBar({
|
|
|
7761
7980
|
]
|
|
7762
7981
|
}
|
|
7763
7982
|
),
|
|
7764
|
-
/* @__PURE__ */
|
|
7983
|
+
/* @__PURE__ */ jsxs35(
|
|
7765
7984
|
"div",
|
|
7766
7985
|
{
|
|
7767
7986
|
"data-slot": "bulk-action-bar-controls",
|
|
@@ -7772,10 +7991,10 @@ function BulkActionBar({
|
|
|
7772
7991
|
gap: "var(--space-1)"
|
|
7773
7992
|
},
|
|
7774
7993
|
children: [
|
|
7775
|
-
count > 0 && actions.length > 0 ? /* @__PURE__ */
|
|
7994
|
+
count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx39(Divider, {}) : null,
|
|
7776
7995
|
actionGroup,
|
|
7777
|
-
/* @__PURE__ */
|
|
7778
|
-
/* @__PURE__ */
|
|
7996
|
+
/* @__PURE__ */ jsx39(Divider, {}),
|
|
7997
|
+
/* @__PURE__ */ jsx39(ClearButton, { onClear })
|
|
7779
7998
|
]
|
|
7780
7999
|
}
|
|
7781
8000
|
),
|
|
@@ -7784,7 +8003,7 @@ function BulkActionBar({
|
|
|
7784
8003
|
}
|
|
7785
8004
|
);
|
|
7786
8005
|
}
|
|
7787
|
-
return /* @__PURE__ */
|
|
8006
|
+
return /* @__PURE__ */ jsxs35(
|
|
7788
8007
|
"div",
|
|
7789
8008
|
{
|
|
7790
8009
|
role: "toolbar",
|
|
@@ -7799,7 +8018,7 @@ function BulkActionBar({
|
|
|
7799
8018
|
style: { ...floatingStyle, ...style },
|
|
7800
8019
|
...props,
|
|
7801
8020
|
children: [
|
|
7802
|
-
/* @__PURE__ */
|
|
8021
|
+
/* @__PURE__ */ jsxs35(
|
|
7803
8022
|
"div",
|
|
7804
8023
|
{
|
|
7805
8024
|
role: "status",
|
|
@@ -7816,10 +8035,10 @@ function BulkActionBar({
|
|
|
7816
8035
|
]
|
|
7817
8036
|
}
|
|
7818
8037
|
),
|
|
7819
|
-
count > 0 && actions.length > 0 ? /* @__PURE__ */
|
|
8038
|
+
count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx39(Divider, {}) : null,
|
|
7820
8039
|
actionGroup,
|
|
7821
|
-
/* @__PURE__ */
|
|
7822
|
-
/* @__PURE__ */
|
|
8040
|
+
/* @__PURE__ */ jsx39(Divider, {}),
|
|
8041
|
+
/* @__PURE__ */ jsx39(ClearButton, { onClear }),
|
|
7823
8042
|
trailingSlot
|
|
7824
8043
|
]
|
|
7825
8044
|
}
|
|
@@ -7827,7 +8046,7 @@ function BulkActionBar({
|
|
|
7827
8046
|
}
|
|
7828
8047
|
|
|
7829
8048
|
// src/components/ui/confirm-dialog.tsx
|
|
7830
|
-
import { jsx as
|
|
8049
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
7831
8050
|
function ConfirmDialog({
|
|
7832
8051
|
open,
|
|
7833
8052
|
onOpenChange,
|
|
@@ -7842,7 +8061,7 @@ function ConfirmDialog({
|
|
|
7842
8061
|
confirmDisabled,
|
|
7843
8062
|
scrim
|
|
7844
8063
|
}) {
|
|
7845
|
-
return /* @__PURE__ */
|
|
8064
|
+
return /* @__PURE__ */ jsx40(
|
|
7846
8065
|
AlertDialog,
|
|
7847
8066
|
{
|
|
7848
8067
|
open,
|
|
@@ -7863,14 +8082,14 @@ function ConfirmDialog({
|
|
|
7863
8082
|
|
|
7864
8083
|
// src/components/ui/separator.tsx
|
|
7865
8084
|
import { Separator as SeparatorPrimitive } from "radix-ui";
|
|
7866
|
-
import { jsx as
|
|
8085
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
7867
8086
|
function Separator2({
|
|
7868
8087
|
className,
|
|
7869
8088
|
orientation = "horizontal",
|
|
7870
8089
|
decorative = true,
|
|
7871
8090
|
...props
|
|
7872
8091
|
}) {
|
|
7873
|
-
return /* @__PURE__ */
|
|
8092
|
+
return /* @__PURE__ */ jsx41(
|
|
7874
8093
|
SeparatorPrimitive.Root,
|
|
7875
8094
|
{
|
|
7876
8095
|
"data-slot": "separator",
|
|
@@ -7887,13 +8106,13 @@ function Separator2({
|
|
|
7887
8106
|
|
|
7888
8107
|
// src/components/ui/avatar.tsx
|
|
7889
8108
|
import { Avatar as AvatarPrimitive } from "radix-ui";
|
|
7890
|
-
import { jsx as
|
|
8109
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
7891
8110
|
function Avatar({
|
|
7892
8111
|
className,
|
|
7893
8112
|
size = "md",
|
|
7894
8113
|
...props
|
|
7895
8114
|
}) {
|
|
7896
|
-
return /* @__PURE__ */
|
|
8115
|
+
return /* @__PURE__ */ jsx42(
|
|
7897
8116
|
AvatarPrimitive.Root,
|
|
7898
8117
|
{
|
|
7899
8118
|
"data-slot": "avatar",
|
|
@@ -7914,7 +8133,7 @@ function AvatarImage({
|
|
|
7914
8133
|
className,
|
|
7915
8134
|
...props
|
|
7916
8135
|
}) {
|
|
7917
|
-
return /* @__PURE__ */
|
|
8136
|
+
return /* @__PURE__ */ jsx42(
|
|
7918
8137
|
AvatarPrimitive.Image,
|
|
7919
8138
|
{
|
|
7920
8139
|
"data-slot": "avatar-image",
|
|
@@ -7939,7 +8158,7 @@ function AvatarFallback({
|
|
|
7939
8158
|
...props
|
|
7940
8159
|
}) {
|
|
7941
8160
|
const fallbackText = children ?? (name ? getAvatarFallbackText(name) : null);
|
|
7942
|
-
return /* @__PURE__ */
|
|
8161
|
+
return /* @__PURE__ */ jsx42(
|
|
7943
8162
|
AvatarPrimitive.Fallback,
|
|
7944
8163
|
{
|
|
7945
8164
|
"data-slot": "avatar-fallback",
|
|
@@ -7958,7 +8177,7 @@ function AvatarFallback({
|
|
|
7958
8177
|
|
|
7959
8178
|
// src/components/ui/sheet-drawer.tsx
|
|
7960
8179
|
import { Maximize2Icon, Minimize2Icon } from "lucide-react";
|
|
7961
|
-
import { jsx as
|
|
8180
|
+
import { jsx as jsx43, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
7962
8181
|
var expandButtonClassName = cn(
|
|
7963
8182
|
"inline-flex cursor-pointer items-center justify-center gap-[var(--space-1)]",
|
|
7964
8183
|
"rounded-[var(--radius-md)] text-text-tertiary transition-colors",
|
|
@@ -7993,7 +8212,7 @@ function SheetDrawer({
|
|
|
7993
8212
|
const showExpandAction = Boolean(hasExpandedToggle || expandHref || onExpand);
|
|
7994
8213
|
const resolvedExpandLabel = hasExpandedToggle && expanded ? collapseLabel : expandLabel;
|
|
7995
8214
|
const ExpandActionIcon = hasExpandedToggle && expanded ? Minimize2Icon : Maximize2Icon;
|
|
7996
|
-
const expandAction = showExpandAction ? hasExpandedToggle ? /* @__PURE__ */
|
|
8215
|
+
const expandAction = showExpandAction ? hasExpandedToggle ? /* @__PURE__ */ jsxs36(
|
|
7997
8216
|
"button",
|
|
7998
8217
|
{
|
|
7999
8218
|
type: "button",
|
|
@@ -8004,14 +8223,14 @@ function SheetDrawer({
|
|
|
8004
8223
|
className: expandButtonClassName,
|
|
8005
8224
|
onClick: () => onExpandedChange(!expanded),
|
|
8006
8225
|
children: [
|
|
8007
|
-
/* @__PURE__ */
|
|
8008
|
-
/* @__PURE__ */
|
|
8226
|
+
/* @__PURE__ */ jsx43(ExpandActionIcon, { className: "size-[16px]" }),
|
|
8227
|
+
/* @__PURE__ */ jsx43("span", { className: "hidden text-sm font-medium leading-normal lg:inline", children: resolvedExpandLabel })
|
|
8009
8228
|
]
|
|
8010
8229
|
}
|
|
8011
|
-
) : expandHref ? /* @__PURE__ */
|
|
8012
|
-
/* @__PURE__ */
|
|
8013
|
-
/* @__PURE__ */
|
|
8014
|
-
] }) : /* @__PURE__ */
|
|
8230
|
+
) : expandHref ? /* @__PURE__ */ jsxs36("a", { href: expandHref, "aria-label": expandLabel, "data-slot": "sheet-drawer-expand", className: expandButtonClassName, children: [
|
|
8231
|
+
/* @__PURE__ */ jsx43(ExpandActionIcon, { className: "size-[16px]" }),
|
|
8232
|
+
/* @__PURE__ */ jsx43("span", { className: "hidden text-sm font-medium leading-normal lg:inline", children: expandLabel })
|
|
8233
|
+
] }) : /* @__PURE__ */ jsxs36(
|
|
8015
8234
|
"button",
|
|
8016
8235
|
{
|
|
8017
8236
|
type: "button",
|
|
@@ -8020,12 +8239,12 @@ function SheetDrawer({
|
|
|
8020
8239
|
className: expandButtonClassName,
|
|
8021
8240
|
onClick: onExpand,
|
|
8022
8241
|
children: [
|
|
8023
|
-
/* @__PURE__ */
|
|
8024
|
-
/* @__PURE__ */
|
|
8242
|
+
/* @__PURE__ */ jsx43(ExpandActionIcon, { className: "size-[16px]" }),
|
|
8243
|
+
/* @__PURE__ */ jsx43("span", { className: "hidden text-sm font-medium leading-normal lg:inline", children: expandLabel })
|
|
8025
8244
|
]
|
|
8026
8245
|
}
|
|
8027
8246
|
) : void 0;
|
|
8028
|
-
return /* @__PURE__ */
|
|
8247
|
+
return /* @__PURE__ */ jsx43(
|
|
8029
8248
|
Sheet,
|
|
8030
8249
|
{
|
|
8031
8250
|
open,
|
|
@@ -8043,210 +8262,6 @@ function SheetDrawer({
|
|
|
8043
8262
|
);
|
|
8044
8263
|
}
|
|
8045
8264
|
|
|
8046
|
-
// src/components/ui/action-menu.tsx
|
|
8047
|
-
import * as React34 from "react";
|
|
8048
|
-
import { Dialog as DialogPrimitive4, Slot as Slot3 } from "radix-ui";
|
|
8049
|
-
import { Fragment as Fragment14, jsx as jsx43, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
8050
|
-
var sheetRowClassName = cn(
|
|
8051
|
-
"group flex min-h-12 w-full cursor-pointer items-center gap-[var(--space-3)] px-[var(--space-4)] py-[var(--space-2)] text-left",
|
|
8052
|
-
"border-t border-[var(--border-subtle)] text-[13px] font-medium leading-normal text-text-primary",
|
|
8053
|
-
"transition-colors motion-reduce:transition-none hover:bg-[var(--action-hover)]",
|
|
8054
|
-
"focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[var(--focus-ring)]",
|
|
8055
|
-
"enabled:data-[destructive]:text-[var(--semantic-error-fg)]",
|
|
8056
|
-
"disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled"
|
|
8057
|
-
);
|
|
8058
|
-
var sheetRowDescriptionClassName = "block text-[12px] font-normal text-text-secondary group-disabled:text-text-disabled";
|
|
8059
|
-
var sheetGroupLabelClassName = "px-[var(--space-4)] pt-[var(--space-3)] pb-[var(--space-2)] text-[12px] font-semibold leading-normal text-text-tertiary";
|
|
8060
|
-
var sheetGroupSeparatorClassName = "h-[var(--space-2)] bg-[var(--bg-inset)]";
|
|
8061
|
-
function ActionMenuSheet({
|
|
8062
|
-
open,
|
|
8063
|
-
onOpenChange,
|
|
8064
|
-
title,
|
|
8065
|
-
description,
|
|
8066
|
-
closeLabel,
|
|
8067
|
-
groups,
|
|
8068
|
-
onOpenAutoFocus,
|
|
8069
|
-
onCloseAutoFocus
|
|
8070
|
-
}) {
|
|
8071
|
-
const pendingRef = React34.useRef(null);
|
|
8072
|
-
const surfaceRef = React34.useRef(null);
|
|
8073
|
-
const labelId = React34.useId();
|
|
8074
|
-
const handleOpenChange = (nextOpen) => {
|
|
8075
|
-
pendingRef.current = null;
|
|
8076
|
-
onOpenChange(nextOpen);
|
|
8077
|
-
};
|
|
8078
|
-
const swipe = useSwipeDismiss({
|
|
8079
|
-
enabled: OVERLAY_POLICY.menu.swipe,
|
|
8080
|
-
onDismiss: () => handleOpenChange(false),
|
|
8081
|
-
surfaceRef,
|
|
8082
|
-
always: true
|
|
8083
|
-
});
|
|
8084
|
-
const handleSelect = (item) => {
|
|
8085
|
-
onOpenChange(false);
|
|
8086
|
-
pendingRef.current = item;
|
|
8087
|
-
};
|
|
8088
|
-
const handleOpenAutoFocus = (event) => {
|
|
8089
|
-
onOpenAutoFocus?.(event);
|
|
8090
|
-
const firstRow = surfaceRef.current?.querySelector('[data-slot="action-menu-item"]:enabled');
|
|
8091
|
-
if (!firstRow) return;
|
|
8092
|
-
event.preventDefault();
|
|
8093
|
-
firstRow.focus();
|
|
8094
|
-
};
|
|
8095
|
-
const handleCloseAutoFocus = (event) => {
|
|
8096
|
-
onCloseAutoFocus(event);
|
|
8097
|
-
const item = pendingRef.current;
|
|
8098
|
-
pendingRef.current = null;
|
|
8099
|
-
item?.onSelect();
|
|
8100
|
-
};
|
|
8101
|
-
return /* @__PURE__ */ jsx43(DialogPrimitive4.Root, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs36(DialogPrimitive4.Portal, { children: [
|
|
8102
|
-
/* @__PURE__ */ jsx43(OverlayScrimLayer, { kind: "menu" }),
|
|
8103
|
-
/* @__PURE__ */ jsxs36(
|
|
8104
|
-
DialogPrimitive4.Content,
|
|
8105
|
-
{
|
|
8106
|
-
ref: surfaceRef,
|
|
8107
|
-
"data-slot": "action-menu-sheet",
|
|
8108
|
-
className: overlayBoxClassName("menu"),
|
|
8109
|
-
onOpenAutoFocus: handleOpenAutoFocus,
|
|
8110
|
-
onCloseAutoFocus: handleCloseAutoFocus,
|
|
8111
|
-
...description ? {} : { "aria-describedby": void 0 },
|
|
8112
|
-
children: [
|
|
8113
|
-
/* @__PURE__ */ jsx43(OverlayGrabber, { always: true, ...swipe.handleProps }),
|
|
8114
|
-
/* @__PURE__ */ jsx43(
|
|
8115
|
-
OverlayHeader,
|
|
8116
|
-
{
|
|
8117
|
-
kind: "menu",
|
|
8118
|
-
title,
|
|
8119
|
-
description,
|
|
8120
|
-
closeLabel,
|
|
8121
|
-
dragHandleProps: swipe.handleProps
|
|
8122
|
-
}
|
|
8123
|
-
),
|
|
8124
|
-
/* @__PURE__ */ jsx43(OverlayBody, { kind: "menu", children: groups.map((group, index) => /* @__PURE__ */ jsxs36(React34.Fragment, { children: [
|
|
8125
|
-
index > 0 ? /* @__PURE__ */ jsx43("div", { role: "separator", className: sheetGroupSeparatorClassName }) : null,
|
|
8126
|
-
/* @__PURE__ */ jsxs36("div", { role: "group", "aria-labelledby": group.label ? `${labelId}-${index}` : void 0, children: [
|
|
8127
|
-
group.label ? /* @__PURE__ */ jsx43("div", { id: `${labelId}-${index}`, className: sheetGroupLabelClassName, children: group.label }) : null,
|
|
8128
|
-
group.items.map((item) => {
|
|
8129
|
-
const Icon = item.icon;
|
|
8130
|
-
return /* @__PURE__ */ jsxs36(
|
|
8131
|
-
"button",
|
|
8132
|
-
{
|
|
8133
|
-
type: "button",
|
|
8134
|
-
"data-slot": "action-menu-item",
|
|
8135
|
-
"data-destructive": item.destructive ? "" : void 0,
|
|
8136
|
-
className: sheetRowClassName,
|
|
8137
|
-
disabled: item.disabled,
|
|
8138
|
-
onClick: () => handleSelect(item),
|
|
8139
|
-
children: [
|
|
8140
|
-
Icon ? /* @__PURE__ */ jsx43(Icon, { "aria-hidden": true, size: 17, strokeWidth: 1.75, className: "shrink-0" }) : null,
|
|
8141
|
-
/* @__PURE__ */ jsxs36("span", { className: "min-w-0 flex-1 break-keep", children: [
|
|
8142
|
-
item.label,
|
|
8143
|
-
item.description ? /* @__PURE__ */ jsx43("span", { className: sheetRowDescriptionClassName, children: item.description }) : null
|
|
8144
|
-
] })
|
|
8145
|
-
]
|
|
8146
|
-
},
|
|
8147
|
-
item.id
|
|
8148
|
-
);
|
|
8149
|
-
})
|
|
8150
|
-
] })
|
|
8151
|
-
] }, group.id)) })
|
|
8152
|
-
]
|
|
8153
|
-
}
|
|
8154
|
-
)
|
|
8155
|
-
] }) });
|
|
8156
|
-
}
|
|
8157
|
-
var readPresentation = () => window.matchMedia?.(OVERLAY_DESKTOP_QUERY).matches ?? true ? "dropdown" : "sheet";
|
|
8158
|
-
var subscribeNothing = () => () => void 0;
|
|
8159
|
-
var useHydrated = () => React34.useSyncExternalStore(
|
|
8160
|
-
subscribeNothing,
|
|
8161
|
-
() => true,
|
|
8162
|
-
() => false
|
|
8163
|
-
);
|
|
8164
|
-
function ActionMenu({
|
|
8165
|
-
trigger,
|
|
8166
|
-
title,
|
|
8167
|
-
description,
|
|
8168
|
-
open: openProp,
|
|
8169
|
-
onOpenChange,
|
|
8170
|
-
closeLabel,
|
|
8171
|
-
items,
|
|
8172
|
-
groups
|
|
8173
|
-
}) {
|
|
8174
|
-
const [uncontrolledOpen, setUncontrolledOpen] = React34.useState(false);
|
|
8175
|
-
const hydrated = useHydrated();
|
|
8176
|
-
const open = (openProp ?? uncontrolledOpen) && hydrated;
|
|
8177
|
-
const [shown, setShown] = React34.useState({
|
|
8178
|
-
open: false,
|
|
8179
|
-
presentation: "dropdown"
|
|
8180
|
-
});
|
|
8181
|
-
let presentation = shown.presentation;
|
|
8182
|
-
if (shown.open !== open) {
|
|
8183
|
-
if (open) presentation = readPresentation();
|
|
8184
|
-
setShown({ open, presentation });
|
|
8185
|
-
}
|
|
8186
|
-
const triggerRef = React34.useRef(null);
|
|
8187
|
-
const pendingRef = React34.useRef(null);
|
|
8188
|
-
const setOpen = (nextOpen) => {
|
|
8189
|
-
if (nextOpen) pendingRef.current = null;
|
|
8190
|
-
if (openProp === void 0) setUncontrolledOpen(nextOpen);
|
|
8191
|
-
onOpenChange?.(nextOpen);
|
|
8192
|
-
};
|
|
8193
|
-
const menuGroups = groups ?? [{ id: "items", items: items ?? [] }];
|
|
8194
|
-
const handleDropdownCloseAutoFocus = (event) => {
|
|
8195
|
-
const item = pendingRef.current;
|
|
8196
|
-
pendingRef.current = null;
|
|
8197
|
-
if (!item) return;
|
|
8198
|
-
event.preventDefault();
|
|
8199
|
-
triggerRef.current?.focus();
|
|
8200
|
-
item.onSelect();
|
|
8201
|
-
};
|
|
8202
|
-
const handleSheetCloseAutoFocus = (event) => {
|
|
8203
|
-
event.preventDefault();
|
|
8204
|
-
triggerRef.current?.focus();
|
|
8205
|
-
};
|
|
8206
|
-
const triggerLabel = trigger.props["aria-label"];
|
|
8207
|
-
return /* @__PURE__ */ jsxs36(Fragment14, { children: [
|
|
8208
|
-
/* @__PURE__ */ jsxs36(DropdownMenu, { open: open && presentation === "dropdown", onOpenChange: setOpen, children: [
|
|
8209
|
-
/* @__PURE__ */ jsx43(DropdownMenuTrigger, { asChild: true, "aria-expanded": open, children: /* @__PURE__ */ jsx43(Slot3.Root, { ref: triggerRef, children: trigger }) }),
|
|
8210
|
-
/* @__PURE__ */ jsx43(DropdownMenuContent, { align: "end", onCloseAutoFocus: handleDropdownCloseAutoFocus, children: menuGroups.map((group, index) => /* @__PURE__ */ jsxs36(React34.Fragment, { children: [
|
|
8211
|
-
index > 0 ? /* @__PURE__ */ jsx43(DropdownMenuSeparator, {}) : null,
|
|
8212
|
-
/* @__PURE__ */ jsxs36(DropdownMenuGroup, { children: [
|
|
8213
|
-
group.label ? /* @__PURE__ */ jsx43(DropdownMenuLabel, { children: group.label }) : null,
|
|
8214
|
-
group.items.map((item) => {
|
|
8215
|
-
const Icon = item.icon;
|
|
8216
|
-
return /* @__PURE__ */ jsxs36(
|
|
8217
|
-
DropdownMenuItem,
|
|
8218
|
-
{
|
|
8219
|
-
variant: item.destructive ? "destructive" : "default",
|
|
8220
|
-
disabled: item.disabled,
|
|
8221
|
-
onSelect: () => {
|
|
8222
|
-
pendingRef.current = item;
|
|
8223
|
-
},
|
|
8224
|
-
children: [
|
|
8225
|
-
Icon ? /* @__PURE__ */ jsx43(Icon, { "aria-hidden": true, size: 16, strokeWidth: 1.75 }) : null,
|
|
8226
|
-
item.label
|
|
8227
|
-
]
|
|
8228
|
-
},
|
|
8229
|
-
item.id
|
|
8230
|
-
);
|
|
8231
|
-
})
|
|
8232
|
-
] })
|
|
8233
|
-
] }, group.id)) })
|
|
8234
|
-
] }),
|
|
8235
|
-
/* @__PURE__ */ jsx43(
|
|
8236
|
-
ActionMenuSheet,
|
|
8237
|
-
{
|
|
8238
|
-
open: open && presentation === "sheet",
|
|
8239
|
-
onOpenChange: setOpen,
|
|
8240
|
-
title: title ?? /* @__PURE__ */ jsx43("span", { className: "sr-only", children: triggerLabel }),
|
|
8241
|
-
description,
|
|
8242
|
-
closeLabel,
|
|
8243
|
-
groups: menuGroups,
|
|
8244
|
-
onCloseAutoFocus: handleSheetCloseAutoFocus
|
|
8245
|
-
}
|
|
8246
|
-
)
|
|
8247
|
-
] });
|
|
8248
|
-
}
|
|
8249
|
-
|
|
8250
8265
|
// src/components/ui/action-sheet.tsx
|
|
8251
8266
|
import { jsx as jsx44 } from "react/jsx-runtime";
|
|
8252
8267
|
function ActionSheet({
|
|
@@ -8539,10 +8554,11 @@ var emptyStateBaseVariants = cva14(
|
|
|
8539
8554
|
lg: "gap-[var(--space-4)] px-[var(--space-8)] py-[var(--space-12)]"
|
|
8540
8555
|
},
|
|
8541
8556
|
bordered: {
|
|
8542
|
-
true: "rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
|
|
8557
|
+
true: "mx-auto w-full max-w-[560px] rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
|
|
8543
8558
|
false: ""
|
|
8544
8559
|
}
|
|
8545
8560
|
},
|
|
8561
|
+
compoundVariants: [{ bordered: true, size: "md", className: "min-h-60" }],
|
|
8546
8562
|
defaultVariants: {
|
|
8547
8563
|
size: "md",
|
|
8548
8564
|
bordered: false
|
|
@@ -8592,7 +8608,7 @@ var emptyStateIconVariants = cva14(
|
|
|
8592
8608
|
}
|
|
8593
8609
|
}
|
|
8594
8610
|
);
|
|
8595
|
-
var
|
|
8611
|
+
var iconSize2 = {
|
|
8596
8612
|
sm: 18,
|
|
8597
8613
|
md: 20,
|
|
8598
8614
|
lg: 24
|
|
@@ -8627,7 +8643,7 @@ var EmptyState = React40.forwardRef(
|
|
|
8627
8643
|
"aria-hidden": "true",
|
|
8628
8644
|
"data-slot": "empty-state-icon",
|
|
8629
8645
|
className: emptyStateIconVariants({ size: resolvedSize }),
|
|
8630
|
-
children: /* @__PURE__ */ jsx50(Icon, { size:
|
|
8646
|
+
children: /* @__PURE__ */ jsx50(Icon, { size: iconSize2[resolvedSize], strokeWidth: 1.75 })
|
|
8631
8647
|
}
|
|
8632
8648
|
) : null,
|
|
8633
8649
|
/* @__PURE__ */ jsxs39("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
|
|
@@ -8745,7 +8761,7 @@ var ErrorState = React41.forwardRef(
|
|
|
8745
8761
|
}
|
|
8746
8762
|
) : null
|
|
8747
8763
|
] }),
|
|
8748
|
-
onRetry ? /* @__PURE__ */ jsx51(Button, { size: "sm",
|
|
8764
|
+
onRetry ? /* @__PURE__ */ jsx51(Button, { size: "sm", appearance: "outline", tone: "neutral", onClick: onRetry, children: retryLabel }) : null
|
|
8749
8765
|
]
|
|
8750
8766
|
}
|
|
8751
8767
|
)
|
|
@@ -9300,8 +9316,9 @@ var actionFooterStatusVariants = cva19(
|
|
|
9300
9316
|
}
|
|
9301
9317
|
}
|
|
9302
9318
|
);
|
|
9303
|
-
var
|
|
9304
|
-
var
|
|
9319
|
+
var actionStyle = (action) => resolveActionStyle(action.appearance, action.tone, "filled");
|
|
9320
|
+
var isDestructive = (action) => actionStyle(action).tone === "danger";
|
|
9321
|
+
var isPrimary = (action) => actionStyle(action).tone === "primary";
|
|
9305
9322
|
function canRenderAction(action, permissions) {
|
|
9306
9323
|
if (!action.permission) {
|
|
9307
9324
|
return true;
|
|
@@ -9313,8 +9330,8 @@ function canRenderAction(action, permissions) {
|
|
|
9313
9330
|
}
|
|
9314
9331
|
function sortMainActions(actions) {
|
|
9315
9332
|
return [...actions].sort((first, second) => {
|
|
9316
|
-
const firstRank =
|
|
9317
|
-
const secondRank =
|
|
9333
|
+
const firstRank = isPrimary(first) ? 1 : 0;
|
|
9334
|
+
const secondRank = isPrimary(second) ? 1 : 0;
|
|
9318
9335
|
return firstRank - secondRank;
|
|
9319
9336
|
});
|
|
9320
9337
|
}
|
|
@@ -9330,20 +9347,28 @@ function getStatusLabel(status) {
|
|
|
9330
9347
|
}
|
|
9331
9348
|
}
|
|
9332
9349
|
function renderAction(action, className) {
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
|
|
9338
|
-
|
|
9339
|
-
|
|
9340
|
-
|
|
9341
|
-
|
|
9342
|
-
|
|
9343
|
-
|
|
9344
|
-
|
|
9345
|
-
|
|
9346
|
-
|
|
9350
|
+
const key = action.id ?? action.label;
|
|
9351
|
+
const common = {
|
|
9352
|
+
className: cn(footerButtonHitAreaClassName, className),
|
|
9353
|
+
disabled: action.disabled,
|
|
9354
|
+
onClick: action.onClick
|
|
9355
|
+
};
|
|
9356
|
+
const style = actionStyle(action);
|
|
9357
|
+
if (action.leadingIcon) {
|
|
9358
|
+
return /* @__PURE__ */ jsx56(
|
|
9359
|
+
IconButton,
|
|
9360
|
+
{
|
|
9361
|
+
...common,
|
|
9362
|
+
...style,
|
|
9363
|
+
size: "lg",
|
|
9364
|
+
icon: action.leadingIcon,
|
|
9365
|
+
label: action.label,
|
|
9366
|
+
loading: action.loading
|
|
9367
|
+
},
|
|
9368
|
+
key
|
|
9369
|
+
);
|
|
9370
|
+
}
|
|
9371
|
+
return /* @__PURE__ */ jsx56(Button, { ...common, ...style, size: "lg", loading: action.loading, children: action.label }, key);
|
|
9347
9372
|
}
|
|
9348
9373
|
var ActionFooter = React44.forwardRef(
|
|
9349
9374
|
({
|
|
@@ -9356,12 +9381,8 @@ var ActionFooter = React44.forwardRef(
|
|
|
9356
9381
|
...props
|
|
9357
9382
|
}, ref) => {
|
|
9358
9383
|
const visibleActions = actions.filter((action) => canRenderAction(action, permissions));
|
|
9359
|
-
const destructiveActions = visibleActions.filter(
|
|
9360
|
-
|
|
9361
|
-
);
|
|
9362
|
-
const mainActions = sortMainActions(
|
|
9363
|
-
visibleActions.filter((action) => !destructiveVariants.has(action.variant ?? "default"))
|
|
9364
|
-
);
|
|
9384
|
+
const destructiveActions = visibleActions.filter(isDestructive);
|
|
9385
|
+
const mainActions = sortMainActions(visibleActions.filter((action) => !isDestructive(action)));
|
|
9365
9386
|
return /* @__PURE__ */ jsxs44(
|
|
9366
9387
|
"div",
|
|
9367
9388
|
{
|
|
@@ -9629,7 +9650,8 @@ var ToastRoot = React45.forwardRef(
|
|
|
9629
9650
|
{
|
|
9630
9651
|
"data-slot": "toast-action",
|
|
9631
9652
|
size: "xs",
|
|
9632
|
-
|
|
9653
|
+
appearance: "outline",
|
|
9654
|
+
tone: "neutral",
|
|
9633
9655
|
onClick: action.onClick,
|
|
9634
9656
|
children: action.label
|
|
9635
9657
|
}
|
|
@@ -9684,7 +9706,7 @@ function ToastProvider({ children, maxToasts = 3, className, ...props }) {
|
|
|
9684
9706
|
import * as React46 from "react";
|
|
9685
9707
|
import { cva as cva21 } from "class-variance-authority";
|
|
9686
9708
|
import { AlertCircle as AlertCircle4 } from "lucide-react";
|
|
9687
|
-
import { Fragment as
|
|
9709
|
+
import { Fragment as Fragment14, jsx as jsx58, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
9688
9710
|
var otpFieldVariants = cva21("flex w-full min-w-0 flex-col gap-[var(--space-3)]", {
|
|
9689
9711
|
variants: {
|
|
9690
9712
|
size: {
|
|
@@ -10006,7 +10028,7 @@ var OTPField = React46.forwardRef(
|
|
|
10006
10028
|
"data-slot": "otp-field-message",
|
|
10007
10029
|
"data-kind": errorText ? "error" : "helper",
|
|
10008
10030
|
className: otpFieldMessageVariants({ state: resolvedState }),
|
|
10009
|
-
children: errorText ? /* @__PURE__ */ jsxs46(
|
|
10031
|
+
children: errorText ? /* @__PURE__ */ jsxs46(Fragment14, { children: [
|
|
10010
10032
|
/* @__PURE__ */ jsx58(
|
|
10011
10033
|
AlertCircle4,
|
|
10012
10034
|
{
|
|
@@ -10100,7 +10122,7 @@ var searchFieldInputVariants = cva22(
|
|
|
10100
10122
|
}
|
|
10101
10123
|
}
|
|
10102
10124
|
);
|
|
10103
|
-
var
|
|
10125
|
+
var iconSize3 = {
|
|
10104
10126
|
sm: 14,
|
|
10105
10127
|
md: 16,
|
|
10106
10128
|
lg: 18
|
|
@@ -10155,7 +10177,7 @@ var SearchField = React47.forwardRef(
|
|
|
10155
10177
|
"aria-hidden": "true",
|
|
10156
10178
|
"data-slot": "search-field-icon",
|
|
10157
10179
|
className: "pointer-events-none absolute left-[10px] top-1/2 -translate-y-1/2 text-text-tertiary",
|
|
10158
|
-
size:
|
|
10180
|
+
size: iconSize3[resolvedSize],
|
|
10159
10181
|
strokeWidth: resolvedSize === "sm" ? 2 : 1.75
|
|
10160
10182
|
}
|
|
10161
10183
|
),
|
|
@@ -10872,7 +10894,7 @@ function TreeView({
|
|
|
10872
10894
|
|
|
10873
10895
|
// src/components/branding/olun-logo.tsx
|
|
10874
10896
|
import { OLUN_MASTER, OLUN_SYMBOL, OLUN_WORDMARK } from "@olundot/tokens/brand";
|
|
10875
|
-
import { Fragment as
|
|
10897
|
+
import { Fragment as Fragment15, jsx as jsx65, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
10876
10898
|
var ACCENT_FILL = "var(--accent-pop)";
|
|
10877
10899
|
var INK = { color: "var(--text-primary)" };
|
|
10878
10900
|
var INK_TIGHT = { ...INK, display: "block", overflow: "visible" };
|
|
@@ -10882,7 +10904,7 @@ function symbolGeometry(size) {
|
|
|
10882
10904
|
function SymbolCircles({ size }) {
|
|
10883
10905
|
const { ring } = OLUN_SYMBOL;
|
|
10884
10906
|
const g = symbolGeometry(size);
|
|
10885
|
-
return /* @__PURE__ */ jsxs51(
|
|
10907
|
+
return /* @__PURE__ */ jsxs51(Fragment15, { children: [
|
|
10886
10908
|
/* @__PURE__ */ jsx65(
|
|
10887
10909
|
"circle",
|
|
10888
10910
|
{
|