@olundot/ui 0.19.1 → 0.20.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1009,7 +1009,7 @@ function XIcon({ size }) {
1009
1009
  );
1010
1010
  }
1011
1011
  var Alert = React5.forwardRef(
1012
- ({ variant = "info", emphasis, title: title2, children, onDismiss, style, ...rest }, ref) => {
1012
+ ({ variant = "info", emphasis, title, children, onDismiss, style, ...rest }, ref) => {
1013
1013
  const weight = emphasis ?? defaultEmphasis(variant);
1014
1014
  const strong = weight === "strong";
1015
1015
  const fg = SEM_FG[variant];
@@ -1042,7 +1042,7 @@ var Alert = React5.forwardRef(
1042
1042
  "aria-hidden": "true",
1043
1043
  "data-slot": "alert-dot",
1044
1044
  style: {
1045
- marginTop: title2 ? 5 : 4,
1045
+ marginTop: title ? 5 : 4,
1046
1046
  width: 7,
1047
1047
  height: 7,
1048
1048
  flexShrink: 0,
@@ -1052,7 +1052,7 @@ var Alert = React5.forwardRef(
1052
1052
  }
1053
1053
  ),
1054
1054
  /* @__PURE__ */ jsxs5("div", { "data-slot": "alert-content", style: { flex: 1, minWidth: 0 }, children: [
1055
- title2 ? /* @__PURE__ */ jsx5(
1055
+ title ? /* @__PURE__ */ jsx5(
1056
1056
  "div",
1057
1057
  {
1058
1058
  "data-slot": "alert-title",
@@ -1063,7 +1063,7 @@ var Alert = React5.forwardRef(
1063
1063
  lineHeight: 1.35,
1064
1064
  color: strong ? fg : "var(--text-primary)"
1065
1065
  },
1066
- children: title2
1066
+ children: title
1067
1067
  }
1068
1068
  ) : null,
1069
1069
  /* @__PURE__ */ jsx5(
@@ -1071,7 +1071,7 @@ var Alert = React5.forwardRef(
1071
1071
  {
1072
1072
  "data-slot": "alert-body",
1073
1073
  style: {
1074
- marginTop: title2 ? 2 : 0,
1074
+ marginTop: title ? 2 : 0,
1075
1075
  fontFamily: "var(--font-sans)",
1076
1076
  fontSize: 12.5,
1077
1077
  lineHeight: 1.45,
@@ -2399,7 +2399,7 @@ var PageHeader = React13.forwardRef(
2399
2399
  className,
2400
2400
  breadcrumb,
2401
2401
  back,
2402
- title: title2,
2402
+ title,
2403
2403
  headingLevel = 1,
2404
2404
  subtitle,
2405
2405
  meta,
@@ -2443,7 +2443,7 @@ var PageHeader = React13.forwardRef(
2443
2443
  {
2444
2444
  "data-slot": "page-header-title",
2445
2445
  className: "max-w-full break-words font-[family-name:var(--font-display)] text-[28px] font-semibold leading-tight text-foreground",
2446
- children: title2
2446
+ children: title
2447
2447
  }
2448
2448
  ),
2449
2449
  subtitle ? /* @__PURE__ */ jsx14(
@@ -3513,14 +3513,55 @@ var FormLayout = React19.forwardRef(
3513
3513
  FormLayout.displayName = "FormLayout";
3514
3514
 
3515
3515
  // src/components/ui/dialog.tsx
3516
- import * as React22 from "react";
3517
- import { Dialog as DialogPrimitive2 } from "radix-ui";
3516
+ import * as React26 from "react";
3517
+ import { Dialog as DialogPrimitive3 } from "radix-ui";
3518
3518
 
3519
- // src/lib/use-return-focus.ts
3519
+ // src/lib/use-overlay-action.ts
3520
3520
  import * as React20 from "react";
3521
+ function useOverlayAction({
3522
+ action,
3523
+ onOpenChange,
3524
+ loading = false,
3525
+ disabled = false,
3526
+ onError
3527
+ }) {
3528
+ const [pending, setPending] = React20.useState(false);
3529
+ const busyRef = React20.useRef(false);
3530
+ const isBusy = loading || pending;
3531
+ const guardOpenChange = React20.useCallback(
3532
+ (nextOpen) => {
3533
+ if (!nextOpen && isBusy) {
3534
+ return;
3535
+ }
3536
+ onOpenChange(nextOpen);
3537
+ },
3538
+ [isBusy, onOpenChange]
3539
+ );
3540
+ const run = React20.useCallback(async () => {
3541
+ if (busyRef.current || loading || disabled) {
3542
+ return;
3543
+ }
3544
+ busyRef.current = true;
3545
+ setPending(true);
3546
+ try {
3547
+ await action();
3548
+ onOpenChange(false);
3549
+ } catch (error) {
3550
+ if (!onError) throw error;
3551
+ onError(error);
3552
+ } finally {
3553
+ busyRef.current = false;
3554
+ setPending(false);
3555
+ }
3556
+ }, [action, disabled, loading, onError, onOpenChange]);
3557
+ return { isBusy, run, guardOpenChange };
3558
+ }
3559
+
3560
+ // src/lib/use-return-focus.ts
3561
+ import * as React21 from "react";
3521
3562
  function useReturnFocus() {
3522
- const returnTo = React20.useRef(null);
3523
- const onOpenAutoFocus = React20.useCallback((event) => {
3563
+ const returnTo = React21.useRef(null);
3564
+ const onOpenAutoFocus = React21.useCallback((event) => {
3524
3565
  const active = document.activeElement;
3525
3566
  const content = event?.target instanceof HTMLElement ? event.target : null;
3526
3567
  const hasTrigger = !!content?.id && Array.from(document.querySelectorAll("[aria-controls]")).some(
@@ -3528,7 +3569,7 @@ function useReturnFocus() {
3528
3569
  );
3529
3570
  returnTo.current = !hasTrigger && active instanceof HTMLElement && active !== document.body ? active : null;
3530
3571
  }, []);
3531
- const onCloseAutoFocus = React20.useCallback((event) => {
3572
+ const onCloseAutoFocus = React21.useCallback((event) => {
3532
3573
  const target = returnTo.current;
3533
3574
  returnTo.current = null;
3534
3575
  if (!target?.isConnected) return;
@@ -3540,14 +3581,136 @@ function useReturnFocus() {
3540
3581
  return { onOpenAutoFocus, onCloseAutoFocus };
3541
3582
  }
3542
3583
 
3584
+ // src/components/ui/overlay-anatomy.tsx
3585
+ import * as React24 from "react";
3586
+ import { AlertDialog as AlertDialogPrimitive, Dialog as DialogPrimitive2 } from "radix-ui";
3587
+
3588
+ // src/components/ui/overlay-bottom-sheet.tsx
3589
+ import * as React22 from "react";
3590
+ import { jsx as jsx21 } from "react/jsx-runtime";
3591
+ var SWIPE_DISMISS_DISTANCE = 80;
3592
+ var SWIPE_DISMISS_VELOCITY = 0.5;
3593
+ var SWIPE_MIN_DISTANCE = 16;
3594
+ var SWIPE_VELOCITY_WINDOW = 100;
3595
+ var NON_DRAG_TARGET = 'button, a[href], input, select, textarea, label, [role="button"], [contenteditable="true"]';
3596
+ var matches = (query) => typeof window.matchMedia === "function" && window.matchMedia(query).matches;
3597
+ function setOffset(surface, distance) {
3598
+ surface?.style.setProperty("transform", `translateY(${distance}px)`, "important");
3599
+ }
3600
+ function clearOffset(surface) {
3601
+ surface?.style.removeProperty("transform");
3602
+ }
3603
+ function useSwipeDismiss({ enabled, onDismiss, surfaceRef, always = false }) {
3604
+ const [dragging, setDragging] = React22.useState(false);
3605
+ const drag = React22.useRef(null);
3606
+ const dismiss = React22.useRef(onDismiss);
3607
+ dismiss.current = onDismiss;
3608
+ const handleProps = React22.useMemo(() => {
3609
+ if (!enabled) return {};
3610
+ const end = (event, release) => {
3611
+ const current = drag.current;
3612
+ if (!current || current.pointerId !== event.pointerId) return;
3613
+ drag.current = null;
3614
+ setDragging(false);
3615
+ if (event.currentTarget.hasPointerCapture?.(event.pointerId)) {
3616
+ event.currentTarget.releasePointerCapture(event.pointerId);
3617
+ }
3618
+ const surface = surfaceRef.current;
3619
+ if (!release) {
3620
+ clearOffset(surface);
3621
+ return;
3622
+ }
3623
+ const now = performance.now();
3624
+ const distance = Math.max(0, event.clientY - current.startY);
3625
+ const from = current.samples.find((sample) => now - sample.t <= SWIPE_VELOCITY_WINDOW) ?? current.samples[current.samples.length - 1];
3626
+ const velocity = from && now > from.t ? (event.clientY - from.y) / (now - from.t) : 0;
3627
+ const closes = distance >= SWIPE_DISMISS_DISTANCE || velocity >= SWIPE_DISMISS_VELOCITY && distance >= SWIPE_MIN_DISTANCE;
3628
+ if (!closes) {
3629
+ clearOffset(surface);
3630
+ return;
3631
+ }
3632
+ dismiss.current();
3633
+ setTimeout(() => {
3634
+ if (surface?.getAttribute("data-state") !== "closed") clearOffset(surface);
3635
+ }, 0);
3636
+ };
3637
+ return {
3638
+ onPointerDown: (event) => {
3639
+ if (drag.current || !event.isPrimary || event.pointerType === "mouse" && event.button !== 0) return;
3640
+ const target = event.target instanceof Element ? event.target.closest(NON_DRAG_TARGET) : null;
3641
+ if (target && event.currentTarget.contains(target)) return;
3642
+ if (!always && !matches("(max-width: 899px)")) return;
3643
+ event.currentTarget.setPointerCapture?.(event.pointerId);
3644
+ drag.current = {
3645
+ pointerId: event.pointerId,
3646
+ startY: event.clientY,
3647
+ follow: !matches("(prefers-reduced-motion: reduce)"),
3648
+ samples: [{ y: event.clientY, t: performance.now() }]
3649
+ };
3650
+ setDragging(true);
3651
+ },
3652
+ onPointerMove: (event) => {
3653
+ const current = drag.current;
3654
+ if (!current || current.pointerId !== event.pointerId) return;
3655
+ const now = performance.now();
3656
+ current.samples.push({ y: event.clientY, t: now });
3657
+ while (current.samples.length > 1 && now - current.samples[0].t > SWIPE_VELOCITY_WINDOW) current.samples.shift();
3658
+ if (current.follow) setOffset(surfaceRef.current, Math.max(0, event.clientY - current.startY));
3659
+ },
3660
+ onPointerUp: (event) => end(event, true),
3661
+ onPointerCancel: (event) => end(event, false)
3662
+ };
3663
+ }, [enabled, always, surfaceRef]);
3664
+ return { handleProps, dragging };
3665
+ }
3666
+ var overlayBottomSheet = {
3667
+ responsive: cn(
3668
+ "max-[899px]:inset-x-0 max-[899px]:top-auto max-[899px]:bottom-0",
3669
+ "max-[899px]:translate-x-0 max-[899px]:translate-y-0",
3670
+ "max-[899px]:w-full max-[899px]:max-w-none max-[899px]:max-h-[85dvh]",
3671
+ "max-[899px]:rounded-t-[var(--radius-lg)] max-[899px]:rounded-b-none max-[899px]:border-x-0 max-[899px]:border-b-0",
3672
+ "max-[899px]:pb-[env(safe-area-inset-bottom)]",
3673
+ "max-[899px]:motion-safe:data-[state=open]:animate-[olun-sheet-in-from-bottom_var(--dur-slow)_var(--ease-out)_both]",
3674
+ "max-[899px]:motion-safe:data-[state=closed]:animate-[olun-sheet-out-to-bottom_var(--dur-base)_var(--ease-in)_both]"
3675
+ ),
3676
+ always: cn(
3677
+ "inset-x-0 top-auto bottom-0",
3678
+ "w-full max-w-none max-h-[85dvh]",
3679
+ "rounded-t-[var(--radius-lg)] rounded-b-none border-x-0 border-b-0",
3680
+ "pb-[env(safe-area-inset-bottom)]",
3681
+ "motion-safe:data-[state=open]:animate-[olun-sheet-in-from-bottom_var(--dur-slow)_var(--ease-out)_both]",
3682
+ "motion-safe:data-[state=closed]:animate-[olun-sheet-out-to-bottom_var(--dur-base)_var(--ease-in)_both]"
3683
+ )
3684
+ };
3685
+ function OverlayGrabber({
3686
+ always = false,
3687
+ className,
3688
+ ...handleProps
3689
+ }) {
3690
+ return /* @__PURE__ */ jsx21(
3691
+ "div",
3692
+ {
3693
+ "aria-hidden": true,
3694
+ "data-slot": "overlay-grabber",
3695
+ className: cn(
3696
+ "flex shrink-0 touch-none justify-center pt-[var(--space-2)] pb-[var(--space-1)]",
3697
+ !always && "min-[900px]:hidden",
3698
+ className
3699
+ ),
3700
+ ...handleProps,
3701
+ children: /* @__PURE__ */ jsx21("span", { className: "h-1 w-9 rounded-[var(--radius-full)] bg-[var(--border-strong)]" })
3702
+ }
3703
+ );
3704
+ }
3705
+
3543
3706
  // src/components/ui/overlay-close-button.tsx
3544
3707
  import { X } from "lucide-react";
3545
3708
  import { Dialog as DialogPrimitive } from "radix-ui";
3546
3709
 
3547
3710
  // src/components/ui/icon-button.tsx
3548
- import * as React21 from "react";
3711
+ import * as React23 from "react";
3549
3712
  import { cva as cva9 } from "class-variance-authority";
3550
- import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
3713
+ import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
3551
3714
  var iconButtonCva = cva9(
3552
3715
  [
3553
3716
  "olun-icon-button relative inline-flex cursor-pointer shrink-0 items-center justify-center before:absolute before:content-['']",
@@ -3678,7 +3841,7 @@ var iconStrokeWidth = {
3678
3841
  md: 2.25,
3679
3842
  lg: 1.75
3680
3843
  };
3681
- var IconButton = React21.forwardRef(
3844
+ var IconButton = React23.forwardRef(
3682
3845
  ({
3683
3846
  className,
3684
3847
  variant = "ghost",
@@ -3690,7 +3853,7 @@ var IconButton = React21.forwardRef(
3690
3853
  badge,
3691
3854
  badgeTone = "info",
3692
3855
  type,
3693
- title: title2,
3856
+ title,
3694
3857
  "aria-label": ariaLabel,
3695
3858
  "aria-labelledby": ariaLabelledBy,
3696
3859
  iconPosition = "start",
@@ -3702,14 +3865,14 @@ var IconButton = React21.forwardRef(
3702
3865
  const usesAxes = appearance != null || tone != null;
3703
3866
  const isToggle = pressed !== void 0;
3704
3867
  const isPressed = pressed === true;
3705
- const hoverTitle = title2 ?? (typeof ariaLabel === "string" ? ariaLabel : void 0);
3868
+ const hoverTitle = title ?? (typeof ariaLabel === "string" ? ariaLabel : void 0);
3706
3869
  const text = label ?? children;
3707
3870
  const hasText = text !== void 0 && text !== null && text !== false;
3708
3871
  const style = usesAxes ? resolveActionStyle(appearance, tone, "ghost") : void 0;
3709
3872
  const axisSize = usesAxes ? resolvedSize : void 0;
3710
3873
  const legacySize = resolvedSize;
3711
3874
  const textBoxSize = axisSize ?? textButtonSize[legacySize];
3712
- const icon = /* @__PURE__ */ jsx21(
3875
+ const icon = /* @__PURE__ */ jsx22(
3713
3876
  Icon,
3714
3877
  {
3715
3878
  "aria-hidden": "true",
@@ -3750,7 +3913,7 @@ var IconButton = React21.forwardRef(
3750
3913
  hasText && iconPosition === "end" ? null : icon,
3751
3914
  hasText ? text : null,
3752
3915
  hasText && iconPosition === "end" ? icon : null,
3753
- badge !== void 0 ? /* @__PURE__ */ jsx21(
3916
+ badge !== void 0 ? /* @__PURE__ */ jsx22(
3754
3917
  "span",
3755
3918
  {
3756
3919
  "aria-hidden": "true",
@@ -3768,12 +3931,319 @@ var IconButton = React21.forwardRef(
3768
3931
  IconButton.displayName = "IconButton";
3769
3932
 
3770
3933
  // src/components/ui/overlay-close-button.tsx
3771
- import { jsx as jsx22 } from "react/jsx-runtime";
3934
+ import { jsx as jsx23 } from "react/jsx-runtime";
3772
3935
  function OverlayCloseButton({
3773
3936
  label = "\uB2EB\uAE30",
3774
3937
  className
3775
3938
  }) {
3776
- return /* @__PURE__ */ jsx22(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx22(IconButton, { appearance: "ghost", size: "md", icon: X, "aria-label": label, className }) });
3939
+ return /* @__PURE__ */ jsx23(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx23(IconButton, { appearance: "ghost", size: "md", icon: X, "aria-label": label, className }) });
3940
+ }
3941
+
3942
+ // src/components/ui/overlay-policy.ts
3943
+ var OVERLAY_POLICY = {
3944
+ alert: {
3945
+ closeButton: "none",
3946
+ grabber: false,
3947
+ closeOnOutsideClick: false,
3948
+ closeOnEscape: true,
3949
+ busyBlocksClose: true,
3950
+ swipe: false,
3951
+ scroll: "none",
3952
+ footerDivider: false,
3953
+ desktop: "center",
3954
+ mobile: "center",
3955
+ heading: "title"
3956
+ },
3957
+ dialog: {
3958
+ closeButton: "visible",
3959
+ grabber: true,
3960
+ closeOnOutsideClick: false,
3961
+ closeOnEscape: true,
3962
+ busyBlocksClose: true,
3963
+ swipe: true,
3964
+ scroll: "body",
3965
+ footerDivider: true,
3966
+ desktop: "center",
3967
+ mobile: "bottom-sheet",
3968
+ heading: "title"
3969
+ },
3970
+ sheet: {
3971
+ closeButton: "visible",
3972
+ grabber: true,
3973
+ closeOnOutsideClick: true,
3974
+ closeOnEscape: true,
3975
+ busyBlocksClose: false,
3976
+ swipe: true,
3977
+ scroll: "body",
3978
+ footerDivider: true,
3979
+ desktop: "side",
3980
+ mobile: "bottom-sheet",
3981
+ heading: "title"
3982
+ },
3983
+ menu: {
3984
+ closeButton: "hidden",
3985
+ grabber: true,
3986
+ closeOnOutsideClick: true,
3987
+ closeOnEscape: true,
3988
+ busyBlocksClose: false,
3989
+ swipe: true,
3990
+ scroll: "list",
3991
+ footerDivider: false,
3992
+ desktop: "dropdown",
3993
+ mobile: "menu-sheet",
3994
+ heading: "menu"
3995
+ }
3996
+ };
3997
+
3998
+ // src/components/ui/overlay-anatomy.tsx
3999
+ import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
4000
+ var overlaySurfaceTone = cn(
4001
+ "bg-[var(--bg-raised)] text-foreground",
4002
+ "border border-[var(--border-subtle)] rounded-[var(--radius-lg)]",
4003
+ "shadow-[var(--shadow-16),inset_0_1px_0_var(--overlay-highlight)]"
4004
+ );
4005
+ var boxBase = cn("fixed z-[var(--z-modal)] flex flex-col outline-none", overlaySurfaceTone);
4006
+ var centerBox = {
4007
+ always: cn(
4008
+ "left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
4009
+ "w-[calc(100vw-2rem)] max-h-[calc(100dvh-2rem)]",
4010
+ "scale-100 motion-safe:transition-[scale] motion-safe:duration-[var(--dur-base)] motion-safe:ease-[var(--ease-out)]",
4011
+ "motion-safe:starting:scale-97",
4012
+ "motion-safe:data-[state=closed]:scale-98 motion-safe:data-[state=closed]:duration-[var(--dur-fast)] motion-safe:data-[state=closed]:ease-[var(--ease-in)]",
4013
+ "motion-safe:data-[state=open]:animate-[olun-sheet-fade-in_var(--dur-base)_var(--ease-out)_both]",
4014
+ "motion-safe:data-[state=closed]:animate-[olun-sheet-fade-out_var(--dur-fast)_var(--ease-in)_both]"
4015
+ ),
4016
+ desktop: cn(
4017
+ "min-[900px]:left-1/2 min-[900px]:top-1/2 min-[900px]:-translate-x-1/2 min-[900px]:-translate-y-1/2",
4018
+ "min-[900px]:w-[calc(100vw-2rem)] min-[900px]:max-h-[calc(100dvh-2rem)]",
4019
+ "min-[900px]:scale-100 min-[900px]:motion-safe:transition-[scale] min-[900px]:motion-safe:duration-[var(--dur-base)] min-[900px]:motion-safe:ease-[var(--ease-out)]",
4020
+ "min-[900px]:motion-safe:starting:scale-97",
4021
+ "min-[900px]:motion-safe:data-[state=closed]:scale-98 min-[900px]:motion-safe:data-[state=closed]:duration-[var(--dur-fast)] min-[900px]:motion-safe:data-[state=closed]:ease-[var(--ease-in)]",
4022
+ "min-[900px]:motion-safe:data-[state=open]:animate-[olun-sheet-fade-in_var(--dur-base)_var(--ease-out)_both]",
4023
+ "min-[900px]:motion-safe:data-[state=closed]:animate-[olun-sheet-fade-out_var(--dur-fast)_var(--ease-in)_both]"
4024
+ )
4025
+ };
4026
+ function overlayBoxClassName(kind) {
4027
+ switch (kind) {
4028
+ case "alert":
4029
+ return cn(boxBase, centerBox.always, overlaySize.alert);
4030
+ case "dialog":
4031
+ return cn(boxBase, centerBox.desktop, overlayBottomSheet.responsive);
4032
+ case "sheet":
4033
+ return cn(boxBase, overlayBottomSheet.responsive);
4034
+ case "menu":
4035
+ return cn(boxBase, overlayBottomSheet.always);
4036
+ }
4037
+ }
4038
+ var overlaySize = {
4039
+ alert: "max-w-[420px]",
4040
+ dialog: {
4041
+ sm: "max-w-[420px]",
4042
+ md: "max-w-[560px]",
4043
+ lg: "max-w-[720px]"
4044
+ },
4045
+ sheet: {
4046
+ md: "min-[900px]:w-[480px] min-[900px]:max-w-[480px]",
4047
+ lg: "min-[900px]:w-[720px] min-[900px]:max-w-[720px]",
4048
+ full: "min-[900px]:w-[calc(100vw_-_var(--space-8))] min-[900px]:max-w-[calc(100vw_-_var(--space-8))]"
4049
+ }
4050
+ };
4051
+ var scrimPreset = {
4052
+ dim: "bg-[var(--scrim-dim)]",
4053
+ blur: "bg-[var(--scrim-soft)] [backdrop-filter:var(--scrim-blur)]",
4054
+ root: cn(
4055
+ "bg-[var(--scrim)]",
4056
+ "[:root[data-scrim=dim]_&]:bg-[var(--scrim-dim)]",
4057
+ "[:root[data-scrim=blur]_&]:bg-[var(--scrim-soft)] [:root[data-scrim=blur]_&]:[backdrop-filter:var(--scrim-blur)]"
4058
+ )
4059
+ };
4060
+ function overlayScrimClassName(scrim) {
4061
+ return scrim ? scrimPreset[scrim] : scrimPreset.root;
4062
+ }
4063
+ var scrimMotion = {
4064
+ center: cn(
4065
+ "motion-safe:data-[state=open]:animate-[olun-sheet-fade-in_var(--dur-base)_var(--ease-out)_both]",
4066
+ "motion-safe:data-[state=closed]:animate-[olun-sheet-fade-out_var(--dur-fast)_var(--ease-in)_both]"
4067
+ ),
4068
+ responsive: cn(
4069
+ "motion-safe:data-[state=open]:animate-[olun-sheet-fade-in_var(--dur-base)_var(--ease-out)_both]",
4070
+ "motion-safe:data-[state=closed]:animate-[olun-sheet-fade-out_var(--dur-fast)_var(--ease-in)_both]",
4071
+ "max-[899px]:motion-safe:data-[state=open]:animate-[olun-sheet-fade-in_var(--dur-slow)_var(--ease-out)_both]",
4072
+ "max-[899px]:motion-safe:data-[state=closed]:animate-[olun-sheet-fade-out_var(--dur-base)_var(--ease-in)_both]"
4073
+ ),
4074
+ // `motion={false}` side panel: the box is still from 900px, so the scrim is too; below it the
4075
+ // bottom sheet slides and the scrim fades with it.
4076
+ responsiveBelow900: cn(
4077
+ "max-[899px]:motion-safe:data-[state=open]:animate-[olun-sheet-fade-in_var(--dur-slow)_var(--ease-out)_both]",
4078
+ "max-[899px]:motion-safe:data-[state=closed]:animate-[olun-sheet-fade-out_var(--dur-base)_var(--ease-in)_both]"
4079
+ ),
4080
+ sheet: cn(
4081
+ "motion-safe:data-[state=open]:animate-[olun-sheet-fade-in_var(--dur-slow)_var(--ease-out)_both]",
4082
+ "motion-safe:data-[state=closed]:animate-[olun-sheet-fade-out_var(--dur-base)_var(--ease-in)_both]"
4083
+ )
4084
+ };
4085
+ var scrimMotionOf = {
4086
+ alert: scrimMotion.center,
4087
+ dialog: scrimMotion.responsive,
4088
+ sheet: scrimMotion.responsive,
4089
+ menu: scrimMotion.sheet
4090
+ };
4091
+ var OverlayScrimLayer = React24.forwardRef(
4092
+ ({ scrim, kind, still, className, ...props }, ref) => {
4093
+ const Overlay = kind === "alert" ? AlertDialogPrimitive.Overlay : DialogPrimitive2.Overlay;
4094
+ return /* @__PURE__ */ jsx24(
4095
+ Overlay,
4096
+ {
4097
+ ref,
4098
+ "data-slot": "overlay-scrim",
4099
+ className: cn(
4100
+ "fixed inset-0 z-[var(--z-modal)]",
4101
+ overlayScrimClassName(scrim),
4102
+ kind && (still ? scrimMotion.responsiveBelow900 : scrimMotionOf[kind]),
4103
+ className
4104
+ ),
4105
+ ...props
4106
+ }
4107
+ );
4108
+ }
4109
+ );
4110
+ OverlayScrimLayer.displayName = "OverlayScrimLayer";
4111
+ function focusBodyInput(event) {
4112
+ const surface = event.target instanceof HTMLElement ? event.target : null;
4113
+ const input = surface?.querySelector(
4114
+ '[data-slot="overlay-body"] :is(input, textarea, select):not([disabled]):not([type="hidden"])'
4115
+ );
4116
+ if (input) {
4117
+ event.preventDefault();
4118
+ input.focus();
4119
+ }
4120
+ }
4121
+ var headingClassName = {
4122
+ title: "text-[18px] font-bold leading-snug text-foreground",
4123
+ menu: "text-[15px] font-semibold leading-snug text-foreground"
4124
+ };
4125
+ var descriptionClassName = {
4126
+ title: "break-keep text-[14px] leading-normal text-text-secondary",
4127
+ menu: "break-keep text-[13px] leading-normal text-text-secondary"
4128
+ };
4129
+ function OverlayHeader({
4130
+ kind,
4131
+ title,
4132
+ description,
4133
+ caption,
4134
+ actions,
4135
+ closeLabel = "\uB2EB\uAE30",
4136
+ dragHandleProps,
4137
+ id,
4138
+ className
4139
+ }) {
4140
+ const policy = OVERLAY_POLICY[kind];
4141
+ const Title = kind === "alert" ? AlertDialogPrimitive.Title : DialogPrimitive2.Title;
4142
+ const Description = kind === "alert" ? AlertDialogPrimitive.Description : DialogPrimitive2.Description;
4143
+ return /* @__PURE__ */ jsxs21(
4144
+ "div",
4145
+ {
4146
+ id,
4147
+ "data-slot": "overlay-header",
4148
+ className: cn(
4149
+ "flex shrink-0 items-start gap-[var(--space-4)] px-[var(--space-6)] pt-[var(--space-6)]",
4150
+ kind === "menu" && "px-[var(--space-4)] pt-[var(--space-2)]",
4151
+ kind !== "menu" && policy.grabber && "max-[899px]:pt-[var(--space-2)]",
4152
+ policy.swipe && "touch-none",
4153
+ className
4154
+ ),
4155
+ ...dragHandleProps,
4156
+ children: [
4157
+ /* @__PURE__ */ jsxs21("div", { className: "flex min-w-0 flex-1 flex-col gap-[var(--space-2)]", children: [
4158
+ caption != null ? /* @__PURE__ */ jsx24("div", { "data-slot": "overlay-caption", className: "flex flex-wrap items-center gap-[var(--space-2)]", children: caption }) : null,
4159
+ /* @__PURE__ */ jsx24(Title, { "data-slot": "overlay-title", className: headingClassName[policy.heading], children: title }),
4160
+ description != null ? /* @__PURE__ */ jsx24(Description, { "data-slot": "overlay-description", className: descriptionClassName[policy.heading], children: description }) : null
4161
+ ] }),
4162
+ actions != null || policy.closeButton === "visible" ? /* @__PURE__ */ jsxs21("div", { "data-slot": "overlay-header-actions", className: "flex shrink-0 items-center gap-[var(--space-1)]", children: [
4163
+ actions,
4164
+ policy.closeButton === "visible" ? /* @__PURE__ */ jsx24(OverlayCloseButton, { label: closeLabel }) : null
4165
+ ] }) : null,
4166
+ policy.closeButton === "hidden" ? /* @__PURE__ */ jsx24(
4167
+ DialogPrimitive2.Close,
4168
+ {
4169
+ "data-slot": "overlay-close-hidden",
4170
+ className: cn(
4171
+ "sr-only",
4172
+ "focus-visible:not-sr-only focus-visible:absolute focus-visible:top-[var(--space-2)] focus-visible:right-[var(--space-4)]",
4173
+ "focus-visible:rounded-[var(--radius-md)] focus-visible:border focus-visible:border-[var(--focus-ring)] focus-visible:bg-[var(--bg-raised)]",
4174
+ "focus-visible:px-[var(--space-3)] focus-visible:py-[var(--space-1)] focus-visible:text-[13px] focus-visible:text-foreground",
4175
+ "focus-visible:outline-none focus-visible:shadow-[0_0_0_2px_var(--focus-ring)]"
4176
+ ),
4177
+ children: closeLabel
4178
+ }
4179
+ ) : null
4180
+ ]
4181
+ }
4182
+ );
4183
+ }
4184
+ var fogClassName = cn(
4185
+ "pointer-events-none sticky z-[1] block h-[var(--space-6)] shrink-0 opacity-0",
4186
+ "from-[var(--bg-raised)] to-transparent"
4187
+ );
4188
+ function OverlayBody({ kind, className, children, ...props }) {
4189
+ const { scroll } = OVERLAY_POLICY[kind];
4190
+ if (scroll !== "body") {
4191
+ return /* @__PURE__ */ jsx24(
4192
+ "div",
4193
+ {
4194
+ "data-slot": "overlay-body",
4195
+ className: cn(
4196
+ "min-w-0 px-[var(--space-6)] pt-[var(--space-4)] text-[14px] leading-relaxed text-text-secondary",
4197
+ scroll === "list" && "min-h-0 flex-1 overflow-y-auto px-0",
4198
+ className
4199
+ ),
4200
+ ...props,
4201
+ children
4202
+ }
4203
+ );
4204
+ }
4205
+ return /* @__PURE__ */ jsxs21(
4206
+ "div",
4207
+ {
4208
+ "data-slot": "overlay-body",
4209
+ className: "relative flex min-h-0 flex-1 flex-col overflow-y-auto [container-type:scroll-state]",
4210
+ ...props,
4211
+ children: [
4212
+ /* @__PURE__ */ jsx24(
4213
+ "span",
4214
+ {
4215
+ "aria-hidden": true,
4216
+ "data-slot": "overlay-fog-top",
4217
+ className: cn(fogClassName, "top-0 -mb-[var(--space-6)] bg-linear-to-b", "[@container_scroll-state(scrollable:top)]:opacity-100")
4218
+ }
4219
+ ),
4220
+ /* @__PURE__ */ jsx24("div", { className: cn("min-w-0 px-[var(--space-6)] py-[var(--space-4)]", className), children }),
4221
+ /* @__PURE__ */ jsx24(
4222
+ "span",
4223
+ {
4224
+ "aria-hidden": true,
4225
+ "data-slot": "overlay-fog-bottom",
4226
+ className: cn(fogClassName, "bottom-0 -mt-[var(--space-6)] bg-linear-to-t", "[@container_scroll-state(scrollable:bottom)]:opacity-100")
4227
+ }
4228
+ )
4229
+ ]
4230
+ }
4231
+ );
4232
+ }
4233
+ function OverlayFooter({ kind, className, ...props }) {
4234
+ const { footerDivider } = OVERLAY_POLICY[kind];
4235
+ return /* @__PURE__ */ jsx24(
4236
+ "div",
4237
+ {
4238
+ "data-slot": "overlay-footer",
4239
+ className: cn(
4240
+ "flex shrink-0 flex-wrap items-center justify-end gap-[var(--space-2)] px-[var(--space-6)]",
4241
+ footerDivider ? "border-t border-[var(--border-subtle)] py-[var(--space-4)]" : "pt-[var(--space-6)] pb-[var(--space-6)]",
4242
+ className
4243
+ ),
4244
+ ...props
4245
+ }
4246
+ );
3777
4247
  }
3778
4248
 
3779
4249
  // src/components/ui/overlay-surface.ts
@@ -3798,25 +4268,13 @@ var bottomSheet = {
3798
4268
  * `sm:max-w-sm` cap so the bottom sheet spans the full viewport width across the whole
3799
4269
  * < 900px band (not capped to 24rem).
3800
4270
  */
3801
- sheetMobile: "max-[899px]:inset-x-0 max-[899px]:bottom-0 max-[899px]:top-auto max-[899px]:h-auto max-[899px]:w-full max-[899px]:max-w-none! max-[899px]:border-t max-[899px]:border-l-0 max-[899px]:rounded-none",
3802
- /** SheetDrawer below 900px: `base` for every width, `full` for `width="full"` / expanded. */
3803
- detail: {
3804
- base: cn(
3805
- "max-[899px]:h-[min(85dvh,720px)] max-[899px]:max-h-[85dvh] max-[899px]:w-full max-[899px]:max-w-none",
3806
- "max-[899px]:rounded-t-[var(--radius-lg)]"
3807
- ),
3808
- full: "max-[899px]:h-[100dvh] max-[899px]:max-h-[100dvh] max-[899px]:rounded-none"
3809
- },
3810
- /** ActionSheet, a SheetContent `side="bottom"` at every width. */
3811
- action: cn(
3812
- "gap-0 max-h-[85dvh] rounded-t-[var(--radius-lg)]",
3813
- "pb-[env(safe-area-inset-bottom)]"
3814
- )
4271
+ sheetMobile: "max-[899px]:inset-x-0 max-[899px]:bottom-0 max-[899px]:top-auto max-[899px]:h-auto max-[899px]:w-full max-[899px]:max-w-none! max-[899px]:border-t max-[899px]:border-l-0 max-[899px]:rounded-none"
3815
4272
  };
3816
4273
 
3817
4274
  // src/components/ui/sheet.tsx
4275
+ import * as React25 from "react";
3818
4276
  import { Dialog as SheetPrimitive } from "radix-ui";
3819
- import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
4277
+ import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
3820
4278
  var defaultSheetMotionConfig = {
3821
4279
  type: "slide",
3822
4280
  duration: 300,
@@ -3852,23 +4310,98 @@ function getSheetMotionStyle(motionConfig, style) {
3852
4310
  function getDefaultSheetMotionStyle(style) {
3853
4311
  return getSheetMotionStyle(defaultSheetMotionConfig, style);
3854
4312
  }
3855
- function Sheet({ ...props }) {
3856
- return /* @__PURE__ */ jsx23(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
4313
+ function Sheet(props) {
4314
+ if (props.title !== void 0) return /* @__PURE__ */ jsx25(StructuredSheet, { ...props });
4315
+ return /* @__PURE__ */ jsx25(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
4316
+ }
4317
+ var structuredSheetSide = {
4318
+ right: "min-[900px]:inset-y-0 min-[900px]:right-0 min-[900px]:h-full min-[900px]:rounded-none min-[900px]:border-y-0 min-[900px]:border-r-0",
4319
+ left: "min-[900px]:inset-y-0 min-[900px]:left-0 min-[900px]:h-full min-[900px]:rounded-none min-[900px]:border-y-0 min-[900px]:border-l-0"
4320
+ };
4321
+ var structuredSheetMotion = {
4322
+ fade: "min-[900px]:motion-safe:data-[state=open]:animate-[olun-sheet-fade-in_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] min-[900px]:motion-safe:data-[state=closed]:animate-[olun-sheet-fade-out_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
4323
+ right: "min-[900px]:motion-safe:data-[state=open]:animate-[olun-sheet-in-from-right_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] min-[900px]:motion-safe:data-[state=closed]:animate-[olun-sheet-out-to-right_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]",
4324
+ left: "min-[900px]:motion-safe:data-[state=open]:animate-[olun-sheet-in-from-left_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both] min-[900px]:motion-safe:data-[state=closed]:animate-[olun-sheet-out-to-left_var(--sheet-motion-duration)_var(--sheet-motion-easing)_both]"
4325
+ };
4326
+ var preventDefault = (event) => event.preventDefault();
4327
+ function StructuredSheet({
4328
+ open,
4329
+ onOpenChange,
4330
+ title,
4331
+ description,
4332
+ caption,
4333
+ headerActions,
4334
+ side = "right",
4335
+ size = "md",
4336
+ children,
4337
+ footer,
4338
+ closeLabel,
4339
+ motion,
4340
+ scrim,
4341
+ className
4342
+ }) {
4343
+ const policy = OVERLAY_POLICY.sheet;
4344
+ const motionConfig = resolveSheetMotionConfig(motion);
4345
+ const surfaceRef = React25.useRef(null);
4346
+ const swipe = useSwipeDismiss({ enabled: policy.swipe, onDismiss: () => onOpenChange(false), surfaceRef });
4347
+ const returnFocus = useReturnFocus();
4348
+ return /* @__PURE__ */ jsx25(SheetPrimitive.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs22(SheetPrimitive.Portal, { children: [
4349
+ /* @__PURE__ */ jsx25(OverlayScrimLayer, { kind: "sheet", scrim, still: motionConfig === false }),
4350
+ /* @__PURE__ */ jsxs22(
4351
+ SheetPrimitive.Content,
4352
+ {
4353
+ ref: surfaceRef,
4354
+ "data-slot": "sheet",
4355
+ className: cn(
4356
+ overlayBoxClassName("sheet"),
4357
+ structuredSheetSide[side],
4358
+ overlaySize.sheet[size],
4359
+ motionConfig && structuredSheetMotion[motionConfig.type === "fade" ? "fade" : side]
4360
+ ),
4361
+ style: getSheetMotionStyle(motionConfig, void 0),
4362
+ ...description == null && { "aria-describedby": void 0 },
4363
+ onOpenAutoFocus: (event) => {
4364
+ returnFocus.onOpenAutoFocus(event);
4365
+ focusBodyInput(event);
4366
+ },
4367
+ onCloseAutoFocus: returnFocus.onCloseAutoFocus,
4368
+ onEscapeKeyDown: policy.closeOnEscape ? void 0 : preventDefault,
4369
+ onInteractOutside: policy.closeOnOutsideClick ? void 0 : preventDefault,
4370
+ children: [
4371
+ policy.grabber ? /* @__PURE__ */ jsx25(OverlayGrabber, { ...swipe.handleProps }) : null,
4372
+ /* @__PURE__ */ jsx25(
4373
+ OverlayHeader,
4374
+ {
4375
+ kind: "sheet",
4376
+ title,
4377
+ description,
4378
+ caption,
4379
+ actions: headerActions,
4380
+ closeLabel,
4381
+ dragHandleProps: swipe.handleProps
4382
+ }
4383
+ ),
4384
+ /* @__PURE__ */ jsx25(OverlayBody, { kind: "sheet", className, children }),
4385
+ footer != null ? /* @__PURE__ */ jsx25(OverlayFooter, { kind: "sheet", children: footer }) : null
4386
+ ]
4387
+ }
4388
+ )
4389
+ ] }) });
3857
4390
  }
3858
4391
  function SheetTrigger({
3859
4392
  ...props
3860
4393
  }) {
3861
- return /* @__PURE__ */ jsx23(SheetPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
4394
+ return /* @__PURE__ */ jsx25(SheetPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
3862
4395
  }
3863
4396
  function SheetClose({
3864
4397
  ...props
3865
4398
  }) {
3866
- return /* @__PURE__ */ jsx23(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
4399
+ return /* @__PURE__ */ jsx25(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
3867
4400
  }
3868
4401
  function SheetPortal({
3869
4402
  ...props
3870
4403
  }) {
3871
- return /* @__PURE__ */ jsx23(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
4404
+ return /* @__PURE__ */ jsx25(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
3872
4405
  }
3873
4406
  function SheetOverlay({
3874
4407
  className,
@@ -3877,12 +4410,11 @@ function SheetOverlay({
3877
4410
  ...props
3878
4411
  }) {
3879
4412
  const motionConfig = resolveSheetMotionConfig(motion);
3880
- return /* @__PURE__ */ jsx23(
3881
- SheetPrimitive.Overlay,
4413
+ return /* @__PURE__ */ jsx25(
4414
+ OverlayScrimLayer,
3882
4415
  {
3883
4416
  "data-slot": "sheet-overlay",
3884
4417
  className: cn(
3885
- "fixed inset-0 z-[var(--z-modal)] bg-[var(--scrim)]",
3886
4418
  motionConfig && cn(
3887
4419
  "transition-opacity motion-reduce:transition-none",
3888
4420
  "duration-[var(--sheet-motion-duration)]",
@@ -3905,6 +4437,7 @@ function SheetContent({
3905
4437
  mobileSide,
3906
4438
  motion,
3907
4439
  showCloseButton = false,
4440
+ scrim,
3908
4441
  style,
3909
4442
  onOpenAutoFocus,
3910
4443
  onCloseAutoFocus,
@@ -3921,9 +4454,9 @@ function SheetContent({
3921
4454
  onCloseAutoFocus?.(event);
3922
4455
  if (!event.defaultPrevented) returnFocus.onCloseAutoFocus(event);
3923
4456
  };
3924
- return /* @__PURE__ */ jsxs21(SheetPortal, { children: [
3925
- /* @__PURE__ */ jsx23(SheetOverlay, { motion: motionConfig }),
3926
- /* @__PURE__ */ jsxs21(
4457
+ return /* @__PURE__ */ jsxs22(SheetPortal, { children: [
4458
+ /* @__PURE__ */ jsx25(SheetOverlay, { motion: motionConfig, scrim }),
4459
+ /* @__PURE__ */ jsxs22(
3927
4460
  SheetPrimitive.Content,
3928
4461
  {
3929
4462
  "data-slot": "sheet-content",
@@ -3974,14 +4507,14 @@ function SheetContent({
3974
4507
  ...props,
3975
4508
  children: [
3976
4509
  children,
3977
- showCloseButton && /* @__PURE__ */ jsx23(OverlayCloseButton, { className: "absolute top-4 right-4" })
4510
+ showCloseButton && /* @__PURE__ */ jsx25(OverlayCloseButton, { className: "absolute top-4 right-4" })
3978
4511
  ]
3979
4512
  }
3980
4513
  )
3981
4514
  ] });
3982
4515
  }
3983
4516
  function SheetBody({ className, ...props }) {
3984
- return /* @__PURE__ */ jsx23(
4517
+ return /* @__PURE__ */ jsx25(
3985
4518
  "div",
3986
4519
  {
3987
4520
  "data-slot": "sheet-body",
@@ -3991,7 +4524,7 @@ function SheetBody({ className, ...props }) {
3991
4524
  );
3992
4525
  }
3993
4526
  function SheetHeader({ className, ...props }) {
3994
- return /* @__PURE__ */ jsx23(
4527
+ return /* @__PURE__ */ jsx25(
3995
4528
  "div",
3996
4529
  {
3997
4530
  "data-slot": "sheet-header",
@@ -4001,7 +4534,7 @@ function SheetHeader({ className, ...props }) {
4001
4534
  );
4002
4535
  }
4003
4536
  function SheetFooter({ className, ...props }) {
4004
- return /* @__PURE__ */ jsx23(
4537
+ return /* @__PURE__ */ jsx25(
4005
4538
  "div",
4006
4539
  {
4007
4540
  "data-slot": "sheet-footer",
@@ -4014,7 +4547,7 @@ function SheetTitle({
4014
4547
  className,
4015
4548
  ...props
4016
4549
  }) {
4017
- return /* @__PURE__ */ jsx23(
4550
+ return /* @__PURE__ */ jsx25(
4018
4551
  SheetPrimitive.Title,
4019
4552
  {
4020
4553
  "data-slot": "sheet-title",
@@ -4027,7 +4560,7 @@ function SheetDescription({
4027
4560
  className,
4028
4561
  ...props
4029
4562
  }) {
4030
- return /* @__PURE__ */ jsx23(
4563
+ return /* @__PURE__ */ jsx25(
4031
4564
  SheetPrimitive.Description,
4032
4565
  {
4033
4566
  "data-slot": "sheet-description",
@@ -4038,45 +4571,144 @@ function SheetDescription({
4038
4571
  }
4039
4572
 
4040
4573
  // src/components/ui/dialog.tsx
4041
- import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
4574
+ import { Fragment as Fragment7, jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
4042
4575
  function dialogMobileSheetStyle(style) {
4043
4576
  return getDefaultSheetMotionStyle(style);
4044
4577
  }
4045
- var DialogModalContext = React22.createContext(true);
4046
- function Dialog({ modal = true, ...props }) {
4047
- return /* @__PURE__ */ jsx24(DialogModalContext.Provider, { value: modal, children: /* @__PURE__ */ jsx24(DialogPrimitive2.Root, { modal, ...props }) });
4578
+ var DialogModalContext = React26.createContext(true);
4579
+ function Dialog(props) {
4580
+ if (props.title !== void 0) return /* @__PURE__ */ jsx26(StructuredDialog, { ...props });
4581
+ return /* @__PURE__ */ jsx26(DialogRoot, { ...props });
4048
4582
  }
4049
- var DialogTrigger = DialogPrimitive2.Trigger;
4050
- var DialogPortal = DialogPrimitive2.Portal;
4051
- var DialogClose = DialogPrimitive2.Close;
4052
- var DialogOverlay = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4053
- DialogPrimitive2.Overlay,
4054
- {
4055
- ref,
4056
- className: cn(
4057
- "fixed inset-0 z-[var(--z-modal)]",
4058
- // 2026: 글래스모피즘 블러 제거 — 단정한 scrim 딤만(FE-skill anti-slop).
4059
- "bg-[var(--scrim)]",
4060
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
4061
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
4062
- "motion-reduce:animate-none",
4063
- className
4583
+ var noAction = () => void 0;
4584
+ function StructuredDialog({
4585
+ open,
4586
+ onOpenChange,
4587
+ title,
4588
+ description,
4589
+ size = "md",
4590
+ children,
4591
+ footer,
4592
+ onSubmit,
4593
+ onError,
4594
+ submitLabel = "\uC800\uC7A5",
4595
+ cancelLabel = "\uCDE8\uC18C",
4596
+ loading = false,
4597
+ closeLabel = "\uB2EB\uAE30",
4598
+ scrim,
4599
+ className
4600
+ }) {
4601
+ const policy = OVERLAY_POLICY.dialog;
4602
+ const formMode = onSubmit !== void 0;
4603
+ const { isBusy, run, guardOpenChange } = useOverlayAction({
4604
+ action: onSubmit ?? noAction,
4605
+ onOpenChange,
4606
+ loading: formMode && loading,
4607
+ onError
4608
+ });
4609
+ const returnFocus = useReturnFocus();
4610
+ const surfaceRef = React26.useRef(null);
4611
+ const swipe = useSwipeDismiss({ enabled: policy.swipe, onDismiss: () => guardOpenChange(false), surfaceRef });
4612
+ const body = /* @__PURE__ */ jsx26(OverlayBody, { kind: "dialog", className, children });
4613
+ const footerRow = formMode ? /* @__PURE__ */ jsxs23(OverlayFooter, { kind: "dialog", children: [
4614
+ /* @__PURE__ */ jsx26(
4615
+ Button,
4616
+ {
4617
+ appearance: "outline",
4618
+ tone: "neutral",
4619
+ size: "lg",
4620
+ className: footerButtonHitAreaClassName,
4621
+ disabled: isBusy,
4622
+ onClick: () => guardOpenChange(false),
4623
+ children: cancelLabel
4624
+ }
4064
4625
  ),
4065
- ...props
4066
- }
4626
+ /* @__PURE__ */ jsx26(Button, { type: "submit", appearance: "filled", tone: "primary", size: "lg", className: footerButtonHitAreaClassName, loading: isBusy, children: submitLabel })
4627
+ ] }) : footer != null ? /* @__PURE__ */ jsx26(OverlayFooter, { kind: "dialog", children: footer }) : null;
4628
+ return /* @__PURE__ */ jsx26(DialogPrimitive3.Root, { open, onOpenChange: guardOpenChange, children: /* @__PURE__ */ jsxs23(DialogPrimitive3.Portal, { children: [
4629
+ /* @__PURE__ */ jsx26(OverlayScrimLayer, { kind: "dialog", scrim }),
4630
+ /* @__PURE__ */ jsxs23(
4631
+ DialogPrimitive3.Content,
4632
+ {
4633
+ ref: surfaceRef,
4634
+ className: cn(overlayBoxClassName("dialog"), overlaySize.dialog[size]),
4635
+ ...description == null && { "aria-describedby": void 0 },
4636
+ onOpenAutoFocus: (event) => {
4637
+ returnFocus.onOpenAutoFocus(event);
4638
+ focusBodyInput(event);
4639
+ },
4640
+ onCloseAutoFocus: returnFocus.onCloseAutoFocus,
4641
+ onInteractOutside: policy.closeOnOutsideClick ? void 0 : (event) => event.preventDefault(),
4642
+ onEscapeKeyDown: policy.closeOnEscape ? void 0 : (event) => event.preventDefault(),
4643
+ children: [
4644
+ /* @__PURE__ */ jsx26(OverlayGrabber, { ...swipe.handleProps }),
4645
+ /* @__PURE__ */ jsx26(
4646
+ OverlayHeader,
4647
+ {
4648
+ kind: "dialog",
4649
+ title,
4650
+ description,
4651
+ closeLabel,
4652
+ dragHandleProps: swipe.handleProps
4653
+ }
4654
+ ),
4655
+ formMode ? /* @__PURE__ */ jsxs23(
4656
+ "form",
4657
+ {
4658
+ className: "flex min-h-0 flex-1 flex-col",
4659
+ onSubmit: (event) => {
4660
+ event.preventDefault();
4661
+ void run();
4662
+ },
4663
+ children: [
4664
+ body,
4665
+ footerRow
4666
+ ]
4667
+ }
4668
+ ) : /* @__PURE__ */ jsxs23(Fragment7, { children: [
4669
+ body,
4670
+ footerRow
4671
+ ] })
4672
+ ]
4673
+ }
4674
+ )
4675
+ ] }) });
4676
+ }
4677
+ function DialogRoot({ modal = true, ...props }) {
4678
+ return /* @__PURE__ */ jsx26(DialogModalContext.Provider, { value: modal, children: /* @__PURE__ */ jsx26(DialogPrimitive3.Root, { modal, ...props }) });
4679
+ }
4680
+ var DialogTrigger = DialogPrimitive3.Trigger;
4681
+ var DialogPortal = DialogPrimitive3.Portal;
4682
+ var DialogClose = DialogPrimitive3.Close;
4683
+ var DialogOverlay = React26.forwardRef(({ className, ...props }, ref) => (
4684
+ // Position and scrim color come from the shared scrim (overlay-anatomy).
4685
+ /* @__PURE__ */ jsx26(
4686
+ OverlayScrimLayer,
4687
+ {
4688
+ ref,
4689
+ className: cn(
4690
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
4691
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
4692
+ "motion-reduce:animate-none",
4693
+ className
4694
+ ),
4695
+ ...props
4696
+ }
4697
+ )
4067
4698
  ));
4068
- DialogOverlay.displayName = DialogPrimitive2.Overlay.displayName;
4069
- var DialogContent = React22.forwardRef(
4699
+ DialogOverlay.displayName = DialogPrimitive3.Overlay.displayName;
4700
+ var DialogContent = React26.forwardRef(
4070
4701
  ({
4071
4702
  className,
4072
4703
  children,
4073
4704
  showCloseButton = false,
4074
4705
  mobilePresentation = "center",
4706
+ scrim,
4075
4707
  onOpenAutoFocus,
4076
4708
  onCloseAutoFocus,
4077
4709
  ...props
4078
4710
  }, ref) => {
4079
- const modal = React22.useContext(DialogModalContext);
4711
+ const modal = React26.useContext(DialogModalContext);
4080
4712
  const returnFocus = useReturnFocus();
4081
4713
  const handleOpenAutoFocus = (event) => {
4082
4714
  if (modal) returnFocus.onOpenAutoFocus(event);
@@ -4086,10 +4718,10 @@ var DialogContent = React22.forwardRef(
4086
4718
  onCloseAutoFocus?.(event);
4087
4719
  if (modal && !event.defaultPrevented) returnFocus.onCloseAutoFocus(event);
4088
4720
  };
4089
- return /* @__PURE__ */ jsxs22(DialogPortal, { children: [
4090
- /* @__PURE__ */ jsx24(DialogOverlay, {}),
4091
- /* @__PURE__ */ jsxs22(
4092
- DialogPrimitive2.Content,
4721
+ return /* @__PURE__ */ jsxs23(DialogPortal, { children: [
4722
+ /* @__PURE__ */ jsx26(DialogOverlay, { scrim }),
4723
+ /* @__PURE__ */ jsxs23(
4724
+ DialogPrimitive3.Content,
4093
4725
  {
4094
4726
  ref,
4095
4727
  className: cn(
@@ -4119,18 +4751,18 @@ var DialogContent = React22.forwardRef(
4119
4751
  onCloseAutoFocus: handleCloseAutoFocus,
4120
4752
  children: [
4121
4753
  children,
4122
- showCloseButton ? /* @__PURE__ */ jsx24(OverlayCloseButton, { className: "absolute right-4 top-4" }) : null
4754
+ showCloseButton ? /* @__PURE__ */ jsx26(OverlayCloseButton, { className: "absolute right-4 top-4" }) : null
4123
4755
  ]
4124
4756
  }
4125
4757
  )
4126
4758
  ] });
4127
4759
  }
4128
4760
  );
4129
- DialogContent.displayName = DialogPrimitive2.Content.displayName;
4761
+ DialogContent.displayName = DialogPrimitive3.Content.displayName;
4130
4762
  var DialogHeader = ({
4131
4763
  className,
4132
4764
  ...props
4133
- }) => /* @__PURE__ */ jsx24(
4765
+ }) => /* @__PURE__ */ jsx26(
4134
4766
  "div",
4135
4767
  {
4136
4768
  className: cn(
@@ -4145,7 +4777,7 @@ DialogHeader.displayName = "DialogHeader";
4145
4777
  var DialogFooter = ({
4146
4778
  className,
4147
4779
  ...props
4148
- }) => /* @__PURE__ */ jsx24(
4780
+ }) => /* @__PURE__ */ jsx26(
4149
4781
  "div",
4150
4782
  {
4151
4783
  className: cn(
@@ -4161,8 +4793,8 @@ var DialogFooter = ({
4161
4793
  }
4162
4794
  );
4163
4795
  DialogFooter.displayName = "DialogFooter";
4164
- var DialogTitle = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4165
- DialogPrimitive2.Title,
4796
+ var DialogTitle = React26.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
4797
+ DialogPrimitive3.Title,
4166
4798
  {
4167
4799
  ref,
4168
4800
  className: cn(
@@ -4172,17 +4804,17 @@ var DialogTitle = React22.forwardRef(({ className, ...props }, ref) => /* @__PUR
4172
4804
  ...props
4173
4805
  }
4174
4806
  ));
4175
- DialogTitle.displayName = DialogPrimitive2.Title.displayName;
4176
- var DialogDescription = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4177
- DialogPrimitive2.Description,
4807
+ DialogTitle.displayName = DialogPrimitive3.Title.displayName;
4808
+ var DialogDescription = React26.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
4809
+ DialogPrimitive3.Description,
4178
4810
  {
4179
4811
  ref,
4180
4812
  className: cn("text-sm text-text-secondary", className),
4181
4813
  ...props
4182
4814
  }
4183
4815
  ));
4184
- DialogDescription.displayName = DialogPrimitive2.Description.displayName;
4185
- var DialogEyebrow = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4816
+ DialogDescription.displayName = DialogPrimitive3.Description.displayName;
4817
+ var DialogEyebrow = React26.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
4186
4818
  "p",
4187
4819
  {
4188
4820
  ref,
@@ -4194,251 +4826,189 @@ var DialogEyebrow = React22.forwardRef(({ className, ...props }, ref) => /* @__P
4194
4826
  }
4195
4827
  ));
4196
4828
  DialogEyebrow.displayName = "DialogEyebrow";
4197
- var DialogRawContent = DialogPrimitive2.Content;
4829
+ var DialogRawContent = DialogPrimitive3.Content;
4198
4830
 
4199
- // src/lib/use-overlay-action.ts
4200
- import * as React23 from "react";
4201
- function useOverlayAction({
4202
- action,
4831
+ // src/components/ui/form-modal.tsx
4832
+ import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
4833
+ function FormModal({
4834
+ open,
4203
4835
  onOpenChange,
4204
- loading = false,
4205
- disabled = false
4836
+ title,
4837
+ description,
4838
+ children,
4839
+ onSubmit,
4840
+ submitLabel,
4841
+ cancelLabel,
4842
+ wide = false,
4843
+ loading,
4844
+ status
4206
4845
  }) {
4207
- const [pending, setPending] = React23.useState(false);
4208
- const busyRef = React23.useRef(false);
4209
- const isBusy = loading || pending;
4210
- const guardOpenChange = React23.useCallback(
4211
- (nextOpen) => {
4212
- if (!nextOpen && isBusy) {
4213
- return;
4214
- }
4215
- onOpenChange(nextOpen);
4216
- },
4217
- [isBusy, onOpenChange]
4218
- );
4219
- const run = React23.useCallback(async () => {
4220
- if (busyRef.current || loading || disabled) {
4221
- return;
4222
- }
4223
- busyRef.current = true;
4224
- setPending(true);
4225
- try {
4226
- await action();
4227
- onOpenChange(false);
4228
- } finally {
4229
- busyRef.current = false;
4230
- setPending(false);
4846
+ return /* @__PURE__ */ jsxs24(
4847
+ Dialog,
4848
+ {
4849
+ open,
4850
+ onOpenChange,
4851
+ title,
4852
+ description,
4853
+ size: wide ? "lg" : "md",
4854
+ onSubmit,
4855
+ submitLabel,
4856
+ cancelLabel,
4857
+ loading,
4858
+ className: "flex flex-col gap-[var(--space-4)]",
4859
+ children: [
4860
+ status ? /* @__PURE__ */ jsx27("div", { "data-slot": "form-modal-status", children: status }) : null,
4861
+ children
4862
+ ]
4231
4863
  }
4232
- }, [action, disabled, loading, onOpenChange]);
4233
- return { isBusy, run, guardOpenChange };
4864
+ );
4234
4865
  }
4235
4866
 
4236
- // src/components/ui/overlay-tokens.ts
4237
- var OVERLAY_WIDTH = {
4238
- compact: "max-w-[420px]",
4239
- form: "max-w-[560px]",
4240
- wide: "max-w-[720px]"
4241
- };
4242
- var OVERLAY_SHADOW = {
4243
- preset: "shadow-[var(--shadow-4)]"
4244
- };
4245
-
4246
- // src/components/ui/preset-surface.ts
4247
- var title = cn("text-[18px] font-bold leading-snug text-foreground");
4248
- var modalHeader = cn(
4249
- "flex flex-col gap-[var(--space-2)]",
4250
- "border-b border-[var(--border-subtle)] pb-[var(--space-4)]",
4251
- "pr-[40px]"
4252
- );
4253
- var modalDescription = cn("break-keep text-[14px] leading-normal text-text-secondary");
4254
- var modalFooter = cn(
4255
- "border-t border-[var(--border-subtle)] pt-[var(--space-4)]",
4256
- "flex flex-col-reverse justify-end gap-[var(--space-2)] sm:flex-row"
4257
- );
4258
- var modalBody = "flex flex-col gap-[var(--space-4)] py-[var(--space-6)]";
4259
- var presetSurface = {
4260
- form: {
4261
- content: cn(
4262
- "w-[calc(100vw-2rem)]",
4263
- OVERLAY_WIDTH.form,
4264
- "gap-0 p-[var(--space-6)]",
4265
- "bg-[var(--bg-surface)]",
4266
- "border-[var(--border)]",
4267
- "rounded-[var(--radius-lg)]",
4268
- OVERLAY_SHADOW.preset,
4269
- "text-foreground"
4270
- ),
4271
- wideContent: OVERLAY_WIDTH.wide,
4272
- header: modalHeader,
4273
- title,
4274
- description: modalDescription,
4275
- body: modalBody,
4276
- footer: modalFooter
4277
- },
4278
- info: {
4279
- content: cn(
4280
- "w-[calc(100vw-2rem)]",
4281
- OVERLAY_WIDTH.compact,
4282
- "gap-0 p-[var(--space-6)]",
4283
- "bg-[var(--bg-surface)]",
4284
- "border border-[var(--border)]",
4285
- "rounded-[var(--radius-lg)]",
4286
- OVERLAY_SHADOW.preset,
4287
- "text-foreground"
4288
- ),
4289
- wideContent: OVERLAY_WIDTH.wide,
4290
- header: modalHeader,
4291
- title,
4292
- description: modalDescription,
4293
- body: cn(modalBody, "text-[14px] leading-normal text-text-secondary"),
4294
- footer: modalFooter
4295
- },
4296
- confirm: {
4297
- content: cn(
4298
- "fixed left-1/2 top-1/2 z-[var(--z-modal)]",
4299
- "-translate-x-1/2 -translate-y-1/2",
4300
- "w-[calc(100vw-2rem)]",
4301
- OVERLAY_WIDTH.compact,
4302
- "flex flex-col gap-[var(--space-6)]",
4303
- "bg-[var(--bg-surface)] border border-[var(--border)]",
4304
- "rounded-[var(--radius-lg)] p-[var(--space-6)]",
4305
- OVERLAY_SHADOW.preset,
4306
- "text-foreground"
4307
- ),
4308
- title,
4309
- description: "break-keep text-[14px] leading-relaxed text-text-secondary",
4310
- body: "min-w-0 text-[14px] leading-relaxed text-text-secondary",
4311
- footer: "flex items-center justify-end gap-[var(--space-3)]"
4312
- }
4313
- };
4314
-
4315
- // src/components/ui/form-modal.tsx
4316
- import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
4317
- function FormModal({
4867
+ // src/components/ui/alert-dialog.tsx
4868
+ import { AlertDialog as AlertDialogPrimitive2 } from "radix-ui";
4869
+ import { Fragment as Fragment8, jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
4870
+ function AlertDialogFrame({
4318
4871
  open,
4319
4872
  onOpenChange,
4320
- title: title2,
4873
+ title,
4321
4874
  description,
4322
4875
  children,
4323
- onSubmit,
4324
- submitLabel = "\uC800\uC7A5",
4876
+ scrim,
4877
+ footer
4878
+ }) {
4879
+ const returnFocus = useReturnFocus();
4880
+ const onOpenAutoFocus = (event) => {
4881
+ returnFocus.onOpenAutoFocus(event);
4882
+ focusBodyInput(event);
4883
+ if (event.defaultPrevented) return;
4884
+ const surface = event.target instanceof HTMLElement ? event.target : null;
4885
+ const control = surface?.querySelector(
4886
+ '[data-slot="overlay-footer"] :is(button, a[href], [tabindex]):not([disabled]):not([tabindex="-1"])'
4887
+ );
4888
+ if (control) {
4889
+ event.preventDefault();
4890
+ control.focus();
4891
+ }
4892
+ };
4893
+ return /* @__PURE__ */ jsx28(AlertDialogPrimitive2.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs25(AlertDialogPrimitive2.Portal, { children: [
4894
+ /* @__PURE__ */ jsx28(OverlayScrimLayer, { kind: "alert", scrim }),
4895
+ /* @__PURE__ */ jsxs25(
4896
+ AlertDialogPrimitive2.Content,
4897
+ {
4898
+ className: overlayBoxClassName("alert"),
4899
+ onOpenAutoFocus,
4900
+ onCloseAutoFocus: returnFocus.onCloseAutoFocus,
4901
+ children: [
4902
+ /* @__PURE__ */ jsx28(OverlayHeader, { kind: "alert", title, description }),
4903
+ children != null ? description != null ? /* @__PURE__ */ jsx28(OverlayBody, { kind: "alert", children }) : /* @__PURE__ */ jsx28(AlertDialogPrimitive2.Description, { asChild: true, children: /* @__PURE__ */ jsx28(OverlayBody, { kind: "alert", children }) }) : null,
4904
+ /* @__PURE__ */ jsx28(OverlayFooter, { kind: "alert", children: footer })
4905
+ ]
4906
+ }
4907
+ )
4908
+ ] }) });
4909
+ }
4910
+ function AlertDialog({
4911
+ open,
4912
+ onOpenChange,
4913
+ title,
4914
+ description,
4915
+ children,
4916
+ scrim,
4917
+ confirmLabel,
4918
+ onConfirm,
4919
+ onError,
4325
4920
  cancelLabel = "\uCDE8\uC18C",
4326
- wide = false,
4921
+ tone = "neutral",
4922
+ confirmDisabled = false,
4327
4923
  loading = false,
4328
- status,
4329
- mobilePresentation = "center"
4924
+ acknowledgeLabel = "\uD655\uC778"
4330
4925
  }) {
4331
4926
  const { isBusy, run, guardOpenChange } = useOverlayAction({
4332
- action: onSubmit,
4927
+ action: onConfirm ?? noop,
4333
4928
  onOpenChange,
4334
- loading
4929
+ loading,
4930
+ disabled: confirmDisabled,
4931
+ onError
4335
4932
  });
4336
- return /* @__PURE__ */ jsx25(Dialog, { open, onOpenChange: guardOpenChange, children: /* @__PURE__ */ jsx25(
4337
- DialogContent,
4933
+ const footer = confirmLabel != null ? /* @__PURE__ */ jsxs25(Fragment8, { children: [
4934
+ /* @__PURE__ */ jsx28(AlertDialogPrimitive2.Cancel, { asChild: true, children: /* @__PURE__ */ jsx28(Button, { appearance: "outline", tone: "neutral", size: "lg", className: footerButtonHitAreaClassName, disabled: isBusy, children: cancelLabel }) }),
4935
+ /* @__PURE__ */ jsx28(
4936
+ Button,
4937
+ {
4938
+ appearance: "filled",
4939
+ tone: tone === "danger" ? "danger" : "primary",
4940
+ size: "lg",
4941
+ className: footerButtonHitAreaClassName,
4942
+ loading: isBusy,
4943
+ disabled: confirmDisabled,
4944
+ onClick: run,
4945
+ children: confirmLabel
4946
+ }
4947
+ )
4948
+ ] }) : /* @__PURE__ */ jsx28(AlertDialogPrimitive2.Cancel, { asChild: true, children: /* @__PURE__ */ jsx28(Button, { appearance: "outline", tone: "neutral", size: "lg", className: footerButtonHitAreaClassName, children: acknowledgeLabel }) });
4949
+ return /* @__PURE__ */ jsx28(
4950
+ AlertDialogFrame,
4338
4951
  {
4339
- "data-slot": "form-modal-content",
4340
- mobilePresentation,
4341
- className: cn(
4342
- presetSurface.form.content,
4343
- wide && presetSurface.form.wideContent
4344
- ),
4345
- children: /* @__PURE__ */ jsxs23("form", { "data-slot": "form-modal-form", onSubmit: (event) => {
4346
- event.preventDefault();
4347
- return run();
4348
- }, children: [
4349
- /* @__PURE__ */ jsxs23("div", { "data-slot": "form-modal-header", className: presetSurface.form.header, children: [
4350
- /* @__PURE__ */ jsx25(DialogTitle, { className: presetSurface.form.title, children: title2 }),
4351
- description ? /* @__PURE__ */ jsx25(DialogDescription, { className: presetSurface.form.description, children: description }) : null,
4352
- status ? /* @__PURE__ */ jsx25("div", { "data-slot": "form-modal-status", children: status }) : null
4353
- ] }),
4354
- /* @__PURE__ */ jsx25("div", { "data-slot": "form-modal-body", className: presetSurface.form.body, children }),
4355
- /* @__PURE__ */ jsxs23(
4356
- "div",
4357
- {
4358
- "data-slot": "form-modal-footer",
4359
- className: presetSurface.form.footer,
4360
- children: [
4361
- /* @__PURE__ */ jsx25(
4362
- Button,
4363
- {
4364
- variant: "secondary",
4365
- size: "lg",
4366
- className: footerButtonHitAreaClassName,
4367
- disabled: isBusy,
4368
- onClick: () => guardOpenChange(false),
4369
- children: cancelLabel
4370
- }
4371
- ),
4372
- /* @__PURE__ */ jsx25(Button, { type: "submit", size: "lg", className: footerButtonHitAreaClassName, loading: isBusy, children: submitLabel })
4373
- ]
4374
- }
4375
- )
4376
- ] })
4952
+ open,
4953
+ onOpenChange: guardOpenChange,
4954
+ title,
4955
+ description,
4956
+ scrim,
4957
+ footer,
4958
+ children
4377
4959
  }
4378
- ) });
4960
+ );
4961
+ }
4962
+ function noop() {
4379
4963
  }
4380
4964
 
4381
4965
  // src/components/ui/info-modal.tsx
4382
- import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
4966
+ import { jsx as jsx29 } from "react/jsx-runtime";
4383
4967
  function InfoModal({
4384
4968
  open,
4385
4969
  onOpenChange,
4386
- title: title2,
4970
+ title,
4387
4971
  description,
4388
4972
  children,
4389
4973
  closeLabel = "\uB2EB\uAE30",
4390
- width = "default",
4391
- footer,
4392
- mobilePresentation = "center"
4974
+ footer
4393
4975
  }) {
4394
- return /* @__PURE__ */ jsx26(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs24(
4395
- DialogContent,
4976
+ if (footer != null) {
4977
+ return /* @__PURE__ */ jsx29(
4978
+ AlertDialogFrame,
4979
+ {
4980
+ open,
4981
+ onOpenChange,
4982
+ title,
4983
+ description,
4984
+ footer,
4985
+ children
4986
+ }
4987
+ );
4988
+ }
4989
+ return /* @__PURE__ */ jsx29(
4990
+ AlertDialog,
4396
4991
  {
4397
- "data-slot": "info-modal-content",
4398
- mobilePresentation,
4399
- className: cn(
4400
- presetSurface.info.content,
4401
- width === "wide" && presetSurface.info.wideContent
4402
- ),
4403
- children: [
4404
- /* @__PURE__ */ jsxs24("div", { "data-slot": "info-modal-header", className: presetSurface.info.header, children: [
4405
- /* @__PURE__ */ jsx26(DialogTitle, { "data-slot": "info-modal-title", className: presetSurface.info.title, children: title2 }),
4406
- description ? /* @__PURE__ */ jsx26(
4407
- DialogDescription,
4408
- {
4409
- "data-slot": "info-modal-description",
4410
- className: presetSurface.info.description,
4411
- children: description
4412
- }
4413
- ) : null
4414
- ] }),
4415
- /* @__PURE__ */ jsx26("div", { "data-slot": "info-modal-body", className: presetSurface.info.body, children }),
4416
- /* @__PURE__ */ jsx26("div", { "data-slot": "info-modal-footer", className: presetSurface.info.footer, children: footer ?? /* @__PURE__ */ jsx26(
4417
- Button,
4418
- {
4419
- "data-slot": "info-modal-close-button",
4420
- variant: "secondary",
4421
- size: "lg",
4422
- className: footerButtonHitAreaClassName,
4423
- onClick: () => onOpenChange(false),
4424
- children: closeLabel
4425
- }
4426
- ) })
4427
- ]
4992
+ open,
4993
+ onOpenChange,
4994
+ title,
4995
+ description,
4996
+ acknowledgeLabel: closeLabel,
4997
+ children
4428
4998
  }
4429
- ) });
4999
+ );
4430
5000
  }
4431
5001
 
4432
5002
  // src/components/ui/filter-toolbar.tsx
4433
- import * as React26 from "react";
5003
+ import * as React29 from "react";
4434
5004
  import { SlidersHorizontal } from "lucide-react";
4435
5005
 
4436
5006
  // src/components/ui/chip.tsx
4437
- import * as React24 from "react";
5007
+ import * as React27 from "react";
4438
5008
  import { cva as cva10 } from "class-variance-authority";
4439
5009
  import { X as X2 } from "lucide-react";
4440
5010
  import { Slot as Slot2 } from "radix-ui";
4441
- import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
5011
+ import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
4442
5012
  var chipVariants = cva10(
4443
5013
  [
4444
5014
  "inline-flex w-fit shrink-0 items-center justify-center whitespace-nowrap",
@@ -4530,7 +5100,7 @@ var chipCountVariants = cva10(
4530
5100
  }
4531
5101
  }
4532
5102
  );
4533
- var Chip = React24.forwardRef(
5103
+ var Chip = React27.forwardRef(
4534
5104
  ({
4535
5105
  className,
4536
5106
  variant = "filter",
@@ -4555,7 +5125,7 @@ var Chip = React24.forwardRef(
4555
5125
  value: _value,
4556
5126
  ...spanProps
4557
5127
  } = props;
4558
- return /* @__PURE__ */ jsxs25(
5128
+ return /* @__PURE__ */ jsxs26(
4559
5129
  "span",
4560
5130
  {
4561
5131
  "data-slot": "chip",
@@ -4564,8 +5134,8 @@ var Chip = React24.forwardRef(
4564
5134
  className: cn(chipVariants({ variant, tone, size, pressed, className })),
4565
5135
  ...spanProps,
4566
5136
  children: [
4567
- /* @__PURE__ */ jsx27("span", { children }),
4568
- count !== void 0 ? /* @__PURE__ */ jsx27(
5137
+ /* @__PURE__ */ jsx30("span", { children }),
5138
+ count !== void 0 ? /* @__PURE__ */ jsx30(
4569
5139
  "span",
4570
5140
  {
4571
5141
  "aria-hidden": "true",
@@ -4575,7 +5145,7 @@ var Chip = React24.forwardRef(
4575
5145
  children: count
4576
5146
  }
4577
5147
  ) : null,
4578
- /* @__PURE__ */ jsx27(
5148
+ /* @__PURE__ */ jsx30(
4579
5149
  "button",
4580
5150
  {
4581
5151
  ref,
@@ -4585,7 +5155,7 @@ var Chip = React24.forwardRef(
4585
5155
  disabled,
4586
5156
  onClick,
4587
5157
  className: "inline-flex size-[var(--space-4)] items-center justify-center rounded-[var(--radius-full)] text-text-tertiary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
4588
- children: /* @__PURE__ */ jsx27(X2, { "aria-hidden": "true", size: 14, strokeWidth: 2.25 })
5158
+ children: /* @__PURE__ */ jsx30(X2, { "aria-hidden": "true", size: 14, strokeWidth: 2.25 })
4589
5159
  }
4590
5160
  )
4591
5161
  ]
@@ -4593,7 +5163,7 @@ var Chip = React24.forwardRef(
4593
5163
  );
4594
5164
  }
4595
5165
  const Comp = asChild ? Slot2.Root : "button";
4596
- return /* @__PURE__ */ jsxs25(
5166
+ return /* @__PURE__ */ jsxs26(
4597
5167
  Comp,
4598
5168
  {
4599
5169
  ref,
@@ -4608,7 +5178,7 @@ var Chip = React24.forwardRef(
4608
5178
  ...props,
4609
5179
  children: [
4610
5180
  children,
4611
- count !== void 0 ? /* @__PURE__ */ jsx27(
5181
+ count !== void 0 ? /* @__PURE__ */ jsx30(
4612
5182
  "span",
4613
5183
  {
4614
5184
  "aria-hidden": "true",
@@ -4626,17 +5196,17 @@ var Chip = React24.forwardRef(
4626
5196
  Chip.displayName = "Chip";
4627
5197
 
4628
5198
  // src/components/ui/popover.tsx
4629
- import * as React25 from "react";
5199
+ import * as React28 from "react";
4630
5200
  import { Popover as PopoverPrimitive } from "radix-ui";
4631
- import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
5201
+ import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
4632
5202
  function Popover({ modal = false, ...props }) {
4633
- return /* @__PURE__ */ jsx28(PopoverPrimitive.Root, { modal, ...props });
5203
+ return /* @__PURE__ */ jsx31(PopoverPrimitive.Root, { modal, ...props });
4634
5204
  }
4635
5205
  var popoverArrowClassName = "fill-[var(--bg-surface)] stroke-[var(--border)] [&>polygon]:[vector-effect:non-scaling-stroke]";
4636
5206
  var PopoverTrigger = PopoverPrimitive.Trigger;
4637
5207
  var PopoverAnchor = PopoverPrimitive.Anchor;
4638
5208
  var PopoverClose = PopoverPrimitive.Close;
4639
- var PopoverContent = React25.forwardRef(({ className, align = "center", sideOffset = 8, collisionPadding = 8, showArrow = false, children, ...props }, ref) => /* @__PURE__ */ jsx28(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsxs26(
5209
+ var PopoverContent = React28.forwardRef(({ className, align = "center", sideOffset = 8, collisionPadding = 8, showArrow = false, children, ...props }, ref) => /* @__PURE__ */ jsx31(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsxs27(
4640
5210
  PopoverPrimitive.Content,
4641
5211
  {
4642
5212
  ref,
@@ -4660,7 +5230,7 @@ var PopoverContent = React25.forwardRef(({ className, align = "center", sideOffs
4660
5230
  ...props,
4661
5231
  children: [
4662
5232
  children,
4663
- showArrow ? /* @__PURE__ */ jsx28(
5233
+ showArrow ? /* @__PURE__ */ jsx31(
4664
5234
  PopoverPrimitive.Arrow,
4665
5235
  {
4666
5236
  "data-slot": "popover-arrow",
@@ -4673,164 +5243,21 @@ var PopoverContent = React25.forwardRef(({ className, align = "center", sideOffs
4673
5243
  }
4674
5244
  ) }));
4675
5245
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
4676
- var PopoverArrow = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx28(
5246
+ var PopoverArrow = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx31(
4677
5247
  PopoverPrimitive.Arrow,
4678
5248
  {
4679
5249
  ref,
4680
5250
  "data-slot": "popover-arrow",
4681
- className: cn(popoverArrowClassName, className),
4682
- width: 11,
4683
- height: 5,
4684
- ...props
4685
- }
4686
- ));
4687
- PopoverArrow.displayName = PopoverPrimitive.Arrow.displayName;
4688
-
4689
- // src/components/ui/sheet-drawer.tsx
4690
- import { Maximize2Icon, Minimize2Icon } from "lucide-react";
4691
- import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
4692
- var sheetDrawerContentClassName = cn(
4693
- "gap-0 p-0",
4694
- "bg-[var(--bg-surface)] text-foreground",
4695
- "border-[var(--border)] shadow-[var(--shadow-16)]",
4696
- "min-[900px]:w-[480px] min-[900px]:max-w-[480px]",
4697
- bottomSheet.detail.base
4698
- );
4699
- var sheetDrawerWideContentClassName = "min-[900px]:w-[720px] min-[900px]:max-w-[720px]";
4700
- var sheetDrawerFullContentClassName = cn(
4701
- "min-[900px]:w-[calc(100vw_-_var(--space-8))] min-[900px]:max-w-[calc(100vw_-_var(--space-8))]",
4702
- bottomSheet.detail.full
4703
- );
4704
- var sheetDrawerHeaderClassName = cn(
4705
- "flex items-start justify-between gap-[var(--space-4)]",
4706
- "border-b border-[var(--border)] px-[var(--space-6)] py-[var(--space-6)]"
4707
- );
4708
- var sheetDrawerHeaderTextClassName = "flex min-w-0 flex-1 flex-col gap-[var(--space-2)]";
4709
- var sheetDrawerCaptionClassName = "flex flex-wrap items-center gap-[var(--space-2)]";
4710
- var sheetDrawerTitleClassName = "text-[18px] font-bold leading-snug text-foreground";
4711
- var sheetDrawerDescriptionClassName = "break-keep text-[14px] leading-normal text-text-secondary";
4712
- var sheetDrawerHeaderActionsClassName = cn(
4713
- "flex shrink-0 items-center gap-[var(--space-1)]"
4714
- );
4715
- var sheetDrawerExpandButtonClassName = cn(
4716
- "inline-flex cursor-pointer items-center justify-center gap-[var(--space-1)]",
4717
- "rounded-[var(--radius-md)] text-text-tertiary transition-colors",
4718
- "hover:bg-[var(--action-hover)] hover:text-foreground",
4719
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2",
4720
- "h-[32px] px-[var(--space-2)]"
4721
- );
4722
- var sheetDrawerBodyClassName = cn(
4723
- "min-h-0 flex-1 overflow-y-auto",
4724
- "px-[var(--space-6)] py-[var(--space-6)]"
4725
- );
4726
- var sheetDrawerFooterClassName = cn(
4727
- "border-t border-[var(--border)] px-[var(--space-6)] py-[var(--space-4)]",
4728
- "flex justify-end gap-[var(--space-2)]"
4729
- );
4730
- function SheetDrawer({
4731
- open,
4732
- onOpenChange,
4733
- caption,
4734
- title: title2,
4735
- description,
4736
- children,
4737
- expandHref,
4738
- onExpand,
4739
- expandLabel = "\uD06C\uAC8C \uBCF4\uAE30",
4740
- expanded = false,
4741
- onExpandedChange,
4742
- collapseLabel = "\uC791\uAC8C \uBCF4\uAE30",
4743
- footer,
4744
- width = "default",
4745
- motion,
4746
- closeLabel = "\uB2EB\uAE30"
4747
- }) {
4748
- const hasExpandedToggle = typeof onExpandedChange === "function";
4749
- const showExpandAction = Boolean(hasExpandedToggle || expandHref || onExpand);
4750
- const resolvedWidth = expanded ? "full" : width;
4751
- const resolvedExpandLabel = hasExpandedToggle && expanded ? collapseLabel : expandLabel;
4752
- const ExpandActionIcon = hasExpandedToggle && expanded ? Minimize2Icon : Maximize2Icon;
4753
- return /* @__PURE__ */ jsx29(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs27(
4754
- SheetContent,
4755
- {
4756
- "data-slot": "sheet-drawer-content",
4757
- side: "right",
4758
- mobileSide: "bottom",
4759
- motion,
4760
- showCloseButton: false,
4761
- className: cn(
4762
- sheetDrawerContentClassName,
4763
- resolvedWidth === "wide" && sheetDrawerWideContentClassName,
4764
- resolvedWidth === "full" && sheetDrawerFullContentClassName
4765
- ),
4766
- children: [
4767
- /* @__PURE__ */ jsxs27("div", { "data-slot": "sheet-drawer-header", className: sheetDrawerHeaderClassName, children: [
4768
- /* @__PURE__ */ jsxs27("div", { className: sheetDrawerHeaderTextClassName, children: [
4769
- caption ? /* @__PURE__ */ jsx29("div", { "data-slot": "sheet-drawer-caption", className: sheetDrawerCaptionClassName, children: caption }) : null,
4770
- /* @__PURE__ */ jsx29(SheetTitle, { "data-slot": "sheet-drawer-title", className: sheetDrawerTitleClassName, children: title2 }),
4771
- description ? /* @__PURE__ */ jsx29(
4772
- SheetDescription,
4773
- {
4774
- "data-slot": "sheet-drawer-description",
4775
- className: sheetDrawerDescriptionClassName,
4776
- children: description
4777
- }
4778
- ) : null
4779
- ] }),
4780
- /* @__PURE__ */ jsxs27("div", { "data-slot": "sheet-drawer-header-actions", className: sheetDrawerHeaderActionsClassName, children: [
4781
- showExpandAction ? hasExpandedToggle ? /* @__PURE__ */ jsxs27(
4782
- "button",
4783
- {
4784
- type: "button",
4785
- "aria-label": resolvedExpandLabel,
4786
- "aria-pressed": expanded,
4787
- "data-slot": "sheet-drawer-expand",
4788
- "data-expanded": expanded ? "true" : "false",
4789
- className: sheetDrawerExpandButtonClassName,
4790
- onClick: () => onExpandedChange(!expanded),
4791
- children: [
4792
- /* @__PURE__ */ jsx29(ExpandActionIcon, { className: "size-[16px]" }),
4793
- /* @__PURE__ */ jsx29("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: resolvedExpandLabel })
4794
- ]
4795
- }
4796
- ) : expandHref ? /* @__PURE__ */ jsxs27(
4797
- "a",
4798
- {
4799
- href: expandHref,
4800
- "aria-label": expandLabel,
4801
- "data-slot": "sheet-drawer-expand",
4802
- className: sheetDrawerExpandButtonClassName,
4803
- children: [
4804
- /* @__PURE__ */ jsx29(ExpandActionIcon, { className: "size-[16px]" }),
4805
- /* @__PURE__ */ jsx29("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: expandLabel })
4806
- ]
4807
- }
4808
- ) : /* @__PURE__ */ jsxs27(
4809
- "button",
4810
- {
4811
- type: "button",
4812
- "aria-label": expandLabel,
4813
- "data-slot": "sheet-drawer-expand",
4814
- className: sheetDrawerExpandButtonClassName,
4815
- onClick: onExpand,
4816
- children: [
4817
- /* @__PURE__ */ jsx29(ExpandActionIcon, { className: "size-[16px]" }),
4818
- /* @__PURE__ */ jsx29("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: expandLabel })
4819
- ]
4820
- }
4821
- ) : null,
4822
- /* @__PURE__ */ jsx29(OverlayCloseButton, { label: closeLabel })
4823
- ] })
4824
- ] }),
4825
- /* @__PURE__ */ jsx29("div", { "data-slot": "sheet-drawer-body", className: sheetDrawerBodyClassName, children }),
4826
- footer ? /* @__PURE__ */ jsx29("div", { "data-slot": "sheet-drawer-footer", className: sheetDrawerFooterClassName, children: footer }) : null
4827
- ]
4828
- }
4829
- ) });
4830
- }
5251
+ className: cn(popoverArrowClassName, className),
5252
+ width: 11,
5253
+ height: 5,
5254
+ ...props
5255
+ }
5256
+ ));
5257
+ PopoverArrow.displayName = PopoverPrimitive.Arrow.displayName;
4831
5258
 
4832
5259
  // src/components/ui/filter-toolbar.tsx
4833
- import { Fragment as Fragment7, jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
5260
+ import { Fragment as Fragment9, jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
4834
5261
  var collapsibleClassNames = {
4835
5262
  sm: {
4836
5263
  inline: "hidden @[640px]:flex",
@@ -4849,7 +5276,7 @@ var collapsibleClassNames = {
4849
5276
  trigger: "hidden"
4850
5277
  }
4851
5278
  };
4852
- var FilterToolbar = React26.forwardRef(
5279
+ var FilterToolbar = React29.forwardRef(
4853
5280
  ({
4854
5281
  className,
4855
5282
  search,
@@ -4864,15 +5291,15 @@ var FilterToolbar = React26.forwardRef(
4864
5291
  actions,
4865
5292
  ...props
4866
5293
  }, ref) => {
4867
- const [rootElement, setRootElement] = React26.useState(
5294
+ const [rootElement, setRootElement] = React29.useState(
4868
5295
  null
4869
5296
  );
4870
- const [containerWidth, setContainerWidth] = React26.useState(
5297
+ const [containerWidth, setContainerWidth] = React29.useState(
4871
5298
  null
4872
5299
  );
4873
- const [overlayOpen, setOverlayOpen] = React26.useState(false);
4874
- const triggerRef = React26.useRef(null);
4875
- const setRootRefs = React26.useCallback(
5300
+ const [overlayOpen, setOverlayOpen] = React29.useState(false);
5301
+ const triggerRef = React29.useRef(null);
5302
+ const setRootRefs = React29.useCallback(
4876
5303
  (element) => {
4877
5304
  setRootElement(element);
4878
5305
  if (typeof ref === "function") ref(element);
@@ -4880,7 +5307,7 @@ var FilterToolbar = React26.forwardRef(
4880
5307
  },
4881
5308
  [ref]
4882
5309
  );
4883
- React26.useEffect(() => {
5310
+ React29.useEffect(() => {
4884
5311
  if (!rootElement) return;
4885
5312
  const updateWidth = () => {
4886
5313
  setContainerWidth(rootElement.getBoundingClientRect().width);
@@ -4891,7 +5318,7 @@ var FilterToolbar = React26.forwardRef(
4891
5318
  observer.observe(rootElement);
4892
5319
  return () => observer.disconnect();
4893
5320
  }, [rootElement]);
4894
- const handleOverlayOpenChange = React26.useCallback((open) => {
5321
+ const handleOverlayOpenChange = React29.useCallback((open) => {
4895
5322
  setOverlayOpen(open);
4896
5323
  if (!open) queueMicrotask(() => triggerRef.current?.focus());
4897
5324
  }, []);
@@ -4901,7 +5328,7 @@ var FilterToolbar = React26.forwardRef(
4901
5328
  const usesSheet = containerWidth !== null && containerWidth < 640;
4902
5329
  const collapseClasses = collapsibleClassNames[collapseBelow];
4903
5330
  const collapseTriggerLabel = hasAppliedFilters ? `${collapsedLabel}, ${activeFilterCount}\uAC1C \uC801\uC6A9` : collapsedLabel;
4904
- const clearFiltersButton = onClearFilters ? /* @__PURE__ */ jsx30(
5331
+ const clearFiltersButton = onClearFilters ? /* @__PURE__ */ jsx32(
4905
5332
  "button",
4906
5333
  {
4907
5334
  type: "button",
@@ -4911,7 +5338,7 @@ var FilterToolbar = React26.forwardRef(
4911
5338
  children: "\uD574\uC81C"
4912
5339
  }
4913
5340
  ) : null;
4914
- const collapsedContent = collapsible ? /* @__PURE__ */ jsx30(
5341
+ const collapsedContent = collapsible ? /* @__PURE__ */ jsx32(
4915
5342
  "div",
4916
5343
  {
4917
5344
  "data-slot": "filter-toolbar-collapsed-content",
@@ -4928,7 +5355,7 @@ var FilterToolbar = React26.forwardRef(
4928
5355
  collapseClasses.trigger
4929
5356
  ),
4930
5357
  children: [
4931
- /* @__PURE__ */ jsx30(
5358
+ /* @__PURE__ */ jsx32(
4932
5359
  IconButton,
4933
5360
  {
4934
5361
  ref: triggerRef,
@@ -4939,7 +5366,7 @@ var FilterToolbar = React26.forwardRef(
4939
5366
  onClick: () => handleOverlayOpenChange(true)
4940
5367
  }
4941
5368
  ),
4942
- hasAppliedFilters ? /* @__PURE__ */ jsx30(
5369
+ hasAppliedFilters ? /* @__PURE__ */ jsx32(
4943
5370
  "span",
4944
5371
  {
4945
5372
  "aria-hidden": "true",
@@ -4971,7 +5398,7 @@ var FilterToolbar = React26.forwardRef(
4971
5398
  "data-slot": "filter-toolbar-row",
4972
5399
  className: "flex min-h-[32px] w-full flex-wrap items-center justify-start gap-x-[var(--space-2)] gap-y-[var(--space-2)]",
4973
5400
  children: [
4974
- search ? /* @__PURE__ */ jsx30(
5401
+ search ? /* @__PURE__ */ jsx32(
4975
5402
  "div",
4976
5403
  {
4977
5404
  "data-slot": "filter-toolbar-search",
@@ -4981,7 +5408,7 @@ var FilterToolbar = React26.forwardRef(
4981
5408
  ) : null,
4982
5409
  collapsible && usesSheet ? collapseTrigger : null,
4983
5410
  collapsible && !usesSheet ? /* @__PURE__ */ jsxs28(Popover, { open: overlayOpen, onOpenChange: handleOverlayOpenChange, children: [
4984
- /* @__PURE__ */ jsx30(PopoverAnchor, { asChild: true, children: collapseTrigger }),
5411
+ /* @__PURE__ */ jsx32(PopoverAnchor, { asChild: true, children: collapseTrigger }),
4985
5412
  overlayOpen ? /* @__PURE__ */ jsxs28(
4986
5413
  PopoverContent,
4987
5414
  {
@@ -4991,14 +5418,14 @@ var FilterToolbar = React26.forwardRef(
4991
5418
  align: "start",
4992
5419
  className: "w-[320px]",
4993
5420
  children: [
4994
- /* @__PURE__ */ jsx30("div", { className: "mb-[var(--space-3)] text-sm font-semibold", children: "\uD544\uD130" }),
5421
+ /* @__PURE__ */ jsx32("div", { className: "mb-[var(--space-3)] text-sm font-semibold", children: "\uD544\uD130" }),
4995
5422
  collapsedContent,
4996
- clearFiltersButton ? /* @__PURE__ */ jsx30("div", { className: "mt-[var(--space-4)] flex justify-end", children: clearFiltersButton }) : null
5423
+ clearFiltersButton ? /* @__PURE__ */ jsx32("div", { className: "mt-[var(--space-4)] flex justify-end", children: clearFiltersButton }) : null
4997
5424
  ]
4998
5425
  }
4999
5426
  ) : null
5000
5427
  ] }) : null,
5001
- filters ? /* @__PURE__ */ jsx30(
5428
+ filters ? /* @__PURE__ */ jsx32(
5002
5429
  "div",
5003
5430
  {
5004
5431
  "data-slot": "filter-toolbar-filters",
@@ -5006,7 +5433,7 @@ var FilterToolbar = React26.forwardRef(
5006
5433
  children: filters
5007
5434
  }
5008
5435
  ) : null,
5009
- collapsible && !overlayOpen ? /* @__PURE__ */ jsx30(
5436
+ collapsible && !overlayOpen ? /* @__PURE__ */ jsx32(
5010
5437
  "div",
5011
5438
  {
5012
5439
  "data-slot": "filter-toolbar-collapsible",
@@ -5020,8 +5447,8 @@ var FilterToolbar = React26.forwardRef(
5020
5447
  ]
5021
5448
  }
5022
5449
  ) : null,
5023
- collapsible && usesSheet && overlayOpen ? /* @__PURE__ */ jsx30(
5024
- SheetDrawer,
5450
+ collapsible && usesSheet && overlayOpen ? /* @__PURE__ */ jsx32(
5451
+ Sheet,
5025
5452
  {
5026
5453
  open: overlayOpen,
5027
5454
  onOpenChange: handleOverlayOpenChange,
@@ -5041,9 +5468,9 @@ var FilterToolbar = React26.forwardRef(
5041
5468
  activeFilterCount,
5042
5469
  "\uAC1C \uC801\uC6A9"
5043
5470
  ] }),
5044
- onClearFilters ? /* @__PURE__ */ jsxs28(Fragment7, { children: [
5045
- /* @__PURE__ */ jsx30("span", { "aria-hidden": "true", children: " \xB7 " }),
5046
- /* @__PURE__ */ jsx30(
5471
+ onClearFilters ? /* @__PURE__ */ jsxs28(Fragment9, { children: [
5472
+ /* @__PURE__ */ jsx32("span", { "aria-hidden": "true", children: " \xB7 " }),
5473
+ /* @__PURE__ */ jsx32(
5047
5474
  "button",
5048
5475
  {
5049
5476
  type: "button",
@@ -5062,7 +5489,7 @@ var FilterToolbar = React26.forwardRef(
5062
5489
  "data-slot": "filter-toolbar-meta",
5063
5490
  className: "flex min-w-0 flex-wrap items-center justify-end gap-[var(--space-2)]",
5064
5491
  children: [
5065
- resultSummary ? /* @__PURE__ */ jsx30(
5492
+ resultSummary ? /* @__PURE__ */ jsx32(
5066
5493
  "div",
5067
5494
  {
5068
5495
  "data-slot": "filter-toolbar-summary",
@@ -5070,8 +5497,8 @@ var FilterToolbar = React26.forwardRef(
5070
5497
  children: resultSummary
5071
5498
  }
5072
5499
  ) : null,
5073
- clearAction ? /* @__PURE__ */ jsx30("div", { "data-slot": "filter-toolbar-clear", className: "shrink-0", children: clearAction }) : null,
5074
- actions ? /* @__PURE__ */ jsx30(
5500
+ clearAction ? /* @__PURE__ */ jsx32("div", { "data-slot": "filter-toolbar-clear", className: "shrink-0", children: clearAction }) : null,
5501
+ actions ? /* @__PURE__ */ jsx32(
5075
5502
  "div",
5076
5503
  {
5077
5504
  "data-slot": "filter-toolbar-actions",
@@ -5090,16 +5517,16 @@ var FilterToolbar = React26.forwardRef(
5090
5517
  FilterToolbar.displayName = "FilterToolbar";
5091
5518
 
5092
5519
  // src/components/ui/data-table.tsx
5093
- import * as React28 from "react";
5520
+ import * as React31 from "react";
5094
5521
  import { ChevronDown as ChevronDown3, ChevronUp as ChevronUp2, ChevronsUpDown } from "lucide-react";
5095
5522
  import { cva as cva12 } from "class-variance-authority";
5096
5523
 
5097
5524
  // src/components/ui/checkbox.tsx
5098
- import * as React27 from "react";
5525
+ import * as React30 from "react";
5099
5526
  import { cva as cva11 } from "class-variance-authority";
5100
5527
  import { Check as Check3, Minus } from "lucide-react";
5101
5528
  import { Checkbox as CheckboxPrimitive } from "radix-ui";
5102
- import { jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
5529
+ import { jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
5103
5530
  var checkboxFieldVariants = cva11(
5104
5531
  "flex flex-col gap-[var(--space-1)]",
5105
5532
  {
@@ -5202,11 +5629,11 @@ var checkboxGroupBoxVariants = cva11(
5202
5629
  }
5203
5630
  }
5204
5631
  );
5205
- var CheckboxGroupContext = React27.createContext(null);
5632
+ var CheckboxGroupContext = React30.createContext(null);
5206
5633
  function getLabel(children, label) {
5207
5634
  return children ?? label;
5208
5635
  }
5209
- var Checkbox = React27.forwardRef(
5636
+ var Checkbox = React30.forwardRef(
5210
5637
  ({
5211
5638
  className,
5212
5639
  size = "md",
@@ -5224,8 +5651,8 @@ var Checkbox = React27.forwardRef(
5224
5651
  onCheckedChange,
5225
5652
  ...props
5226
5653
  }, ref) => {
5227
- const group = React27.useContext(CheckboxGroupContext);
5228
- const generatedId = React27.useId();
5654
+ const group = React30.useContext(CheckboxGroupContext);
5655
+ const generatedId = React30.useId();
5229
5656
  const checkboxId = id ?? generatedId;
5230
5657
  const labelContent = getLabel(children, label);
5231
5658
  const isGrouped = Boolean(group && value != null);
@@ -5267,7 +5694,7 @@ var Checkbox = React27.forwardRef(
5267
5694
  onCheckedChange: handleCheckedChange,
5268
5695
  ...props,
5269
5696
  children: [
5270
- /* @__PURE__ */ jsx31(
5697
+ /* @__PURE__ */ jsx33(
5271
5698
  "span",
5272
5699
  {
5273
5700
  "aria-hidden": "true",
@@ -5276,12 +5703,12 @@ var Checkbox = React27.forwardRef(
5276
5703
  checkboxBoxVariants({ size }),
5277
5704
  checkboxGroupBoxVariants({ appearance })
5278
5705
  ),
5279
- children: /* @__PURE__ */ jsx31(
5706
+ children: /* @__PURE__ */ jsx33(
5280
5707
  CheckboxPrimitive.Indicator,
5281
5708
  {
5282
5709
  "data-slot": "checkbox-indicator",
5283
5710
  className: "flex items-center justify-center",
5284
- children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx31(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx31(Check3, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 })
5711
+ children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx33(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx33(Check3, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 })
5285
5712
  }
5286
5713
  )
5287
5714
  }
@@ -5295,7 +5722,7 @@ var Checkbox = React27.forwardRef(
5295
5722
  className: "text-sm font-medium leading-snug text-foreground group-disabled:text-text-disabled",
5296
5723
  children: [
5297
5724
  labelContent,
5298
- required ? /* @__PURE__ */ jsx31(
5725
+ required ? /* @__PURE__ */ jsx33(
5299
5726
  "span",
5300
5727
  {
5301
5728
  "aria-hidden": "true",
@@ -5307,7 +5734,7 @@ var Checkbox = React27.forwardRef(
5307
5734
  ]
5308
5735
  }
5309
5736
  ),
5310
- error ? /* @__PURE__ */ jsx31(
5737
+ error ? /* @__PURE__ */ jsx33(
5311
5738
  "span",
5312
5739
  {
5313
5740
  id: errorId,
@@ -5316,7 +5743,7 @@ var Checkbox = React27.forwardRef(
5316
5743
  className: "text-xs font-medium leading-normal text-[var(--error)]",
5317
5744
  children: error
5318
5745
  }
5319
- ) : description ? /* @__PURE__ */ jsx31(
5746
+ ) : description ? /* @__PURE__ */ jsx33(
5320
5747
  "span",
5321
5748
  {
5322
5749
  id: descriptionId,
@@ -5343,7 +5770,7 @@ var Checkbox = React27.forwardRef(
5343
5770
  className: checkboxFieldVariants({ fullWidth }),
5344
5771
  children: [
5345
5772
  /* @__PURE__ */ jsxs29("div", { className: "inline-flex items-center gap-[var(--space-3)]", children: [
5346
- /* @__PURE__ */ jsx31(
5773
+ /* @__PURE__ */ jsx33(
5347
5774
  CheckboxPrimitive.Root,
5348
5775
  {
5349
5776
  ref,
@@ -5359,18 +5786,18 @@ var Checkbox = React27.forwardRef(
5359
5786
  className: cn(checkboxRootVariants(), className),
5360
5787
  onCheckedChange: handleCheckedChange,
5361
5788
  ...props,
5362
- children: /* @__PURE__ */ jsx31(
5789
+ children: /* @__PURE__ */ jsx33(
5363
5790
  "span",
5364
5791
  {
5365
5792
  "aria-hidden": "true",
5366
5793
  "data-slot": "checkbox-box",
5367
5794
  className: checkboxBoxVariants({ size }),
5368
- children: /* @__PURE__ */ jsx31(
5795
+ children: /* @__PURE__ */ jsx33(
5369
5796
  CheckboxPrimitive.Indicator,
5370
5797
  {
5371
5798
  "data-slot": "checkbox-indicator",
5372
5799
  className: "flex items-center justify-center",
5373
- children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx31(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx31(Check3, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 })
5800
+ children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx33(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx33(Check3, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 })
5374
5801
  }
5375
5802
  )
5376
5803
  }
@@ -5386,7 +5813,7 @@ var Checkbox = React27.forwardRef(
5386
5813
  className: labelClassName,
5387
5814
  children: [
5388
5815
  labelContent,
5389
- required ? /* @__PURE__ */ jsx31(
5816
+ required ? /* @__PURE__ */ jsx33(
5390
5817
  "span",
5391
5818
  {
5392
5819
  "aria-hidden": "true",
@@ -5399,7 +5826,7 @@ var Checkbox = React27.forwardRef(
5399
5826
  }
5400
5827
  ) : null
5401
5828
  ] }),
5402
- error ? /* @__PURE__ */ jsx31(
5829
+ error ? /* @__PURE__ */ jsx33(
5403
5830
  "p",
5404
5831
  {
5405
5832
  id: errorId,
@@ -5408,7 +5835,7 @@ var Checkbox = React27.forwardRef(
5408
5835
  className: "ml-[32px] text-xs font-medium leading-normal text-[var(--error)]",
5409
5836
  children: error
5410
5837
  }
5411
- ) : description ? /* @__PURE__ */ jsx31(
5838
+ ) : description ? /* @__PURE__ */ jsx33(
5412
5839
  "p",
5413
5840
  {
5414
5841
  id: descriptionId,
@@ -5428,7 +5855,7 @@ var Checkbox = React27.forwardRef(
5428
5855
  Checkbox.displayName = "Checkbox";
5429
5856
 
5430
5857
  // src/components/ui/data-table.tsx
5431
- import { jsx as jsx32, jsxs as jsxs30 } from "react/jsx-runtime";
5858
+ import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
5432
5859
  var dataTableVariants = cva12(
5433
5860
  [
5434
5861
  "relative overflow-hidden rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
@@ -5491,7 +5918,7 @@ function getRenderedCell(row, column) {
5491
5918
  if (value === null || value === void 0) {
5492
5919
  return null;
5493
5920
  }
5494
- if (React28.isValidElement(value)) {
5921
+ if (React31.isValidElement(value)) {
5495
5922
  return value;
5496
5923
  }
5497
5924
  return String(value);
@@ -5531,7 +5958,7 @@ function isInteractiveTarget(target) {
5531
5958
  function SortIcon({ sort, columnKey }) {
5532
5959
  const isActive = sort?.key === columnKey;
5533
5960
  if (!isActive) {
5534
- return /* @__PURE__ */ jsx32(
5961
+ return /* @__PURE__ */ jsx34(
5535
5962
  ChevronsUpDown,
5536
5963
  {
5537
5964
  "aria-hidden": "true",
@@ -5543,7 +5970,7 @@ function SortIcon({ sort, columnKey }) {
5543
5970
  );
5544
5971
  }
5545
5972
  const Icon = sort.dir === "asc" ? ChevronUp2 : ChevronDown3;
5546
- return /* @__PURE__ */ jsx32(
5973
+ return /* @__PURE__ */ jsx34(
5547
5974
  Icon,
5548
5975
  {
5549
5976
  "aria-hidden": "true",
@@ -5577,11 +6004,11 @@ function MobileSortControls({
5577
6004
  surfaceClassNames[surface]
5578
6005
  ),
5579
6006
  children: [
5580
- /* @__PURE__ */ jsx32("span", { className: "text-[12px] font-medium text-text-tertiary", children: "\uC815\uB82C" }),
6007
+ /* @__PURE__ */ jsx34("span", { className: "text-[12px] font-medium text-text-tertiary", children: "\uC815\uB82C" }),
5581
6008
  sortableColumns.map((column) => {
5582
6009
  const active = sortBy?.key === column.key;
5583
6010
  const nextSort = getNextSort(sortBy, column.key);
5584
- return /* @__PURE__ */ jsx32(
6011
+ return /* @__PURE__ */ jsx34(
5585
6012
  Button,
5586
6013
  {
5587
6014
  type: "button",
@@ -5592,8 +6019,8 @@ function MobileSortControls({
5592
6019
  className: active ? "border-[var(--border-strong)] bg-[var(--action-selected)] hover:border-[var(--border-strong)] hover:bg-[var(--action-selected)]" : void 0,
5593
6020
  onClick: () => onSortChange?.(column.key, nextSort),
5594
6021
  children: /* @__PURE__ */ jsxs30("span", { className: "inline-flex min-w-0 items-center gap-[var(--space-1)]", children: [
5595
- /* @__PURE__ */ jsx32("span", { className: "truncate", children: column.header }),
5596
- /* @__PURE__ */ jsx32(SortIcon, { sort: sortBy, columnKey: column.key })
6022
+ /* @__PURE__ */ jsx34("span", { className: "truncate", children: column.header }),
6023
+ /* @__PURE__ */ jsx34(SortIcon, { sort: sortBy, columnKey: column.key })
5597
6024
  ] })
5598
6025
  },
5599
6026
  column.key
@@ -5614,7 +6041,7 @@ function SkeletonRows({
5614
6041
  // 로딩 알림은 그 안의 row/cell 안에 둔다 — 종전에는 컨테이너가 role="status"라
5615
6042
  // aria-required-children(Critical)이 났다.
5616
6043
  /* @__PURE__ */ jsxs30("div", { role: "rowgroup", children: [
5617
- /* @__PURE__ */ jsx32("div", { role: "row", children: /* @__PURE__ */ jsx32("div", { role: "cell", "aria-colindex": 1, "aria-label": "\uB370\uC774\uD130 \uB85C\uB4DC \uC911", children: /* @__PURE__ */ jsx32("span", { role: "status", className: "sr-only", children: "\uB370\uC774\uD130 \uB85C\uB4DC \uC911" }) }) }),
6044
+ /* @__PURE__ */ jsx34("div", { role: "row", children: /* @__PURE__ */ jsx34("div", { role: "cell", "aria-colindex": 1, "aria-label": "\uB370\uC774\uD130 \uB85C\uB4DC \uC911", children: /* @__PURE__ */ jsx34("span", { role: "status", className: "sr-only", children: "\uB370\uC774\uD130 \uB85C\uB4DC \uC911" }) }) }),
5618
6045
  Array.from({ length: count }, (_, rowIndex) => /* @__PURE__ */ jsxs30(
5619
6046
  "div",
5620
6047
  {
@@ -5622,8 +6049,8 @@ function SkeletonRows({
5622
6049
  className: "grid min-h-[48px] items-center border-t border-[var(--border-subtle)]",
5623
6050
  style: { gridTemplateColumns },
5624
6051
  children: [
5625
- selectable ? /* @__PURE__ */ jsx32("div", { "aria-hidden": "true", className: "px-[var(--space-4)]" }) : null,
5626
- columns.map((column, columnIndex) => /* @__PURE__ */ jsx32("div", { className: "px-[var(--space-4)] py-[var(--space-2)]", children: /* @__PURE__ */ jsx32(
6052
+ selectable ? /* @__PURE__ */ jsx34("div", { "aria-hidden": "true", className: "px-[var(--space-4)]" }) : null,
6053
+ columns.map((column, columnIndex) => /* @__PURE__ */ jsx34("div", { className: "px-[var(--space-4)] py-[var(--space-2)]", children: /* @__PURE__ */ jsx34(
5627
6054
  "div",
5628
6055
  {
5629
6056
  className: cn(
@@ -5640,7 +6067,7 @@ function SkeletonRows({
5640
6067
  );
5641
6068
  }
5642
6069
  function MobileSkeletonCards({ count }) {
5643
- return /* @__PURE__ */ jsx32(
6070
+ return /* @__PURE__ */ jsx34(
5644
6071
  "div",
5645
6072
  {
5646
6073
  "data-slot": "data-table-mobile-skeleton",
@@ -5653,9 +6080,9 @@ function MobileSkeletonCards({ count }) {
5653
6080
  "data-slot": "data-table-mobile-skeleton-card",
5654
6081
  className: "flex flex-col gap-[var(--space-2)] border-t border-[var(--border-subtle)] px-[var(--space-4)] py-[var(--space-4)]",
5655
6082
  children: [
5656
- /* @__PURE__ */ jsx32("div", { className: "h-[14px] w-[72%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-inset)]" }),
5657
- /* @__PURE__ */ jsx32("div", { className: "h-[12px] w-[56%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-inset)]" }),
5658
- /* @__PURE__ */ jsx32("div", { className: "h-[12px] w-[64%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-inset)]" })
6083
+ /* @__PURE__ */ jsx34("div", { className: "h-[14px] w-[72%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-inset)]" }),
6084
+ /* @__PURE__ */ jsx34("div", { className: "h-[12px] w-[56%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-inset)]" }),
6085
+ /* @__PURE__ */ jsx34("div", { className: "h-[12px] w-[64%] animate-pulse rounded-[var(--radius-sm)] bg-[var(--bg-inset)]" })
5659
6086
  ]
5660
6087
  },
5661
6088
  rowIndex
@@ -5723,7 +6150,7 @@ function DataTableRowView({
5723
6150
  onClick: handlers.onClick,
5724
6151
  onKeyDown: handlers.onKeyDown,
5725
6152
  children: [
5726
- selectable ? /* @__PURE__ */ jsx32("div", { role: "cell", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx32(
6153
+ selectable ? /* @__PURE__ */ jsx34("div", { role: "cell", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx34(
5727
6154
  Checkbox,
5728
6155
  {
5729
6156
  "aria-label": `${String(row[columns[0]?.key] ?? rowId)} \uD589 \uC120\uD0DD`,
@@ -5738,7 +6165,7 @@ function DataTableRowView({
5738
6165
  columns.map((column, columnIndex) => {
5739
6166
  const align = column.align ?? "left";
5740
6167
  const content = getRenderedCell(row, column);
5741
- return /* @__PURE__ */ jsx32(
6168
+ return /* @__PURE__ */ jsx34(
5742
6169
  "div",
5743
6170
  {
5744
6171
  "data-slot": "data-table-cell",
@@ -5749,7 +6176,7 @@ function DataTableRowView({
5749
6176
  column.tabular ? "font-[family-name:var(--font-display)] tabular-nums" : null,
5750
6177
  align === "right" ? "text-text-tertiary" : null
5751
6178
  ),
5752
- children: /* @__PURE__ */ jsx32("span", { className: "min-w-0 truncate", children: linked && columnIndex === 0 && LinkComponent ? /* @__PURE__ */ jsx32(LinkComponent, { href, "data-slot": "data-table-row-link", className: rowLinkClass, children: content }) : content })
6179
+ children: /* @__PURE__ */ jsx34("span", { className: "min-w-0 truncate", children: linked && columnIndex === 0 && LinkComponent ? /* @__PURE__ */ jsx34(LinkComponent, { href, "data-slot": "data-table-row-link", className: rowLinkClass, children: content }) : content })
5753
6180
  },
5754
6181
  column.key
5755
6182
  );
@@ -5804,7 +6231,7 @@ function DataTableMobileCardView({
5804
6231
  onKeyDown: handlers.onKeyDown,
5805
6232
  children: [
5806
6233
  /* @__PURE__ */ jsxs30("div", { className: "flex min-w-0 items-start gap-[var(--space-3)]", children: [
5807
- selectable ? /* @__PURE__ */ jsx32("div", { "data-slot": "data-table-mobile-card-select", className: "shrink-0 pt-[2px]", children: /* @__PURE__ */ jsx32(
6234
+ selectable ? /* @__PURE__ */ jsx34("div", { "data-slot": "data-table-mobile-card-select", className: "shrink-0 pt-[2px]", children: /* @__PURE__ */ jsx34(
5808
6235
  Checkbox,
5809
6236
  {
5810
6237
  "aria-label": `${primaryText} \uBAA8\uBC14\uC77C \uCE74\uB4DC \uC120\uD0DD`,
@@ -5816,16 +6243,16 @@ function DataTableMobileCardView({
5816
6243
  ] })
5817
6244
  }
5818
6245
  ) }) : null,
5819
- /* @__PURE__ */ jsx32(
6246
+ /* @__PURE__ */ jsx34(
5820
6247
  "div",
5821
6248
  {
5822
6249
  "data-slot": "data-table-mobile-card-primary",
5823
6250
  className: "min-w-0 flex-1 font-medium text-foreground",
5824
- children: linked && LinkComponent ? /* @__PURE__ */ jsx32(LinkComponent, { href, "data-slot": "data-table-row-link", className: rowLinkClass, children: primaryContent }) : primaryContent
6251
+ children: linked && LinkComponent ? /* @__PURE__ */ jsx34(LinkComponent, { href, "data-slot": "data-table-row-link", className: rowLinkClass, children: primaryContent }) : primaryContent
5825
6252
  }
5826
6253
  )
5827
6254
  ] }),
5828
- secondaryColumns.length > 0 ? /* @__PURE__ */ jsx32("dl", { className: "grid min-w-0 gap-[var(--space-2)]", children: secondaryColumns.map((column) => {
6255
+ secondaryColumns.length > 0 ? /* @__PURE__ */ jsx34("dl", { className: "grid min-w-0 gap-[var(--space-2)]", children: secondaryColumns.map((column) => {
5829
6256
  const align = column.align ?? "left";
5830
6257
  return /* @__PURE__ */ jsxs30(
5831
6258
  "div",
@@ -5833,8 +6260,8 @@ function DataTableMobileCardView({
5833
6260
  "data-slot": "data-table-mobile-card-field",
5834
6261
  className: "grid min-w-0 grid-cols-[minmax(0,0.42fr)_minmax(0,1fr)] gap-[var(--space-2)] text-[12px] leading-snug",
5835
6262
  children: [
5836
- /* @__PURE__ */ jsx32("dt", { className: "min-w-0 text-text-tertiary", children: /* @__PURE__ */ jsx32("span", { className: "truncate", children: column.header }) }),
5837
- /* @__PURE__ */ jsx32(
6263
+ /* @__PURE__ */ jsx34("dt", { className: "min-w-0 text-text-tertiary", children: /* @__PURE__ */ jsx34("span", { className: "truncate", children: column.header }) }),
6264
+ /* @__PURE__ */ jsx34(
5838
6265
  "dd",
5839
6266
  {
5840
6267
  className: cn(
@@ -5842,7 +6269,7 @@ function DataTableMobileCardView({
5842
6269
  alignmentClass[align],
5843
6270
  column.tabular ? "font-[family-name:var(--font-display)] tabular-nums" : null
5844
6271
  ),
5845
- children: /* @__PURE__ */ jsx32("span", { className: "min-w-0 truncate", children: getRenderedCell(row, column) })
6272
+ children: /* @__PURE__ */ jsx34("span", { className: "min-w-0 truncate", children: getRenderedCell(row, column) })
5846
6273
  }
5847
6274
  )
5848
6275
  ]
@@ -5854,9 +6281,9 @@ function DataTableMobileCardView({
5854
6281
  }
5855
6282
  );
5856
6283
  }
5857
- var MemoDataTableRow = React28.memo(DataTableRowView);
5858
- var MemoDataTableMobileCard = React28.memo(DataTableMobileCardView);
5859
- var useIsomorphicLayoutEffect = typeof window === "undefined" ? React28.useEffect : React28.useLayoutEffect;
6284
+ var MemoDataTableRow = React31.memo(DataTableRowView);
6285
+ var MemoDataTableMobileCard = React31.memo(DataTableMobileCardView);
6286
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? React31.useEffect : React31.useLayoutEffect;
5860
6287
  var VIRTUAL_DEFAULT_OVERSCAN = 8;
5861
6288
  var VIRTUAL_INITIAL_ROWS = 24;
5862
6289
  var VIRTUAL_FALLBACK_SIZE = { desktop: 48, mobile: 120 };
@@ -5879,16 +6306,16 @@ function useVirtualWindow({
5879
6306
  desktopListRef,
5880
6307
  mobileListRef
5881
6308
  }) {
5882
- const [win, setWin] = React28.useState({
6309
+ const [win, setWin] = React31.useState({
5883
6310
  layout: null,
5884
6311
  start: 0,
5885
6312
  end: VIRTUAL_INITIAL_ROWS,
5886
6313
  size: 0
5887
6314
  });
5888
- const measuredSize = React28.useRef({ desktop: 0, mobile: 0 });
5889
- const update = React28.useRef(() => void 0);
5890
- const reported = React28.useRef("");
5891
- const latest = React28.useRef({ count, layout: "desktop" });
6315
+ const measuredSize = React31.useRef({ desktop: 0, mobile: 0 });
6316
+ const update = React31.useRef(() => void 0);
6317
+ const reported = React31.useRef("");
6318
+ const latest = React31.useRef({ count, layout: "desktop" });
5892
6319
  update.current = () => {
5893
6320
  if (!enabled) {
5894
6321
  return;
@@ -5935,7 +6362,7 @@ function useVirtualWindow({
5935
6362
  useIsomorphicLayoutEffect(() => {
5936
6363
  update.current();
5937
6364
  });
5938
- React28.useEffect(() => {
6365
+ React31.useEffect(() => {
5939
6366
  if (!enabled) {
5940
6367
  return;
5941
6368
  }
@@ -5957,7 +6384,7 @@ function useVirtualWindow({
5957
6384
  window.cancelAnimationFrame(frame);
5958
6385
  };
5959
6386
  }, [enabled]);
5960
- const scrollToIndex = React28.useCallback(
6387
+ const scrollToIndex = React31.useCallback(
5961
6388
  (index) => {
5962
6389
  const { count: rowCount, layout } = latest.current;
5963
6390
  const list = (layout === "desktop" ? desktopListRef : mobileListRef).current;
@@ -6014,10 +6441,10 @@ function DataTableInner({
6014
6441
  }, ref) {
6015
6442
  const virtualOptions = virtual ? virtual === true ? {} : virtual : null;
6016
6443
  const isVirtual = virtualOptions !== null;
6017
- const desktopRef = React28.useRef(null);
6018
- const headerRef = React28.useRef(null);
6019
- const desktopListRef = React28.useRef(null);
6020
- const mobileListRef = React28.useRef(null);
6444
+ const desktopRef = React31.useRef(null);
6445
+ const headerRef = React31.useRef(null);
6446
+ const desktopListRef = React31.useRef(null);
6447
+ const mobileListRef = React31.useRef(null);
6021
6448
  const { win: virtualWindow, scrollToIndex } = useVirtualWindow({
6022
6449
  enabled: isVirtual,
6023
6450
  count: data.length,
@@ -6028,7 +6455,7 @@ function DataTableInner({
6028
6455
  desktopListRef,
6029
6456
  mobileListRef
6030
6457
  });
6031
- React28.useImperativeHandle(virtualOptions?.handleRef, () => ({ scrollToIndex }), [scrollToIndex]);
6458
+ React31.useImperativeHandle(virtualOptions?.handleRef, () => ({ scrollToIndex }), [scrollToIndex]);
6032
6459
  const resolvedSelectedIds = selectedIds ?? /* @__PURE__ */ new Set();
6033
6460
  const rowIds = data.map((row) => getRowId(row, keyField));
6034
6461
  const selectedCount = rowIds.filter((id) => resolvedSelectedIds.has(id)).length;
@@ -6063,19 +6490,19 @@ function DataTableInner({
6063
6490
  window.location.assign(href);
6064
6491
  }
6065
6492
  };
6066
- const latestHandlers = React28.useRef({ toggleRow, activateRow, onRowContextMenu });
6493
+ const latestHandlers = React31.useRef({ toggleRow, activateRow, onRowContextMenu });
6067
6494
  useIsomorphicLayoutEffect(() => {
6068
6495
  latestHandlers.current = { toggleRow, activateRow, onRowContextMenu };
6069
6496
  });
6070
- const stableToggleRow = React28.useCallback(
6497
+ const stableToggleRow = React31.useCallback(
6071
6498
  (id, checked) => latestHandlers.current.toggleRow(id, checked),
6072
6499
  []
6073
6500
  );
6074
- const stableActivateRow = React28.useCallback(
6501
+ const stableActivateRow = React31.useCallback(
6075
6502
  (row, href, event) => latestHandlers.current.activateRow(row, href, event),
6076
6503
  []
6077
6504
  );
6078
- const stableRowContextMenu = React28.useCallback(
6505
+ const stableRowContextMenu = React31.useCallback(
6079
6506
  (rowId, event) => latestHandlers.current.onRowContextMenu?.(rowId, event),
6080
6507
  []
6081
6508
  );
@@ -6133,7 +6560,7 @@ function DataTableInner({
6133
6560
  ),
6134
6561
  ...props,
6135
6562
  children: [
6136
- selectable && announceSelection ? /* @__PURE__ */ jsx32(
6563
+ selectable && announceSelection ? /* @__PURE__ */ jsx34(
6137
6564
  "div",
6138
6565
  {
6139
6566
  "data-slot": "data-table-selection-status",
@@ -6142,16 +6569,16 @@ function DataTableInner({
6142
6569
  children: selectedCount > 0 ? `${selectedCount.toLocaleString("ko-KR")}${selectionUnit} \uC120\uD0DD\uB428` : ""
6143
6570
  }
6144
6571
  ) : null,
6145
- loading && data.length > 0 ? /* @__PURE__ */ jsx32(
6572
+ loading && data.length > 0 ? /* @__PURE__ */ jsx34(
6146
6573
  "div",
6147
6574
  {
6148
6575
  "data-slot": "data-table-progress",
6149
6576
  "aria-hidden": "true",
6150
6577
  className: "absolute left-0 right-0 top-0 z-10 h-[2px] overflow-hidden bg-[var(--action-selected)]",
6151
- children: /* @__PURE__ */ jsx32("div", { className: "h-full w-1/3 animate-pulse bg-[var(--primary)]" })
6578
+ children: /* @__PURE__ */ jsx34("div", { className: "h-full w-1/3 animate-pulse bg-[var(--primary)]" })
6152
6579
  }
6153
6580
  ) : null,
6154
- /* @__PURE__ */ jsx32("div", { ref: desktopRef, "data-slot": "data-table-desktop", className: "max-md:hidden md:block", children: /* @__PURE__ */ jsxs30(
6581
+ /* @__PURE__ */ jsx34("div", { ref: desktopRef, "data-slot": "data-table-desktop", className: "max-md:hidden md:block", children: /* @__PURE__ */ jsxs30(
6155
6582
  "div",
6156
6583
  {
6157
6584
  role: "table",
@@ -6173,20 +6600,20 @@ function DataTableInner({
6173
6600
  ),
6174
6601
  style: { gridTemplateColumns },
6175
6602
  children: [
6176
- selectable ? /* @__PURE__ */ jsx32("div", { role: "columnheader", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx32(
6603
+ selectable ? /* @__PURE__ */ jsx34("div", { role: "columnheader", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx34(
6177
6604
  Checkbox,
6178
6605
  {
6179
6606
  "aria-label": "\uC804\uCCB4 \uD589 \uC120\uD0DD",
6180
6607
  checked: partiallySelected ? "indeterminate" : allVisibleRowsSelected,
6181
6608
  onCheckedChange: (nextChecked) => toggleAllRows(nextChecked === true),
6182
- children: /* @__PURE__ */ jsx32("span", { className: "sr-only", children: "\uC804\uCCB4 \uD589 \uC120\uD0DD" })
6609
+ children: /* @__PURE__ */ jsx34("span", { className: "sr-only", children: "\uC804\uCCB4 \uD589 \uC120\uD0DD" })
6183
6610
  }
6184
6611
  ) }) : null,
6185
6612
  columns.map((column) => {
6186
6613
  const align = column.align ?? "left";
6187
6614
  const nextSort = getNextSort(sortBy, column.key);
6188
6615
  const ariaSort = sortBy?.key === column.key ? sortBy.dir === "asc" ? "ascending" : "descending" : void 0;
6189
- return /* @__PURE__ */ jsx32(
6616
+ return /* @__PURE__ */ jsx34(
6190
6617
  "div",
6191
6618
  {
6192
6619
  role: "columnheader",
@@ -6206,11 +6633,11 @@ function DataTableInner({
6206
6633
  ),
6207
6634
  onClick: () => onSortChange?.(column.key, nextSort),
6208
6635
  children: [
6209
- /* @__PURE__ */ jsx32("span", { className: "truncate", children: column.header }),
6210
- /* @__PURE__ */ jsx32(SortIcon, { sort: sortBy, columnKey: column.key })
6636
+ /* @__PURE__ */ jsx34("span", { className: "truncate", children: column.header }),
6637
+ /* @__PURE__ */ jsx34(SortIcon, { sort: sortBy, columnKey: column.key })
6211
6638
  ]
6212
6639
  }
6213
- ) : /* @__PURE__ */ jsx32("span", { className: "truncate", children: column.header })
6640
+ ) : /* @__PURE__ */ jsx34("span", { className: "truncate", children: column.header })
6214
6641
  },
6215
6642
  column.key
6216
6643
  );
@@ -6218,7 +6645,7 @@ function DataTableInner({
6218
6645
  ]
6219
6646
  }
6220
6647
  ),
6221
- loading && data.length === 0 ? /* @__PURE__ */ jsx32(
6648
+ loading && data.length === 0 ? /* @__PURE__ */ jsx34(
6222
6649
  SkeletonRows,
6223
6650
  {
6224
6651
  columns,
@@ -6229,7 +6656,7 @@ function DataTableInner({
6229
6656
  ) : data.length === 0 ? (
6230
6657
  /* role="table" 직계 자식은 row/rowgroup이어야 한다. data-slot과 테두리는
6231
6658
  그대로 유지해 시각 계약을 깨지 않는다(빈 상태에서도 표가 테두리를 그린다). */
6232
- /* @__PURE__ */ jsx32("div", { role: "rowgroup", children: /* @__PURE__ */ jsx32("div", { role: "row", children: /* @__PURE__ */ jsx32(
6659
+ /* @__PURE__ */ jsx34("div", { role: "rowgroup", children: /* @__PURE__ */ jsx34("div", { role: "row", children: /* @__PURE__ */ jsx34(
6233
6660
  "div",
6234
6661
  {
6235
6662
  role: "cell",
@@ -6239,9 +6666,9 @@ function DataTableInner({
6239
6666
  children: emptyState
6240
6667
  }
6241
6668
  ) }) })
6242
- ) : /* @__PURE__ */ jsx32("div", { ref: desktopListRef, role: "rowgroup", style: desktopSlice.style, children: desktopSlice.rows.map((row, index) => {
6669
+ ) : /* @__PURE__ */ jsx34("div", { ref: desktopListRef, role: "rowgroup", style: desktopSlice.style, children: desktopSlice.rows.map((row, index) => {
6243
6670
  const itemProps = getItemProps(row);
6244
- return /* @__PURE__ */ jsx32(
6671
+ return /* @__PURE__ */ jsx34(
6245
6672
  RowComponent,
6246
6673
  {
6247
6674
  ...itemProps,
@@ -6254,7 +6681,7 @@ function DataTableInner({
6254
6681
  ]
6255
6682
  }
6256
6683
  ) }),
6257
- /* @__PURE__ */ jsx32(
6684
+ /* @__PURE__ */ jsx34(
6258
6685
  MobileSortControls,
6259
6686
  {
6260
6687
  columns,
@@ -6264,14 +6691,14 @@ function DataTableInner({
6264
6691
  surface
6265
6692
  }
6266
6693
  ),
6267
- loading && data.length === 0 ? /* @__PURE__ */ jsx32(MobileSkeletonCards, { count: skeletonRowCount }) : data.length === 0 ? /* @__PURE__ */ jsx32(
6694
+ loading && data.length === 0 ? /* @__PURE__ */ jsx34(MobileSkeletonCards, { count: skeletonRowCount }) : data.length === 0 ? /* @__PURE__ */ jsx34(
6268
6695
  "div",
6269
6696
  {
6270
6697
  "data-slot": "data-table-mobile-empty",
6271
6698
  className: "border-t border-[var(--border-subtle)] p-[var(--space-4)] md:hidden",
6272
6699
  children: emptyState
6273
6700
  }
6274
- ) : /* @__PURE__ */ jsx32(
6701
+ ) : /* @__PURE__ */ jsx34(
6275
6702
  "div",
6276
6703
  {
6277
6704
  ref: mobileListRef,
@@ -6282,7 +6709,7 @@ function DataTableInner({
6282
6709
  style: mobileSlice.style,
6283
6710
  children: mobileSlice.rows.map((row, index) => {
6284
6711
  const itemProps = getItemProps(row);
6285
- return /* @__PURE__ */ jsx32(
6712
+ return /* @__PURE__ */ jsx34(
6286
6713
  CardComponent,
6287
6714
  {
6288
6715
  ...itemProps,
@@ -6298,27 +6725,27 @@ function DataTableInner({
6298
6725
  }
6299
6726
  );
6300
6727
  }
6301
- var DataTable = React28.forwardRef(DataTableInner);
6728
+ var DataTable = React31.forwardRef(DataTableInner);
6302
6729
  DataTable.displayName = "DataTable";
6303
6730
 
6304
6731
  // src/components/ui/dropdown-menu.tsx
6305
6732
  import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
6306
6733
  import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
6307
- import { jsx as jsx33, jsxs as jsxs31 } from "react/jsx-runtime";
6734
+ import { jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
6308
6735
  function DropdownMenu({
6309
6736
  ...props
6310
6737
  }) {
6311
- return /* @__PURE__ */ jsx33(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
6738
+ return /* @__PURE__ */ jsx35(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
6312
6739
  }
6313
6740
  function DropdownMenuPortal({
6314
6741
  ...props
6315
6742
  }) {
6316
- return /* @__PURE__ */ jsx33(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
6743
+ return /* @__PURE__ */ jsx35(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
6317
6744
  }
6318
6745
  function DropdownMenuTrigger({
6319
6746
  ...props
6320
6747
  }) {
6321
- return /* @__PURE__ */ jsx33(
6748
+ return /* @__PURE__ */ jsx35(
6322
6749
  DropdownMenuPrimitive.Trigger,
6323
6750
  {
6324
6751
  "data-slot": "dropdown-menu-trigger",
@@ -6331,7 +6758,7 @@ function DropdownMenuContent({
6331
6758
  sideOffset = 4,
6332
6759
  ...props
6333
6760
  }) {
6334
- return /* @__PURE__ */ jsx33(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx33(
6761
+ return /* @__PURE__ */ jsx35(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx35(
6335
6762
  DropdownMenuPrimitive.Content,
6336
6763
  {
6337
6764
  "data-slot": "dropdown-menu-content",
@@ -6354,7 +6781,7 @@ function DropdownMenuContent({
6354
6781
  function DropdownMenuGroup({
6355
6782
  ...props
6356
6783
  }) {
6357
- return /* @__PURE__ */ jsx33(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
6784
+ return /* @__PURE__ */ jsx35(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
6358
6785
  }
6359
6786
  function DropdownMenuItem({
6360
6787
  className,
@@ -6362,7 +6789,7 @@ function DropdownMenuItem({
6362
6789
  variant = "default",
6363
6790
  ...props
6364
6791
  }) {
6365
- return /* @__PURE__ */ jsx33(
6792
+ return /* @__PURE__ */ jsx35(
6366
6793
  DropdownMenuPrimitive.Item,
6367
6794
  {
6368
6795
  "data-slot": "dropdown-menu-item",
@@ -6405,7 +6832,7 @@ function DropdownMenuCheckboxItem({
6405
6832
  checked,
6406
6833
  ...props,
6407
6834
  children: [
6408
- /* @__PURE__ */ jsx33("span", { className: "pointer-events-none absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx33(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx33(CheckIcon, { size: 16 }) }) }),
6835
+ /* @__PURE__ */ jsx35("span", { className: "pointer-events-none absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx35(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx35(CheckIcon, { size: 16 }) }) }),
6409
6836
  children
6410
6837
  ]
6411
6838
  }
@@ -6414,7 +6841,7 @@ function DropdownMenuCheckboxItem({
6414
6841
  function DropdownMenuRadioGroup({
6415
6842
  ...props
6416
6843
  }) {
6417
- return /* @__PURE__ */ jsx33(
6844
+ return /* @__PURE__ */ jsx35(
6418
6845
  DropdownMenuPrimitive.RadioGroup,
6419
6846
  {
6420
6847
  "data-slot": "dropdown-menu-radio-group",
@@ -6442,7 +6869,7 @@ function DropdownMenuRadioItem({
6442
6869
  ),
6443
6870
  ...props,
6444
6871
  children: [
6445
- /* @__PURE__ */ jsx33("span", { className: "pointer-events-none absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx33(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx33(CircleIcon, { size: 8, className: "fill-current" }) }) }),
6872
+ /* @__PURE__ */ jsx35("span", { className: "pointer-events-none absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx35(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx35(CircleIcon, { size: 8, className: "fill-current" }) }) }),
6446
6873
  children
6447
6874
  ]
6448
6875
  }
@@ -6453,7 +6880,7 @@ function DropdownMenuLabel({
6453
6880
  inset,
6454
6881
  ...props
6455
6882
  }) {
6456
- return /* @__PURE__ */ jsx33(
6883
+ return /* @__PURE__ */ jsx35(
6457
6884
  DropdownMenuPrimitive.Label,
6458
6885
  {
6459
6886
  "data-slot": "dropdown-menu-label",
@@ -6470,7 +6897,7 @@ function DropdownMenuSeparator({
6470
6897
  className,
6471
6898
  ...props
6472
6899
  }) {
6473
- return /* @__PURE__ */ jsx33(
6900
+ return /* @__PURE__ */ jsx35(
6474
6901
  DropdownMenuPrimitive.Separator,
6475
6902
  {
6476
6903
  "data-slot": "dropdown-menu-separator",
@@ -6483,7 +6910,7 @@ function DropdownMenuShortcut({
6483
6910
  className,
6484
6911
  ...props
6485
6912
  }) {
6486
- return /* @__PURE__ */ jsx33(
6913
+ return /* @__PURE__ */ jsx35(
6487
6914
  "span",
6488
6915
  {
6489
6916
  "data-slot": "dropdown-menu-shortcut",
@@ -6498,7 +6925,7 @@ function DropdownMenuShortcut({
6498
6925
  function DropdownMenuSub({
6499
6926
  ...props
6500
6927
  }) {
6501
- return /* @__PURE__ */ jsx33(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
6928
+ return /* @__PURE__ */ jsx35(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
6502
6929
  }
6503
6930
  function DropdownMenuSubTrigger({
6504
6931
  className,
@@ -6523,7 +6950,7 @@ function DropdownMenuSubTrigger({
6523
6950
  ...props,
6524
6951
  children: [
6525
6952
  children,
6526
- /* @__PURE__ */ jsx33(ChevronRightIcon, { className: "ml-auto", size: 16 })
6953
+ /* @__PURE__ */ jsx35(ChevronRightIcon, { className: "ml-auto", size: 16 })
6527
6954
  ]
6528
6955
  }
6529
6956
  );
@@ -6532,7 +6959,7 @@ function DropdownMenuSubContent({
6532
6959
  className,
6533
6960
  ...props
6534
6961
  }) {
6535
- return /* @__PURE__ */ jsx33(
6962
+ return /* @__PURE__ */ jsx35(
6536
6963
  DropdownMenuPrimitive.SubContent,
6537
6964
  {
6538
6965
  "data-slot": "dropdown-menu-sub-content",
@@ -6552,7 +6979,7 @@ function DropdownMenuSubContent({
6552
6979
  }
6553
6980
 
6554
6981
  // src/components/ui/context-menu.tsx
6555
- import { jsx as jsx34, jsxs as jsxs32 } from "react/jsx-runtime";
6982
+ import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
6556
6983
  function ContextMenu({
6557
6984
  open,
6558
6985
  onOpenChange,
@@ -6564,7 +6991,7 @@ function ContextMenu({
6564
6991
  return null;
6565
6992
  }
6566
6993
  return /* @__PURE__ */ jsxs32(DropdownMenu, { open, onOpenChange, modal: false, children: [
6567
- /* @__PURE__ */ jsx34(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx34(
6994
+ /* @__PURE__ */ jsx36(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx36(
6568
6995
  "span",
6569
6996
  {
6570
6997
  "aria-hidden": "true",
@@ -6578,14 +7005,14 @@ function ContextMenu({
6578
7005
  }
6579
7006
  }
6580
7007
  ) }),
6581
- /* @__PURE__ */ jsx34(DropdownMenuContent, { ...contentProps, children })
7008
+ /* @__PURE__ */ jsx36(DropdownMenuContent, { ...contentProps, children })
6582
7009
  ] });
6583
7010
  }
6584
7011
 
6585
7012
  // src/components/ui/bulk-action-bar.tsx
6586
- import * as React29 from "react";
7013
+ import * as React32 from "react";
6587
7014
  import { X as X3 } from "lucide-react";
6588
- import { jsx as jsx35, jsxs as jsxs33 } from "react/jsx-runtime";
7015
+ import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
6589
7016
  function ActionButton({ action }) {
6590
7017
  const danger = action.variant === "destructive";
6591
7018
  const off = action.disabled;
@@ -6617,7 +7044,7 @@ function ActionButton({ action }) {
6617
7044
  whiteSpace: "nowrap"
6618
7045
  },
6619
7046
  children: [
6620
- Icon ? /* @__PURE__ */ jsx35(
7047
+ Icon ? /* @__PURE__ */ jsx37(
6621
7048
  Icon,
6622
7049
  {
6623
7050
  "aria-hidden": "true",
@@ -6632,7 +7059,7 @@ function ActionButton({ action }) {
6632
7059
  );
6633
7060
  }
6634
7061
  function Divider() {
6635
- return /* @__PURE__ */ jsx35(
7062
+ return /* @__PURE__ */ jsx37(
6636
7063
  "span",
6637
7064
  {
6638
7065
  "aria-hidden": "true",
@@ -6647,7 +7074,7 @@ function Divider() {
6647
7074
  );
6648
7075
  }
6649
7076
  function ClearButton({ onClear }) {
6650
- return /* @__PURE__ */ jsx35(
7077
+ return /* @__PURE__ */ jsx37(
6651
7078
  "button",
6652
7079
  {
6653
7080
  type: "button",
@@ -6669,7 +7096,7 @@ function ClearButton({ onClear }) {
6669
7096
  justifyContent: "center",
6670
7097
  borderRadius: "var(--radius-md)"
6671
7098
  },
6672
- children: /* @__PURE__ */ jsx35(X3, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" })
7099
+ children: /* @__PURE__ */ jsx37(X3, { size: 16, strokeWidth: 1.75, "aria-hidden": "true" })
6673
7100
  }
6674
7101
  );
6675
7102
  }
@@ -6724,10 +7151,10 @@ var idleLineStyle = {
6724
7151
  fontVariantNumeric: "tabular-nums",
6725
7152
  color: "var(--text-secondary)"
6726
7153
  };
6727
- var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React29.useEffect : React29.useLayoutEffect;
7154
+ var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React32.useEffect : React32.useLayoutEffect;
6728
7155
  function useCompactSummary(slot, enabled) {
6729
- const [fullWidth, setFullWidth] = React29.useState(null);
6730
- const measure = React29.useCallback(() => {
7156
+ const [fullWidth, setFullWidth] = React32.useState(null);
7157
+ const measure = React32.useCallback(() => {
6731
7158
  if (!slot) return;
6732
7159
  setFullWidth((prev) => {
6733
7160
  if (prev === null) return slot.scrollWidth > slot.clientWidth ? slot.scrollWidth : null;
@@ -6737,7 +7164,7 @@ function useCompactSummary(slot, enabled) {
6737
7164
  useIsomorphicLayoutEffect2(() => {
6738
7165
  if (enabled) measure();
6739
7166
  });
6740
- React29.useEffect(() => {
7167
+ React32.useEffect(() => {
6741
7168
  if (!enabled || !slot || typeof ResizeObserver === "undefined") return;
6742
7169
  const observer = new ResizeObserver(measure);
6743
7170
  observer.observe(slot);
@@ -6761,7 +7188,7 @@ function BulkActionBar({
6761
7188
  ...props
6762
7189
  }) {
6763
7190
  const inline = placement === "inline";
6764
- const trailingSlot = trailing !== void 0 && trailing !== null ? /* @__PURE__ */ jsx35(
7191
+ const trailingSlot = trailing !== void 0 && trailing !== null ? /* @__PURE__ */ jsx37(
6765
7192
  "div",
6766
7193
  {
6767
7194
  "data-slot": "bulk-action-bar-trailing",
@@ -6774,7 +7201,7 @@ function BulkActionBar({
6774
7201
  children: trailing
6775
7202
  }
6776
7203
  ) : null;
6777
- const [summaryElement, setSummaryElement] = React29.useState(null);
7204
+ const [summaryElement, setSummaryElement] = React32.useState(null);
6778
7205
  const compact = useCompactSummary(
6779
7206
  summaryElement,
6780
7207
  inline && compactSummary !== void 0 && compactSummary !== null
@@ -6790,7 +7217,7 @@ function BulkActionBar({
6790
7217
  style: { ...idleLineStyle, overflow: "visible", ...style },
6791
7218
  ...props,
6792
7219
  children: [
6793
- /* @__PURE__ */ jsx35(
7220
+ /* @__PURE__ */ jsx37(
6794
7221
  "div",
6795
7222
  {
6796
7223
  role: "status",
@@ -6812,7 +7239,7 @@ function BulkActionBar({
6812
7239
  );
6813
7240
  }
6814
7241
  if (count === 0 && idleContent !== void 0) {
6815
- return /* @__PURE__ */ jsx35(
7242
+ return /* @__PURE__ */ jsx37(
6816
7243
  "div",
6817
7244
  {
6818
7245
  role: "status",
@@ -6829,7 +7256,7 @@ function BulkActionBar({
6829
7256
  if (count === 0 && emptyHint === void 0) {
6830
7257
  return null;
6831
7258
  }
6832
- const countLabel = /* @__PURE__ */ jsx35(
7259
+ const countLabel = /* @__PURE__ */ jsx37(
6833
7260
  "span",
6834
7261
  {
6835
7262
  "data-slot": "bulk-action-bar-count",
@@ -6846,7 +7273,7 @@ function BulkActionBar({
6846
7273
  children: count > 0 ? `${count.toLocaleString("ko-KR")}${unit} \uC120\uD0DD\uB428` : emptyHint
6847
7274
  }
6848
7275
  );
6849
- const summarySlot = summary !== void 0 && summary !== null ? /* @__PURE__ */ jsx35(
7276
+ const summarySlot = summary !== void 0 && summary !== null ? /* @__PURE__ */ jsx37(
6850
7277
  "span",
6851
7278
  {
6852
7279
  ref: setSummaryElement,
@@ -6880,7 +7307,7 @@ function BulkActionBar({
6880
7307
  children: compact ? compactSummary : summary
6881
7308
  }
6882
7309
  ) : null;
6883
- const actionGroup = /* @__PURE__ */ jsx35(
7310
+ const actionGroup = /* @__PURE__ */ jsx37(
6884
7311
  "div",
6885
7312
  {
6886
7313
  "data-slot": "bulk-action-bar-actions",
@@ -6892,7 +7319,7 @@ function BulkActionBar({
6892
7319
  justifyContent: "flex-end",
6893
7320
  gap: 2
6894
7321
  },
6895
- children: actions.map((action) => /* @__PURE__ */ jsx35(ActionButton, { action }, action.key))
7322
+ children: actions.map((action) => /* @__PURE__ */ jsx37(ActionButton, { action }, action.key))
6896
7323
  }
6897
7324
  );
6898
7325
  if (inline) {
@@ -6936,10 +7363,10 @@ function BulkActionBar({
6936
7363
  gap: "var(--space-1)"
6937
7364
  },
6938
7365
  children: [
6939
- count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx35(Divider, {}) : null,
7366
+ count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx37(Divider, {}) : null,
6940
7367
  actionGroup,
6941
- /* @__PURE__ */ jsx35(Divider, {}),
6942
- /* @__PURE__ */ jsx35(ClearButton, { onClear })
7368
+ /* @__PURE__ */ jsx37(Divider, {}),
7369
+ /* @__PURE__ */ jsx37(ClearButton, { onClear })
6943
7370
  ]
6944
7371
  }
6945
7372
  ),
@@ -6980,10 +7407,10 @@ function BulkActionBar({
6980
7407
  ]
6981
7408
  }
6982
7409
  ),
6983
- count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx35(Divider, {}) : null,
7410
+ count > 0 && actions.length > 0 ? /* @__PURE__ */ jsx37(Divider, {}) : null,
6984
7411
  actionGroup,
6985
- /* @__PURE__ */ jsx35(Divider, {}),
6986
- /* @__PURE__ */ jsx35(ClearButton, { onClear }),
7412
+ /* @__PURE__ */ jsx37(Divider, {}),
7413
+ /* @__PURE__ */ jsx37(ClearButton, { onClear }),
6987
7414
  trailingSlot
6988
7415
  ]
6989
7416
  }
@@ -6991,110 +7418,50 @@ function BulkActionBar({
6991
7418
  }
6992
7419
 
6993
7420
  // src/components/ui/confirm-dialog.tsx
6994
- import { Fragment as Fragment8, jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
7421
+ import { jsx as jsx38 } from "react/jsx-runtime";
6995
7422
  function ConfirmDialog({
6996
7423
  open,
6997
7424
  onOpenChange,
6998
- title: title2,
7425
+ title,
6999
7426
  description,
7000
7427
  tone = "default",
7001
7428
  confirmLabel,
7002
- cancelLabel = "\uCDE8\uC18C",
7429
+ cancelLabel,
7003
7430
  onConfirm,
7004
- loading = false,
7431
+ loading,
7005
7432
  children,
7006
- confirmDisabled = false,
7007
- mobilePresentation = "center"
7433
+ confirmDisabled,
7434
+ scrim
7008
7435
  }) {
7009
- const returnFocus = useReturnFocus();
7010
- const { isBusy, run, guardOpenChange } = useOverlayAction({
7011
- action: onConfirm,
7012
- onOpenChange,
7013
- loading,
7014
- disabled: confirmDisabled
7015
- });
7016
- const dialogBody = /* @__PURE__ */ jsxs34(Fragment8, { children: [
7017
- /* @__PURE__ */ jsx36("div", { className: "flex items-start justify-between gap-[var(--space-4)]", children: /* @__PURE__ */ jsxs34("div", { className: "min-w-0 space-y-[var(--space-2)]", children: [
7018
- /* @__PURE__ */ jsx36(
7019
- DialogTitle,
7020
- {
7021
- "data-slot": "dialog-title",
7022
- className: presetSurface.confirm.title,
7023
- children: title2
7024
- }
7025
- ),
7026
- description ? /* @__PURE__ */ jsx36(
7027
- DialogDescription,
7028
- {
7029
- "data-slot": "dialog-description",
7030
- className: presetSurface.confirm.description,
7031
- children: description
7032
- }
7033
- ) : null
7034
- ] }) }),
7035
- children != null ? /* @__PURE__ */ jsx36("div", { "data-slot": "confirm-dialog-body", className: presetSurface.confirm.body, children }) : null,
7036
- /* @__PURE__ */ jsxs34(
7037
- "div",
7038
- {
7039
- "data-slot": "dialog-footer",
7040
- className: presetSurface.confirm.footer,
7041
- children: [
7042
- /* @__PURE__ */ jsx36(
7043
- Button,
7044
- {
7045
- variant: "secondary",
7046
- size: "lg",
7047
- className: footerButtonHitAreaClassName,
7048
- disabled: isBusy,
7049
- onClick: () => guardOpenChange(false),
7050
- children: cancelLabel
7051
- }
7052
- ),
7053
- /* @__PURE__ */ jsx36(
7054
- Button,
7055
- {
7056
- variant: tone === "destructive" ? "destructive" : "primary",
7057
- size: "lg",
7058
- className: footerButtonHitAreaClassName,
7059
- loading: isBusy,
7060
- disabled: confirmDisabled,
7061
- onClick: run,
7062
- children: confirmLabel
7063
- }
7064
- )
7065
- ]
7066
- }
7067
- )
7068
- ] });
7069
- return /* @__PURE__ */ jsx36(Dialog, { open, onOpenChange: guardOpenChange, children: /* @__PURE__ */ jsxs34(DialogPortal, { children: [
7070
- /* @__PURE__ */ jsx36(DialogOverlay, {}),
7071
- /* @__PURE__ */ jsx36(
7072
- DialogRawContent,
7073
- {
7074
- role: "alertdialog",
7075
- "data-slot": "dialog-content",
7076
- className: cn(
7077
- presetSurface.confirm.content,
7078
- mobilePresentation === "sheet" && bottomSheet.dialog
7079
- ),
7080
- style: mobilePresentation === "sheet" ? dialogMobileSheetStyle() : void 0,
7081
- ...returnFocus,
7082
- children: dialogBody
7083
- }
7084
- )
7085
- ] }) });
7436
+ return /* @__PURE__ */ jsx38(
7437
+ AlertDialog,
7438
+ {
7439
+ open,
7440
+ onOpenChange,
7441
+ title,
7442
+ description,
7443
+ tone: tone === "destructive" ? "danger" : "neutral",
7444
+ confirmLabel,
7445
+ cancelLabel,
7446
+ onConfirm,
7447
+ loading,
7448
+ confirmDisabled,
7449
+ scrim,
7450
+ children
7451
+ }
7452
+ );
7086
7453
  }
7087
7454
 
7088
7455
  // src/components/ui/separator.tsx
7089
7456
  import { Separator as SeparatorPrimitive } from "radix-ui";
7090
- import { jsx as jsx37 } from "react/jsx-runtime";
7457
+ import { jsx as jsx39 } from "react/jsx-runtime";
7091
7458
  function Separator2({
7092
7459
  className,
7093
7460
  orientation = "horizontal",
7094
7461
  decorative = true,
7095
7462
  ...props
7096
7463
  }) {
7097
- return /* @__PURE__ */ jsx37(
7464
+ return /* @__PURE__ */ jsx39(
7098
7465
  SeparatorPrimitive.Root,
7099
7466
  {
7100
7467
  "data-slot": "separator",
@@ -7111,13 +7478,13 @@ function Separator2({
7111
7478
 
7112
7479
  // src/components/ui/avatar.tsx
7113
7480
  import { Avatar as AvatarPrimitive } from "radix-ui";
7114
- import { jsx as jsx38 } from "react/jsx-runtime";
7481
+ import { jsx as jsx40 } from "react/jsx-runtime";
7115
7482
  function Avatar({
7116
7483
  className,
7117
7484
  size = "md",
7118
7485
  ...props
7119
7486
  }) {
7120
- return /* @__PURE__ */ jsx38(
7487
+ return /* @__PURE__ */ jsx40(
7121
7488
  AvatarPrimitive.Root,
7122
7489
  {
7123
7490
  "data-slot": "avatar",
@@ -7138,7 +7505,7 @@ function AvatarImage({
7138
7505
  className,
7139
7506
  ...props
7140
7507
  }) {
7141
- return /* @__PURE__ */ jsx38(
7508
+ return /* @__PURE__ */ jsx40(
7142
7509
  AvatarPrimitive.Image,
7143
7510
  {
7144
7511
  "data-slot": "avatar-image",
@@ -7163,7 +7530,7 @@ function AvatarFallback({
7163
7530
  ...props
7164
7531
  }) {
7165
7532
  const fallbackText = children ?? (name ? getAvatarFallbackText(name) : null);
7166
- return /* @__PURE__ */ jsx38(
7533
+ return /* @__PURE__ */ jsx40(
7167
7534
  AvatarPrimitive.Fallback,
7168
7535
  {
7169
7536
  "data-slot": "avatar-fallback",
@@ -7180,95 +7547,327 @@ function AvatarFallback({
7180
7547
  );
7181
7548
  }
7182
7549
 
7183
- // src/components/ui/action-sheet.tsx
7184
- import * as React30 from "react";
7185
- import { jsx as jsx39, jsxs as jsxs35 } from "react/jsx-runtime";
7186
- var actionSheetHeaderClassName = cn(
7187
- "flex items-start gap-[var(--space-3)] px-[var(--space-4)] pt-[var(--space-4)] pb-[var(--space-3)]"
7188
- );
7189
- var actionSheetTitleClassName = cn(
7190
- "break-keep text-[15px] font-semibold leading-snug text-foreground"
7191
- );
7192
- var actionSheetDescriptionClassName = cn(
7193
- "mt-[var(--space-1)] break-keep text-[13px] leading-normal text-text-secondary"
7550
+ // src/components/ui/sheet-drawer.tsx
7551
+ import { Maximize2Icon, Minimize2Icon } from "lucide-react";
7552
+ import { jsx as jsx41, jsxs as jsxs34 } from "react/jsx-runtime";
7553
+ var expandButtonClassName = cn(
7554
+ "inline-flex cursor-pointer items-center justify-center gap-[var(--space-1)]",
7555
+ "rounded-[var(--radius-md)] text-text-tertiary transition-colors",
7556
+ "hover:bg-[var(--action-hover)] hover:text-foreground",
7557
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2",
7558
+ "h-[32px] px-[var(--space-2)]"
7194
7559
  );
7195
- var actionSheetListClassName = "min-h-0 overflow-y-auto";
7196
- var actionSheetItemClassName = cn(
7197
- "flex min-h-12 w-full cursor-pointer items-center gap-[var(--space-3)] px-[var(--space-4)] text-left",
7198
- "border-t border-[var(--border-subtle)] text-[13px] font-medium text-text-primary",
7560
+ var sizeOfWidth = {
7561
+ default: "md",
7562
+ wide: "lg",
7563
+ full: "full"
7564
+ };
7565
+ function SheetDrawer({
7566
+ open,
7567
+ onOpenChange,
7568
+ caption,
7569
+ title,
7570
+ description,
7571
+ children,
7572
+ expandHref,
7573
+ onExpand,
7574
+ expandLabel = "\uD06C\uAC8C \uBCF4\uAE30",
7575
+ expanded = false,
7576
+ onExpandedChange,
7577
+ collapseLabel = "\uC791\uAC8C \uBCF4\uAE30",
7578
+ footer,
7579
+ width = "default",
7580
+ motion,
7581
+ closeLabel = "\uB2EB\uAE30"
7582
+ }) {
7583
+ const hasExpandedToggle = typeof onExpandedChange === "function";
7584
+ const showExpandAction = Boolean(hasExpandedToggle || expandHref || onExpand);
7585
+ const resolvedExpandLabel = hasExpandedToggle && expanded ? collapseLabel : expandLabel;
7586
+ const ExpandActionIcon = hasExpandedToggle && expanded ? Minimize2Icon : Maximize2Icon;
7587
+ const expandAction = showExpandAction ? hasExpandedToggle ? /* @__PURE__ */ jsxs34(
7588
+ "button",
7589
+ {
7590
+ type: "button",
7591
+ "aria-label": resolvedExpandLabel,
7592
+ "aria-pressed": expanded,
7593
+ "data-slot": "sheet-drawer-expand",
7594
+ "data-expanded": expanded ? "true" : "false",
7595
+ className: expandButtonClassName,
7596
+ onClick: () => onExpandedChange(!expanded),
7597
+ children: [
7598
+ /* @__PURE__ */ jsx41(ExpandActionIcon, { className: "size-[16px]" }),
7599
+ /* @__PURE__ */ jsx41("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: resolvedExpandLabel })
7600
+ ]
7601
+ }
7602
+ ) : expandHref ? /* @__PURE__ */ jsxs34("a", { href: expandHref, "aria-label": expandLabel, "data-slot": "sheet-drawer-expand", className: expandButtonClassName, children: [
7603
+ /* @__PURE__ */ jsx41(ExpandActionIcon, { className: "size-[16px]" }),
7604
+ /* @__PURE__ */ jsx41("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: expandLabel })
7605
+ ] }) : /* @__PURE__ */ jsxs34(
7606
+ "button",
7607
+ {
7608
+ type: "button",
7609
+ "aria-label": expandLabel,
7610
+ "data-slot": "sheet-drawer-expand",
7611
+ className: expandButtonClassName,
7612
+ onClick: onExpand,
7613
+ children: [
7614
+ /* @__PURE__ */ jsx41(ExpandActionIcon, { className: "size-[16px]" }),
7615
+ /* @__PURE__ */ jsx41("span", { className: "hidden text-sm font-medium leading-normal md:inline", children: expandLabel })
7616
+ ]
7617
+ }
7618
+ ) : void 0;
7619
+ return /* @__PURE__ */ jsx41(
7620
+ Sheet,
7621
+ {
7622
+ open,
7623
+ onOpenChange,
7624
+ title,
7625
+ description: description || void 0,
7626
+ caption: caption || void 0,
7627
+ headerActions: expandAction,
7628
+ size: expanded ? "full" : sizeOfWidth[width],
7629
+ footer: footer || void 0,
7630
+ motion,
7631
+ closeLabel,
7632
+ children
7633
+ }
7634
+ );
7635
+ }
7636
+
7637
+ // src/components/ui/action-menu.tsx
7638
+ import * as React33 from "react";
7639
+ import { Dialog as DialogPrimitive4, Slot as Slot3 } from "radix-ui";
7640
+ import { Fragment as Fragment11, jsx as jsx42, jsxs as jsxs35 } from "react/jsx-runtime";
7641
+ var sheetRowClassName = cn(
7642
+ "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",
7643
+ "border-t border-[var(--border-subtle)] text-[13px] font-medium leading-normal text-text-primary",
7199
7644
  "transition-colors motion-reduce:transition-none hover:bg-[var(--action-hover)]",
7200
7645
  "focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[var(--focus-ring)]",
7201
7646
  "enabled:data-[destructive]:text-[var(--semantic-error-fg)]",
7202
7647
  "disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled"
7203
7648
  );
7204
- function ActionSheet({
7649
+ var sheetRowDescriptionClassName = "block text-[12px] font-normal text-text-secondary group-disabled:text-text-disabled";
7650
+ var sheetGroupLabelClassName = "px-[var(--space-4)] pt-[var(--space-3)] pb-[var(--space-2)] text-[12px] font-semibold leading-normal text-text-tertiary";
7651
+ var sheetGroupSeparatorClassName = "h-[var(--space-2)] bg-[var(--bg-inset)]";
7652
+ function ActionMenuSheet({
7205
7653
  open,
7206
7654
  onOpenChange,
7207
- title: title2,
7655
+ title,
7208
7656
  description,
7209
- items,
7210
- closeLabel = "\uB2EB\uAE30"
7657
+ closeLabel,
7658
+ groups,
7659
+ onOpenAutoFocus,
7660
+ onCloseAutoFocus
7211
7661
  }) {
7212
- const pendingRef = React30.useRef(null);
7213
- const returnFocus = useReturnFocus();
7662
+ const pendingRef = React33.useRef(null);
7663
+ const surfaceRef = React33.useRef(null);
7664
+ const labelId = React33.useId();
7214
7665
  const handleOpenChange = (nextOpen) => {
7215
7666
  pendingRef.current = null;
7216
7667
  onOpenChange(nextOpen);
7217
7668
  };
7669
+ const swipe = useSwipeDismiss({
7670
+ enabled: OVERLAY_POLICY.menu.swipe,
7671
+ onDismiss: () => handleOpenChange(false),
7672
+ surfaceRef,
7673
+ always: true
7674
+ });
7218
7675
  const handleSelect = (item) => {
7219
7676
  onOpenChange(false);
7220
7677
  pendingRef.current = item;
7221
7678
  };
7679
+ const handleOpenAutoFocus = (event) => {
7680
+ onOpenAutoFocus?.(event);
7681
+ const firstRow = surfaceRef.current?.querySelector('[data-slot="action-menu-item"]:enabled');
7682
+ if (!firstRow) return;
7683
+ event.preventDefault();
7684
+ firstRow.focus();
7685
+ };
7222
7686
  const handleCloseAutoFocus = (event) => {
7223
- returnFocus.onCloseAutoFocus(event);
7687
+ onCloseAutoFocus(event);
7224
7688
  const item = pendingRef.current;
7225
7689
  pendingRef.current = null;
7226
7690
  item?.onSelect();
7227
7691
  };
7228
- return /* @__PURE__ */ jsx39(Sheet, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs35(
7229
- SheetContent,
7692
+ return /* @__PURE__ */ jsx42(DialogPrimitive4.Root, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs35(DialogPrimitive4.Portal, { children: [
7693
+ /* @__PURE__ */ jsx42(OverlayScrimLayer, { kind: "menu" }),
7694
+ /* @__PURE__ */ jsxs35(
7695
+ DialogPrimitive4.Content,
7696
+ {
7697
+ ref: surfaceRef,
7698
+ "data-slot": "action-menu-sheet",
7699
+ className: overlayBoxClassName("menu"),
7700
+ onOpenAutoFocus: handleOpenAutoFocus,
7701
+ onCloseAutoFocus: handleCloseAutoFocus,
7702
+ ...description ? {} : { "aria-describedby": void 0 },
7703
+ children: [
7704
+ /* @__PURE__ */ jsx42(OverlayGrabber, { always: true, ...swipe.handleProps }),
7705
+ /* @__PURE__ */ jsx42(
7706
+ OverlayHeader,
7707
+ {
7708
+ kind: "menu",
7709
+ title,
7710
+ description,
7711
+ closeLabel,
7712
+ dragHandleProps: swipe.handleProps
7713
+ }
7714
+ ),
7715
+ /* @__PURE__ */ jsx42(OverlayBody, { kind: "menu", children: groups.map((group, index) => /* @__PURE__ */ jsxs35(React33.Fragment, { children: [
7716
+ index > 0 ? /* @__PURE__ */ jsx42("div", { role: "separator", className: sheetGroupSeparatorClassName }) : null,
7717
+ /* @__PURE__ */ jsxs35("div", { role: "group", "aria-labelledby": group.label ? `${labelId}-${index}` : void 0, children: [
7718
+ group.label ? /* @__PURE__ */ jsx42("div", { id: `${labelId}-${index}`, className: sheetGroupLabelClassName, children: group.label }) : null,
7719
+ group.items.map((item) => {
7720
+ const Icon = item.icon;
7721
+ return /* @__PURE__ */ jsxs35(
7722
+ "button",
7723
+ {
7724
+ type: "button",
7725
+ "data-slot": "action-menu-item",
7726
+ "data-destructive": item.destructive ? "" : void 0,
7727
+ className: sheetRowClassName,
7728
+ disabled: item.disabled,
7729
+ onClick: () => handleSelect(item),
7730
+ children: [
7731
+ Icon ? /* @__PURE__ */ jsx42(Icon, { "aria-hidden": true, size: 17, strokeWidth: 1.75, className: "shrink-0" }) : null,
7732
+ /* @__PURE__ */ jsxs35("span", { className: "min-w-0 flex-1 break-keep", children: [
7733
+ item.label,
7734
+ item.description ? /* @__PURE__ */ jsx42("span", { className: sheetRowDescriptionClassName, children: item.description }) : null
7735
+ ] })
7736
+ ]
7737
+ },
7738
+ item.id
7739
+ );
7740
+ })
7741
+ ] })
7742
+ ] }, group.id)) })
7743
+ ]
7744
+ }
7745
+ )
7746
+ ] }) });
7747
+ }
7748
+ var DESKTOP_QUERY = "(min-width: 900px)";
7749
+ var readPresentation = () => window.matchMedia?.(DESKTOP_QUERY).matches ?? true ? "dropdown" : "sheet";
7750
+ var subscribeNothing = () => () => void 0;
7751
+ var useHydrated = () => React33.useSyncExternalStore(
7752
+ subscribeNothing,
7753
+ () => true,
7754
+ () => false
7755
+ );
7756
+ function ActionMenu({
7757
+ trigger,
7758
+ title,
7759
+ description,
7760
+ open: openProp,
7761
+ onOpenChange,
7762
+ closeLabel,
7763
+ items,
7764
+ groups
7765
+ }) {
7766
+ const [uncontrolledOpen, setUncontrolledOpen] = React33.useState(false);
7767
+ const hydrated = useHydrated();
7768
+ const open = (openProp ?? uncontrolledOpen) && hydrated;
7769
+ const [shown, setShown] = React33.useState({
7770
+ open: false,
7771
+ presentation: "dropdown"
7772
+ });
7773
+ let presentation = shown.presentation;
7774
+ if (shown.open !== open) {
7775
+ if (open) presentation = readPresentation();
7776
+ setShown({ open, presentation });
7777
+ }
7778
+ const triggerRef = React33.useRef(null);
7779
+ const pendingRef = React33.useRef(null);
7780
+ const setOpen = (nextOpen) => {
7781
+ if (nextOpen) pendingRef.current = null;
7782
+ if (openProp === void 0) setUncontrolledOpen(nextOpen);
7783
+ onOpenChange?.(nextOpen);
7784
+ };
7785
+ const menuGroups = groups ?? [{ id: "items", items: items ?? [] }];
7786
+ const handleDropdownCloseAutoFocus = (event) => {
7787
+ const item = pendingRef.current;
7788
+ pendingRef.current = null;
7789
+ if (!item) return;
7790
+ event.preventDefault();
7791
+ triggerRef.current?.focus();
7792
+ item.onSelect();
7793
+ };
7794
+ const handleSheetCloseAutoFocus = (event) => {
7795
+ event.preventDefault();
7796
+ triggerRef.current?.focus();
7797
+ };
7798
+ const triggerLabel = trigger.props["aria-label"];
7799
+ return /* @__PURE__ */ jsxs35(Fragment11, { children: [
7800
+ /* @__PURE__ */ jsxs35(DropdownMenu, { open: open && presentation === "dropdown", onOpenChange: setOpen, children: [
7801
+ /* @__PURE__ */ jsx42(DropdownMenuTrigger, { asChild: true, "aria-expanded": open, children: /* @__PURE__ */ jsx42(Slot3.Root, { ref: triggerRef, children: trigger }) }),
7802
+ /* @__PURE__ */ jsx42(DropdownMenuContent, { align: "end", onCloseAutoFocus: handleDropdownCloseAutoFocus, children: menuGroups.map((group, index) => /* @__PURE__ */ jsxs35(React33.Fragment, { children: [
7803
+ index > 0 ? /* @__PURE__ */ jsx42(DropdownMenuSeparator, {}) : null,
7804
+ /* @__PURE__ */ jsxs35(DropdownMenuGroup, { children: [
7805
+ group.label ? /* @__PURE__ */ jsx42(DropdownMenuLabel, { children: group.label }) : null,
7806
+ group.items.map((item) => {
7807
+ const Icon = item.icon;
7808
+ return /* @__PURE__ */ jsxs35(
7809
+ DropdownMenuItem,
7810
+ {
7811
+ variant: item.destructive ? "destructive" : "default",
7812
+ disabled: item.disabled,
7813
+ onSelect: () => {
7814
+ pendingRef.current = item;
7815
+ },
7816
+ children: [
7817
+ Icon ? /* @__PURE__ */ jsx42(Icon, { "aria-hidden": true, size: 16, strokeWidth: 1.75 }) : null,
7818
+ item.label
7819
+ ]
7820
+ },
7821
+ item.id
7822
+ );
7823
+ })
7824
+ ] })
7825
+ ] }, group.id)) })
7826
+ ] }),
7827
+ /* @__PURE__ */ jsx42(
7828
+ ActionMenuSheet,
7829
+ {
7830
+ open: open && presentation === "sheet",
7831
+ onOpenChange: setOpen,
7832
+ title: title ?? /* @__PURE__ */ jsx42("span", { className: "sr-only", children: triggerLabel }),
7833
+ description,
7834
+ closeLabel,
7835
+ groups: menuGroups,
7836
+ onCloseAutoFocus: handleSheetCloseAutoFocus
7837
+ }
7838
+ )
7839
+ ] });
7840
+ }
7841
+
7842
+ // src/components/ui/action-sheet.tsx
7843
+ import { jsx as jsx43 } from "react/jsx-runtime";
7844
+ function ActionSheet({
7845
+ open,
7846
+ onOpenChange,
7847
+ title,
7848
+ description,
7849
+ items,
7850
+ closeLabel = "\uB2EB\uAE30"
7851
+ }) {
7852
+ const returnFocus = useReturnFocus();
7853
+ return /* @__PURE__ */ jsx43(
7854
+ ActionMenuSheet,
7230
7855
  {
7231
- side: "bottom",
7232
- "data-slot": "action-sheet-content",
7233
- className: bottomSheet.action,
7856
+ open,
7857
+ onOpenChange,
7858
+ title,
7859
+ description,
7860
+ closeLabel,
7861
+ groups: [{ id: "items", items }],
7234
7862
  onOpenAutoFocus: returnFocus.onOpenAutoFocus,
7235
- onCloseAutoFocus: handleCloseAutoFocus,
7236
- ...description ? {} : { "aria-describedby": void 0 },
7237
- children: [
7238
- /* @__PURE__ */ jsxs35("div", { "data-slot": "action-sheet-header", className: actionSheetHeaderClassName, children: [
7239
- /* @__PURE__ */ jsxs35("div", { className: "min-w-0 flex-1", children: [
7240
- /* @__PURE__ */ jsx39(SheetTitle, { className: actionSheetTitleClassName, children: title2 }),
7241
- description ? /* @__PURE__ */ jsx39(SheetDescription, { className: actionSheetDescriptionClassName, children: description }) : null
7242
- ] }),
7243
- /* @__PURE__ */ jsx39(OverlayCloseButton, { label: closeLabel })
7244
- ] }),
7245
- /* @__PURE__ */ jsx39("div", { "data-slot": "action-sheet-list", className: actionSheetListClassName, children: items.map((item) => {
7246
- const Icon = item.icon;
7247
- return /* @__PURE__ */ jsxs35(
7248
- "button",
7249
- {
7250
- type: "button",
7251
- "data-slot": "action-sheet-item",
7252
- "data-destructive": item.destructive ? "" : void 0,
7253
- className: actionSheetItemClassName,
7254
- disabled: item.disabled,
7255
- onClick: () => handleSelect(item),
7256
- children: [
7257
- Icon ? /* @__PURE__ */ jsx39(Icon, { "aria-hidden": true, size: 17, strokeWidth: 1.75, className: "shrink-0" }) : null,
7258
- /* @__PURE__ */ jsx39("span", { className: "min-w-0 flex-1 break-keep", children: item.label })
7259
- ]
7260
- },
7261
- item.id
7262
- );
7263
- }) })
7264
- ]
7863
+ onCloseAutoFocus: returnFocus.onCloseAutoFocus
7265
7864
  }
7266
- ) });
7865
+ );
7267
7866
  }
7268
7867
 
7269
7868
  // src/components/ui/badge.tsx
7270
- import * as React31 from "react";
7271
- import { jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
7869
+ import * as React34 from "react";
7870
+ import { jsx as jsx44, jsxs as jsxs36 } from "react/jsx-runtime";
7272
7871
  var DOT = {
7273
7872
  error: "var(--semantic-error-fg)",
7274
7873
  warning: "var(--semantic-warning-fg)",
@@ -7277,7 +7876,7 @@ var DOT = {
7277
7876
  neutral: "var(--text-tertiary)",
7278
7877
  brand: "var(--accent-pop)"
7279
7878
  };
7280
- var Badge = React31.forwardRef(
7879
+ var Badge = React34.forwardRef(
7281
7880
  ({ tone = "neutral", className, children, ...props }, ref) => /* @__PURE__ */ jsxs36(
7282
7881
  "span",
7283
7882
  {
@@ -7292,7 +7891,7 @@ var Badge = React31.forwardRef(
7292
7891
  ),
7293
7892
  ...props,
7294
7893
  children: [
7295
- /* @__PURE__ */ jsx40(
7894
+ /* @__PURE__ */ jsx44(
7296
7895
  "span",
7297
7896
  {
7298
7897
  "aria-hidden": "true",
@@ -7309,8 +7908,8 @@ var Badge = React31.forwardRef(
7309
7908
  Badge.displayName = "Badge";
7310
7909
 
7311
7910
  // src/components/ui/two-tier-badge.tsx
7312
- import * as React32 from "react";
7313
- import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
7911
+ import * as React35 from "react";
7912
+ import { jsx as jsx45, jsxs as jsxs37 } from "react/jsx-runtime";
7314
7913
  var FG = {
7315
7914
  neutral: "var(--text-secondary)",
7316
7915
  info: "var(--semantic-info-fg)",
@@ -7331,7 +7930,7 @@ var SEGMENT = {
7331
7930
  md: "gap-[7px] py-[var(--space-1)] px-[var(--space-3)] text-[14px]"
7332
7931
  };
7333
7932
  var DOT2 = { xs: 5, sm: 6, md: 7 };
7334
- var TwoTierBadge = React32.forwardRef(
7933
+ var TwoTierBadge = React35.forwardRef(
7335
7934
  ({ primary, secondary, tone = "neutral", emphasis = "subtle", size = "sm", showDot = false, className, style, ...props }, ref) => {
7336
7935
  const strong = emphasis === "strong";
7337
7936
  const fg = FG[tone];
@@ -7361,7 +7960,7 @@ var TwoTierBadge = React32.forwardRef(
7361
7960
  className: cn("inline-flex items-center whitespace-nowrap font-semibold", SEGMENT[size]),
7362
7961
  style: { color: fg, background: strong ? BG[tone] : "transparent" },
7363
7962
  children: [
7364
- showDot ? /* @__PURE__ */ jsx41(
7963
+ showDot ? /* @__PURE__ */ jsx45(
7365
7964
  "span",
7366
7965
  {
7367
7966
  "aria-hidden": "true",
@@ -7376,11 +7975,11 @@ var TwoTierBadge = React32.forwardRef(
7376
7975
  }
7377
7976
  }
7378
7977
  ) : null,
7379
- /* @__PURE__ */ jsx41("span", { children: primary })
7978
+ /* @__PURE__ */ jsx45("span", { children: primary })
7380
7979
  ]
7381
7980
  }
7382
7981
  ),
7383
- secondary != null ? /* @__PURE__ */ jsx41(
7982
+ secondary != null ? /* @__PURE__ */ jsx45(
7384
7983
  "span",
7385
7984
  {
7386
7985
  "data-slot": "two-tier-badge-secondary",
@@ -7401,8 +8000,8 @@ var TwoTierBadge = React32.forwardRef(
7401
8000
  TwoTierBadge.displayName = "TwoTierBadge";
7402
8001
 
7403
8002
  // src/components/ui/status-badge.tsx
7404
- import * as React33 from "react";
7405
- import { jsx as jsx42, jsxs as jsxs38 } from "react/jsx-runtime";
8003
+ import * as React36 from "react";
8004
+ import { jsx as jsx46, jsxs as jsxs38 } from "react/jsx-runtime";
7406
8005
  var ROLE = {
7407
8006
  error: "error",
7408
8007
  warning: "warning",
@@ -7431,7 +8030,7 @@ var SIZE = {
7431
8030
  sm: { cls: "gap-[6px] py-[var(--space-1)] px-[var(--space-2)] text-[12px]", dot: 6 },
7432
8031
  md: { cls: "gap-[var(--space-2)] py-[var(--space-1)] px-[14px] text-[14px]", dot: 7 }
7433
8032
  };
7434
- var StatusBadge = React33.forwardRef(
8033
+ var StatusBadge = React36.forwardRef(
7435
8034
  ({ status = "active", emphasis = "subtle", size = "sm", showDot = true, pulse = true, className, children, style, ...props }, ref) => {
7436
8035
  const role = ROLE[status];
7437
8036
  const fg = FG2[role];
@@ -7455,7 +8054,7 @@ var StatusBadge = React33.forwardRef(
7455
8054
  },
7456
8055
  ...props,
7457
8056
  children: [
7458
- showDot ? /* @__PURE__ */ jsx42(
8057
+ showDot ? /* @__PURE__ */ jsx46(
7459
8058
  "span",
7460
8059
  {
7461
8060
  "aria-hidden": "true",
@@ -7473,7 +8072,7 @@ var StatusBadge = React33.forwardRef(
7473
8072
  }
7474
8073
  ) : null,
7475
8074
  children,
7476
- /* @__PURE__ */ jsx42("style", { children: "@keyframes olun-status-pulse{0%,100%{opacity:1}50%{opacity:.4}}@media (prefers-reduced-motion: reduce){[data-slot=status-badge-dot]{animation:none!important}}" })
8075
+ /* @__PURE__ */ jsx46("style", { children: "@keyframes olun-status-pulse{0%,100%{opacity:1}50%{opacity:.4}}@media (prefers-reduced-motion: reduce){[data-slot=status-badge-dot]{animation:none!important}}" })
7477
8076
  ]
7478
8077
  }
7479
8078
  );
@@ -7482,9 +8081,9 @@ var StatusBadge = React33.forwardRef(
7482
8081
  StatusBadge.displayName = "StatusBadge";
7483
8082
 
7484
8083
  // src/components/ui/notification-badge.tsx
7485
- import * as React34 from "react";
8084
+ import * as React37 from "react";
7486
8085
  import { cva as cva13 } from "class-variance-authority";
7487
- import { jsx as jsx43 } from "react/jsx-runtime";
8086
+ import { jsx as jsx47 } from "react/jsx-runtime";
7488
8087
  var notificationBadgeVariants = cva13(
7489
8088
  [
7490
8089
  "inline-flex shrink-0 items-center justify-center rounded-[var(--radius-full)]",
@@ -7515,7 +8114,7 @@ function formatNotificationCount(count, max) {
7515
8114
  }
7516
8115
  return String(count);
7517
8116
  }
7518
- var NotificationBadge = React34.forwardRef(
8117
+ var NotificationBadge = React37.forwardRef(
7519
8118
  ({
7520
8119
  className,
7521
8120
  count,
@@ -7530,7 +8129,7 @@ var NotificationBadge = React34.forwardRef(
7530
8129
  }
7531
8130
  const normalizedMax = Math.max(1, Math.floor(max));
7532
8131
  const label = ariaLabel ?? (count > normalizedMax ? `\uC77D\uC9C0 \uC54A\uC740 \uC54C\uB9BC ${normalizedMax}\uAC1C \uC774\uC0C1` : `\uC77D\uC9C0 \uC54A\uC740 \uC54C\uB9BC ${count}\uAC1C`);
7533
- return /* @__PURE__ */ jsx43(
8132
+ return /* @__PURE__ */ jsx47(
7534
8133
  "span",
7535
8134
  {
7536
8135
  ref,
@@ -7548,9 +8147,9 @@ var NotificationBadge = React34.forwardRef(
7548
8147
  NotificationBadge.displayName = "NotificationBadge";
7549
8148
 
7550
8149
  // src/components/ui/empty-state.tsx
7551
- import * as React35 from "react";
8150
+ import * as React38 from "react";
7552
8151
  import { cva as cva14 } from "class-variance-authority";
7553
- import { jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
8152
+ import { jsx as jsx48, jsxs as jsxs39 } from "react/jsx-runtime";
7554
8153
  var emptyStateBaseVariants = cva14(
7555
8154
  [
7556
8155
  "flex flex-col items-center justify-center text-center",
@@ -7622,14 +8221,14 @@ var iconSize3 = {
7622
8221
  md: 20,
7623
8222
  lg: 24
7624
8223
  };
7625
- var EmptyState = React35.forwardRef(
8224
+ var EmptyState = React38.forwardRef(
7626
8225
  ({
7627
8226
  className,
7628
8227
  size = "md",
7629
8228
  tone = "neutral",
7630
8229
  surface,
7631
8230
  icon: Icon,
7632
- title: title2,
8231
+ title,
7633
8232
  description,
7634
8233
  hint,
7635
8234
  action,
@@ -7646,25 +8245,25 @@ var EmptyState = React35.forwardRef(
7646
8245
  className: cn(emptyStateVariants({ size, tone, surface, bordered, className })),
7647
8246
  ...props,
7648
8247
  children: [
7649
- Icon ? /* @__PURE__ */ jsx44(
8248
+ Icon ? /* @__PURE__ */ jsx48(
7650
8249
  "span",
7651
8250
  {
7652
8251
  "aria-hidden": "true",
7653
8252
  "data-slot": "empty-state-icon",
7654
8253
  className: emptyStateIconVariants({ size: resolvedSize }),
7655
- children: /* @__PURE__ */ jsx44(Icon, { size: iconSize3[resolvedSize], strokeWidth: 1.75 })
8254
+ children: /* @__PURE__ */ jsx48(Icon, { size: iconSize3[resolvedSize], strokeWidth: 1.75 })
7656
8255
  }
7657
8256
  ) : null,
7658
8257
  /* @__PURE__ */ jsxs39("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
7659
- /* @__PURE__ */ jsx44(
8258
+ /* @__PURE__ */ jsx48(
7660
8259
  "h2",
7661
8260
  {
7662
8261
  "data-slot": "empty-state-title",
7663
8262
  className: "break-keep text-base font-semibold leading-snug text-foreground",
7664
- children: title2
8263
+ children: title
7665
8264
  }
7666
8265
  ),
7667
- description ? /* @__PURE__ */ jsx44(
8266
+ description ? /* @__PURE__ */ jsx48(
7668
8267
  "p",
7669
8268
  {
7670
8269
  "data-slot": "empty-state-description",
@@ -7672,7 +8271,7 @@ var EmptyState = React35.forwardRef(
7672
8271
  children: description
7673
8272
  }
7674
8273
  ) : null,
7675
- hint ? /* @__PURE__ */ jsx44(
8274
+ hint ? /* @__PURE__ */ jsx48(
7676
8275
  "p",
7677
8276
  {
7678
8277
  "data-slot": "empty-state-hint",
@@ -7681,7 +8280,7 @@ var EmptyState = React35.forwardRef(
7681
8280
  }
7682
8281
  ) : null
7683
8282
  ] }),
7684
- action ? /* @__PURE__ */ jsx44("div", { "data-slot": "empty-state-action", className: "mt-[var(--space-2)]", children: action }) : null
8283
+ action ? /* @__PURE__ */ jsx48("div", { "data-slot": "empty-state-action", className: "mt-[var(--space-2)]", children: action }) : null
7685
8284
  ]
7686
8285
  }
7687
8286
  );
@@ -7690,10 +8289,10 @@ var EmptyState = React35.forwardRef(
7690
8289
  EmptyState.displayName = "EmptyState";
7691
8290
 
7692
8291
  // src/components/ui/error-state.tsx
7693
- import * as React36 from "react";
8292
+ import * as React39 from "react";
7694
8293
  import { AlertTriangle } from "lucide-react";
7695
8294
  import { cva as cva15 } from "class-variance-authority";
7696
- import { jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
8295
+ import { jsx as jsx49, jsxs as jsxs40 } from "react/jsx-runtime";
7697
8296
  var errorStateVariants = cva15(
7698
8297
  [
7699
8298
  "flex flex-col items-center justify-center text-center",
@@ -7715,12 +8314,12 @@ var errorStateVariants = cva15(
7715
8314
  }
7716
8315
  }
7717
8316
  );
7718
- var ErrorState = React36.forwardRef(
8317
+ var ErrorState = React39.forwardRef(
7719
8318
  ({
7720
8319
  className,
7721
8320
  size = "md",
7722
8321
  surface = "surface",
7723
- title: title2 = "\uBD88\uB7EC\uC624\uAE30 \uC2E4\uD328",
8322
+ title = "\uBD88\uB7EC\uC624\uAE30 \uC2E4\uD328",
7724
8323
  message = "\uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.",
7725
8324
  errorCode,
7726
8325
  onRetry,
@@ -7735,25 +8334,25 @@ var ErrorState = React36.forwardRef(
7735
8334
  className: cn(errorStateVariants({ size, surface, className })),
7736
8335
  ...props,
7737
8336
  children: [
7738
- /* @__PURE__ */ jsx45(
8337
+ /* @__PURE__ */ jsx49(
7739
8338
  "span",
7740
8339
  {
7741
8340
  "aria-hidden": "true",
7742
8341
  "data-slot": "error-state-icon",
7743
8342
  className: "inline-flex size-[48px] items-center justify-center rounded-[var(--radius-full)] bg-[var(--error-bg)] text-[var(--error)]",
7744
- children: /* @__PURE__ */ jsx45(AlertTriangle, { size: 24, strokeWidth: 1.75 })
8343
+ children: /* @__PURE__ */ jsx49(AlertTriangle, { size: 24, strokeWidth: 1.75 })
7745
8344
  }
7746
8345
  ),
7747
8346
  /* @__PURE__ */ jsxs40("div", { className: "flex max-w-[420px] flex-col items-center gap-[var(--space-2)]", children: [
7748
- /* @__PURE__ */ jsx45(
8347
+ /* @__PURE__ */ jsx49(
7749
8348
  "h2",
7750
8349
  {
7751
8350
  "data-slot": "error-state-title",
7752
8351
  className: "break-keep text-base font-semibold leading-snug text-foreground",
7753
- children: title2
8352
+ children: title
7754
8353
  }
7755
8354
  ),
7756
- /* @__PURE__ */ jsx45(
8355
+ /* @__PURE__ */ jsx49(
7757
8356
  "p",
7758
8357
  {
7759
8358
  "data-slot": "error-state-message",
@@ -7761,7 +8360,7 @@ var ErrorState = React36.forwardRef(
7761
8360
  children: message
7762
8361
  }
7763
8362
  ),
7764
- errorCode ? /* @__PURE__ */ jsx45(
8363
+ errorCode ? /* @__PURE__ */ jsx49(
7765
8364
  "p",
7766
8365
  {
7767
8366
  "data-slot": "error-state-code",
@@ -7770,7 +8369,7 @@ var ErrorState = React36.forwardRef(
7770
8369
  }
7771
8370
  ) : null
7772
8371
  ] }),
7773
- onRetry ? /* @__PURE__ */ jsx45(Button, { size: "sm", variant: "secondary", onClick: onRetry, children: retryLabel }) : null
8372
+ onRetry ? /* @__PURE__ */ jsx49(Button, { size: "sm", variant: "secondary", onClick: onRetry, children: retryLabel }) : null
7774
8373
  ]
7775
8374
  }
7776
8375
  )
@@ -7778,9 +8377,9 @@ var ErrorState = React36.forwardRef(
7778
8377
  ErrorState.displayName = "ErrorState";
7779
8378
 
7780
8379
  // src/components/ui/skeleton.tsx
7781
- import * as React37 from "react";
8380
+ import * as React40 from "react";
7782
8381
  import { cva as cva16 } from "class-variance-authority";
7783
- import { jsx as jsx46 } from "react/jsx-runtime";
8382
+ import { jsx as jsx50 } from "react/jsx-runtime";
7784
8383
  var skeletonVariants = cva16(
7785
8384
  [
7786
8385
  // bg-inset: light #F1F2F4 reads on white surfaces (bg-raised was white = invisible);
@@ -7824,8 +8423,8 @@ var spinnerVariants = cva16(
7824
8423
  }
7825
8424
  }
7826
8425
  );
7827
- var Skeleton = React37.forwardRef(
7828
- ({ className, shape, style, ...props }, ref) => /* @__PURE__ */ jsx46(
8426
+ var Skeleton = React40.forwardRef(
8427
+ ({ className, shape, style, ...props }, ref) => /* @__PURE__ */ jsx50(
7829
8428
  "div",
7830
8429
  {
7831
8430
  ref,
@@ -7838,15 +8437,15 @@ var Skeleton = React37.forwardRef(
7838
8437
  );
7839
8438
  Skeleton.displayName = "Skeleton";
7840
8439
  var defaultTextWidths = ["92%", "84%", "68%", "76%"];
7841
- var SkeletonText = React37.forwardRef(
7842
- ({ className, lines = 3, widths = defaultTextWidths, ...props }, ref) => /* @__PURE__ */ jsx46(
8440
+ var SkeletonText = React40.forwardRef(
8441
+ ({ className, lines = 3, widths = defaultTextWidths, ...props }, ref) => /* @__PURE__ */ jsx50(
7843
8442
  "div",
7844
8443
  {
7845
8444
  ref,
7846
8445
  "data-slot": "skeleton-text",
7847
8446
  className: cn("flex flex-col gap-[var(--space-2)]", className),
7848
8447
  ...props,
7849
- children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx46(
8448
+ children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx50(
7850
8449
  Skeleton,
7851
8450
  {
7852
8451
  shape: "text",
@@ -7858,7 +8457,7 @@ var SkeletonText = React37.forwardRef(
7858
8457
  )
7859
8458
  );
7860
8459
  SkeletonText.displayName = "SkeletonText";
7861
- var SkeletonRow = React37.forwardRef(
8460
+ var SkeletonRow = React40.forwardRef(
7862
8461
  ({
7863
8462
  className,
7864
8463
  columns,
@@ -7869,7 +8468,7 @@ var SkeletonRow = React37.forwardRef(
7869
8468
  }, ref) => {
7870
8469
  const rowCount = Math.max(5, count);
7871
8470
  const gridTemplateColumns = columns.map((column) => column.width ?? "1fr").join(" ");
7872
- return /* @__PURE__ */ jsx46(
8471
+ return /* @__PURE__ */ jsx50(
7873
8472
  "div",
7874
8473
  {
7875
8474
  ref,
@@ -7883,7 +8482,7 @@ var SkeletonRow = React37.forwardRef(
7883
8482
  className
7884
8483
  ),
7885
8484
  ...props,
7886
- children: Array.from({ length: rowCount }, (_, rowIndex) => /* @__PURE__ */ jsx46(
8485
+ children: Array.from({ length: rowCount }, (_, rowIndex) => /* @__PURE__ */ jsx50(
7887
8486
  "div",
7888
8487
  {
7889
8488
  "data-slot": "skeleton-row",
@@ -7891,11 +8490,11 @@ var SkeletonRow = React37.forwardRef(
7891
8490
  "grid min-h-[48px] items-center border-t border-[var(--border-subtle)] first:border-t-0"
7892
8491
  ),
7893
8492
  style: { gridTemplateColumns },
7894
- children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx46(
8493
+ children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx50(
7895
8494
  "div",
7896
8495
  {
7897
8496
  className: "px-[var(--space-4)] py-[var(--space-2)]",
7898
- children: /* @__PURE__ */ jsx46(
8497
+ children: /* @__PURE__ */ jsx50(
7899
8498
  Skeleton,
7900
8499
  {
7901
8500
  shape: "text",
@@ -7915,8 +8514,8 @@ var SkeletonRow = React37.forwardRef(
7915
8514
  }
7916
8515
  );
7917
8516
  SkeletonRow.displayName = "SkeletonRow";
7918
- var Spinner = React37.forwardRef(
7919
- ({ className, size, label = "\uB85C\uB529 \uC911", ...props }, ref) => /* @__PURE__ */ jsx46(
8517
+ var Spinner = React40.forwardRef(
8518
+ ({ className, size, label = "\uB85C\uB529 \uC911", ...props }, ref) => /* @__PURE__ */ jsx50(
7920
8519
  "span",
7921
8520
  {
7922
8521
  ref,
@@ -7931,12 +8530,12 @@ var Spinner = React37.forwardRef(
7931
8530
  Spinner.displayName = "Spinner";
7932
8531
 
7933
8532
  // src/components/ui/pagination.tsx
7934
- import * as React38 from "react";
8533
+ import * as React41 from "react";
7935
8534
  import { ChevronsLeft, ChevronLeft, ChevronRight as ChevronRight2, ChevronsRight } from "lucide-react";
7936
8535
  import { cva as cva17 } from "class-variance-authority";
7937
8536
 
7938
8537
  // src/components/ui/page-size-select.tsx
7939
- import { jsx as jsx47, jsxs as jsxs41 } from "react/jsx-runtime";
8538
+ import { jsx as jsx51, jsxs as jsxs41 } from "react/jsx-runtime";
7940
8539
  var DEFAULT_OPTIONS = [10, 20, 50, 100];
7941
8540
  function PageSizeSelect({
7942
8541
  value,
@@ -7964,8 +8563,8 @@ function PageSizeSelect({
7964
8563
  className
7965
8564
  ),
7966
8565
  children: [
7967
- label != null ? /* @__PURE__ */ jsx47("span", { children: label }) : null,
7968
- /* @__PURE__ */ jsx47(
8566
+ label != null ? /* @__PURE__ */ jsx51("span", { children: label }) : null,
8567
+ /* @__PURE__ */ jsx51(
7969
8568
  Select,
7970
8569
  {
7971
8570
  id,
@@ -7987,7 +8586,7 @@ function PageSizeSelect({
7987
8586
  }
7988
8587
 
7989
8588
  // src/components/ui/pagination.tsx
7990
- import { jsx as jsx48, jsxs as jsxs42 } from "react/jsx-runtime";
8589
+ import { jsx as jsx52, jsxs as jsxs42 } from "react/jsx-runtime";
7991
8590
  var paginationVariants = cva17(
7992
8591
  [
7993
8592
  "flex w-full flex-col gap-[var(--space-3)]",
@@ -8060,7 +8659,7 @@ function NavigationButton({
8060
8659
  icon: Icon,
8061
8660
  onPageChange
8062
8661
  }) {
8063
- return /* @__PURE__ */ jsx48(
8662
+ return /* @__PURE__ */ jsx52(
8064
8663
  "button",
8065
8664
  {
8066
8665
  "aria-label": label,
@@ -8068,11 +8667,11 @@ function NavigationButton({
8068
8667
  className: paginationControlVariants({ size }),
8069
8668
  type: "button",
8070
8669
  onClick: () => onPageChange?.(page),
8071
- children: /* @__PURE__ */ jsx48(Icon, { "aria-hidden": "true", "data-slot": "pagination-icon" })
8670
+ children: /* @__PURE__ */ jsx52(Icon, { "aria-hidden": "true", "data-slot": "pagination-icon" })
8072
8671
  }
8073
8672
  );
8074
8673
  }
8075
- var Pagination = React38.forwardRef(
8674
+ var Pagination = React41.forwardRef(
8076
8675
  ({
8077
8676
  className,
8078
8677
  size = "standard",
@@ -8108,8 +8707,8 @@ var Pagination = React38.forwardRef(
8108
8707
  ...props,
8109
8708
  children: [
8110
8709
  /* @__PURE__ */ jsxs42("div", { className: "flex flex-wrap items-center gap-[var(--space-3)]", children: [
8111
- /* @__PURE__ */ jsx48("span", { "data-slot": "pagination-total", className: "font-medium text-text-secondary", children: totalLabel(total) }),
8112
- showPageSize ? /* @__PURE__ */ jsx48("div", { "data-slot": "pagination-size", children: /* @__PURE__ */ jsx48(
8710
+ /* @__PURE__ */ jsx52("span", { "data-slot": "pagination-total", className: "font-medium text-text-secondary", children: totalLabel(total) }),
8711
+ showPageSize ? /* @__PURE__ */ jsx52("div", { "data-slot": "pagination-size", children: /* @__PURE__ */ jsx52(
8113
8712
  PageSizeSelect,
8114
8713
  {
8115
8714
  label: pageSizeLabel,
@@ -8127,7 +8726,7 @@ var Pagination = React38.forwardRef(
8127
8726
  "data-slot": "pagination-list",
8128
8727
  className: "flex items-center justify-center gap-[var(--space-1)]",
8129
8728
  children: [
8130
- /* @__PURE__ */ jsx48(
8729
+ /* @__PURE__ */ jsx52(
8131
8730
  NavigationButton,
8132
8731
  {
8133
8732
  label: "\uCCAB \uD398\uC774\uC9C0",
@@ -8138,7 +8737,7 @@ var Pagination = React38.forwardRef(
8138
8737
  onPageChange
8139
8738
  }
8140
8739
  ),
8141
- /* @__PURE__ */ jsx48(
8740
+ /* @__PURE__ */ jsx52(
8142
8741
  NavigationButton,
8143
8742
  {
8144
8743
  label: "\uC774\uC804 \uD398\uC774\uC9C0",
@@ -8150,7 +8749,7 @@ var Pagination = React38.forwardRef(
8150
8749
  }
8151
8750
  ),
8152
8751
  items.map(
8153
- (item, index) => item === "ellipsis" ? /* @__PURE__ */ jsx48(
8752
+ (item, index) => item === "ellipsis" ? /* @__PURE__ */ jsx52(
8154
8753
  "span",
8155
8754
  {
8156
8755
  "data-slot": "pagination-ellipsis",
@@ -8162,7 +8761,7 @@ var Pagination = React38.forwardRef(
8162
8761
  children: "..."
8163
8762
  },
8164
8763
  `ellipsis-${index}`
8165
- ) : /* @__PURE__ */ jsx48(
8764
+ ) : /* @__PURE__ */ jsx52(
8166
8765
  "button",
8167
8766
  {
8168
8767
  "aria-label": `${item} \uD398\uC774\uC9C0`,
@@ -8176,7 +8775,7 @@ var Pagination = React38.forwardRef(
8176
8775
  item
8177
8776
  )
8178
8777
  ),
8179
- /* @__PURE__ */ jsx48(
8778
+ /* @__PURE__ */ jsx52(
8180
8779
  NavigationButton,
8181
8780
  {
8182
8781
  label: "\uB2E4\uC74C \uD398\uC774\uC9C0",
@@ -8187,7 +8786,7 @@ var Pagination = React38.forwardRef(
8187
8786
  onPageChange
8188
8787
  }
8189
8788
  ),
8190
- /* @__PURE__ */ jsx48(
8789
+ /* @__PURE__ */ jsx52(
8191
8790
  NavigationButton,
8192
8791
  {
8193
8792
  label: "\uB9C8\uC9C0\uB9C9 \uD398\uC774\uC9C0",
@@ -8210,7 +8809,7 @@ Pagination.displayName = "Pagination";
8210
8809
 
8211
8810
  // src/components/ui/mode-toggle.tsx
8212
8811
  import { cva as cva18 } from "class-variance-authority";
8213
- import { jsx as jsx49, jsxs as jsxs43 } from "react/jsx-runtime";
8812
+ import { jsx as jsx53, jsxs as jsxs43 } from "react/jsx-runtime";
8214
8813
  var modeToggleVariants = cva18(
8215
8814
  [
8216
8815
  "inline-flex items-center rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
@@ -8240,7 +8839,7 @@ function ModeToggle({
8240
8839
  onChange,
8241
8840
  ...props
8242
8841
  }) {
8243
- return /* @__PURE__ */ jsx49(
8842
+ return /* @__PURE__ */ jsx53(
8244
8843
  "div",
8245
8844
  {
8246
8845
  role: "group",
@@ -8266,8 +8865,8 @@ function ModeToggle({
8266
8865
  }
8267
8866
  },
8268
8867
  children: [
8269
- Icon ? /* @__PURE__ */ jsx49(Icon, { "aria-hidden": "true", "data-slot": "mode-toggle-icon" }) : null,
8270
- /* @__PURE__ */ jsx49("span", { children: option.label })
8868
+ Icon ? /* @__PURE__ */ jsx53(Icon, { "aria-hidden": "true", "data-slot": "mode-toggle-icon" }) : null,
8869
+ /* @__PURE__ */ jsx53("span", { children: option.label })
8271
8870
  ]
8272
8871
  },
8273
8872
  option.value
@@ -8278,9 +8877,9 @@ function ModeToggle({
8278
8877
  }
8279
8878
 
8280
8879
  // src/components/ui/action-footer.tsx
8281
- import * as React39 from "react";
8880
+ import * as React42 from "react";
8282
8881
  import { cva as cva19 } from "class-variance-authority";
8283
- import { jsx as jsx50, jsxs as jsxs44 } from "react/jsx-runtime";
8882
+ import { jsx as jsx54, jsxs as jsxs44 } from "react/jsx-runtime";
8284
8883
  var actionFooterVariants = cva19(
8285
8884
  [
8286
8885
  "flex flex-wrap items-center gap-[var(--space-4)] border-t border-[var(--border-subtle)]",
@@ -8351,7 +8950,7 @@ function getStatusLabel(status) {
8351
8950
  }
8352
8951
  }
8353
8952
  function renderAction(action) {
8354
- return /* @__PURE__ */ jsx50(
8953
+ return /* @__PURE__ */ jsx54(
8355
8954
  Button,
8356
8955
  {
8357
8956
  variant: action.variant,
@@ -8366,7 +8965,7 @@ function renderAction(action) {
8366
8965
  action.id ?? action.label
8367
8966
  );
8368
8967
  }
8369
- var ActionFooter = React39.forwardRef(
8968
+ var ActionFooter = React42.forwardRef(
8370
8969
  ({
8371
8970
  className,
8372
8971
  status,
@@ -8392,7 +8991,7 @@ var ActionFooter = React39.forwardRef(
8392
8991
  className: cn(actionFooterVariants({ position, surface, className })),
8393
8992
  ...props,
8394
8993
  children: [
8395
- destructiveActions.length > 0 ? /* @__PURE__ */ jsx50(
8994
+ destructiveActions.length > 0 ? /* @__PURE__ */ jsx54(
8396
8995
  "div",
8397
8996
  {
8398
8997
  "data-slot": "action-footer-destructive-actions",
@@ -8408,7 +9007,7 @@ var ActionFooter = React39.forwardRef(
8408
9007
  "aria-live": "polite",
8409
9008
  className: cn(actionFooterStatusVariants({ kind: status.kind })),
8410
9009
  children: [
8411
- /* @__PURE__ */ jsx50(
9010
+ /* @__PURE__ */ jsx54(
8412
9011
  "span",
8413
9012
  {
8414
9013
  "aria-hidden": "true",
@@ -8416,11 +9015,11 @@ var ActionFooter = React39.forwardRef(
8416
9015
  className: "size-[6px] shrink-0 rounded-[var(--radius-full)]"
8417
9016
  }
8418
9017
  ),
8419
- /* @__PURE__ */ jsx50("span", { className: "truncate", children: getStatusLabel(status) })
9018
+ /* @__PURE__ */ jsx54("span", { className: "truncate", children: getStatusLabel(status) })
8420
9019
  ]
8421
9020
  }
8422
9021
  ) : null,
8423
- /* @__PURE__ */ jsx50(
9022
+ /* @__PURE__ */ jsx54(
8424
9023
  "div",
8425
9024
  {
8426
9025
  "data-slot": "action-footer-main-actions",
@@ -8436,9 +9035,9 @@ var ActionFooter = React39.forwardRef(
8436
9035
  ActionFooter.displayName = "ActionFooter";
8437
9036
 
8438
9037
  // src/components/ui/toast.tsx
8439
- import * as React40 from "react";
9038
+ import * as React43 from "react";
8440
9039
  import { cva as cva20 } from "class-variance-authority";
8441
- import { jsx as jsx51, jsxs as jsxs45 } from "react/jsx-runtime";
9040
+ import { jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
8442
9041
  var DOT3 = {
8443
9042
  default: "var(--neutral)",
8444
9043
  success: "var(--success)",
@@ -8556,7 +9155,7 @@ var toast = {
8556
9155
  }
8557
9156
  };
8558
9157
  var Toast = toast;
8559
- var ToastRoot = React40.forwardRef(
9158
+ var ToastRoot = React43.forwardRef(
8560
9159
  ({
8561
9160
  className,
8562
9161
  id,
@@ -8573,10 +9172,10 @@ var ToastRoot = React40.forwardRef(
8573
9172
  ...props
8574
9173
  }, ref) => {
8575
9174
  const durationMs = getToastDuration({ message, variant, duration });
8576
- const onCloseRef = React40.useRef(onClose);
9175
+ const onCloseRef = React43.useRef(onClose);
8577
9176
  onCloseRef.current = onClose;
8578
- const timerRef = React40.useRef(null);
8579
- React40.useEffect(() => {
9177
+ const timerRef = React43.useRef(null);
9178
+ React43.useEffect(() => {
8580
9179
  if (!onCloseRef.current) return void 0;
8581
9180
  const timer = createToastTimer(durationMs, () => onCloseRef.current?.());
8582
9181
  timerRef.current = timer;
@@ -8613,7 +9212,7 @@ var ToastRoot = React40.forwardRef(
8613
9212
  },
8614
9213
  ...props,
8615
9214
  children: [
8616
- /* @__PURE__ */ jsx51(
9215
+ /* @__PURE__ */ jsx55(
8617
9216
  "span",
8618
9217
  {
8619
9218
  "aria-hidden": "true",
@@ -8623,7 +9222,7 @@ var ToastRoot = React40.forwardRef(
8623
9222
  }
8624
9223
  ),
8625
9224
  /* @__PURE__ */ jsxs45("div", { "data-slot": "toast-body", className: "min-w-0 flex-1", children: [
8626
- /* @__PURE__ */ jsx51(
9225
+ /* @__PURE__ */ jsx55(
8627
9226
  "div",
8628
9227
  {
8629
9228
  "data-slot": "toast-message",
@@ -8631,7 +9230,7 @@ var ToastRoot = React40.forwardRef(
8631
9230
  children: message
8632
9231
  }
8633
9232
  ),
8634
- description ? /* @__PURE__ */ jsx51(
9233
+ description ? /* @__PURE__ */ jsx55(
8635
9234
  "div",
8636
9235
  {
8637
9236
  "data-slot": "toast-description",
@@ -8641,7 +9240,7 @@ var ToastRoot = React40.forwardRef(
8641
9240
  ) : null
8642
9241
  ] }),
8643
9242
  /* @__PURE__ */ jsxs45("div", { "data-slot": "toast-actions", className: "flex shrink-0 items-center gap-[2px]", children: [
8644
- action ? /* @__PURE__ */ jsx51(
9243
+ action ? /* @__PURE__ */ jsx55(
8645
9244
  Button,
8646
9245
  {
8647
9246
  "data-slot": "toast-action",
@@ -8651,7 +9250,7 @@ var ToastRoot = React40.forwardRef(
8651
9250
  children: action.label
8652
9251
  }
8653
9252
  ) : null,
8654
- /* @__PURE__ */ jsx51(
9253
+ /* @__PURE__ */ jsx55(
8655
9254
  "button",
8656
9255
  {
8657
9256
  type: "button",
@@ -8673,7 +9272,7 @@ var ToastRoot = React40.forwardRef(
8673
9272
  }
8674
9273
  );
8675
9274
  ToastRoot.displayName = "ToastRoot";
8676
- var ToastViewport = React40.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx51(
9275
+ var ToastViewport = React43.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx55(
8677
9276
  "ol",
8678
9277
  {
8679
9278
  ref,
@@ -8684,8 +9283,8 @@ var ToastViewport = React40.forwardRef(({ className, ...props }, ref) => /* @__P
8684
9283
  ));
8685
9284
  ToastViewport.displayName = "ToastViewport";
8686
9285
  function ToastProvider({ children, maxToasts = 3, className, ...props }) {
8687
- const [items, setItems] = React40.useState([]);
8688
- React40.useEffect(
9286
+ const [items, setItems] = React43.useState([]);
9287
+ React43.useEffect(
8689
9288
  () => toast.subscribe((nextItems) => {
8690
9289
  setItems(limitToasts(nextItems, maxToasts));
8691
9290
  }),
@@ -8693,15 +9292,15 @@ function ToastProvider({ children, maxToasts = 3, className, ...props }) {
8693
9292
  );
8694
9293
  return /* @__PURE__ */ jsxs45("div", { "data-slot": "toast-provider", className, ...props, children: [
8695
9294
  children,
8696
- /* @__PURE__ */ jsx51(ToastViewport, { children: items.map((item) => /* @__PURE__ */ jsx51("li", { children: /* @__PURE__ */ jsx51(ToastRoot, { ...item, onClose: () => toast.dismiss(item.id) }) }, item.id)) })
9295
+ /* @__PURE__ */ jsx55(ToastViewport, { children: items.map((item) => /* @__PURE__ */ jsx55("li", { children: /* @__PURE__ */ jsx55(ToastRoot, { ...item, onClose: () => toast.dismiss(item.id) }) }, item.id)) })
8697
9296
  ] });
8698
9297
  }
8699
9298
 
8700
9299
  // src/components/ui/otp-field.tsx
8701
- import * as React41 from "react";
9300
+ import * as React44 from "react";
8702
9301
  import { cva as cva21 } from "class-variance-authority";
8703
9302
  import { AlertCircle as AlertCircle4 } from "lucide-react";
8704
- import { Fragment as Fragment9, jsx as jsx52, jsxs as jsxs46 } from "react/jsx-runtime";
9303
+ import { Fragment as Fragment12, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
8705
9304
  var otpFieldVariants = cva21("flex w-full min-w-0 flex-col gap-[var(--space-3)]", {
8706
9305
  variants: {
8707
9306
  size: {
@@ -8828,7 +9427,7 @@ function fillDigitsFromIndex(slots, index, inserted, length) {
8828
9427
  focusIndex: Math.min(cursor, length - 1)
8829
9428
  };
8830
9429
  }
8831
- var OTPField = React41.forwardRef(
9430
+ var OTPField = React44.forwardRef(
8832
9431
  ({
8833
9432
  className,
8834
9433
  defaultValue,
@@ -8850,24 +9449,24 @@ var OTPField = React41.forwardRef(
8850
9449
  required,
8851
9450
  ...props
8852
9451
  }, ref) => {
8853
- const generatedId = React41.useId();
9452
+ const generatedId = React44.useId();
8854
9453
  const fieldId = id ?? generatedId;
8855
9454
  const labelId = `${fieldId}-label`;
8856
9455
  const helperId = helperText ? `${fieldId}-helper` : void 0;
8857
9456
  const errorId = errorText ? `${fieldId}-error` : void 0;
8858
9457
  const resolvedState = invalid || errorText ? "error" : "default";
8859
9458
  const isControlled = value !== void 0;
8860
- const [uncontrolledSlots, setUncontrolledSlots] = React41.useState(
9459
+ const [uncontrolledSlots, setUncontrolledSlots] = React44.useState(
8861
9460
  () => toDigitsArray(onlyDigits(defaultValue, length), length)
8862
9461
  );
8863
- const resolvedSlots = React41.useMemo(
9462
+ const resolvedSlots = React44.useMemo(
8864
9463
  () => isControlled ? toDigitsArray(onlyDigits(value, length), length) : uncontrolledSlots,
8865
9464
  [isControlled, length, uncontrolledSlots, value]
8866
9465
  );
8867
9466
  const resolvedValue = joinDigits(resolvedSlots).slice(0, length);
8868
- const cellsRef = React41.useRef([]);
9467
+ const cellsRef = React44.useRef([]);
8869
9468
  const groupDescribedBy = [helperId, errorId].filter(Boolean).join(" ") || void 0;
8870
- const setResolvedValue = React41.useCallback(
9469
+ const setResolvedValue = React44.useCallback(
8871
9470
  (nextSlots, focusIndex) => {
8872
9471
  const normalizedSlots = nextSlots.slice(0, length);
8873
9472
  const normalizedValue = joinDigits(normalizedSlots).slice(0, length);
@@ -8907,11 +9506,11 @@ var OTPField = React41.forwardRef(
8907
9506
  className: "text-sm font-medium leading-snug text-foreground",
8908
9507
  children: [
8909
9508
  label,
8910
- required ? /* @__PURE__ */ jsx52("span", { "aria-hidden": "true", className: "ml-1 font-bold text-[var(--error)]", children: "*" }) : null
9509
+ required ? /* @__PURE__ */ jsx56("span", { "aria-hidden": "true", className: "ml-1 font-bold text-[var(--error)]", children: "*" }) : null
8911
9510
  ]
8912
9511
  }
8913
9512
  ),
8914
- /* @__PURE__ */ jsx52(
9513
+ /* @__PURE__ */ jsx56(
8915
9514
  "div",
8916
9515
  {
8917
9516
  "data-slot": "otp-field-group",
@@ -8921,7 +9520,7 @@ var OTPField = React41.forwardRef(
8921
9520
  children: Array.from({ length }, (_, index) => {
8922
9521
  const digit = resolvedSlots[index] ?? "";
8923
9522
  const inputId = `${fieldId}-cell-${index + 1}`;
8924
- return /* @__PURE__ */ jsx52(
9523
+ return /* @__PURE__ */ jsx56(
8925
9524
  "input",
8926
9525
  {
8927
9526
  ref: (node) => {
@@ -9016,15 +9615,15 @@ var OTPField = React41.forwardRef(
9016
9615
  })
9017
9616
  }
9018
9617
  ),
9019
- helperText || errorText ? /* @__PURE__ */ jsx52(
9618
+ helperText || errorText ? /* @__PURE__ */ jsx56(
9020
9619
  "p",
9021
9620
  {
9022
9621
  id: errorText ? errorId : helperId,
9023
9622
  "data-slot": "otp-field-message",
9024
9623
  "data-kind": errorText ? "error" : "helper",
9025
9624
  className: otpFieldMessageVariants({ state: resolvedState }),
9026
- children: errorText ? /* @__PURE__ */ jsxs46(Fragment9, { children: [
9027
- /* @__PURE__ */ jsx52(
9625
+ children: errorText ? /* @__PURE__ */ jsxs46(Fragment12, { children: [
9626
+ /* @__PURE__ */ jsx56(
9028
9627
  AlertCircle4,
9029
9628
  {
9030
9629
  "aria-hidden": "true",
@@ -9032,11 +9631,11 @@ var OTPField = React41.forwardRef(
9032
9631
  strokeWidth: 2
9033
9632
  }
9034
9633
  ),
9035
- /* @__PURE__ */ jsx52("span", { children: errorText })
9036
- ] }) : /* @__PURE__ */ jsx52("span", { children: helperText })
9634
+ /* @__PURE__ */ jsx56("span", { children: errorText })
9635
+ ] }) : /* @__PURE__ */ jsx56("span", { children: helperText })
9037
9636
  }
9038
9637
  ) : null,
9039
- name ? /* @__PURE__ */ jsx52(
9638
+ name ? /* @__PURE__ */ jsx56(
9040
9639
  "input",
9041
9640
  {
9042
9641
  "aria-hidden": "true",
@@ -9057,10 +9656,10 @@ var OTPField = React41.forwardRef(
9057
9656
  OTPField.displayName = "OTPField";
9058
9657
 
9059
9658
  // src/components/ui/search-field.tsx
9060
- import * as React42 from "react";
9659
+ import * as React45 from "react";
9061
9660
  import { Search, X as X4 } from "lucide-react";
9062
9661
  import { cva as cva22 } from "class-variance-authority";
9063
- import { jsx as jsx53, jsxs as jsxs47 } from "react/jsx-runtime";
9662
+ import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
9064
9663
  var searchFieldVariants = cva22("relative flex w-full items-center", {
9065
9664
  variants: {
9066
9665
  size: {
@@ -9125,7 +9724,7 @@ var iconSize4 = {
9125
9724
  function hasVisibleValue(value) {
9126
9725
  return typeof value === "string" ? value.length > 0 : value !== void 0;
9127
9726
  }
9128
- var SearchField = React42.forwardRef(
9727
+ var SearchField = React45.forwardRef(
9129
9728
  ({
9130
9729
  className,
9131
9730
  inputMode = "search",
@@ -9141,12 +9740,12 @@ var SearchField = React42.forwardRef(
9141
9740
  ...props
9142
9741
  }, ref) => {
9143
9742
  const resolvedSize = size ?? "md";
9144
- const inputRef = React42.useRef(null);
9145
- const [hasText, setHasText] = React42.useState(
9743
+ const inputRef = React45.useRef(null);
9744
+ const [hasText, setHasText] = React45.useState(
9146
9745
  () => hasVisibleValue(value ?? defaultValue)
9147
9746
  );
9148
- React42.useImperativeHandle(ref, () => inputRef.current);
9149
- React42.useEffect(() => {
9747
+ React45.useImperativeHandle(ref, () => inputRef.current);
9748
+ React45.useEffect(() => {
9150
9749
  if (value !== void 0) {
9151
9750
  setHasText(hasVisibleValue(value));
9152
9751
  }
@@ -9166,7 +9765,7 @@ var SearchField = React42.forwardRef(
9166
9765
  "data-size": resolvedSize,
9167
9766
  className: cn(searchFieldVariants({ size, className })),
9168
9767
  children: [
9169
- /* @__PURE__ */ jsx53(
9768
+ /* @__PURE__ */ jsx57(
9170
9769
  Search,
9171
9770
  {
9172
9771
  "aria-hidden": "true",
@@ -9176,7 +9775,7 @@ var SearchField = React42.forwardRef(
9176
9775
  strokeWidth: resolvedSize === "sm" ? 2 : 1.75
9177
9776
  }
9178
9777
  ),
9179
- /* @__PURE__ */ jsx53(
9778
+ /* @__PURE__ */ jsx57(
9180
9779
  "input",
9181
9780
  {
9182
9781
  ref: inputRef,
@@ -9197,7 +9796,7 @@ var SearchField = React42.forwardRef(
9197
9796
  ...props
9198
9797
  }
9199
9798
  ),
9200
- showClear ? /* @__PURE__ */ jsx53(
9799
+ showClear ? /* @__PURE__ */ jsx57(
9201
9800
  "button",
9202
9801
  {
9203
9802
  type: "button",
@@ -9205,7 +9804,7 @@ var SearchField = React42.forwardRef(
9205
9804
  "data-slot": "search-field-clear",
9206
9805
  className: "absolute right-[8px] top-1/2 inline-flex size-[var(--space-4)] -translate-y-1/2 cursor-pointer items-center justify-center rounded-[var(--radius-full)] text-text-tertiary transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
9207
9806
  onClick: clearInput,
9208
- children: /* @__PURE__ */ jsx53(X4, { "aria-hidden": "true", size: 16, strokeWidth: 1.75 })
9807
+ children: /* @__PURE__ */ jsx57(X4, { "aria-hidden": "true", size: 16, strokeWidth: 1.75 })
9209
9808
  }
9210
9809
  ) : null
9211
9810
  ]
@@ -9216,9 +9815,9 @@ var SearchField = React42.forwardRef(
9216
9815
  SearchField.displayName = "SearchField";
9217
9816
 
9218
9817
  // src/components/ui/checkbox-group.tsx
9219
- import * as React43 from "react";
9818
+ import * as React46 from "react";
9220
9819
  import { cva as cva23 } from "class-variance-authority";
9221
- import { jsx as jsx54 } from "react/jsx-runtime";
9820
+ import { jsx as jsx58 } from "react/jsx-runtime";
9222
9821
  var checkboxGroupVariants = cva23("gap-[var(--space-2)]", {
9223
9822
  variants: {
9224
9823
  appearance: {
@@ -9244,7 +9843,7 @@ var checkboxGroupVariants = cva23("gap-[var(--space-2)]", {
9244
9843
  function toSelectionSet(value) {
9245
9844
  return new Set(value ?? []);
9246
9845
  }
9247
- var CheckboxGroup = React43.forwardRef(
9846
+ var CheckboxGroup = React46.forwardRef(
9248
9847
  ({
9249
9848
  className,
9250
9849
  children,
@@ -9260,14 +9859,14 @@ var CheckboxGroup = React43.forwardRef(
9260
9859
  ...props
9261
9860
  }, ref) => {
9262
9861
  const isControlled = value != null;
9263
- const [uncontrolledValue, setUncontrolledValue] = React43.useState(
9862
+ const [uncontrolledValue, setUncontrolledValue] = React46.useState(
9264
9863
  () => toSelectionSet(defaultValue)
9265
9864
  );
9266
- const selectedValues = React43.useMemo(
9865
+ const selectedValues = React46.useMemo(
9267
9866
  () => isControlled ? toSelectionSet(value) : uncontrolledValue,
9268
9867
  [isControlled, uncontrolledValue, value]
9269
9868
  );
9270
- const toggleValue = React43.useCallback(
9869
+ const toggleValue = React46.useCallback(
9271
9870
  (itemValue, checked) => {
9272
9871
  const nextValues = new Set(selectedValues);
9273
9872
  if (checked) {
@@ -9283,7 +9882,7 @@ var CheckboxGroup = React43.forwardRef(
9283
9882
  },
9284
9883
  [isControlled, onValueChange, selectedValues]
9285
9884
  );
9286
- const contextValue = React43.useMemo(
9885
+ const contextValue = React46.useMemo(
9287
9886
  () => ({
9288
9887
  appearance,
9289
9888
  density,
@@ -9294,7 +9893,7 @@ var CheckboxGroup = React43.forwardRef(
9294
9893
  }),
9295
9894
  [appearance, density, disabled, name, selectedValues, toggleValue]
9296
9895
  );
9297
- return /* @__PURE__ */ jsx54(CheckboxGroupContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx54(
9896
+ return /* @__PURE__ */ jsx58(CheckboxGroupContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx58(
9298
9897
  "div",
9299
9898
  {
9300
9899
  ref,
@@ -9318,11 +9917,11 @@ var CheckboxGroup = React43.forwardRef(
9318
9917
  CheckboxGroup.displayName = "CheckboxGroup";
9319
9918
 
9320
9919
  // src/components/ui/radio-group.tsx
9321
- import * as React44 from "react";
9920
+ import * as React47 from "react";
9322
9921
  import { cva as cva24 } from "class-variance-authority";
9323
9922
  import { Circle } from "lucide-react";
9324
9923
  import { RadioGroup as RadioGroupPrimitive } from "radix-ui";
9325
- import { jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
9924
+ import { jsx as jsx59, jsxs as jsxs48 } from "react/jsx-runtime";
9326
9925
  var radioGroupVariants = cva24("gap-[var(--space-2)]", {
9327
9926
  variants: {
9328
9927
  appearance: {
@@ -9411,11 +10010,11 @@ var radioControlVariants = cva24(
9411
10010
  }
9412
10011
  }
9413
10012
  );
9414
- var RadioGroupContext = React44.createContext({
10013
+ var RadioGroupContext = React47.createContext({
9415
10014
  appearance: "plain",
9416
10015
  density: "comfortable"
9417
10016
  });
9418
- var RadioGroup = React44.forwardRef(
10017
+ var RadioGroup = React47.forwardRef(
9419
10018
  ({
9420
10019
  className,
9421
10020
  children,
@@ -9426,11 +10025,11 @@ var RadioGroup = React44.forwardRef(
9426
10025
  required,
9427
10026
  ...props
9428
10027
  }, ref) => {
9429
- const contextValue = React44.useMemo(
10028
+ const contextValue = React47.useMemo(
9430
10029
  () => ({ appearance, density }),
9431
10030
  [appearance, density]
9432
10031
  );
9433
- return /* @__PURE__ */ jsx55(RadioGroupContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx55(
10032
+ return /* @__PURE__ */ jsx59(RadioGroupContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx59(
9434
10033
  RadioGroupPrimitive.Root,
9435
10034
  {
9436
10035
  ref,
@@ -9453,9 +10052,9 @@ var RadioGroup = React44.forwardRef(
9453
10052
  }
9454
10053
  );
9455
10054
  RadioGroup.displayName = "RadioGroup";
9456
- var Radio = React44.forwardRef(({ className, children, description, id, ...props }, ref) => {
9457
- const { appearance, density } = React44.useContext(RadioGroupContext);
9458
- const generatedId = React44.useId();
10055
+ var Radio = React47.forwardRef(({ className, children, description, id, ...props }, ref) => {
10056
+ const { appearance, density } = React47.useContext(RadioGroupContext);
10057
+ const generatedId = React47.useId();
9459
10058
  const radioId = id ?? generatedId;
9460
10059
  const labelId = `${radioId}-label`;
9461
10060
  const descriptionId = description ? `${radioId}-description` : void 0;
@@ -9470,24 +10069,24 @@ var Radio = React44.forwardRef(({ className, children, description, id, ...props
9470
10069
  className: cn(radioVariants({ appearance, density }), className),
9471
10070
  ...props,
9472
10071
  children: [
9473
- /* @__PURE__ */ jsx55(
10072
+ /* @__PURE__ */ jsx59(
9474
10073
  "span",
9475
10074
  {
9476
10075
  "aria-hidden": "true",
9477
10076
  "data-slot": "radio-control",
9478
10077
  className: radioControlVariants({ appearance }),
9479
- children: /* @__PURE__ */ jsx55(
10078
+ children: /* @__PURE__ */ jsx59(
9480
10079
  RadioGroupPrimitive.Indicator,
9481
10080
  {
9482
10081
  "data-slot": "radio-indicator",
9483
10082
  className: "flex items-center justify-center",
9484
- children: /* @__PURE__ */ jsx55(Circle, { "aria-hidden": "true", size: 8, fill: "currentColor" })
10083
+ children: /* @__PURE__ */ jsx59(Circle, { "aria-hidden": "true", size: 8, fill: "currentColor" })
9485
10084
  }
9486
10085
  )
9487
10086
  }
9488
10087
  ),
9489
10088
  /* @__PURE__ */ jsxs48("span", { className: "flex min-w-0 flex-col gap-[var(--space-1)]", children: [
9490
- /* @__PURE__ */ jsx55(
10089
+ /* @__PURE__ */ jsx59(
9491
10090
  "span",
9492
10091
  {
9493
10092
  id: labelId,
@@ -9499,7 +10098,7 @@ var Radio = React44.forwardRef(({ className, children, description, id, ...props
9499
10098
  children
9500
10099
  }
9501
10100
  ),
9502
- description ? /* @__PURE__ */ jsx55(
10101
+ description ? /* @__PURE__ */ jsx59(
9503
10102
  "span",
9504
10103
  {
9505
10104
  id: descriptionId,
@@ -9517,7 +10116,7 @@ Radio.displayName = "Radio";
9517
10116
 
9518
10117
  // src/components/ui/scroll-area.tsx
9519
10118
  import { ScrollArea as ScrollAreaPrimitive } from "radix-ui";
9520
- import { jsx as jsx56, jsxs as jsxs49 } from "react/jsx-runtime";
10119
+ import { jsx as jsx60, jsxs as jsxs49 } from "react/jsx-runtime";
9521
10120
  function ScrollArea({
9522
10121
  className,
9523
10122
  children,
@@ -9530,7 +10129,7 @@ function ScrollArea({
9530
10129
  className: cn("relative", className),
9531
10130
  ...props,
9532
10131
  children: [
9533
- /* @__PURE__ */ jsx56(
10132
+ /* @__PURE__ */ jsx60(
9534
10133
  ScrollAreaPrimitive.Viewport,
9535
10134
  {
9536
10135
  "data-slot": "scroll-area-viewport",
@@ -9538,8 +10137,8 @@ function ScrollArea({
9538
10137
  children
9539
10138
  }
9540
10139
  ),
9541
- /* @__PURE__ */ jsx56(ScrollBar, {}),
9542
- /* @__PURE__ */ jsx56(ScrollAreaPrimitive.Corner, {})
10140
+ /* @__PURE__ */ jsx60(ScrollBar, {}),
10141
+ /* @__PURE__ */ jsx60(ScrollAreaPrimitive.Corner, {})
9543
10142
  ]
9544
10143
  }
9545
10144
  );
@@ -9549,7 +10148,7 @@ function ScrollBar({
9549
10148
  orientation = "vertical",
9550
10149
  ...props
9551
10150
  }) {
9552
- return /* @__PURE__ */ jsx56(
10151
+ return /* @__PURE__ */ jsx60(
9553
10152
  ScrollAreaPrimitive.ScrollAreaScrollbar,
9554
10153
  {
9555
10154
  "data-slot": "scroll-area-scrollbar",
@@ -9561,7 +10160,7 @@ function ScrollBar({
9561
10160
  className
9562
10161
  ),
9563
10162
  ...props,
9564
- children: /* @__PURE__ */ jsx56(
10163
+ children: /* @__PURE__ */ jsx60(
9565
10164
  ScrollAreaPrimitive.ScrollAreaThumb,
9566
10165
  {
9567
10166
  "data-slot": "scroll-area-thumb",
@@ -9573,7 +10172,7 @@ function ScrollBar({
9573
10172
  }
9574
10173
 
9575
10174
  // src/components/ui/progress.tsx
9576
- import { jsx as jsx57 } from "react/jsx-runtime";
10175
+ import { jsx as jsx61 } from "react/jsx-runtime";
9577
10176
  var progressFillByStatus = {
9578
10177
  active: "bg-[var(--primary)]",
9579
10178
  success: "bg-[var(--success)]",
@@ -9594,7 +10193,7 @@ function Progress({
9594
10193
  const clamped = Math.max(0, Math.min(safeMax, value));
9595
10194
  const percent = clamped / safeMax * 100;
9596
10195
  const w = typeof width === "number" ? `${width}px` : width;
9597
- return /* @__PURE__ */ jsx57(
10196
+ return /* @__PURE__ */ jsx61(
9598
10197
  "div",
9599
10198
  {
9600
10199
  role: "progressbar",
@@ -9608,7 +10207,7 @@ function Progress({
9608
10207
  ),
9609
10208
  style: { width: w, height: `${height}px`, ...style },
9610
10209
  ...props,
9611
- children: /* @__PURE__ */ jsx57(
10210
+ children: /* @__PURE__ */ jsx61(
9612
10211
  "div",
9613
10212
  {
9614
10213
  className: cn(
@@ -9623,10 +10222,10 @@ function Progress({
9623
10222
  }
9624
10223
 
9625
10224
  // src/components/ui/tree-view.tsx
9626
- import * as React45 from "react";
10225
+ import * as React48 from "react";
9627
10226
  import { ChevronRight as ChevronRight3 } from "lucide-react";
9628
10227
  import { cva as cva25 } from "class-variance-authority";
9629
- import { jsx as jsx58, jsxs as jsxs50 } from "react/jsx-runtime";
10228
+ import { jsx as jsx62, jsxs as jsxs50 } from "react/jsx-runtime";
9630
10229
  var treeViewVariants = cva25(
9631
10230
  "m-0 list-none p-[var(--space-1)] text-body-sm text-foreground"
9632
10231
  );
@@ -9729,27 +10328,27 @@ function TreeView({
9729
10328
  ...rest
9730
10329
  }) {
9731
10330
  const isExpandedControlled = expandedIds !== void 0;
9732
- const [internalExpanded, setInternalExpanded] = React45.useState(
10331
+ const [internalExpanded, setInternalExpanded] = React48.useState(
9733
10332
  () => defaultExpandedIds ?? []
9734
10333
  );
9735
10334
  const expandedList = isExpandedControlled ? expandedIds : internalExpanded;
9736
- const expandedSet = React45.useMemo(() => new Set(expandedList), [expandedList]);
9737
- const items = React45.useMemo(
10335
+ const expandedSet = React48.useMemo(() => new Set(expandedList), [expandedList]);
10336
+ const items = React48.useMemo(
9738
10337
  () => flattenVisibleNodes(nodes, getChildren, expandedSet),
9739
10338
  [nodes, getChildren, expandedSet]
9740
10339
  );
9741
- const [focusedId, setFocusedId] = React45.useState(null);
10340
+ const [focusedId, setFocusedId] = React48.useState(null);
9742
10341
  const visibleIds = items.map((item) => item.id);
9743
10342
  const activeId = focusedId && visibleIds.includes(focusedId) ? focusedId : selectedId && visibleIds.includes(selectedId) ? selectedId : visibleIds[0] ?? null;
9744
- const itemRefs = React45.useRef(/* @__PURE__ */ new Map());
9745
- const commitExpanded = React45.useCallback(
10343
+ const itemRefs = React48.useRef(/* @__PURE__ */ new Map());
10344
+ const commitExpanded = React48.useCallback(
9746
10345
  (next) => {
9747
10346
  if (!isExpandedControlled) setInternalExpanded(next);
9748
10347
  onExpandedChange?.(next);
9749
10348
  },
9750
10349
  [isExpandedControlled, onExpandedChange]
9751
10350
  );
9752
- const setExpanded = React45.useCallback(
10351
+ const setExpanded = React48.useCallback(
9753
10352
  (id, expand) => {
9754
10353
  const has = expandedSet.has(id);
9755
10354
  if (expand && !has) {
@@ -9760,7 +10359,7 @@ function TreeView({
9760
10359
  },
9761
10360
  [commitExpanded, expandedList, expandedSet]
9762
10361
  );
9763
- const focusItem = React45.useCallback((id) => {
10362
+ const focusItem = React48.useCallback((id) => {
9764
10363
  setFocusedId(id);
9765
10364
  itemRefs.current.get(id)?.focus();
9766
10365
  }, []);
@@ -9830,7 +10429,7 @@ function TreeView({
9830
10429
  },
9831
10430
  className: treeItemRowVariants({ selected }),
9832
10431
  children: [
9833
- hasChildren ? /* @__PURE__ */ jsx58(
10432
+ hasChildren ? /* @__PURE__ */ jsx62(
9834
10433
  "span",
9835
10434
  {
9836
10435
  "data-slot": "treeitem-toggle",
@@ -9840,7 +10439,7 @@ function TreeView({
9840
10439
  setExpanded(node.id, !expanded);
9841
10440
  },
9842
10441
  className: "flex size-[var(--space-4)] shrink-0 items-center justify-center text-text-tertiary",
9843
- children: /* @__PURE__ */ jsx58(
10442
+ children: /* @__PURE__ */ jsx62(
9844
10443
  ChevronRight3,
9845
10444
  {
9846
10445
  "aria-hidden": "true",
@@ -9853,7 +10452,7 @@ function TreeView({
9853
10452
  }
9854
10453
  )
9855
10454
  }
9856
- ) : /* @__PURE__ */ jsx58(
10455
+ ) : /* @__PURE__ */ jsx62(
9857
10456
  "span",
9858
10457
  {
9859
10458
  "data-slot": "treeitem-spacer",
@@ -9861,18 +10460,18 @@ function TreeView({
9861
10460
  className: "size-[var(--space-4)] shrink-0"
9862
10461
  }
9863
10462
  ),
9864
- /* @__PURE__ */ jsx58("span", { className: "flex min-w-0 flex-1 items-center gap-[var(--space-2)]", children: renderItem(node, itemState) })
10463
+ /* @__PURE__ */ jsx62("span", { className: "flex min-w-0 flex-1 items-center gap-[var(--space-2)]", children: renderItem(node, itemState) })
9865
10464
  ]
9866
10465
  }
9867
10466
  ),
9868
- hasChildren && expanded && children ? /* @__PURE__ */ jsx58("ul", { role: "group", "data-slot": "tree-group", className: "m-0 list-none p-0", children: renderLevel(children, depth + 1) }) : null
10467
+ hasChildren && expanded && children ? /* @__PURE__ */ jsx62("ul", { role: "group", "data-slot": "tree-group", className: "m-0 list-none p-0", children: renderLevel(children, depth + 1) }) : null
9869
10468
  ]
9870
10469
  },
9871
10470
  node.id
9872
10471
  );
9873
10472
  });
9874
10473
  }
9875
- return /* @__PURE__ */ jsx58(
10474
+ return /* @__PURE__ */ jsx62(
9876
10475
  "ul",
9877
10476
  {
9878
10477
  role: "tree",
@@ -9888,7 +10487,7 @@ function TreeView({
9888
10487
  }
9889
10488
 
9890
10489
  // src/components/branding/olun-logo.tsx
9891
- import { jsx as jsx59, jsxs as jsxs51 } from "react/jsx-runtime";
10490
+ import { jsx as jsx63, jsxs as jsxs51 } from "react/jsx-runtime";
9892
10491
  var SYMBOL_LARGE = { stroke: 24, dotX: 184, dotY: 180, dotR: 13 };
9893
10492
  var SYMBOL_SMALL = { stroke: 18, dotX: 185, dotY: 175, dotR: 22 };
9894
10493
  function OlunSymbol({ size = 28, className }) {
@@ -9904,7 +10503,7 @@ function OlunSymbol({ size = 28, className }) {
9904
10503
  className,
9905
10504
  "aria-hidden": "true",
9906
10505
  children: [
9907
- /* @__PURE__ */ jsx59(
10506
+ /* @__PURE__ */ jsx63(
9908
10507
  "circle",
9909
10508
  {
9910
10509
  cx: "108",
@@ -9916,7 +10515,7 @@ function OlunSymbol({ size = 28, className }) {
9916
10515
  style: { color: "var(--text-primary)" }
9917
10516
  }
9918
10517
  ),
9919
- /* @__PURE__ */ jsx59("circle", { cx: g.dotX, cy: g.dotY, r: g.dotR, fill: "var(--accent-pop)" })
10518
+ /* @__PURE__ */ jsx63("circle", { cx: g.dotX, cy: g.dotY, r: g.dotR, fill: "var(--accent-pop)" })
9920
10519
  ]
9921
10520
  }
9922
10521
  );
@@ -9937,7 +10536,7 @@ function OlunLogo({
9937
10536
  gap: "var(--space-3)"
9938
10537
  },
9939
10538
  children: [
9940
- showSymbol && /* @__PURE__ */ jsx59(OlunSymbol, { size: symbolSize }),
10539
+ showSymbol && /* @__PURE__ */ jsx63(OlunSymbol, { size: symbolSize }),
9941
10540
  /* @__PURE__ */ jsxs51(
9942
10541
  "span",
9943
10542
  {
@@ -9950,7 +10549,7 @@ function OlunLogo({
9950
10549
  },
9951
10550
  children: [
9952
10551
  "OLUN",
9953
- !showSymbol && /* @__PURE__ */ jsx59("span", { style: { color: "var(--accent)" }, children: "." })
10552
+ !showSymbol && /* @__PURE__ */ jsx63("span", { style: { color: "var(--accent)" }, children: "." })
9954
10553
  ]
9955
10554
  }
9956
10555
  )
@@ -9961,11 +10560,11 @@ function OlunLogo({
9961
10560
 
9962
10561
  // src/components/branding/theme-toggle.tsx
9963
10562
  import { Sun, Moon } from "lucide-react";
9964
- import { jsx as jsx60 } from "react/jsx-runtime";
10563
+ import { jsx as jsx64 } from "react/jsx-runtime";
9965
10564
  function ThemeToggle({ className }) {
9966
10565
  const { resolvedTheme, toggleTheme } = useOlunTheme();
9967
10566
  const Icon = resolvedTheme === "dark" ? Moon : Sun;
9968
- return /* @__PURE__ */ jsx60(
10567
+ return /* @__PURE__ */ jsx64(
9969
10568
  "button",
9970
10569
  {
9971
10570
  onClick: () => toggleTheme(),
@@ -9977,14 +10576,14 @@ function ThemeToggle({ className }) {
9977
10576
  ),
9978
10577
  "aria-label": "\uD14C\uB9C8 \uC804\uD658",
9979
10578
  title: resolvedTheme === "dark" ? "\uB77C\uC774\uD2B8 \uBAA8\uB4DC\uB85C" : "\uB2E4\uD06C \uBAA8\uB4DC\uB85C",
9980
- children: /* @__PURE__ */ jsx60(Icon, { className: "size-[18px]", strokeWidth: 1.75 })
10579
+ children: /* @__PURE__ */ jsx64(Icon, { className: "size-[18px]", strokeWidth: 1.75 })
9981
10580
  }
9982
10581
  );
9983
10582
  }
9984
10583
 
9985
10584
  // src/components/branding/theme-fab.tsx
9986
10585
  import { Sun as Sun2, Moon as Moon2 } from "lucide-react";
9987
- import { jsx as jsx61 } from "react/jsx-runtime";
10586
+ import { jsx as jsx65 } from "react/jsx-runtime";
9988
10587
  function ThemeFab({ variant = "square" } = {}) {
9989
10588
  const { mounted, resolvedTheme, toggleTheme } = useOlunTheme();
9990
10589
  if (!mounted) {
@@ -10024,7 +10623,7 @@ function ThemeFab({ variant = "square" } = {}) {
10024
10623
  WebkitBackdropFilter: "blur(16px)",
10025
10624
  zIndex: 9999
10026
10625
  };
10027
- return /* @__PURE__ */ jsx61(
10626
+ return /* @__PURE__ */ jsx65(
10028
10627
  "button",
10029
10628
  {
10030
10629
  onClick: () => toggleTheme(),
@@ -10049,7 +10648,7 @@ function ThemeFab({ variant = "square" } = {}) {
10049
10648
  e.currentTarget.style.color = "var(--text-secondary)";
10050
10649
  }
10051
10650
  },
10052
- children: /* @__PURE__ */ jsx61(
10651
+ children: /* @__PURE__ */ jsx65(
10053
10652
  Icon,
10054
10653
  {
10055
10654
  size: isCircle ? 22 : 16,
@@ -10061,7 +10660,7 @@ function ThemeFab({ variant = "square" } = {}) {
10061
10660
  }
10062
10661
 
10063
10662
  // src/components/logos/organization-logo.tsx
10064
- import { jsx as jsx62 } from "react/jsx-runtime";
10663
+ import { jsx as jsx66 } from "react/jsx-runtime";
10065
10664
  var organizationLogoRegistry = {
10066
10665
  jbnu: {
10067
10666
  label: "\uC804\uBD81\uB300\uD559\uAD50 \uC5E0\uBE14\uB7FC",
@@ -10090,7 +10689,7 @@ function OrganizationLogo({
10090
10689
  }) {
10091
10690
  const asset = organizationLogoRegistry[organization];
10092
10691
  const isDecorative = ariaHidden === true || ariaHidden === "true";
10093
- return /* @__PURE__ */ jsx62(
10692
+ return /* @__PURE__ */ jsx66(
10094
10693
  "svg",
10095
10694
  {
10096
10695
  viewBox: asset.viewBox,
@@ -10108,14 +10707,16 @@ function OrganizationLogo({
10108
10707
  ...style
10109
10708
  },
10110
10709
  ...props,
10111
- children: asset.paths.map((path) => /* @__PURE__ */ jsx62("path", { d: path }, path))
10710
+ children: asset.paths.map((path) => /* @__PURE__ */ jsx66("path", { d: path }, path))
10112
10711
  }
10113
10712
  );
10114
10713
  }
10115
10714
  export {
10116
10715
  ActionFooter,
10716
+ ActionMenu,
10117
10717
  ActionSheet,
10118
10718
  Alert,
10719
+ AlertDialog,
10119
10720
  Avatar,
10120
10721
  AvatarFallback,
10121
10722
  AvatarImage,