@olundot/ui 0.20.0-next.9 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +394 -0
- package/dist/index.d.ts +144 -42
- package/dist/index.js +863 -250
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1019,13 +1019,38 @@ var MARKER_ICON = {
|
|
|
1019
1019
|
error: CircleAlert
|
|
1020
1020
|
};
|
|
1021
1021
|
var TITLE_LINE_HEIGHT = 21;
|
|
1022
|
-
var
|
|
1022
|
+
var actionPlacement = {
|
|
1023
|
+
oneLine: "col-start-2 row-start-2 justify-self-start mt-[var(--space-1)] @[344px]:col-start-3 @[344px]:row-start-1 @[344px]:mt-0 @[344px]:ms-[var(--space-2)]",
|
|
1024
|
+
twoLine: "col-start-2 row-start-3 justify-self-start mt-[var(--space-1)] @[344px]:col-start-3 @[344px]:row-[1/span_2] @[344px]:mt-0 @[344px]:ms-[var(--space-2)]"
|
|
1025
|
+
};
|
|
1026
|
+
var textWrap = { wordBreak: "keep-all", overflowWrap: "break-word", minWidth: 0 };
|
|
1027
|
+
var isEmpty = (node) => {
|
|
1028
|
+
if (node == null || typeof node === "boolean" || node === "") return true;
|
|
1029
|
+
if (Array.isArray(node)) return node.every(isEmpty);
|
|
1030
|
+
if (React6.isValidElement(node) && node.type === React6.Fragment) {
|
|
1031
|
+
return isEmpty(node.props.children);
|
|
1032
|
+
}
|
|
1033
|
+
return false;
|
|
1034
|
+
};
|
|
1023
1035
|
var Alert = React6.forwardRef(
|
|
1024
|
-
({
|
|
1025
|
-
|
|
1026
|
-
|
|
1036
|
+
({
|
|
1037
|
+
variant = "info",
|
|
1038
|
+
emphasis = "subtle",
|
|
1039
|
+
marker = "icon",
|
|
1040
|
+
title,
|
|
1041
|
+
children,
|
|
1042
|
+
action,
|
|
1043
|
+
onDismiss,
|
|
1044
|
+
className,
|
|
1045
|
+
style,
|
|
1046
|
+
...rest
|
|
1047
|
+
}, ref) => {
|
|
1048
|
+
const strong = emphasis === "strong";
|
|
1027
1049
|
const fg = SEM_FG[variant];
|
|
1028
1050
|
const MarkerIcon = MARKER_ICON[variant];
|
|
1051
|
+
const hasBody = !isEmpty(children);
|
|
1052
|
+
const hasAction = !isEmpty(action);
|
|
1053
|
+
const controlRow = hasBody ? "1 / span 2" : 1;
|
|
1029
1054
|
return /* @__PURE__ */ jsxs5(
|
|
1030
1055
|
"div",
|
|
1031
1056
|
{
|
|
@@ -1034,12 +1059,14 @@ var Alert = React6.forwardRef(
|
|
|
1034
1059
|
"aria-live": variant === "error" ? "assertive" : "polite",
|
|
1035
1060
|
"data-slot": "alert",
|
|
1036
1061
|
"data-variant": variant,
|
|
1037
|
-
"data-emphasis":
|
|
1062
|
+
"data-emphasis": emphasis,
|
|
1038
1063
|
"data-marker": marker,
|
|
1064
|
+
className: cn(hasAction && "@container w-full", className),
|
|
1039
1065
|
style: {
|
|
1040
|
-
display: "
|
|
1041
|
-
|
|
1042
|
-
|
|
1066
|
+
display: "grid",
|
|
1067
|
+
gridTemplateColumns: "auto minmax(0, 1fr) auto auto",
|
|
1068
|
+
rowGap: 2,
|
|
1069
|
+
alignItems: hasBody ? "start" : "center",
|
|
1043
1070
|
borderRadius: "var(--radius-md)",
|
|
1044
1071
|
border: "1px solid " + (strong ? "color-mix(in srgb, " + fg + " 26%, transparent)" : "var(--border)"),
|
|
1045
1072
|
background: strong ? SEM_BG[variant] : "var(--bg-surface)",
|
|
@@ -1055,9 +1082,11 @@ var Alert = React6.forwardRef(
|
|
|
1055
1082
|
"aria-hidden": "true",
|
|
1056
1083
|
"data-slot": "alert-marker",
|
|
1057
1084
|
style: {
|
|
1085
|
+
gridColumn: 1,
|
|
1086
|
+
gridRow: 1,
|
|
1058
1087
|
display: "inline-flex",
|
|
1059
1088
|
height: TITLE_LINE_HEIGHT,
|
|
1060
|
-
|
|
1089
|
+
marginInlineEnd: "var(--space-2)",
|
|
1061
1090
|
alignItems: "center",
|
|
1062
1091
|
justifyContent: "center",
|
|
1063
1092
|
color: fg
|
|
@@ -1071,37 +1100,49 @@ var Alert = React6.forwardRef(
|
|
|
1071
1100
|
) : /* @__PURE__ */ jsx5(MarkerIcon, { "data-slot": "alert-icon", size: 16, strokeWidth: 2.25 })
|
|
1072
1101
|
}
|
|
1073
1102
|
),
|
|
1074
|
-
/* @__PURE__ */
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1103
|
+
/* @__PURE__ */ jsx5(
|
|
1104
|
+
"div",
|
|
1105
|
+
{
|
|
1106
|
+
"data-slot": "alert-title",
|
|
1107
|
+
style: {
|
|
1108
|
+
gridColumn: 2,
|
|
1109
|
+
gridRow: 1,
|
|
1110
|
+
...textWrap,
|
|
1111
|
+
fontFamily: "var(--font-sans)",
|
|
1112
|
+
fontSize: 14,
|
|
1113
|
+
fontWeight: "var(--fw-medium)",
|
|
1114
|
+
lineHeight: TITLE_LINE_HEIGHT + "px",
|
|
1115
|
+
color: strong ? fg : "var(--text-primary)"
|
|
1116
|
+
},
|
|
1117
|
+
children: title
|
|
1118
|
+
}
|
|
1119
|
+
),
|
|
1120
|
+
hasBody ? /* @__PURE__ */ jsx5(
|
|
1121
|
+
"div",
|
|
1122
|
+
{
|
|
1123
|
+
"data-slot": "alert-body",
|
|
1124
|
+
style: {
|
|
1125
|
+
gridColumn: 2,
|
|
1126
|
+
gridRow: 2,
|
|
1127
|
+
...textWrap,
|
|
1128
|
+
fontFamily: "var(--font-sans)",
|
|
1129
|
+
fontSize: "var(--fs-sm)",
|
|
1130
|
+
lineHeight: "var(--lh-normal)",
|
|
1131
|
+
color: strong ? "color-mix(in srgb, " + fg + " 88%, var(--text-primary))" : "var(--text-secondary)"
|
|
1132
|
+
},
|
|
1133
|
+
children
|
|
1134
|
+
}
|
|
1135
|
+
) : null,
|
|
1136
|
+
hasAction ? /* @__PURE__ */ jsx5(
|
|
1137
|
+
"div",
|
|
1138
|
+
{
|
|
1139
|
+
"data-slot": "alert-action",
|
|
1140
|
+
className: hasBody ? actionPlacement.twoLine : actionPlacement.oneLine,
|
|
1141
|
+
style: { display: "flex", alignItems: "center" },
|
|
1142
|
+
children: action
|
|
1143
|
+
}
|
|
1144
|
+
) : null,
|
|
1145
|
+
onDismiss ? /* @__PURE__ */ jsx5(DismissButton, { onDismiss, strong, fg, row: controlRow }) : null
|
|
1105
1146
|
]
|
|
1106
1147
|
}
|
|
1107
1148
|
);
|
|
@@ -1111,7 +1152,8 @@ Alert.displayName = "Alert";
|
|
|
1111
1152
|
function DismissButton({
|
|
1112
1153
|
onDismiss,
|
|
1113
1154
|
strong,
|
|
1114
|
-
fg
|
|
1155
|
+
fg,
|
|
1156
|
+
row
|
|
1115
1157
|
}) {
|
|
1116
1158
|
const [hover, setHover] = React6.useState(false);
|
|
1117
1159
|
const [focus, setFocus] = React6.useState(false);
|
|
@@ -1126,8 +1168,11 @@ function DismissButton({
|
|
|
1126
1168
|
onMouseLeave: () => setHover(false),
|
|
1127
1169
|
onFocus: (e) => setFocus(e.currentTarget.matches(":focus-visible")),
|
|
1128
1170
|
onBlur: () => setFocus(false),
|
|
1171
|
+
className: "relative before:absolute before:-inset-[9px] before:content-['']",
|
|
1129
1172
|
style: {
|
|
1130
|
-
|
|
1173
|
+
gridColumn: 4,
|
|
1174
|
+
gridRow: row,
|
|
1175
|
+
marginInlineStart: "var(--space-2)",
|
|
1131
1176
|
display: "inline-flex",
|
|
1132
1177
|
width: 28,
|
|
1133
1178
|
height: 28,
|
|
@@ -2007,7 +2052,7 @@ import * as React11 from "react";
|
|
|
2007
2052
|
import { cva as cva7 } from "class-variance-authority";
|
|
2008
2053
|
import { Loader2 as Loader22 } from "lucide-react";
|
|
2009
2054
|
import { Switch as SwitchPrimitive } from "radix-ui";
|
|
2010
|
-
import { Fragment, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2055
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2011
2056
|
var switchFieldVariants = cva7("", {
|
|
2012
2057
|
variants: {
|
|
2013
2058
|
labelPlacement: {
|
|
@@ -2132,13 +2177,13 @@ var Switch = React11.forwardRef(
|
|
|
2132
2177
|
"data-slot": "switch-field",
|
|
2133
2178
|
"data-disabled": isDisabled ? "" : void 0,
|
|
2134
2179
|
className: switchFieldVariants({ labelPlacement, fullWidth }),
|
|
2135
|
-
children: isStart ? /* @__PURE__ */ jsxs10(
|
|
2180
|
+
children: isStart ? /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
2136
2181
|
/* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 grow flex-col gap-[var(--space-1)]", children: [
|
|
2137
2182
|
labelNode,
|
|
2138
2183
|
descriptionNode
|
|
2139
2184
|
] }),
|
|
2140
2185
|
track
|
|
2141
|
-
] }) : /* @__PURE__ */ jsxs10(
|
|
2186
|
+
] }) : /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
2142
2187
|
/* @__PURE__ */ jsxs10("div", { className: "inline-flex items-center gap-[var(--space-3)]", children: [
|
|
2143
2188
|
track,
|
|
2144
2189
|
labelNode
|
|
@@ -2250,7 +2295,7 @@ function TooltipContent({
|
|
|
2250
2295
|
}
|
|
2251
2296
|
|
|
2252
2297
|
// src/components/ui/permission-guard.tsx
|
|
2253
|
-
import { Fragment as
|
|
2298
|
+
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2254
2299
|
var defaultDisabledReason = "\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4";
|
|
2255
2300
|
var PermissionContext = React13.createContext(
|
|
2256
2301
|
void 0
|
|
@@ -2297,7 +2342,7 @@ function PermissionGuard({
|
|
|
2297
2342
|
const state = React13.useContext(PermissionContext);
|
|
2298
2343
|
const allowed = evaluatePermission(permission, permissions ?? state, scope);
|
|
2299
2344
|
if (allowed) {
|
|
2300
|
-
return /* @__PURE__ */ jsx12(
|
|
2345
|
+
return /* @__PURE__ */ jsx12(Fragment4, { children });
|
|
2301
2346
|
}
|
|
2302
2347
|
if (fallback === "hide" || fallback == null) {
|
|
2303
2348
|
return null;
|
|
@@ -2305,7 +2350,7 @@ function PermissionGuard({
|
|
|
2305
2350
|
if (fallback === "disabled") {
|
|
2306
2351
|
return renderDisabledFallback(children, disabledReason);
|
|
2307
2352
|
}
|
|
2308
|
-
return /* @__PURE__ */ jsx12(
|
|
2353
|
+
return /* @__PURE__ */ jsx12(Fragment4, { children: fallback });
|
|
2309
2354
|
}
|
|
2310
2355
|
function getPermissionCandidates(permission, scope) {
|
|
2311
2356
|
const candidates = /* @__PURE__ */ new Set([permission]);
|
|
@@ -2732,7 +2777,7 @@ var DataLayout = React17.forwardRef(
|
|
|
2732
2777
|
"div",
|
|
2733
2778
|
{
|
|
2734
2779
|
"data-slot": "data-layout-bulkbar",
|
|
2735
|
-
className: "pointer-events-none sticky bottom-[var(--space-4)] z-20 mt-[var(--space-2)] flex justify-center",
|
|
2780
|
+
className: "pointer-events-none sticky bottom-[calc(var(--space-4)+env(safe-area-inset-bottom))] z-20 mt-[var(--space-2)] flex justify-center",
|
|
2736
2781
|
children: /* @__PURE__ */ jsx16("div", { className: "flex w-full flex-col items-center [&>*:has([data-slot=bulk-action-bar])]:self-stretch [&>*:not(:has([data-slot=bulk-action-bar]))]:pointer-events-auto [&>*]:max-w-full [&_[data-slot=bulk-action-bar]]:pointer-events-auto", children: bulkBar })
|
|
2737
2782
|
}
|
|
2738
2783
|
) : null
|
|
@@ -2749,7 +2794,7 @@ DataLayout.displayName = "DataLayout";
|
|
|
2749
2794
|
// src/components/ui/wizard-layout.tsx
|
|
2750
2795
|
import * as React18 from "react";
|
|
2751
2796
|
import { Check as Check2 } from "lucide-react";
|
|
2752
|
-
import { Fragment as
|
|
2797
|
+
import { Fragment as Fragment7, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2753
2798
|
var circleBaseClassName = [
|
|
2754
2799
|
"flex items-center justify-center rounded-[var(--radius-full)] border text-[12px] font-semibold leading-none",
|
|
2755
2800
|
"transition-[background-color,border-color,color] motion-reduce:transition-none"
|
|
@@ -3040,7 +3085,7 @@ var WizardLayout = React18.forwardRef(
|
|
|
3040
3085
|
) : null
|
|
3041
3086
|
]
|
|
3042
3087
|
}
|
|
3043
|
-
) : /* @__PURE__ */ jsxs16(
|
|
3088
|
+
) : /* @__PURE__ */ jsxs16(Fragment7, { children: [
|
|
3044
3089
|
/* @__PURE__ */ jsx17(
|
|
3045
3090
|
"span",
|
|
3046
3091
|
{
|
|
@@ -3109,7 +3154,7 @@ import * as React19 from "react";
|
|
|
3109
3154
|
import { Tabs as TabsPrimitive } from "radix-ui";
|
|
3110
3155
|
import { cva as cva9 } from "class-variance-authority";
|
|
3111
3156
|
import { Lock } from "lucide-react";
|
|
3112
|
-
import { Fragment as
|
|
3157
|
+
import { Fragment as Fragment8, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3113
3158
|
var tabsRootVariants = cva9("w-full", {
|
|
3114
3159
|
variants: {
|
|
3115
3160
|
orientation: {
|
|
@@ -3376,7 +3421,7 @@ var Tabs = React19.forwardRef(
|
|
|
3376
3421
|
className: cn("group", tabsTriggerVariants({ variant, orientation }), triggerClassName),
|
|
3377
3422
|
children: [
|
|
3378
3423
|
isLine ? /* @__PURE__ */ jsx18("span", { "data-label": tab.label, className: tabsLabelReserveClassName, children: tab.label }) : /* @__PURE__ */ jsx18("span", { children: tab.label }),
|
|
3379
|
-
isShownTabBadge(tab.badge) ? /* @__PURE__ */ jsxs17(
|
|
3424
|
+
isShownTabBadge(tab.badge) ? /* @__PURE__ */ jsxs17(Fragment8, { children: [
|
|
3380
3425
|
/* @__PURE__ */ jsx18("span", { "aria-hidden": "true", "data-slot": "tabs-badge", className: tabsBadgeVariants(), children: formatTabBadge(tab.badge) }),
|
|
3381
3426
|
/* @__PURE__ */ jsx18("span", { className: "sr-only", children: ` ${tab.badge}` })
|
|
3382
3427
|
] }) : null,
|
|
@@ -3435,7 +3480,7 @@ var TabsContent = React19.forwardRef(({ className, tabKey, baseId, ...props }, r
|
|
|
3435
3480
|
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
3436
3481
|
|
|
3437
3482
|
// src/components/ui/detail-layout.tsx
|
|
3438
|
-
import { Fragment as
|
|
3483
|
+
import { Fragment as Fragment9, jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3439
3484
|
function DetailLayoutBody({
|
|
3440
3485
|
children,
|
|
3441
3486
|
aside,
|
|
@@ -3488,7 +3533,7 @@ function appendFooterToActiveTabsContent(children, activeTab, footer) {
|
|
|
3488
3533
|
return React20.cloneElement(
|
|
3489
3534
|
child,
|
|
3490
3535
|
void 0,
|
|
3491
|
-
/* @__PURE__ */ jsxs18(
|
|
3536
|
+
/* @__PURE__ */ jsxs18(Fragment9, { children: [
|
|
3492
3537
|
child.props.children,
|
|
3493
3538
|
/* @__PURE__ */ jsx19("div", { "data-slot": "detail-layout-footer", className: "min-w-0", children: footer })
|
|
3494
3539
|
] })
|
|
@@ -3570,7 +3615,7 @@ var DetailLayout = React20.forwardRef(
|
|
|
3570
3615
|
baseId,
|
|
3571
3616
|
forceMount: true,
|
|
3572
3617
|
hidden: tab.key !== activeTab,
|
|
3573
|
-
children: tab.key === activeTab ? /* @__PURE__ */ jsxs18(
|
|
3618
|
+
children: tab.key === activeTab ? /* @__PURE__ */ jsxs18(Fragment9, { children: [
|
|
3574
3619
|
body,
|
|
3575
3620
|
footer ? /* @__PURE__ */ jsx19("div", { "data-slot": "detail-layout-footer", className: "min-w-0", children: footer }) : null
|
|
3576
3621
|
] }) : null
|
|
@@ -3578,7 +3623,7 @@ var DetailLayout = React20.forwardRef(
|
|
|
3578
3623
|
tab.key
|
|
3579
3624
|
))
|
|
3580
3625
|
}
|
|
3581
|
-
) : /* @__PURE__ */ jsxs18(
|
|
3626
|
+
) : /* @__PURE__ */ jsxs18(Fragment9, { children: [
|
|
3582
3627
|
body,
|
|
3583
3628
|
footer ? /* @__PURE__ */ jsx19("div", { "data-slot": "detail-layout-footer", className: "min-w-0", children: footer }) : null
|
|
3584
3629
|
] })
|
|
@@ -4008,9 +4053,31 @@ import { Dialog as DialogPrimitive } from "radix-ui";
|
|
|
4008
4053
|
// src/components/ui/icon-button.tsx
|
|
4009
4054
|
import * as React25 from "react";
|
|
4010
4055
|
import { cva as cva10 } from "class-variance-authority";
|
|
4011
|
-
import { ChevronDown as ChevronDown4, Loader2 as Loader23 } from "lucide-react";
|
|
4056
|
+
import { Check as Check3, ChevronDown as ChevronDown4, Loader2 as Loader23 } from "lucide-react";
|
|
4012
4057
|
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4013
4058
|
var pressedNeutralClassName = "border-[var(--border-strong)] bg-[var(--action-selected)] text-foreground";
|
|
4059
|
+
var doneClassName = "cursor-default text-[var(--success)]";
|
|
4060
|
+
var doneRestPaint = (classes) => classes.split(" ").filter(
|
|
4061
|
+
(name) => !name.startsWith("hover:") && (!name.startsWith("aria-disabled:") || name.startsWith("aria-disabled:active:"))
|
|
4062
|
+
).join(" ");
|
|
4063
|
+
var tabbing = false;
|
|
4064
|
+
var tabListeners = 0;
|
|
4065
|
+
var markTab = (event) => {
|
|
4066
|
+
if (event.key !== "Tab") return;
|
|
4067
|
+
tabbing = true;
|
|
4068
|
+
setTimeout(() => {
|
|
4069
|
+
tabbing = false;
|
|
4070
|
+
}, 0);
|
|
4071
|
+
};
|
|
4072
|
+
function useTabMark(enabled) {
|
|
4073
|
+
React25.useEffect(() => {
|
|
4074
|
+
if (!enabled) return;
|
|
4075
|
+
if (tabListeners++ === 0) document.addEventListener("keydown", markTab, true);
|
|
4076
|
+
return () => {
|
|
4077
|
+
if (--tabListeners === 0) document.removeEventListener("keydown", markTab, true);
|
|
4078
|
+
};
|
|
4079
|
+
}, [enabled]);
|
|
4080
|
+
}
|
|
4014
4081
|
var iconButtonCva = cva10(
|
|
4015
4082
|
[
|
|
4016
4083
|
"olun-icon-button relative inline-flex cursor-pointer shrink-0 items-center justify-center before:absolute before:content-['']",
|
|
@@ -4078,7 +4145,8 @@ var iconButtonBadgeVariants = cva10(
|
|
|
4078
4145
|
variants: {
|
|
4079
4146
|
tone: {
|
|
4080
4147
|
info: "bg-[var(--accent-pop)] text-[var(--accent-on-fill)]",
|
|
4081
|
-
error: "bg-[var(--error)] text-[var(--error-contrast)]"
|
|
4148
|
+
error: "bg-[var(--error)] text-[var(--error-contrast)]",
|
|
4149
|
+
success: "bg-[var(--success)] text-[var(--success-contrast)]"
|
|
4082
4150
|
}
|
|
4083
4151
|
},
|
|
4084
4152
|
defaultVariants: {
|
|
@@ -4100,21 +4168,35 @@ var IconButton = React25.forwardRef(
|
|
|
4100
4168
|
title,
|
|
4101
4169
|
"aria-label": ariaLabel,
|
|
4102
4170
|
"aria-labelledby": ariaLabelledBy,
|
|
4171
|
+
"aria-describedby": ariaDescribedBy,
|
|
4103
4172
|
iconPosition = "start",
|
|
4104
4173
|
loading,
|
|
4174
|
+
done,
|
|
4105
4175
|
menuIndicator,
|
|
4106
4176
|
disabled,
|
|
4107
4177
|
label,
|
|
4108
4178
|
children,
|
|
4179
|
+
tooltip,
|
|
4180
|
+
tooltipSide = "top",
|
|
4181
|
+
onClick,
|
|
4109
4182
|
...props
|
|
4110
4183
|
}, ref) => {
|
|
4111
4184
|
const resolvedSize = size ?? "md";
|
|
4112
|
-
const
|
|
4113
|
-
const
|
|
4114
|
-
const
|
|
4185
|
+
const isDisabled = disabled || loading;
|
|
4186
|
+
const isDone = done === true && !isDisabled;
|
|
4187
|
+
const isToggle = pressed !== void 0 && !isDone;
|
|
4188
|
+
const isPressed = pressed === true && !isDone;
|
|
4189
|
+
const tooltipText = tooltip === true ? ariaLabel : tooltip;
|
|
4190
|
+
const hoverTitle = tooltip !== void 0 ? void 0 : title ?? (typeof ariaLabel === "string" ? ariaLabel : void 0);
|
|
4115
4191
|
const text = label ?? children;
|
|
4116
4192
|
const hasText = text !== void 0 && text !== null && text !== false;
|
|
4117
|
-
const
|
|
4193
|
+
const resolvedBadge = badge === void 0 && isDone ? /* @__PURE__ */ jsx22(Check3, { strokeWidth: 3 }) : badge;
|
|
4194
|
+
const resolvedBadgeTone = badge === void 0 && isDone ? "success" : badgeTone;
|
|
4195
|
+
const [tooltipOpen, setTooltipOpen] = React25.useState(false);
|
|
4196
|
+
useTabMark(tooltip !== void 0);
|
|
4197
|
+
React25.useEffect(() => {
|
|
4198
|
+
if (isDisabled) setTooltipOpen(false);
|
|
4199
|
+
}, [isDisabled]);
|
|
4118
4200
|
const style = resolveActionStyle(appearance, tone, "ghost");
|
|
4119
4201
|
const icon = loading ? /* @__PURE__ */ jsx22(
|
|
4120
4202
|
Loader23,
|
|
@@ -4134,7 +4216,14 @@ var IconButton = React25.forwardRef(
|
|
|
4134
4216
|
strokeWidth: axisIcon[resolvedSize].strokeWidth
|
|
4135
4217
|
}
|
|
4136
4218
|
);
|
|
4137
|
-
|
|
4219
|
+
const paint = hasText ? [
|
|
4220
|
+
"olun-icon-button",
|
|
4221
|
+
buttonVariants({ ...style, size: resolvedSize }),
|
|
4222
|
+
isPressed && style.tone === "neutral" && pressedNeutralClassName,
|
|
4223
|
+
// The badge sits on the corner; Button xs/sm are already relative.
|
|
4224
|
+
resolvedBadge !== void 0 && "relative"
|
|
4225
|
+
] : iconButtonVariants({ appearance, tone, size: resolvedSize, pressed: isPressed });
|
|
4226
|
+
const button = /* @__PURE__ */ jsxs20(
|
|
4138
4227
|
"button",
|
|
4139
4228
|
{
|
|
4140
4229
|
ref,
|
|
@@ -4146,24 +4235,24 @@ var IconButton = React25.forwardRef(
|
|
|
4146
4235
|
"data-icon-position": hasText ? iconPosition : void 0,
|
|
4147
4236
|
"data-pressed": isToggle ? String(isPressed) : void 0,
|
|
4148
4237
|
"data-loading": loading ? "true" : void 0,
|
|
4238
|
+
"data-done": isDone ? "true" : void 0,
|
|
4149
4239
|
"aria-busy": loading ? true : void 0,
|
|
4150
|
-
"aria-disabled": isDisabled ? true : void 0,
|
|
4240
|
+
"aria-disabled": isDisabled || isDone ? true : void 0,
|
|
4151
4241
|
disabled: isDisabled,
|
|
4152
4242
|
"aria-label": ariaLabel,
|
|
4153
4243
|
"aria-labelledby": ariaLabelledBy,
|
|
4244
|
+
"aria-describedby": ariaDescribedBy,
|
|
4154
4245
|
"aria-pressed": isToggle ? isPressed : void 0,
|
|
4155
4246
|
title: hoverTitle,
|
|
4156
|
-
className: cn(
|
|
4157
|
-
hasText ? [
|
|
4158
|
-
"olun-icon-button",
|
|
4159
|
-
buttonVariants({ ...style, size: resolvedSize }),
|
|
4160
|
-
isPressed && style.tone === "neutral" && pressedNeutralClassName,
|
|
4161
|
-
// The badge sits on the corner; Button xs/sm are already relative.
|
|
4162
|
-
badge !== void 0 && "relative"
|
|
4163
|
-
] : iconButtonVariants({ appearance, tone, size: resolvedSize, pressed: isPressed }),
|
|
4164
|
-
className
|
|
4165
|
-
),
|
|
4247
|
+
className: cn(isDone ? [doneRestPaint(cn(paint)), doneClassName] : paint, className),
|
|
4166
4248
|
type: type ?? "button",
|
|
4249
|
+
onClick: (event) => {
|
|
4250
|
+
if (isDone) {
|
|
4251
|
+
event.preventDefault();
|
|
4252
|
+
return;
|
|
4253
|
+
}
|
|
4254
|
+
onClick?.(event);
|
|
4255
|
+
},
|
|
4167
4256
|
children: [
|
|
4168
4257
|
hasText && iconPosition === "end" ? null : icon,
|
|
4169
4258
|
hasText ? text : null,
|
|
@@ -4177,19 +4266,41 @@ var IconButton = React25.forwardRef(
|
|
|
4177
4266
|
strokeWidth: axisIcon[resolvedSize].strokeWidth
|
|
4178
4267
|
}
|
|
4179
4268
|
) : null,
|
|
4180
|
-
|
|
4269
|
+
resolvedBadge !== void 0 ? /* @__PURE__ */ jsx22(
|
|
4181
4270
|
"span",
|
|
4182
4271
|
{
|
|
4183
4272
|
"aria-hidden": "true",
|
|
4184
4273
|
"data-slot": "icon-button-badge",
|
|
4185
|
-
"data-badge-tone":
|
|
4186
|
-
className: iconButtonBadgeVariants({ tone:
|
|
4187
|
-
children:
|
|
4274
|
+
"data-badge-tone": resolvedBadgeTone,
|
|
4275
|
+
className: iconButtonBadgeVariants({ tone: resolvedBadgeTone }),
|
|
4276
|
+
children: resolvedBadge
|
|
4188
4277
|
}
|
|
4189
4278
|
) : null
|
|
4190
4279
|
]
|
|
4191
4280
|
}
|
|
4192
4281
|
);
|
|
4282
|
+
if (tooltip === void 0) return button;
|
|
4283
|
+
return /* @__PURE__ */ jsx22(TooltipProvider, { children: /* @__PURE__ */ jsxs20(
|
|
4284
|
+
Tooltip,
|
|
4285
|
+
{
|
|
4286
|
+
open: tooltipOpen && !isDisabled,
|
|
4287
|
+
onOpenChange: (open) => setTooltipOpen(open && !isDisabled),
|
|
4288
|
+
children: [
|
|
4289
|
+
/* @__PURE__ */ jsx22(
|
|
4290
|
+
TooltipTrigger,
|
|
4291
|
+
{
|
|
4292
|
+
asChild: true,
|
|
4293
|
+
onFocus: (event) => {
|
|
4294
|
+
const root = event.currentTarget.getRootNode();
|
|
4295
|
+
if (!tabbing || root.activeElement !== event.currentTarget) event.preventDefault();
|
|
4296
|
+
},
|
|
4297
|
+
children: button
|
|
4298
|
+
}
|
|
4299
|
+
),
|
|
4300
|
+
/* @__PURE__ */ jsx22(TooltipContent, { side: tooltipSide, children: tooltipText })
|
|
4301
|
+
]
|
|
4302
|
+
}
|
|
4303
|
+
) });
|
|
4193
4304
|
}
|
|
4194
4305
|
);
|
|
4195
4306
|
IconButton.displayName = "IconButton";
|
|
@@ -4248,7 +4359,8 @@ var overlaySize = {
|
|
|
4248
4359
|
dialog: {
|
|
4249
4360
|
sm: "max-w-[420px]",
|
|
4250
4361
|
md: "max-w-[560px]",
|
|
4251
|
-
lg: "max-w-[720px]"
|
|
4362
|
+
lg: "max-w-[720px]",
|
|
4363
|
+
xl: "max-w-[960px]"
|
|
4252
4364
|
},
|
|
4253
4365
|
sheet: {
|
|
4254
4366
|
md: "lg:w-[480px] lg:max-w-[480px]",
|
|
@@ -4316,14 +4428,32 @@ var OverlayScrimLayer = React26.forwardRef(
|
|
|
4316
4428
|
}
|
|
4317
4429
|
);
|
|
4318
4430
|
OverlayScrimLayer.displayName = "OverlayScrimLayer";
|
|
4431
|
+
var TABBABLE_CANDIDATE = 'a[href], button, input, select, textarea, [tabindex], [contenteditable]:not([contenteditable="false"])';
|
|
4432
|
+
var INPUT_CANDIDATE = "input, textarea, select";
|
|
4433
|
+
function isTabbable(element) {
|
|
4434
|
+
if (element.matches(":disabled") || element instanceof HTMLInputElement && element.type === "hidden") return false;
|
|
4435
|
+
if (element.hasAttribute("tabindex") && element.tabIndex < 0) return false;
|
|
4436
|
+
if (element.closest('[hidden], [inert], [aria-hidden="true"]')) return false;
|
|
4437
|
+
if (typeof element.checkVisibility === "function") return element.checkVisibility({ visibilityProperty: true });
|
|
4438
|
+
const view = element.ownerDocument.defaultView;
|
|
4439
|
+
if (!view) return true;
|
|
4440
|
+
if (["hidden", "collapse"].includes(view.getComputedStyle(element).visibility)) return false;
|
|
4441
|
+
for (let node = element; node; node = node.parentElement) {
|
|
4442
|
+
if (view.getComputedStyle(node).display === "none") return false;
|
|
4443
|
+
}
|
|
4444
|
+
return true;
|
|
4445
|
+
}
|
|
4446
|
+
var firstTabbable = (root, selector) => [...root.querySelectorAll(selector)].find(isTabbable);
|
|
4319
4447
|
function focusBodyInput(event) {
|
|
4320
4448
|
const surface = event.target instanceof HTMLElement ? event.target : null;
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
if (input) {
|
|
4325
|
-
event.preventDefault();
|
|
4449
|
+
if (!surface) return;
|
|
4450
|
+
for (const input of surface.querySelectorAll(`:is([data-slot="overlay-body"], [data-slot="overlay-list"]) :is(${INPUT_CANDIDATE})`)) {
|
|
4451
|
+
if (!isTabbable(input)) continue;
|
|
4326
4452
|
input.focus();
|
|
4453
|
+
if (input.ownerDocument.activeElement === input) {
|
|
4454
|
+
event.preventDefault();
|
|
4455
|
+
return;
|
|
4456
|
+
}
|
|
4327
4457
|
}
|
|
4328
4458
|
}
|
|
4329
4459
|
var headingClassName = {
|
|
@@ -4341,6 +4471,7 @@ function OverlayHeader({
|
|
|
4341
4471
|
caption,
|
|
4342
4472
|
actions,
|
|
4343
4473
|
closeLabel = "\uB2EB\uAE30",
|
|
4474
|
+
titleHidden = false,
|
|
4344
4475
|
dragHandleProps,
|
|
4345
4476
|
id,
|
|
4346
4477
|
className
|
|
@@ -4364,7 +4495,7 @@ function OverlayHeader({
|
|
|
4364
4495
|
children: [
|
|
4365
4496
|
/* @__PURE__ */ jsxs21("div", { className: "flex min-w-0 flex-1 flex-col gap-[var(--space-2)]", children: [
|
|
4366
4497
|
caption != null ? /* @__PURE__ */ jsx24("div", { "data-slot": "overlay-caption", className: "flex flex-wrap items-center gap-[var(--space-2)]", children: caption }) : null,
|
|
4367
|
-
/* @__PURE__ */ jsx24(Title, { "data-slot": "overlay-title", className: headingClassName[policy.heading], children: title }),
|
|
4498
|
+
/* @__PURE__ */ jsx24(Title, { "data-slot": "overlay-title", className: cn(headingClassName[policy.heading], titleHidden && "sr-only"), children: title }),
|
|
4368
4499
|
description != null ? /* @__PURE__ */ jsx24(Description, { "data-slot": "overlay-description", className: descriptionClassName[policy.heading], children: description }) : null
|
|
4369
4500
|
] }),
|
|
4370
4501
|
actions != null || policy.closeButton === "visible" ? /* @__PURE__ */ jsxs21("div", { "data-slot": "overlay-header-actions", className: "flex shrink-0 items-center gap-[var(--space-1)]", children: [
|
|
@@ -4393,28 +4524,18 @@ var fogClassName = cn(
|
|
|
4393
4524
|
"pointer-events-none sticky z-[1] block h-[var(--space-6)] shrink-0 opacity-0",
|
|
4394
4525
|
"from-[var(--bg-raised)] to-transparent"
|
|
4395
4526
|
);
|
|
4396
|
-
function
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
className: cn(
|
|
4404
|
-
"min-w-0 px-[var(--space-6)] pt-[var(--space-4)] text-[14px] leading-relaxed text-text-secondary",
|
|
4405
|
-
scroll === "list" && "min-h-0 flex-1 overflow-y-auto px-0",
|
|
4406
|
-
className
|
|
4407
|
-
),
|
|
4408
|
-
...props,
|
|
4409
|
-
children
|
|
4410
|
-
}
|
|
4411
|
-
);
|
|
4412
|
-
}
|
|
4527
|
+
function FogScroller({
|
|
4528
|
+
scrollerRef,
|
|
4529
|
+
className,
|
|
4530
|
+
contentClassName,
|
|
4531
|
+
children,
|
|
4532
|
+
...props
|
|
4533
|
+
}) {
|
|
4413
4534
|
return /* @__PURE__ */ jsxs21(
|
|
4414
4535
|
"div",
|
|
4415
4536
|
{
|
|
4416
|
-
|
|
4417
|
-
className: "relative flex min-h-0 flex-
|
|
4537
|
+
ref: scrollerRef,
|
|
4538
|
+
className: cn("relative flex min-h-0 flex-col overflow-y-auto [container-type:scroll-state]", className),
|
|
4418
4539
|
...props,
|
|
4419
4540
|
children: [
|
|
4420
4541
|
/* @__PURE__ */ jsx24(
|
|
@@ -4425,7 +4546,7 @@ function OverlayBody({ kind, className, children, ...props }) {
|
|
|
4425
4546
|
className: cn(fogClassName, "top-0 -mb-[var(--space-6)] bg-linear-to-b", "[@container_scroll-state(scrollable:top)]:opacity-100")
|
|
4426
4547
|
}
|
|
4427
4548
|
),
|
|
4428
|
-
/* @__PURE__ */ jsx24("div", { className:
|
|
4549
|
+
/* @__PURE__ */ jsx24("div", { className: contentClassName, children }),
|
|
4429
4550
|
/* @__PURE__ */ jsx24(
|
|
4430
4551
|
"span",
|
|
4431
4552
|
{
|
|
@@ -4438,6 +4559,90 @@ function OverlayBody({ kind, className, children, ...props }) {
|
|
|
4438
4559
|
}
|
|
4439
4560
|
);
|
|
4440
4561
|
}
|
|
4562
|
+
function OverlayBody({ kind, fixed = false, className, children, ...props }) {
|
|
4563
|
+
const { scroll } = OVERLAY_POLICY[kind];
|
|
4564
|
+
if (fixed) {
|
|
4565
|
+
return /* @__PURE__ */ jsx24(
|
|
4566
|
+
"div",
|
|
4567
|
+
{
|
|
4568
|
+
"data-slot": "overlay-body",
|
|
4569
|
+
className: cn(
|
|
4570
|
+
"relative z-[2] -mb-[var(--space-1)] min-h-0 min-w-0 shrink overflow-y-auto px-[var(--space-6)] pt-[var(--space-4)] pb-[var(--space-1)]",
|
|
4571
|
+
className
|
|
4572
|
+
),
|
|
4573
|
+
...props,
|
|
4574
|
+
children
|
|
4575
|
+
}
|
|
4576
|
+
);
|
|
4577
|
+
}
|
|
4578
|
+
if (scroll !== "body") {
|
|
4579
|
+
return /* @__PURE__ */ jsx24(
|
|
4580
|
+
"div",
|
|
4581
|
+
{
|
|
4582
|
+
"data-slot": "overlay-body",
|
|
4583
|
+
className: cn(
|
|
4584
|
+
"min-w-0 px-[var(--space-6)] pt-[var(--space-4)] text-[14px] leading-relaxed text-text-secondary",
|
|
4585
|
+
scroll === "list" && "min-h-0 flex-1 overflow-y-auto px-0",
|
|
4586
|
+
className
|
|
4587
|
+
),
|
|
4588
|
+
...props,
|
|
4589
|
+
children
|
|
4590
|
+
}
|
|
4591
|
+
);
|
|
4592
|
+
}
|
|
4593
|
+
return /* @__PURE__ */ jsx24(FogScroller, { "data-slot": "overlay-body", className: "flex-1", contentClassName: cn("min-w-0 px-[var(--space-6)] py-[var(--space-4)]", className), ...props, children });
|
|
4594
|
+
}
|
|
4595
|
+
var listBoxClassName = {
|
|
4596
|
+
max: {
|
|
4597
|
+
sm: "basis-[content] max-h-[calc(216px+var(--space-3)+var(--space-4))]",
|
|
4598
|
+
md: "basis-[content] max-h-[calc(460px+var(--space-3)+var(--space-4))]",
|
|
4599
|
+
lg: "basis-[content] max-h-[calc(628px+var(--space-3)+var(--space-4))]"
|
|
4600
|
+
},
|
|
4601
|
+
fixed: {
|
|
4602
|
+
sm: "basis-[calc(216px+var(--space-3)+var(--space-4))]",
|
|
4603
|
+
md: "basis-[calc(460px+var(--space-3)+var(--space-4))]",
|
|
4604
|
+
lg: "basis-[calc(628px+var(--space-3)+var(--space-4))]"
|
|
4605
|
+
}
|
|
4606
|
+
};
|
|
4607
|
+
var listFloorClassName = "h-[calc(112px+var(--space-3))]";
|
|
4608
|
+
function OverlayList({ height = "md", fit = "max", label, children }) {
|
|
4609
|
+
const ref = React26.useRef(null);
|
|
4610
|
+
const [hasFocusable, setHasFocusable] = React26.useState(true);
|
|
4611
|
+
React26.useLayoutEffect(() => {
|
|
4612
|
+
const node = ref.current;
|
|
4613
|
+
if (!node) return;
|
|
4614
|
+
const check = () => setHasFocusable(firstTabbable(node, TABBABLE_CANDIDATE) != null);
|
|
4615
|
+
check();
|
|
4616
|
+
let frame = 0;
|
|
4617
|
+
const observer = new MutationObserver(() => {
|
|
4618
|
+
frame ||= requestAnimationFrame(() => {
|
|
4619
|
+
frame = 0;
|
|
4620
|
+
check();
|
|
4621
|
+
});
|
|
4622
|
+
});
|
|
4623
|
+
observer.observe(node, {
|
|
4624
|
+
childList: true,
|
|
4625
|
+
subtree: true,
|
|
4626
|
+
attributes: true,
|
|
4627
|
+
attributeFilter: ["aria-hidden", "class", "contenteditable", "disabled", "hidden", "href", "inert", "style", "tabindex", "type"]
|
|
4628
|
+
});
|
|
4629
|
+
return () => {
|
|
4630
|
+
observer.disconnect();
|
|
4631
|
+
cancelAnimationFrame(frame);
|
|
4632
|
+
};
|
|
4633
|
+
}, []);
|
|
4634
|
+
return /* @__PURE__ */ jsx24("div", { "data-slot": "overlay-list-box", className: cn("flex shrink-[10000] flex-col", listFloorClassName, listBoxClassName[fit][height]), children: /* @__PURE__ */ jsx24(
|
|
4635
|
+
FogScroller,
|
|
4636
|
+
{
|
|
4637
|
+
scrollerRef: ref,
|
|
4638
|
+
"data-slot": "overlay-list",
|
|
4639
|
+
className: "flex-auto outline-none focus-visible:inset-ring-2 focus-visible:inset-ring-[var(--focus-ring)]",
|
|
4640
|
+
contentClassName: "min-w-0 px-[var(--space-6)] pt-[var(--space-3)] pb-[var(--space-4)]",
|
|
4641
|
+
...!hasFocusable && { tabIndex: 0, role: "region", "aria-label": label },
|
|
4642
|
+
children
|
|
4643
|
+
}
|
|
4644
|
+
) });
|
|
4645
|
+
}
|
|
4441
4646
|
function OverlayFooter({ kind, className, ...props }) {
|
|
4442
4647
|
const { footerDivider } = OVERLAY_POLICY[kind];
|
|
4443
4648
|
return /* @__PURE__ */ jsx24(
|
|
@@ -4779,7 +4984,7 @@ function SheetDescription({
|
|
|
4779
4984
|
}
|
|
4780
4985
|
|
|
4781
4986
|
// src/components/ui/dialog.tsx
|
|
4782
|
-
import { Fragment as
|
|
4987
|
+
import { Fragment as Fragment10, jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
4783
4988
|
function dialogMobileSheetStyle(style) {
|
|
4784
4989
|
return getDefaultSheetMotionStyle(style);
|
|
4785
4990
|
}
|
|
@@ -4794,8 +4999,13 @@ function StructuredDialog({
|
|
|
4794
4999
|
onOpenChange,
|
|
4795
5000
|
title,
|
|
4796
5001
|
description,
|
|
5002
|
+
hideTitle = false,
|
|
4797
5003
|
size = "md",
|
|
4798
5004
|
children,
|
|
5005
|
+
list,
|
|
5006
|
+
listHeight = "md",
|
|
5007
|
+
listFit = "max",
|
|
5008
|
+
listLabel = title,
|
|
4799
5009
|
footer,
|
|
4800
5010
|
onSubmit,
|
|
4801
5011
|
onError,
|
|
@@ -4817,7 +5027,13 @@ function StructuredDialog({
|
|
|
4817
5027
|
const returnFocus = useReturnFocus();
|
|
4818
5028
|
const surfaceRef = React28.useRef(null);
|
|
4819
5029
|
const swipe = useSwipeDismiss({ enabled: policy.swipe, onDismiss: () => guardOpenChange(false), surfaceRef });
|
|
4820
|
-
const body =
|
|
5030
|
+
const body = list != null ? (
|
|
5031
|
+
// Scrolls only on a screen too low for the body's 16 and the list floor; the footer stays.
|
|
5032
|
+
/* @__PURE__ */ jsxs23("div", { "data-slot": "overlay-list-frame", className: "flex min-h-0 flex-col overflow-y-auto", children: [
|
|
5033
|
+
/* @__PURE__ */ jsx26(OverlayBody, { kind: "dialog", fixed: true, className, children }),
|
|
5034
|
+
/* @__PURE__ */ jsx26(OverlayList, { height: listHeight, fit: listFit, label: listLabel, children: list })
|
|
5035
|
+
] })
|
|
5036
|
+
) : /* @__PURE__ */ jsx26(OverlayBody, { kind: "dialog", className, children });
|
|
4821
5037
|
const footerRow = formMode ? /* @__PURE__ */ jsxs23(OverlayFooter, { kind: "dialog", children: [
|
|
4822
5038
|
/* @__PURE__ */ jsx26(
|
|
4823
5039
|
Button,
|
|
@@ -4856,6 +5072,7 @@ function StructuredDialog({
|
|
|
4856
5072
|
kind: "dialog",
|
|
4857
5073
|
title,
|
|
4858
5074
|
description,
|
|
5075
|
+
titleHidden: hideTitle,
|
|
4859
5076
|
closeLabel,
|
|
4860
5077
|
dragHandleProps: swipe.handleProps
|
|
4861
5078
|
}
|
|
@@ -4873,7 +5090,7 @@ function StructuredDialog({
|
|
|
4873
5090
|
footerRow
|
|
4874
5091
|
]
|
|
4875
5092
|
}
|
|
4876
|
-
) : /* @__PURE__ */ jsxs23(
|
|
5093
|
+
) : /* @__PURE__ */ jsxs23(Fragment10, { children: [
|
|
4877
5094
|
body,
|
|
4878
5095
|
footerRow
|
|
4879
5096
|
] })
|
|
@@ -5077,7 +5294,7 @@ function FormModal({
|
|
|
5077
5294
|
|
|
5078
5295
|
// src/components/ui/alert-dialog.tsx
|
|
5079
5296
|
import { AlertDialog as AlertDialogPrimitive2 } from "radix-ui";
|
|
5080
|
-
import { Fragment as
|
|
5297
|
+
import { Fragment as Fragment11, jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
5081
5298
|
function AlertDialogFrame({
|
|
5082
5299
|
open,
|
|
5083
5300
|
onOpenChange,
|
|
@@ -5141,7 +5358,7 @@ function AlertDialog({
|
|
|
5141
5358
|
disabled: confirmDisabled,
|
|
5142
5359
|
onError
|
|
5143
5360
|
});
|
|
5144
|
-
const footer = confirmLabel != null ? /* @__PURE__ */ jsxs25(
|
|
5361
|
+
const footer = confirmLabel != null ? /* @__PURE__ */ jsxs25(Fragment11, { children: [
|
|
5145
5362
|
/* @__PURE__ */ jsx28(AlertDialogPrimitive2.Cancel, { asChild: true, children: /* @__PURE__ */ jsx28(Button, { appearance: "outline", tone: "neutral", size: "lg", className: footerButtonHitAreaClassName, disabled: isBusy, children: cancelLabel }) }),
|
|
5146
5363
|
/* @__PURE__ */ jsx28(
|
|
5147
5364
|
Button,
|
|
@@ -5219,7 +5436,7 @@ import * as React29 from "react";
|
|
|
5219
5436
|
import { cva as cva11 } from "class-variance-authority";
|
|
5220
5437
|
import { X as X3 } from "lucide-react";
|
|
5221
5438
|
import { Slot as Slot2 } from "radix-ui";
|
|
5222
|
-
import { Fragment as
|
|
5439
|
+
import { Fragment as Fragment12, jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
5223
5440
|
var chipVariants = cva11(
|
|
5224
5441
|
[
|
|
5225
5442
|
"inline-flex w-fit shrink-0 items-center justify-center whitespace-nowrap",
|
|
@@ -5318,7 +5535,7 @@ function ChipCount({
|
|
|
5318
5535
|
tone,
|
|
5319
5536
|
size
|
|
5320
5537
|
}) {
|
|
5321
|
-
return /* @__PURE__ */ jsxs26(
|
|
5538
|
+
return /* @__PURE__ */ jsxs26(Fragment12, { children: [
|
|
5322
5539
|
/* @__PURE__ */ jsx30(
|
|
5323
5540
|
"span",
|
|
5324
5541
|
{
|
|
@@ -5501,7 +5718,7 @@ var PopoverArrow = React30.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
5501
5718
|
PopoverArrow.displayName = PopoverPrimitive.Arrow.displayName;
|
|
5502
5719
|
|
|
5503
5720
|
// src/components/ui/filter-toolbar.tsx
|
|
5504
|
-
import { Fragment as
|
|
5721
|
+
import { Fragment as Fragment14, jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
5505
5722
|
var collapsibleClassNames = {
|
|
5506
5723
|
sm: {
|
|
5507
5724
|
inline: "hidden @[640px]:flex",
|
|
@@ -5520,6 +5737,41 @@ var collapsibleClassNames = {
|
|
|
5520
5737
|
trigger: "hidden"
|
|
5521
5738
|
}
|
|
5522
5739
|
};
|
|
5740
|
+
var gridCollapsibleClassNames = {
|
|
5741
|
+
sm: { inline: "hidden", trigger: "" },
|
|
5742
|
+
md: { inline: "hidden", trigger: "" },
|
|
5743
|
+
lg: { inline: "hidden", trigger: "" },
|
|
5744
|
+
never: { inline: "flex @[640px]:hidden", trigger: "hidden @[640px]:inline" }
|
|
5745
|
+
};
|
|
5746
|
+
var gridSearchClassName = "order-1 min-w-[min(160px,100%)] max-w-full flex-[1_1_0%] @[640px]:min-w-0 @[640px]:flex-[3_1_0%]";
|
|
5747
|
+
var gridFiltersClassName = "order-3 flex min-w-0 flex-[1_0_100%] flex-wrap items-center gap-[var(--space-2)] @[640px]:contents";
|
|
5748
|
+
var gridCellClassName = cn(
|
|
5749
|
+
"contents @[640px]:block @[640px]:order-3 @[640px]:min-w-0 @[640px]:flex-[3_1_0%]",
|
|
5750
|
+
"@[640px]:[&:has([data-slot=select-trigger])]:flex-[2_1_0%]",
|
|
5751
|
+
"@[640px]:[&:has(>[data-slot=chip])]:flex-none",
|
|
5752
|
+
// A Chip group is named: a role="group" child that holds the Chips. A control that shows its
|
|
5753
|
+
// values as Chips keeps the default share.
|
|
5754
|
+
"@[640px]:[&:has(>[role=group]>[data-slot=chip])]:flex-none",
|
|
5755
|
+
// The control fills its cell, through a width the consumer put on a wrapper.
|
|
5756
|
+
"@[640px]:[&>:not([data-slot=chip])]:w-full @[640px]:[&_[data-slot=select-trigger]]:w-full"
|
|
5757
|
+
);
|
|
5758
|
+
var MAX_GRID_FILTERS = 3;
|
|
5759
|
+
var focusableSelector = "input, button, [tabindex]:not([tabindex='-1'])";
|
|
5760
|
+
function canTakeFocus(element) {
|
|
5761
|
+
return Boolean(element && element.getClientRects().length > 0 && !element.matches(":disabled"));
|
|
5762
|
+
}
|
|
5763
|
+
function filterCells(node, prefix = "") {
|
|
5764
|
+
return React31.Children.toArray(node).flatMap((child, index) => {
|
|
5765
|
+
const key = `${prefix}${React31.isValidElement(child) ? child.key : index}`;
|
|
5766
|
+
return React31.isValidElement(child) && child.type === React31.Fragment ? filterCells(child.props.children, `${key}/`) : [{ key, cell: child }];
|
|
5767
|
+
});
|
|
5768
|
+
}
|
|
5769
|
+
function warnGridFilters(count) {
|
|
5770
|
+
if (typeof process === "undefined" || process.env.NODE_ENV === "production") return;
|
|
5771
|
+
console.warn(
|
|
5772
|
+
`FilterToolbar: layout="grid" fits ${MAX_GRID_FILTERS} filters on the line, got ${count}. Move the rest to \`collapsible\`.`
|
|
5773
|
+
);
|
|
5774
|
+
}
|
|
5523
5775
|
var FilterToolbar = React31.forwardRef(
|
|
5524
5776
|
({
|
|
5525
5777
|
className,
|
|
@@ -5527,12 +5779,14 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5527
5779
|
filters,
|
|
5528
5780
|
collapsible,
|
|
5529
5781
|
collapseBelow = "lg",
|
|
5530
|
-
activeFilterCount
|
|
5782
|
+
activeFilterCount: activeFilterCountProp,
|
|
5531
5783
|
onClearFilters,
|
|
5532
5784
|
collapsedLabel = "\uD544\uD130",
|
|
5533
5785
|
resultSummary,
|
|
5534
5786
|
clearAction,
|
|
5535
5787
|
actions,
|
|
5788
|
+
layout = "flow",
|
|
5789
|
+
appliedFilters,
|
|
5536
5790
|
...props
|
|
5537
5791
|
}, ref) => {
|
|
5538
5792
|
const [rootElement, setRootElement] = React31.useState(
|
|
@@ -5543,6 +5797,10 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5543
5797
|
);
|
|
5544
5798
|
const [overlayOpen, setOverlayOpen] = React31.useState(false);
|
|
5545
5799
|
const triggerRef = React31.useRef(null);
|
|
5800
|
+
const rowRef = React31.useRef(null);
|
|
5801
|
+
const chipsRef = React31.useRef(null);
|
|
5802
|
+
const chipRemoveRefs = React31.useRef(/* @__PURE__ */ new Map());
|
|
5803
|
+
const pendingFocusRef = React31.useRef(null);
|
|
5546
5804
|
const setRootRefs = React31.useCallback(
|
|
5547
5805
|
(element) => {
|
|
5548
5806
|
setRootElement(element);
|
|
@@ -5566,13 +5824,49 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5566
5824
|
setOverlayOpen(open);
|
|
5567
5825
|
if (!open) queueMicrotask(() => triggerRef.current?.focus());
|
|
5568
5826
|
}, []);
|
|
5827
|
+
const isGrid = layout === "grid";
|
|
5828
|
+
const gridCells = isGrid ? filterCells(filters) : [];
|
|
5829
|
+
const filterCellCount = gridCells.length;
|
|
5830
|
+
React31.useEffect(() => {
|
|
5831
|
+
if (filterCellCount > MAX_GRID_FILTERS) warnGridFilters(filterCellCount);
|
|
5832
|
+
}, [filterCellCount]);
|
|
5833
|
+
React31.useEffect(() => {
|
|
5834
|
+
const ownerDocument = rootElement?.ownerDocument;
|
|
5835
|
+
if (!ownerDocument) return;
|
|
5836
|
+
const dropOutside = (event) => {
|
|
5837
|
+
if (!chipsRef.current?.contains(event.target)) pendingFocusRef.current = null;
|
|
5838
|
+
};
|
|
5839
|
+
ownerDocument.addEventListener("focusin", dropOutside);
|
|
5840
|
+
ownerDocument.addEventListener("pointerdown", dropOutside, true);
|
|
5841
|
+
return () => {
|
|
5842
|
+
ownerDocument.removeEventListener("focusin", dropOutside);
|
|
5843
|
+
ownerDocument.removeEventListener("pointerdown", dropOutside, true);
|
|
5844
|
+
};
|
|
5845
|
+
}, [rootElement]);
|
|
5846
|
+
React31.useEffect(() => {
|
|
5847
|
+
const request = pendingFocusRef.current;
|
|
5848
|
+
if (!request) return;
|
|
5849
|
+
const present = new Set(appliedFilters?.map((filter) => filter.key));
|
|
5850
|
+
if (request.removed.some((key) => present.has(key))) return;
|
|
5851
|
+
pendingFocusRef.current = null;
|
|
5852
|
+
const active = rootElement?.ownerDocument.activeElement;
|
|
5853
|
+
if (active && active !== rootElement.ownerDocument.body) return;
|
|
5854
|
+
const candidates = [
|
|
5855
|
+
...request.next.map((key) => chipRemoveRefs.current.get(key)),
|
|
5856
|
+
triggerRef.current,
|
|
5857
|
+
...rowRef.current?.querySelectorAll(focusableSelector) ?? []
|
|
5858
|
+
];
|
|
5859
|
+
candidates.find(canTakeFocus)?.focus();
|
|
5860
|
+
}, [appliedFilters, rootElement]);
|
|
5569
5861
|
const hasControls = Boolean(search || filters || collapsible);
|
|
5570
5862
|
const hasMeta = Boolean(
|
|
5571
5863
|
resultSummary || clearAction || actions && !hasControls
|
|
5572
5864
|
);
|
|
5865
|
+
const activeFilterCount = activeFilterCountProp ?? appliedFilters?.length ?? 0;
|
|
5573
5866
|
const hasAppliedFilters = activeFilterCount > 0;
|
|
5867
|
+
const hasAppliedChips = Boolean(appliedFilters && appliedFilters.length > 0);
|
|
5574
5868
|
const usesSheet = containerWidth !== null && containerWidth < 640;
|
|
5575
|
-
const collapseClasses = collapsibleClassNames[collapseBelow];
|
|
5869
|
+
const collapseClasses = (isGrid ? gridCollapsibleClassNames : collapsibleClassNames)[collapseBelow];
|
|
5576
5870
|
const collapseTriggerLabel = hasAppliedFilters ? `${collapsedLabel}, ${activeFilterCount}\uAC1C \uC801\uC6A9` : collapsedLabel;
|
|
5577
5871
|
const clearFiltersButton = onClearFilters ? /* @__PURE__ */ jsx32(
|
|
5578
5872
|
"button",
|
|
@@ -5643,14 +5937,18 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5643
5937
|
hasControls ? /* @__PURE__ */ jsxs28(
|
|
5644
5938
|
"div",
|
|
5645
5939
|
{
|
|
5940
|
+
ref: rowRef,
|
|
5646
5941
|
"data-slot": "filter-toolbar-row",
|
|
5647
|
-
className:
|
|
5942
|
+
className: cn(
|
|
5943
|
+
"flex min-h-[32px] w-full flex-wrap items-center justify-start gap-x-[var(--space-2)] gap-y-[var(--space-2)]",
|
|
5944
|
+
isGrid && "@[640px]:flex-nowrap"
|
|
5945
|
+
),
|
|
5648
5946
|
children: [
|
|
5649
5947
|
search ? /* @__PURE__ */ jsx32(
|
|
5650
5948
|
"div",
|
|
5651
5949
|
{
|
|
5652
5950
|
"data-slot": "filter-toolbar-search",
|
|
5653
|
-
className: "order-1 min-w-[min(160px,100%)] max-w-full flex-[1_1_0%] @[640px]:min-w-0 @[640px]:flex-[1_1_280px]",
|
|
5951
|
+
className: isGrid ? gridSearchClassName : "order-1 min-w-[min(160px,100%)] max-w-full flex-[1_1_0%] @[640px]:min-w-0 @[640px]:flex-[1_1_280px]",
|
|
5654
5952
|
children: search
|
|
5655
5953
|
}
|
|
5656
5954
|
) : null,
|
|
@@ -5677,8 +5975,16 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5677
5975
|
"div",
|
|
5678
5976
|
{
|
|
5679
5977
|
"data-slot": "filter-toolbar-filters",
|
|
5680
|
-
className: "order-3 flex min-w-0 flex-[1_0_100%] flex-wrap items-center gap-[var(--space-2)] @[640px]:flex-[2_1_auto]",
|
|
5681
|
-
children:
|
|
5978
|
+
className: isGrid ? gridFiltersClassName : "order-3 flex min-w-0 flex-[1_0_100%] flex-wrap items-center gap-[var(--space-2)] @[640px]:flex-[2_1_auto]",
|
|
5979
|
+
children: isGrid ? gridCells.map(({ key, cell }) => /* @__PURE__ */ jsx32(
|
|
5980
|
+
"div",
|
|
5981
|
+
{
|
|
5982
|
+
"data-slot": "filter-toolbar-cell",
|
|
5983
|
+
className: gridCellClassName,
|
|
5984
|
+
children: cell
|
|
5985
|
+
},
|
|
5986
|
+
key
|
|
5987
|
+
)) : filters
|
|
5682
5988
|
}
|
|
5683
5989
|
) : null,
|
|
5684
5990
|
collapsible && !overlayOpen ? /* @__PURE__ */ jsx32(
|
|
@@ -5713,18 +6019,72 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5713
6019
|
children: collapsedContent
|
|
5714
6020
|
}
|
|
5715
6021
|
) : null,
|
|
6022
|
+
hasAppliedChips ? /* @__PURE__ */ jsxs28(
|
|
6023
|
+
"div",
|
|
6024
|
+
{
|
|
6025
|
+
ref: chipsRef,
|
|
6026
|
+
role: "group",
|
|
6027
|
+
"aria-label": collapsedLabel,
|
|
6028
|
+
"data-slot": "filter-toolbar-applied-chips",
|
|
6029
|
+
className: "hidden flex-wrap items-center gap-[var(--space-2)] @[640px]:flex",
|
|
6030
|
+
children: [
|
|
6031
|
+
appliedFilters.map((filter, index) => /* @__PURE__ */ jsx32(
|
|
6032
|
+
Chip,
|
|
6033
|
+
{
|
|
6034
|
+
ref: (button) => {
|
|
6035
|
+
if (button) chipRemoveRefs.current.set(filter.key, button);
|
|
6036
|
+
else chipRemoveRefs.current.delete(filter.key);
|
|
6037
|
+
},
|
|
6038
|
+
variant: "removable",
|
|
6039
|
+
size: "md",
|
|
6040
|
+
removeLabel: `${filter.label} \uC81C\uAC70`,
|
|
6041
|
+
onClick: () => {
|
|
6042
|
+
pendingFocusRef.current = {
|
|
6043
|
+
removed: [filter.key],
|
|
6044
|
+
next: [appliedFilters[index + 1]?.key, appliedFilters[index - 1]?.key].filter(
|
|
6045
|
+
(key) => key !== void 0
|
|
6046
|
+
)
|
|
6047
|
+
};
|
|
6048
|
+
filter.onRemove();
|
|
6049
|
+
},
|
|
6050
|
+
children: filter.label
|
|
6051
|
+
},
|
|
6052
|
+
filter.key
|
|
6053
|
+
)),
|
|
6054
|
+
onClearFilters ? /* @__PURE__ */ jsx32(
|
|
6055
|
+
"button",
|
|
6056
|
+
{
|
|
6057
|
+
type: "button",
|
|
6058
|
+
"data-slot": "filter-toolbar-clear-filters",
|
|
6059
|
+
className: "cursor-pointer border-0 bg-transparent p-0 text-body-sm font-medium text-text-secondary no-underline",
|
|
6060
|
+
onClick: () => {
|
|
6061
|
+
pendingFocusRef.current = {
|
|
6062
|
+
removed: appliedFilters.map((filter) => filter.key),
|
|
6063
|
+
next: []
|
|
6064
|
+
};
|
|
6065
|
+
onClearFilters();
|
|
6066
|
+
},
|
|
6067
|
+
children: "\uD574\uC81C"
|
|
6068
|
+
}
|
|
6069
|
+
) : null
|
|
6070
|
+
]
|
|
6071
|
+
}
|
|
6072
|
+
) : null,
|
|
5716
6073
|
hasAppliedFilters ? /* @__PURE__ */ jsxs28(
|
|
5717
6074
|
"div",
|
|
5718
6075
|
{
|
|
5719
6076
|
"data-slot": "filter-toolbar-applied",
|
|
5720
|
-
className:
|
|
6077
|
+
className: cn(
|
|
6078
|
+
"flex items-center gap-[var(--space-1)] text-[11px] text-text-tertiary",
|
|
6079
|
+
hasAppliedChips && "@[640px]:hidden"
|
|
6080
|
+
),
|
|
5721
6081
|
children: [
|
|
5722
6082
|
/* @__PURE__ */ jsxs28("span", { children: [
|
|
5723
6083
|
"\uD544\uD130 ",
|
|
5724
6084
|
activeFilterCount,
|
|
5725
6085
|
"\uAC1C \uC801\uC6A9"
|
|
5726
6086
|
] }),
|
|
5727
|
-
onClearFilters ? /* @__PURE__ */ jsxs28(
|
|
6087
|
+
onClearFilters ? /* @__PURE__ */ jsxs28(Fragment14, { children: [
|
|
5728
6088
|
/* @__PURE__ */ jsx32("span", { "aria-hidden": "true", children: " \xB7 " }),
|
|
5729
6089
|
/* @__PURE__ */ jsx32(
|
|
5730
6090
|
"button",
|
|
@@ -6032,16 +6392,19 @@ function DropdownMenuSubContent({
|
|
|
6032
6392
|
}
|
|
6033
6393
|
|
|
6034
6394
|
// src/components/ui/action-menu.tsx
|
|
6035
|
-
import { Fragment as
|
|
6395
|
+
import { Fragment as Fragment16, jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
6036
6396
|
var sheetRowClassName = cn(
|
|
6037
6397
|
"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",
|
|
6038
6398
|
"border-t border-[var(--border-subtle)] text-[13px] font-medium leading-normal text-text-primary",
|
|
6039
6399
|
"transition-colors motion-reduce:transition-none hover:bg-[var(--action-hover)]",
|
|
6040
6400
|
"focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[var(--focus-ring)]",
|
|
6041
6401
|
"enabled:data-[destructive]:text-[var(--semantic-error-fg)]",
|
|
6042
|
-
"disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled"
|
|
6402
|
+
"disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled",
|
|
6403
|
+
"aria-disabled:cursor-not-allowed"
|
|
6043
6404
|
);
|
|
6044
6405
|
var sheetRowDescriptionClassName = "block text-[12px] font-normal text-text-secondary group-disabled:text-text-disabled";
|
|
6406
|
+
var unavailableClassName = "text-text-disabled";
|
|
6407
|
+
var reasonClassName = "block text-[12px] font-normal leading-normal text-text-tertiary";
|
|
6045
6408
|
var sheetGroupLabelClassName = "px-[var(--space-4)] pt-[var(--space-3)] pb-[var(--space-2)] text-[12px] font-semibold leading-normal text-text-tertiary";
|
|
6046
6409
|
var sheetGroupSeparatorClassName = "h-[var(--space-2)] bg-[var(--bg-inset)]";
|
|
6047
6410
|
function ActionMenuSheet({
|
|
@@ -6111,23 +6474,34 @@ function ActionMenuSheet({
|
|
|
6111
6474
|
index > 0 ? /* @__PURE__ */ jsx34("div", { role: "separator", className: sheetGroupSeparatorClassName }) : null,
|
|
6112
6475
|
/* @__PURE__ */ jsxs30("div", { role: "group", "aria-labelledby": group.label ? `${labelId}-${index}` : void 0, children: [
|
|
6113
6476
|
group.label ? /* @__PURE__ */ jsx34("div", { id: `${labelId}-${index}`, className: sheetGroupLabelClassName, children: group.label }) : null,
|
|
6114
|
-
group.items.map((item) => {
|
|
6477
|
+
group.items.map((item, itemIndex) => {
|
|
6115
6478
|
const Icon = item.icon;
|
|
6479
|
+
const reason = item.disabledReason || void 0;
|
|
6480
|
+
const reasonId = `${labelId}-${index}-${itemIndex}-reason`;
|
|
6481
|
+
const itemLabelId = `${labelId}-${index}-${itemIndex}-label`;
|
|
6116
6482
|
return /* @__PURE__ */ jsxs30(
|
|
6117
6483
|
"button",
|
|
6118
6484
|
{
|
|
6119
6485
|
type: "button",
|
|
6120
6486
|
"data-slot": "action-menu-item",
|
|
6121
|
-
"data-destructive": item.destructive ? "" : void 0,
|
|
6487
|
+
"data-destructive": item.destructive && !reason ? "" : void 0,
|
|
6122
6488
|
className: sheetRowClassName,
|
|
6123
|
-
disabled: item.disabled,
|
|
6124
|
-
|
|
6489
|
+
disabled: item.disabled && !reason,
|
|
6490
|
+
"aria-disabled": reason ? true : void 0,
|
|
6491
|
+
"aria-labelledby": reason ? itemLabelId : void 0,
|
|
6492
|
+
"aria-describedby": reason ? reasonId : void 0,
|
|
6493
|
+
onClick: () => {
|
|
6494
|
+
if (!reason) handleSelect(item);
|
|
6495
|
+
},
|
|
6125
6496
|
children: [
|
|
6126
|
-
Icon ? /* @__PURE__ */ jsx34(Icon, { "aria-hidden": true, size: 17, strokeWidth: 1.75, className: "shrink-0" }) : null,
|
|
6127
|
-
/* @__PURE__ */
|
|
6497
|
+
Icon ? /* @__PURE__ */ jsx34(Icon, { "aria-hidden": true, size: 17, strokeWidth: 1.75, className: cn("shrink-0", reason && unavailableClassName) }) : null,
|
|
6498
|
+
/* @__PURE__ */ jsx34("span", { className: "min-w-0 flex-1 break-keep", children: reason ? /* @__PURE__ */ jsxs30(Fragment16, { children: [
|
|
6499
|
+
/* @__PURE__ */ jsx34("span", { id: itemLabelId, className: unavailableClassName, children: item.label }),
|
|
6500
|
+
/* @__PURE__ */ jsx34("span", { id: reasonId, className: reasonClassName, children: reason })
|
|
6501
|
+
] }) : /* @__PURE__ */ jsxs30(Fragment16, { children: [
|
|
6128
6502
|
item.label,
|
|
6129
6503
|
item.description ? /* @__PURE__ */ jsx34("span", { className: sheetRowDescriptionClassName, children: item.description }) : null
|
|
6130
|
-
] })
|
|
6504
|
+
] }) })
|
|
6131
6505
|
]
|
|
6132
6506
|
},
|
|
6133
6507
|
item.id
|
|
@@ -6140,6 +6514,48 @@ function ActionMenuSheet({
|
|
|
6140
6514
|
)
|
|
6141
6515
|
] }) }) });
|
|
6142
6516
|
}
|
|
6517
|
+
function ActionMenuDropdownItem({
|
|
6518
|
+
item,
|
|
6519
|
+
onPick
|
|
6520
|
+
}) {
|
|
6521
|
+
const id = React32.useId();
|
|
6522
|
+
const labelId = `${id}-label`;
|
|
6523
|
+
const reasonId = `${id}-reason`;
|
|
6524
|
+
const Icon = item.icon;
|
|
6525
|
+
const reason = item.disabledReason || void 0;
|
|
6526
|
+
if (!reason) {
|
|
6527
|
+
return /* @__PURE__ */ jsxs30(
|
|
6528
|
+
DropdownMenuItem,
|
|
6529
|
+
{
|
|
6530
|
+
variant: item.destructive ? "destructive" : "default",
|
|
6531
|
+
disabled: item.disabled,
|
|
6532
|
+
onSelect: () => onPick(item),
|
|
6533
|
+
children: [
|
|
6534
|
+
Icon ? /* @__PURE__ */ jsx34(Icon, { "aria-hidden": true, size: 16, strokeWidth: 1.75 }) : null,
|
|
6535
|
+
item.label
|
|
6536
|
+
]
|
|
6537
|
+
}
|
|
6538
|
+
);
|
|
6539
|
+
}
|
|
6540
|
+
return /* @__PURE__ */ jsxs30(
|
|
6541
|
+
DropdownMenuItem,
|
|
6542
|
+
{
|
|
6543
|
+
"aria-disabled": true,
|
|
6544
|
+
"aria-labelledby": labelId,
|
|
6545
|
+
"aria-describedby": reasonId,
|
|
6546
|
+
textValue: item.label,
|
|
6547
|
+
className: "aria-disabled:cursor-not-allowed",
|
|
6548
|
+
onSelect: (event) => event.preventDefault(),
|
|
6549
|
+
children: [
|
|
6550
|
+
Icon ? /* @__PURE__ */ jsx34(Icon, { "aria-hidden": true, size: 16, strokeWidth: 1.75, className: unavailableClassName }) : null,
|
|
6551
|
+
/* @__PURE__ */ jsxs30("span", { className: "min-w-0 flex-1 break-keep", children: [
|
|
6552
|
+
/* @__PURE__ */ jsx34("span", { id: labelId, className: unavailableClassName, children: item.label }),
|
|
6553
|
+
/* @__PURE__ */ jsx34("span", { id: reasonId, className: cn(reasonClassName, "max-w-64"), children: reason })
|
|
6554
|
+
] })
|
|
6555
|
+
]
|
|
6556
|
+
}
|
|
6557
|
+
);
|
|
6558
|
+
}
|
|
6143
6559
|
var readPresentation = () => window.matchMedia?.(OVERLAY_DESKTOP_QUERY).matches ?? true ? "dropdown" : "sheet";
|
|
6144
6560
|
var subscribeNothing = () => () => void 0;
|
|
6145
6561
|
var useHydrated = () => React32.useSyncExternalStore(
|
|
@@ -6190,31 +6606,23 @@ function ActionMenu({
|
|
|
6190
6606
|
triggerRef.current?.focus();
|
|
6191
6607
|
};
|
|
6192
6608
|
const triggerLabel = trigger.props["aria-label"];
|
|
6193
|
-
return /* @__PURE__ */ jsxs30(
|
|
6609
|
+
return /* @__PURE__ */ jsxs30(Fragment16, { children: [
|
|
6194
6610
|
/* @__PURE__ */ jsxs30(DropdownMenu, { open: open && presentation === "dropdown", onOpenChange: setOpen, children: [
|
|
6195
6611
|
/* @__PURE__ */ jsx34(DropdownMenuTrigger, { asChild: true, "aria-expanded": open, children: /* @__PURE__ */ jsx34(Slot3.Root, { ref: triggerRef, children: trigger }) }),
|
|
6196
6612
|
/* @__PURE__ */ jsx34(DropdownMenuContent, { align: "end", onCloseAutoFocus: handleDropdownCloseAutoFocus, children: menuGroups.map((group, index) => /* @__PURE__ */ jsxs30(React32.Fragment, { children: [
|
|
6197
6613
|
index > 0 ? /* @__PURE__ */ jsx34(DropdownMenuSeparator, {}) : null,
|
|
6198
6614
|
/* @__PURE__ */ jsxs30(DropdownMenuGroup, { children: [
|
|
6199
6615
|
group.label ? /* @__PURE__ */ jsx34(DropdownMenuLabel, { children: group.label }) : null,
|
|
6200
|
-
group.items.map((item) =>
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
{
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
children: [
|
|
6211
|
-
Icon ? /* @__PURE__ */ jsx34(Icon, { "aria-hidden": true, size: 16, strokeWidth: 1.75 }) : null,
|
|
6212
|
-
item.label
|
|
6213
|
-
]
|
|
6214
|
-
},
|
|
6215
|
-
item.id
|
|
6216
|
-
);
|
|
6217
|
-
})
|
|
6616
|
+
group.items.map((item) => /* @__PURE__ */ jsx34(
|
|
6617
|
+
ActionMenuDropdownItem,
|
|
6618
|
+
{
|
|
6619
|
+
item,
|
|
6620
|
+
onPick: (picked) => {
|
|
6621
|
+
pendingRef.current = picked;
|
|
6622
|
+
}
|
|
6623
|
+
},
|
|
6624
|
+
item.id
|
|
6625
|
+
))
|
|
6218
6626
|
] })
|
|
6219
6627
|
] }, group.id)) })
|
|
6220
6628
|
] }),
|
|
@@ -6236,7 +6644,7 @@ function ActionMenu({
|
|
|
6236
6644
|
// src/components/ui/checkbox.tsx
|
|
6237
6645
|
import * as React33 from "react";
|
|
6238
6646
|
import { cva as cva12 } from "class-variance-authority";
|
|
6239
|
-
import { Check as
|
|
6647
|
+
import { Check as Check4, Minus } from "lucide-react";
|
|
6240
6648
|
import { Checkbox as CheckboxPrimitive } from "radix-ui";
|
|
6241
6649
|
import { jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
6242
6650
|
var checkboxFieldVariants = cva12(
|
|
@@ -6430,7 +6838,7 @@ var Checkbox = React33.forwardRef(
|
|
|
6430
6838
|
{
|
|
6431
6839
|
"data-slot": "checkbox-indicator",
|
|
6432
6840
|
className: "flex items-center justify-center",
|
|
6433
|
-
children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx35(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx35(
|
|
6841
|
+
children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx35(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx35(Check4, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 })
|
|
6434
6842
|
}
|
|
6435
6843
|
)
|
|
6436
6844
|
}
|
|
@@ -6519,7 +6927,7 @@ var Checkbox = React33.forwardRef(
|
|
|
6519
6927
|
{
|
|
6520
6928
|
"data-slot": "checkbox-indicator",
|
|
6521
6929
|
className: "flex items-center justify-center",
|
|
6522
|
-
children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx35(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx35(
|
|
6930
|
+
children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx35(Minus, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 }) : /* @__PURE__ */ jsx35(Check4, { "aria-hidden": "true", size: 14, strokeWidth: 2.5 })
|
|
6523
6931
|
}
|
|
6524
6932
|
)
|
|
6525
6933
|
}
|
|
@@ -6610,7 +7018,7 @@ function ContextMenu({
|
|
|
6610
7018
|
// src/components/ui/list-card.tsx
|
|
6611
7019
|
import * as React34 from "react";
|
|
6612
7020
|
import { ChevronRight as ChevronRight2, MoreVertical } from "lucide-react";
|
|
6613
|
-
import { Fragment as
|
|
7021
|
+
import { Fragment as Fragment17, jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
6614
7022
|
function lineTokens(value) {
|
|
6615
7023
|
return React34.Children.toArray(value).filter((token) => token !== "");
|
|
6616
7024
|
}
|
|
@@ -6697,7 +7105,7 @@ function ListCard({
|
|
|
6697
7105
|
children: overlay && href != null ? React34.createElement(linkComponent ?? "a", { ...linkProps, href, className: overlayClassName }, title) : title
|
|
6698
7106
|
}
|
|
6699
7107
|
);
|
|
6700
|
-
const content = /* @__PURE__ */ jsxs33(
|
|
7108
|
+
const content = /* @__PURE__ */ jsxs33(Fragment17, { children: [
|
|
6701
7109
|
leading != null ? /* @__PURE__ */ jsx37("span", { className: "flex min-h-[18px] items-center", children: leading }) : null,
|
|
6702
7110
|
/* @__PURE__ */ jsxs33("span", { className: "min-w-0", children: [
|
|
6703
7111
|
overlay && href == null ? (
|
|
@@ -6728,7 +7136,7 @@ function ListCard({
|
|
|
6728
7136
|
),
|
|
6729
7137
|
children: [
|
|
6730
7138
|
hasValue ? /* @__PURE__ */ jsx37("span", { "data-slot": `${slot}-value`, className: "text-[13px] leading-[20px] text-text-secondary tabular-nums", children: value }) : null,
|
|
6731
|
-
actions != null ? /* @__PURE__ */ jsx37("span", { className: "relative z-[1] flex", children: /* @__PURE__ */ jsx37(
|
|
7139
|
+
actions != null ? /* @__PURE__ */ jsx37("span", { "data-slot": `${slot}-actions`, className: "relative z-[1] flex", children: /* @__PURE__ */ jsx37(
|
|
6732
7140
|
ActionMenu,
|
|
6733
7141
|
{
|
|
6734
7142
|
title: typeof title === "string" ? title : void 0,
|
|
@@ -6762,7 +7170,7 @@ function ListCard({
|
|
|
6762
7170
|
}
|
|
6763
7171
|
|
|
6764
7172
|
// src/components/ui/data-table.tsx
|
|
6765
|
-
import { Fragment as
|
|
7173
|
+
import { Fragment as Fragment19, jsx as jsx38, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
6766
7174
|
var dataTableVariants = cva13(
|
|
6767
7175
|
[
|
|
6768
7176
|
"relative overflow-hidden rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
|
|
@@ -6885,25 +7293,24 @@ function RowActionsCell({
|
|
|
6885
7293
|
);
|
|
6886
7294
|
}
|
|
6887
7295
|
function RowContextMenu({
|
|
6888
|
-
|
|
7296
|
+
menuKey,
|
|
6889
7297
|
position,
|
|
6890
7298
|
groups,
|
|
7299
|
+
cards,
|
|
6891
7300
|
onClose
|
|
6892
7301
|
}) {
|
|
6893
|
-
const [open, setOpen] = React35.useState(
|
|
6894
|
-
const
|
|
6895
|
-
const
|
|
7302
|
+
const [open, setOpen] = React35.useState(true);
|
|
7303
|
+
const closeRef = React35.useRef(null);
|
|
7304
|
+
const pressedOutside = React35.useRef(false);
|
|
7305
|
+
const close = (reason) => {
|
|
7306
|
+
closeRef.current ??= reason;
|
|
7307
|
+
setOpen(false);
|
|
7308
|
+
};
|
|
6896
7309
|
const shownGroups = React35.useRef([]);
|
|
6897
7310
|
if (groups) shownGroups.current = groups;
|
|
6898
|
-
const gone =
|
|
7311
|
+
const gone = groups === null;
|
|
6899
7312
|
const contentRef = React35.useRef(null);
|
|
6900
7313
|
const focusInsideRef = React35.useRef(false);
|
|
6901
|
-
React35.useEffect(() => {
|
|
6902
|
-
pendingRef.current = null;
|
|
6903
|
-
outsideRef.current = false;
|
|
6904
|
-
focusInsideRef.current = false;
|
|
6905
|
-
setOpen(openKey !== null);
|
|
6906
|
-
}, [openKey]);
|
|
6907
7314
|
useIsomorphicLayoutEffect(() => {
|
|
6908
7315
|
const content = contentRef.current;
|
|
6909
7316
|
if (!open || !focusInsideRef.current || !content?.isConnected) return;
|
|
@@ -6913,13 +7320,20 @@ function RowContextMenu({
|
|
|
6913
7320
|
next.focus();
|
|
6914
7321
|
});
|
|
6915
7322
|
React35.useEffect(() => {
|
|
6916
|
-
if (gone)
|
|
7323
|
+
if (gone) close({ by: "dismiss", outside: false });
|
|
6917
7324
|
}, [gone]);
|
|
7325
|
+
useIsomorphicLayoutEffect(() => {
|
|
7326
|
+
if (!cards || !open || closeRef.current) return;
|
|
7327
|
+
const active = document.activeElement;
|
|
7328
|
+
close({ by: "layout", focusInside: Boolean(active && contentRef.current?.contains(active)) });
|
|
7329
|
+
}, [cards, open]);
|
|
6918
7330
|
return /* @__PURE__ */ jsx38(
|
|
6919
7331
|
ContextMenu,
|
|
6920
7332
|
{
|
|
6921
7333
|
open: open && !gone,
|
|
6922
|
-
onOpenChange:
|
|
7334
|
+
onOpenChange: (next) => {
|
|
7335
|
+
if (!next) close({ by: "dismiss", outside: false });
|
|
7336
|
+
},
|
|
6923
7337
|
position,
|
|
6924
7338
|
contentProps: {
|
|
6925
7339
|
align: "start",
|
|
@@ -6933,37 +7347,31 @@ function RowContextMenu({
|
|
|
6933
7347
|
}
|
|
6934
7348
|
},
|
|
6935
7349
|
onInteractOutside: () => {
|
|
6936
|
-
|
|
7350
|
+
pressedOutside.current = true;
|
|
7351
|
+
close({ by: "dismiss", outside: true });
|
|
6937
7352
|
},
|
|
6938
7353
|
onCloseAutoFocus: (event) => {
|
|
6939
7354
|
event.preventDefault();
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
7355
|
+
let reason = closeRef.current ?? { by: "dismiss", outside: false };
|
|
7356
|
+
if (pressedOutside.current && reason.by === "dismiss") reason = { by: "dismiss", outside: true };
|
|
7357
|
+
if (pressedOutside.current && reason.by === "layout") reason = { by: "layout", focusInside: false };
|
|
7358
|
+
onClose(menuKey, reason);
|
|
6943
7359
|
}
|
|
6944
7360
|
},
|
|
6945
7361
|
children: shownGroups.current.map((group, index) => /* @__PURE__ */ jsxs34(React35.Fragment, { children: [
|
|
6946
7362
|
index > 0 ? /* @__PURE__ */ jsx38(DropdownMenuSeparator, {}) : null,
|
|
6947
7363
|
/* @__PURE__ */ jsxs34(DropdownMenuGroup, { children: [
|
|
6948
7364
|
group.label ? /* @__PURE__ */ jsx38(DropdownMenuLabel, { children: group.label }) : null,
|
|
6949
|
-
group.items.map((item) =>
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
{
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
children: [
|
|
6960
|
-
Icon ? /* @__PURE__ */ jsx38(Icon, { "aria-hidden": true, size: 16, strokeWidth: 1.75 }) : null,
|
|
6961
|
-
item.label
|
|
6962
|
-
]
|
|
6963
|
-
},
|
|
6964
|
-
item.id
|
|
6965
|
-
);
|
|
6966
|
-
})
|
|
7365
|
+
group.items.map((item) => /* @__PURE__ */ jsx38(
|
|
7366
|
+
ActionMenuDropdownItem,
|
|
7367
|
+
{
|
|
7368
|
+
item,
|
|
7369
|
+
onPick: (picked) => {
|
|
7370
|
+
closeRef.current ??= { by: "item", item: picked };
|
|
7371
|
+
}
|
|
7372
|
+
},
|
|
7373
|
+
item.id
|
|
7374
|
+
))
|
|
6967
7375
|
] })
|
|
6968
7376
|
] }, group.id))
|
|
6969
7377
|
}
|
|
@@ -7044,7 +7452,7 @@ function MobileSortMenu({
|
|
|
7044
7452
|
size: "sm",
|
|
7045
7453
|
className: "ml-auto min-w-0",
|
|
7046
7454
|
children: [
|
|
7047
|
-
active && sortBy ? /* @__PURE__ */ jsxs34(
|
|
7455
|
+
active && sortBy ? /* @__PURE__ */ jsxs34(Fragment19, { children: [
|
|
7048
7456
|
/* @__PURE__ */ jsx38("span", { className: "sr-only", children: "\uC815\uB82C " }),
|
|
7049
7457
|
/* @__PURE__ */ jsx38("span", { className: "truncate", children: active.header }),
|
|
7050
7458
|
/* @__PURE__ */ jsxs34("span", { className: "sr-only", children: [
|
|
@@ -7317,7 +7725,7 @@ function DataTableRowView({
|
|
|
7317
7725
|
if (!expand) {
|
|
7318
7726
|
return dataRow;
|
|
7319
7727
|
}
|
|
7320
|
-
return /* @__PURE__ */ jsxs34(
|
|
7728
|
+
return /* @__PURE__ */ jsxs34(Fragment19, { children: [
|
|
7321
7729
|
dataRow,
|
|
7322
7730
|
/* @__PURE__ */ jsx38(
|
|
7323
7731
|
"div",
|
|
@@ -7929,15 +8337,22 @@ function DataTableInner({
|
|
|
7929
8337
|
contextMenuKey.current += 1;
|
|
7930
8338
|
setContextMenu({ rowId, position: { x: event.clientX, y: event.clientY }, key: contextMenuKey.current });
|
|
7931
8339
|
};
|
|
7932
|
-
const closeRowContextMenu = (
|
|
8340
|
+
const closeRowContextMenu = (key, close) => {
|
|
8341
|
+
if (key !== contextMenuKey.current) {
|
|
8342
|
+
return;
|
|
8343
|
+
}
|
|
7933
8344
|
const rowId = contextMenu?.rowId;
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
const
|
|
7937
|
-
|
|
8345
|
+
const refocus = close.by === "item" || (close.by === "dismiss" ? !close.outside : close.focusInside);
|
|
8346
|
+
if (rowId !== void 0 && refocus) {
|
|
8347
|
+
const cards = readLayout(desktopRef.current) === "mobile";
|
|
8348
|
+
const list = cards ? mobileListRef.current : desktopListRef.current;
|
|
8349
|
+
const row = Array.from(
|
|
8350
|
+
list?.querySelectorAll(cards ? '[data-slot="data-table-mobile-card"]' : '[data-slot="data-table-row"]') ?? []
|
|
8351
|
+
).find((node) => node.getAttribute("data-row-id") === rowId);
|
|
8352
|
+
const trigger = row?.querySelector(
|
|
8353
|
+
cards ? '[data-slot="list-card-actions"] button' : '[data-slot="data-table-row-actions"] button'
|
|
7938
8354
|
);
|
|
7939
|
-
const
|
|
7940
|
-
const target = trigger ?? (row?.hasAttribute("tabindex") ? row : null) ?? list ?? desktopRef.current;
|
|
8355
|
+
const target = trigger ?? (row && (cards || row.hasAttribute("tabindex")) ? row : null) ?? list ?? (cards ? mobileRef : desktopRef).current;
|
|
7941
8356
|
if (target) {
|
|
7942
8357
|
if (!target.hasAttribute("tabindex") && !target.matches("a[href],button,input")) {
|
|
7943
8358
|
target.tabIndex = -1;
|
|
@@ -7946,7 +8361,7 @@ function DataTableInner({
|
|
|
7946
8361
|
}
|
|
7947
8362
|
}
|
|
7948
8363
|
setContextMenu(null);
|
|
7949
|
-
item
|
|
8364
|
+
if (close.by === "item") close.item.onSelect();
|
|
7950
8365
|
};
|
|
7951
8366
|
const handleRowContextMenu = rowActions ? openRowContextMenu : onRowContextMenu;
|
|
7952
8367
|
const latestHandlers = React35.useRef({ toggleRow, activateRow, onRowContextMenu, handleRowContextMenu });
|
|
@@ -8198,14 +8613,16 @@ function DataTableInner({
|
|
|
8198
8613
|
)
|
|
8199
8614
|
] }),
|
|
8200
8615
|
footer != null ? /* @__PURE__ */ jsx38("div", { "data-slot": "data-table-footer", className: "border-t border-[var(--border-subtle)] empty:hidden", children: footer }) : null,
|
|
8201
|
-
hasRowActions ? /* @__PURE__ */ jsx38(
|
|
8616
|
+
hasRowActions && contextMenu ? /* @__PURE__ */ jsx38(
|
|
8202
8617
|
RowContextMenu,
|
|
8203
8618
|
{
|
|
8204
|
-
|
|
8205
|
-
position: contextMenu
|
|
8619
|
+
menuKey: contextMenu.key,
|
|
8620
|
+
position: contextMenu.position,
|
|
8206
8621
|
groups: contextGroups,
|
|
8622
|
+
cards: activeLayout === "mobile",
|
|
8207
8623
|
onClose: closeRowContextMenu
|
|
8208
|
-
}
|
|
8624
|
+
},
|
|
8625
|
+
contextMenu.key
|
|
8209
8626
|
) : null
|
|
8210
8627
|
]
|
|
8211
8628
|
}
|
|
@@ -8263,6 +8680,35 @@ function ActionButton({ action }) {
|
|
|
8263
8680
|
}
|
|
8264
8681
|
);
|
|
8265
8682
|
}
|
|
8683
|
+
function CardActionButton({ action }) {
|
|
8684
|
+
const Icon = action.icon;
|
|
8685
|
+
return /* @__PURE__ */ jsxs35(
|
|
8686
|
+
Button,
|
|
8687
|
+
{
|
|
8688
|
+
appearance: "outline",
|
|
8689
|
+
tone: action.variant === "destructive" ? "danger" : "neutral",
|
|
8690
|
+
size: "sm",
|
|
8691
|
+
className: "before:-inset-y-[5px]",
|
|
8692
|
+
"data-slot": "bulk-action-bar-action",
|
|
8693
|
+
"data-variant": action.variant ?? "default",
|
|
8694
|
+
disabled: action.disabled,
|
|
8695
|
+
title: action.title,
|
|
8696
|
+
onClick: action.onClick,
|
|
8697
|
+
children: [
|
|
8698
|
+
Icon ? /* @__PURE__ */ jsx39(
|
|
8699
|
+
Icon,
|
|
8700
|
+
{
|
|
8701
|
+
"aria-hidden": "true",
|
|
8702
|
+
"data-slot": "bulk-action-bar-action-icon",
|
|
8703
|
+
size: 16,
|
|
8704
|
+
strokeWidth: 1.75
|
|
8705
|
+
}
|
|
8706
|
+
) : null,
|
|
8707
|
+
action.label
|
|
8708
|
+
]
|
|
8709
|
+
}
|
|
8710
|
+
);
|
|
8711
|
+
}
|
|
8266
8712
|
function Divider() {
|
|
8267
8713
|
return /* @__PURE__ */ jsx39(
|
|
8268
8714
|
"span",
|
|
@@ -8305,24 +8751,24 @@ function ClearButton({ onClear }) {
|
|
|
8305
8751
|
}
|
|
8306
8752
|
);
|
|
8307
8753
|
}
|
|
8754
|
+
var CLEAR_CLEARANCE = 32;
|
|
8308
8755
|
var INLINE_HEIGHT = 40;
|
|
8309
8756
|
var HIT_AREA = 44;
|
|
8310
8757
|
var HIT_INSET = 8;
|
|
8758
|
+
var FLOATING_BOTTOM = "calc(var(--space-4) + env(safe-area-inset-bottom))";
|
|
8311
8759
|
var floatingStyle = {
|
|
8312
8760
|
position: "sticky",
|
|
8313
|
-
bottom:
|
|
8761
|
+
bottom: FLOATING_BOTTOM,
|
|
8314
8762
|
zIndex: 1100,
|
|
8315
8763
|
margin: "0 auto",
|
|
8316
8764
|
display: "flex",
|
|
8317
|
-
|
|
8318
|
-
width: "
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
gap: "var(--space-2)",
|
|
8322
|
-
borderRadius: 9999,
|
|
8765
|
+
boxSizing: "border-box",
|
|
8766
|
+
width: "min(360px, calc(100% - var(--space-8)))",
|
|
8767
|
+
flexDirection: "column",
|
|
8768
|
+
borderRadius: "var(--radius-xl)",
|
|
8323
8769
|
border: "1px solid var(--border)",
|
|
8324
8770
|
background: "var(--bg-raised)",
|
|
8325
|
-
padding: "var(--space-
|
|
8771
|
+
padding: "var(--space-2) var(--space-4) var(--space-3)",
|
|
8326
8772
|
boxShadow: "var(--shadow-8)"
|
|
8327
8773
|
};
|
|
8328
8774
|
var inlineStyle = {
|
|
@@ -8364,7 +8810,117 @@ function warnInlineOnce() {
|
|
|
8364
8810
|
warnedInline = true;
|
|
8365
8811
|
console.warn('BulkActionBar: placement="inline" is deprecated and removed in the next minor. Use "floating".');
|
|
8366
8812
|
}
|
|
8813
|
+
var warnedTrailing = false;
|
|
8814
|
+
function warnTrailingOnce() {
|
|
8815
|
+
if (warnedTrailing || typeof process === "undefined" || process.env.NODE_ENV === "production") {
|
|
8816
|
+
return;
|
|
8817
|
+
}
|
|
8818
|
+
warnedTrailing = true;
|
|
8819
|
+
console.warn("BulkActionBar: the floating card ignores `trailing`. Put edit-mode controls at the right end of the toolbar.");
|
|
8820
|
+
}
|
|
8821
|
+
var OFFSET_PROPERTY = "--olun-bulk-bar-offset";
|
|
8822
|
+
var LIFT_ZONE = 204;
|
|
8823
|
+
var cardOffsets = /* @__PURE__ */ new Map();
|
|
8824
|
+
function writeOffset() {
|
|
8825
|
+
const root = document.documentElement;
|
|
8826
|
+
const offset = Math.max(0, ...cardOffsets.values());
|
|
8827
|
+
const value = offset > 0 ? `${offset}px` : "";
|
|
8828
|
+
if (root.style.getPropertyValue(OFFSET_PROPERTY) === value) return;
|
|
8829
|
+
if (value) root.style.setProperty(OFFSET_PROPERTY, value);
|
|
8830
|
+
else root.style.removeProperty(OFFSET_PROPERTY);
|
|
8831
|
+
}
|
|
8832
|
+
function reportOffset(key, card) {
|
|
8833
|
+
let offset = 0;
|
|
8834
|
+
if (card.offsetHeight > 0) {
|
|
8835
|
+
const { top, bottom } = card.getBoundingClientRect();
|
|
8836
|
+
if (window.innerHeight - bottom <= LIFT_ZONE) offset = Math.max(0, Math.round(window.innerHeight - top));
|
|
8837
|
+
}
|
|
8838
|
+
if (offset === (cardOffsets.get(key) ?? 0)) return;
|
|
8839
|
+
if (offset > 0) cardOffsets.set(key, offset);
|
|
8840
|
+
else cardOffsets.delete(key);
|
|
8841
|
+
writeOffset();
|
|
8842
|
+
}
|
|
8367
8843
|
var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React36.useEffect : React36.useLayoutEffect;
|
|
8844
|
+
function useBottomOffset(card) {
|
|
8845
|
+
const [key] = React36.useState(() => ({}));
|
|
8846
|
+
React36.useEffect(() => {
|
|
8847
|
+
if (!card) return;
|
|
8848
|
+
let frame = 0;
|
|
8849
|
+
let stopped = false;
|
|
8850
|
+
let listening = false;
|
|
8851
|
+
const schedule = () => {
|
|
8852
|
+
if (frame || stopped) return;
|
|
8853
|
+
frame = requestAnimationFrame(measure);
|
|
8854
|
+
};
|
|
8855
|
+
const listen = (on) => {
|
|
8856
|
+
if (on === listening) return;
|
|
8857
|
+
listening = on;
|
|
8858
|
+
if (on) {
|
|
8859
|
+
window.addEventListener("resize", schedule);
|
|
8860
|
+
window.addEventListener("scroll", schedule, { capture: true, passive: true });
|
|
8861
|
+
} else {
|
|
8862
|
+
window.removeEventListener("resize", schedule);
|
|
8863
|
+
window.removeEventListener("scroll", schedule, { capture: true });
|
|
8864
|
+
}
|
|
8865
|
+
};
|
|
8866
|
+
let watcher = null;
|
|
8867
|
+
let watched = "";
|
|
8868
|
+
const arm = (margin, threshold) => {
|
|
8869
|
+
let first = true;
|
|
8870
|
+
watcher = new IntersectionObserver(
|
|
8871
|
+
([entry]) => {
|
|
8872
|
+
if (stopped) return;
|
|
8873
|
+
if (first) {
|
|
8874
|
+
first = false;
|
|
8875
|
+
if (entry.intersectionRatio === threshold) return;
|
|
8876
|
+
watcher?.disconnect();
|
|
8877
|
+
arm(margin, entry.intersectionRatio);
|
|
8878
|
+
}
|
|
8879
|
+
schedule();
|
|
8880
|
+
},
|
|
8881
|
+
{ root: document, rootMargin: margin, threshold }
|
|
8882
|
+
);
|
|
8883
|
+
watcher.observe(card);
|
|
8884
|
+
};
|
|
8885
|
+
const watch = (on) => {
|
|
8886
|
+
let margin = "";
|
|
8887
|
+
if (on && typeof IntersectionObserver !== "undefined") {
|
|
8888
|
+
const { top, right, bottom, left } = card.getBoundingClientRect();
|
|
8889
|
+
const { clientWidth, clientHeight } = document.documentElement;
|
|
8890
|
+
margin = [top, clientWidth - right, clientHeight - bottom, left].map((inset) => `${-Math.floor(inset)}px`).join(" ");
|
|
8891
|
+
}
|
|
8892
|
+
if (margin === watched) return;
|
|
8893
|
+
watched = margin;
|
|
8894
|
+
watcher?.disconnect();
|
|
8895
|
+
watcher = null;
|
|
8896
|
+
if (margin) arm(margin, 1);
|
|
8897
|
+
};
|
|
8898
|
+
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(() => schedule());
|
|
8899
|
+
const measure = () => {
|
|
8900
|
+
frame = 0;
|
|
8901
|
+
reportOffset(key, card);
|
|
8902
|
+
const shown = card.offsetHeight > 0;
|
|
8903
|
+
listen(shown || !observer);
|
|
8904
|
+
watch(shown);
|
|
8905
|
+
};
|
|
8906
|
+
measure();
|
|
8907
|
+
observer?.observe(card);
|
|
8908
|
+
card.addEventListener("animationend", schedule);
|
|
8909
|
+
return () => {
|
|
8910
|
+
stopped = true;
|
|
8911
|
+
cancelAnimationFrame(frame);
|
|
8912
|
+
listen(false);
|
|
8913
|
+
watcher?.disconnect();
|
|
8914
|
+
observer?.disconnect();
|
|
8915
|
+
card.removeEventListener("animationend", schedule);
|
|
8916
|
+
cardOffsets.delete(key);
|
|
8917
|
+
writeOffset();
|
|
8918
|
+
};
|
|
8919
|
+
}, [key, card]);
|
|
8920
|
+
useIsomorphicLayoutEffect2(() => {
|
|
8921
|
+
if (card && typeof ResizeObserver === "undefined") reportOffset(key, card);
|
|
8922
|
+
});
|
|
8923
|
+
}
|
|
8368
8924
|
function useCompactSummary(slot, enabled) {
|
|
8369
8925
|
const [fullWidth, setFullWidth] = React36.useState(null);
|
|
8370
8926
|
const measure = React36.useCallback(() => {
|
|
@@ -8402,7 +8958,9 @@ function BulkActionBar({
|
|
|
8402
8958
|
}) {
|
|
8403
8959
|
const inline = placement === "inline";
|
|
8404
8960
|
if (inline) warnInlineOnce();
|
|
8405
|
-
const
|
|
8961
|
+
const hasTrailing = trailing !== void 0 && trailing !== null;
|
|
8962
|
+
if (!inline && hasTrailing) warnTrailingOnce();
|
|
8963
|
+
const trailingSlot = inline && hasTrailing ? /* @__PURE__ */ jsx39(
|
|
8406
8964
|
"div",
|
|
8407
8965
|
{
|
|
8408
8966
|
"data-slot": "bulk-action-bar-trailing",
|
|
@@ -8420,6 +8978,8 @@ function BulkActionBar({
|
|
|
8420
8978
|
summaryElement,
|
|
8421
8979
|
inline && compactSummary !== void 0 && compactSummary !== null
|
|
8422
8980
|
);
|
|
8981
|
+
const [card, setCard] = React36.useState(null);
|
|
8982
|
+
useBottomOffset(card);
|
|
8423
8983
|
if (count === 0 && idleContent !== void 0 && trailingSlot) {
|
|
8424
8984
|
return /* @__PURE__ */ jsxs35(
|
|
8425
8985
|
"div",
|
|
@@ -8474,16 +9034,31 @@ function BulkActionBar({
|
|
|
8474
9034
|
"span",
|
|
8475
9035
|
{
|
|
8476
9036
|
"data-slot": "bulk-action-bar-count",
|
|
8477
|
-
style: {
|
|
8478
|
-
paddingLeft: inline ? void 0 : "var(--space-2)",
|
|
9037
|
+
style: inline ? {
|
|
8479
9038
|
paddingRight: "var(--space-1)",
|
|
8480
9039
|
fontFamily: "var(--font-sans)",
|
|
8481
9040
|
fontSize: 13,
|
|
8482
|
-
fontWeight:
|
|
9041
|
+
fontWeight: 600,
|
|
8483
9042
|
fontVariantNumeric: "tabular-nums",
|
|
8484
9043
|
color: "var(--text-primary)",
|
|
8485
9044
|
whiteSpace: "nowrap"
|
|
8486
|
-
}
|
|
9045
|
+
} : (
|
|
9046
|
+
// First row, 32px like the ✕ beside it; the right padding keeps text clear of it,
|
|
9047
|
+
// and a long unbroken unit or hint breaks instead of running under it.
|
|
9048
|
+
{
|
|
9049
|
+
display: "flex",
|
|
9050
|
+
minHeight: 32,
|
|
9051
|
+
alignItems: "center",
|
|
9052
|
+
paddingRight: CLEAR_CLEARANCE,
|
|
9053
|
+
fontFamily: "var(--font-sans)",
|
|
9054
|
+
fontSize: 13,
|
|
9055
|
+
fontWeight: 500,
|
|
9056
|
+
fontVariantNumeric: "tabular-nums",
|
|
9057
|
+
color: "var(--text-primary)",
|
|
9058
|
+
wordBreak: "keep-all",
|
|
9059
|
+
overflowWrap: "anywhere"
|
|
9060
|
+
}
|
|
9061
|
+
),
|
|
8487
9062
|
children: count > 0 ? `${count.toLocaleString("ko-KR")}${unit} \uC120\uD0DD\uB428` : emptyHint
|
|
8488
9063
|
}
|
|
8489
9064
|
);
|
|
@@ -8493,7 +9068,7 @@ function BulkActionBar({
|
|
|
8493
9068
|
ref: setSummaryElement,
|
|
8494
9069
|
"data-slot": "bulk-action-bar-summary",
|
|
8495
9070
|
style: {
|
|
8496
|
-
display:
|
|
9071
|
+
display: "flex",
|
|
8497
9072
|
minWidth: 0,
|
|
8498
9073
|
alignItems: "center",
|
|
8499
9074
|
columnGap: "var(--space-3)",
|
|
@@ -8516,27 +9091,30 @@ function BulkActionBar({
|
|
|
8516
9091
|
whiteSpace: "nowrap",
|
|
8517
9092
|
contain: "inline-size"
|
|
8518
9093
|
}
|
|
8519
|
-
) :
|
|
9094
|
+
) : (
|
|
9095
|
+
// Its own row at the card's full inner width; wraps, never clips.
|
|
9096
|
+
{ flexWrap: "wrap", lineHeight: 1.5, wordBreak: "keep-all", overflowWrap: "anywhere" }
|
|
9097
|
+
)
|
|
8520
9098
|
},
|
|
8521
9099
|
children: compact ? compactSummary : summary
|
|
8522
9100
|
}
|
|
8523
9101
|
) : null;
|
|
8524
|
-
const actionGroup = /* @__PURE__ */ jsx39(
|
|
8525
|
-
"div",
|
|
8526
|
-
{
|
|
8527
|
-
"data-slot": "bulk-action-bar-actions",
|
|
8528
|
-
style: {
|
|
8529
|
-
display: "flex",
|
|
8530
|
-
minWidth: 0,
|
|
8531
|
-
flexWrap: inline ? "nowrap" : "wrap",
|
|
8532
|
-
alignItems: "center",
|
|
8533
|
-
justifyContent: "flex-end",
|
|
8534
|
-
gap: 2
|
|
8535
|
-
},
|
|
8536
|
-
children: actions.map((action) => /* @__PURE__ */ jsx39(ActionButton, { action }, action.key))
|
|
8537
|
-
}
|
|
8538
|
-
);
|
|
8539
9102
|
if (inline) {
|
|
9103
|
+
const actionGroup = /* @__PURE__ */ jsx39(
|
|
9104
|
+
"div",
|
|
9105
|
+
{
|
|
9106
|
+
"data-slot": "bulk-action-bar-actions",
|
|
9107
|
+
style: {
|
|
9108
|
+
display: "flex",
|
|
9109
|
+
minWidth: 0,
|
|
9110
|
+
flexWrap: "nowrap",
|
|
9111
|
+
alignItems: "center",
|
|
9112
|
+
justifyContent: "flex-end",
|
|
9113
|
+
gap: 2
|
|
9114
|
+
},
|
|
9115
|
+
children: actions.map((action) => /* @__PURE__ */ jsx39(ActionButton, { action }, action.key))
|
|
9116
|
+
}
|
|
9117
|
+
);
|
|
8540
9118
|
return /* @__PURE__ */ jsxs35(
|
|
8541
9119
|
"div",
|
|
8542
9120
|
{
|
|
@@ -8601,6 +9179,7 @@ function BulkActionBar({
|
|
|
8601
9179
|
"animate-[olun-bulk-action-bar-in_var(--dur-fast)_var(--ease-out)_both] motion-reduce:animate-none",
|
|
8602
9180
|
className
|
|
8603
9181
|
),
|
|
9182
|
+
ref: setCard,
|
|
8604
9183
|
style: { ...floatingStyle, ...style },
|
|
8605
9184
|
...props,
|
|
8606
9185
|
children: [
|
|
@@ -8612,8 +9191,8 @@ function BulkActionBar({
|
|
|
8612
9191
|
style: {
|
|
8613
9192
|
display: "flex",
|
|
8614
9193
|
minWidth: 0,
|
|
8615
|
-
|
|
8616
|
-
|
|
9194
|
+
flexDirection: "column",
|
|
9195
|
+
rowGap: "var(--space-2)"
|
|
8617
9196
|
},
|
|
8618
9197
|
children: [
|
|
8619
9198
|
countLabel,
|
|
@@ -8621,11 +9200,29 @@ function BulkActionBar({
|
|
|
8621
9200
|
]
|
|
8622
9201
|
}
|
|
8623
9202
|
),
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
9203
|
+
actions.length > 0 ? /* @__PURE__ */ jsx39(
|
|
9204
|
+
"div",
|
|
9205
|
+
{
|
|
9206
|
+
"data-slot": "bulk-action-bar-actions",
|
|
9207
|
+
style: {
|
|
9208
|
+
display: "flex",
|
|
9209
|
+
flexWrap: "wrap",
|
|
9210
|
+
justifyContent: "flex-end",
|
|
9211
|
+
gap: "var(--space-2)",
|
|
9212
|
+
marginTop: "var(--space-3)"
|
|
9213
|
+
},
|
|
9214
|
+
children: actions.map((action) => /* @__PURE__ */ jsx39(CardActionButton, { action }, action.key))
|
|
9215
|
+
}
|
|
9216
|
+
) : null,
|
|
9217
|
+
/* @__PURE__ */ jsx39(
|
|
9218
|
+
IconButton,
|
|
9219
|
+
{
|
|
9220
|
+
icon: X4,
|
|
9221
|
+
"aria-label": "\uC120\uD0DD \uD574\uC81C",
|
|
9222
|
+
onClick: onClear,
|
|
9223
|
+
style: { position: "absolute", top: "var(--space-2)", right: "var(--space-2)" }
|
|
9224
|
+
}
|
|
9225
|
+
)
|
|
8629
9226
|
]
|
|
8630
9227
|
}
|
|
8631
9228
|
);
|
|
@@ -9957,7 +10554,7 @@ function TablePagination({
|
|
|
9957
10554
|
|
|
9958
10555
|
// src/components/ui/mode-toggle.tsx
|
|
9959
10556
|
import { cva as cva19 } from "class-variance-authority";
|
|
9960
|
-
import { jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
10557
|
+
import { Fragment as Fragment20, jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
9961
10558
|
var modeToggleVariants = cva19(
|
|
9962
10559
|
[
|
|
9963
10560
|
"inline-flex items-center rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
|
|
@@ -9980,6 +10577,17 @@ var modeToggleItemVariants = cva19(
|
|
|
9980
10577
|
"[&_svg]:pointer-events-none [&_svg]:size-[14px] [&_svg]:shrink-0 [&_svg]:stroke-[1.75]"
|
|
9981
10578
|
].join(" ")
|
|
9982
10579
|
);
|
|
10580
|
+
function formatModeToggleCount(value) {
|
|
10581
|
+
return value > 99 ? "99+" : String(value);
|
|
10582
|
+
}
|
|
10583
|
+
function isShownModeToggleCount(value) {
|
|
10584
|
+
if (value === void 0) return false;
|
|
10585
|
+
if (Number.isInteger(value) && value >= 0) return true;
|
|
10586
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
|
|
10587
|
+
console.warn(`ModeToggle: count must be an integer 0 or greater (got ${value}). The count is not shown.`);
|
|
10588
|
+
}
|
|
10589
|
+
return false;
|
|
10590
|
+
}
|
|
9983
10591
|
function ModeToggle({
|
|
9984
10592
|
className,
|
|
9985
10593
|
itemClassName,
|
|
@@ -10020,7 +10628,11 @@ function ModeToggle({
|
|
|
10020
10628
|
},
|
|
10021
10629
|
children: [
|
|
10022
10630
|
Icon ? /* @__PURE__ */ jsx56(Icon, { "aria-hidden": "true", "data-slot": "mode-toggle-icon" }) : null,
|
|
10023
|
-
/* @__PURE__ */ jsx56("span", { children: option.label })
|
|
10631
|
+
/* @__PURE__ */ jsx56("span", { children: option.label }),
|
|
10632
|
+
isShownModeToggleCount(option.count) ? /* @__PURE__ */ jsxs45(Fragment20, { children: [
|
|
10633
|
+
/* @__PURE__ */ jsx56("span", { "aria-hidden": "true", "data-slot": "mode-toggle-count", className: tabsBadgeVariants(), children: formatModeToggleCount(option.count) }),
|
|
10634
|
+
/* @__PURE__ */ jsx56("span", { className: "sr-only", children: ` ${option.count}` })
|
|
10635
|
+
] }) : null
|
|
10024
10636
|
]
|
|
10025
10637
|
},
|
|
10026
10638
|
option.value
|
|
@@ -10236,7 +10848,8 @@ var toastVariants = cva21(
|
|
|
10236
10848
|
);
|
|
10237
10849
|
var toastViewportVariants = cva21(
|
|
10238
10850
|
[
|
|
10239
|
-
|
|
10851
|
+
// A floating BulkActionBar publishes --olun-bulk-bar-offset while it is up; sit 8px above it.
|
|
10852
|
+
"fixed bottom-[max(var(--space-6),calc(var(--olun-bulk-bar-offset,0px)+var(--space-2)))] right-[var(--space-6)] z-[var(--z-toast,50)]",
|
|
10240
10853
|
"flex w-[min(420px,calc(100vw-var(--space-12)))] list-none flex-col gap-[var(--space-2)]",
|
|
10241
10854
|
"pointer-events-none outline-none"
|
|
10242
10855
|
].join(" ")
|
|
@@ -10468,7 +11081,7 @@ function ToastProvider({ children, maxToasts = 3, className, ...props }) {
|
|
|
10468
11081
|
import * as React48 from "react";
|
|
10469
11082
|
import { cva as cva22 } from "class-variance-authority";
|
|
10470
11083
|
import { AlertCircle as AlertCircle4 } from "lucide-react";
|
|
10471
|
-
import { Fragment as
|
|
11084
|
+
import { Fragment as Fragment21, jsx as jsx59, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
10472
11085
|
var otpFieldVariants = cva22("flex w-full min-w-0 flex-col gap-[var(--space-3)]", {
|
|
10473
11086
|
variants: {
|
|
10474
11087
|
size: {
|
|
@@ -10798,7 +11411,7 @@ var OTPField = React48.forwardRef(
|
|
|
10798
11411
|
"data-slot": "otp-field-message",
|
|
10799
11412
|
"data-kind": errorText ? "error" : "helper",
|
|
10800
11413
|
className: otpFieldMessageVariants({ state: resolvedState }),
|
|
10801
|
-
children: errorText ? /* @__PURE__ */ jsxs48(
|
|
11414
|
+
children: errorText ? /* @__PURE__ */ jsxs48(Fragment21, { children: [
|
|
10802
11415
|
/* @__PURE__ */ jsx59(
|
|
10803
11416
|
AlertCircle4,
|
|
10804
11417
|
{
|
|
@@ -11686,7 +12299,7 @@ function TreeView({
|
|
|
11686
12299
|
|
|
11687
12300
|
// src/components/branding/olun-logo.tsx
|
|
11688
12301
|
import { OLUN_MASTER, OLUN_SYMBOL, OLUN_WORDMARK } from "@olundot/tokens/brand";
|
|
11689
|
-
import { Fragment as
|
|
12302
|
+
import { Fragment as Fragment22, jsx as jsx66, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
11690
12303
|
var ACCENT_FILL = "var(--accent-pop)";
|
|
11691
12304
|
var INK = { color: "var(--text-primary)" };
|
|
11692
12305
|
var INK_TIGHT = { ...INK, display: "block", overflow: "visible" };
|
|
@@ -11696,7 +12309,7 @@ function symbolGeometry(size) {
|
|
|
11696
12309
|
function SymbolCircles({ size }) {
|
|
11697
12310
|
const { ring } = OLUN_SYMBOL;
|
|
11698
12311
|
const g = symbolGeometry(size);
|
|
11699
|
-
return /* @__PURE__ */ jsxs53(
|
|
12312
|
+
return /* @__PURE__ */ jsxs53(Fragment22, { children: [
|
|
11700
12313
|
/* @__PURE__ */ jsx66(
|
|
11701
12314
|
"circle",
|
|
11702
12315
|
{
|