@olundot/ui 0.20.0-next.9 → 0.20.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/CHANGELOG.md +377 -0
- package/dist/index.d.ts +97 -58
- package/dist/index.js +640 -198
- 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
|
] })
|
|
@@ -4248,7 +4293,8 @@ var overlaySize = {
|
|
|
4248
4293
|
dialog: {
|
|
4249
4294
|
sm: "max-w-[420px]",
|
|
4250
4295
|
md: "max-w-[560px]",
|
|
4251
|
-
lg: "max-w-[720px]"
|
|
4296
|
+
lg: "max-w-[720px]",
|
|
4297
|
+
xl: "max-w-[960px]"
|
|
4252
4298
|
},
|
|
4253
4299
|
sheet: {
|
|
4254
4300
|
md: "lg:w-[480px] lg:max-w-[480px]",
|
|
@@ -4779,7 +4825,7 @@ function SheetDescription({
|
|
|
4779
4825
|
}
|
|
4780
4826
|
|
|
4781
4827
|
// src/components/ui/dialog.tsx
|
|
4782
|
-
import { Fragment as
|
|
4828
|
+
import { Fragment as Fragment10, jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
4783
4829
|
function dialogMobileSheetStyle(style) {
|
|
4784
4830
|
return getDefaultSheetMotionStyle(style);
|
|
4785
4831
|
}
|
|
@@ -4873,7 +4919,7 @@ function StructuredDialog({
|
|
|
4873
4919
|
footerRow
|
|
4874
4920
|
]
|
|
4875
4921
|
}
|
|
4876
|
-
) : /* @__PURE__ */ jsxs23(
|
|
4922
|
+
) : /* @__PURE__ */ jsxs23(Fragment10, { children: [
|
|
4877
4923
|
body,
|
|
4878
4924
|
footerRow
|
|
4879
4925
|
] })
|
|
@@ -5077,7 +5123,7 @@ function FormModal({
|
|
|
5077
5123
|
|
|
5078
5124
|
// src/components/ui/alert-dialog.tsx
|
|
5079
5125
|
import { AlertDialog as AlertDialogPrimitive2 } from "radix-ui";
|
|
5080
|
-
import { Fragment as
|
|
5126
|
+
import { Fragment as Fragment11, jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
5081
5127
|
function AlertDialogFrame({
|
|
5082
5128
|
open,
|
|
5083
5129
|
onOpenChange,
|
|
@@ -5141,7 +5187,7 @@ function AlertDialog({
|
|
|
5141
5187
|
disabled: confirmDisabled,
|
|
5142
5188
|
onError
|
|
5143
5189
|
});
|
|
5144
|
-
const footer = confirmLabel != null ? /* @__PURE__ */ jsxs25(
|
|
5190
|
+
const footer = confirmLabel != null ? /* @__PURE__ */ jsxs25(Fragment11, { children: [
|
|
5145
5191
|
/* @__PURE__ */ jsx28(AlertDialogPrimitive2.Cancel, { asChild: true, children: /* @__PURE__ */ jsx28(Button, { appearance: "outline", tone: "neutral", size: "lg", className: footerButtonHitAreaClassName, disabled: isBusy, children: cancelLabel }) }),
|
|
5146
5192
|
/* @__PURE__ */ jsx28(
|
|
5147
5193
|
Button,
|
|
@@ -5219,7 +5265,7 @@ import * as React29 from "react";
|
|
|
5219
5265
|
import { cva as cva11 } from "class-variance-authority";
|
|
5220
5266
|
import { X as X3 } from "lucide-react";
|
|
5221
5267
|
import { Slot as Slot2 } from "radix-ui";
|
|
5222
|
-
import { Fragment as
|
|
5268
|
+
import { Fragment as Fragment12, jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
5223
5269
|
var chipVariants = cva11(
|
|
5224
5270
|
[
|
|
5225
5271
|
"inline-flex w-fit shrink-0 items-center justify-center whitespace-nowrap",
|
|
@@ -5318,7 +5364,7 @@ function ChipCount({
|
|
|
5318
5364
|
tone,
|
|
5319
5365
|
size
|
|
5320
5366
|
}) {
|
|
5321
|
-
return /* @__PURE__ */ jsxs26(
|
|
5367
|
+
return /* @__PURE__ */ jsxs26(Fragment12, { children: [
|
|
5322
5368
|
/* @__PURE__ */ jsx30(
|
|
5323
5369
|
"span",
|
|
5324
5370
|
{
|
|
@@ -5501,7 +5547,7 @@ var PopoverArrow = React30.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
5501
5547
|
PopoverArrow.displayName = PopoverPrimitive.Arrow.displayName;
|
|
5502
5548
|
|
|
5503
5549
|
// src/components/ui/filter-toolbar.tsx
|
|
5504
|
-
import { Fragment as
|
|
5550
|
+
import { Fragment as Fragment14, jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
5505
5551
|
var collapsibleClassNames = {
|
|
5506
5552
|
sm: {
|
|
5507
5553
|
inline: "hidden @[640px]:flex",
|
|
@@ -5520,6 +5566,41 @@ var collapsibleClassNames = {
|
|
|
5520
5566
|
trigger: "hidden"
|
|
5521
5567
|
}
|
|
5522
5568
|
};
|
|
5569
|
+
var gridCollapsibleClassNames = {
|
|
5570
|
+
sm: { inline: "hidden", trigger: "" },
|
|
5571
|
+
md: { inline: "hidden", trigger: "" },
|
|
5572
|
+
lg: { inline: "hidden", trigger: "" },
|
|
5573
|
+
never: { inline: "flex @[640px]:hidden", trigger: "hidden @[640px]:inline" }
|
|
5574
|
+
};
|
|
5575
|
+
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%]";
|
|
5576
|
+
var gridFiltersClassName = "order-3 flex min-w-0 flex-[1_0_100%] flex-wrap items-center gap-[var(--space-2)] @[640px]:contents";
|
|
5577
|
+
var gridCellClassName = cn(
|
|
5578
|
+
"contents @[640px]:block @[640px]:order-3 @[640px]:min-w-0 @[640px]:flex-[3_1_0%]",
|
|
5579
|
+
"@[640px]:[&:has([data-slot=select-trigger])]:flex-[2_1_0%]",
|
|
5580
|
+
"@[640px]:[&:has(>[data-slot=chip])]:flex-none",
|
|
5581
|
+
// A Chip group is named: a role="group" child that holds the Chips. A control that shows its
|
|
5582
|
+
// values as Chips keeps the default share.
|
|
5583
|
+
"@[640px]:[&:has(>[role=group]>[data-slot=chip])]:flex-none",
|
|
5584
|
+
// The control fills its cell, through a width the consumer put on a wrapper.
|
|
5585
|
+
"@[640px]:[&>:not([data-slot=chip])]:w-full @[640px]:[&_[data-slot=select-trigger]]:w-full"
|
|
5586
|
+
);
|
|
5587
|
+
var MAX_GRID_FILTERS = 3;
|
|
5588
|
+
var focusableSelector = "input, button, [tabindex]:not([tabindex='-1'])";
|
|
5589
|
+
function canTakeFocus(element) {
|
|
5590
|
+
return Boolean(element && element.getClientRects().length > 0 && !element.matches(":disabled"));
|
|
5591
|
+
}
|
|
5592
|
+
function filterCells(node, prefix = "") {
|
|
5593
|
+
return React31.Children.toArray(node).flatMap((child, index) => {
|
|
5594
|
+
const key = `${prefix}${React31.isValidElement(child) ? child.key : index}`;
|
|
5595
|
+
return React31.isValidElement(child) && child.type === React31.Fragment ? filterCells(child.props.children, `${key}/`) : [{ key, cell: child }];
|
|
5596
|
+
});
|
|
5597
|
+
}
|
|
5598
|
+
function warnGridFilters(count) {
|
|
5599
|
+
if (typeof process === "undefined" || process.env.NODE_ENV === "production") return;
|
|
5600
|
+
console.warn(
|
|
5601
|
+
`FilterToolbar: layout="grid" fits ${MAX_GRID_FILTERS} filters on the line, got ${count}. Move the rest to \`collapsible\`.`
|
|
5602
|
+
);
|
|
5603
|
+
}
|
|
5523
5604
|
var FilterToolbar = React31.forwardRef(
|
|
5524
5605
|
({
|
|
5525
5606
|
className,
|
|
@@ -5527,12 +5608,14 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5527
5608
|
filters,
|
|
5528
5609
|
collapsible,
|
|
5529
5610
|
collapseBelow = "lg",
|
|
5530
|
-
activeFilterCount
|
|
5611
|
+
activeFilterCount: activeFilterCountProp,
|
|
5531
5612
|
onClearFilters,
|
|
5532
5613
|
collapsedLabel = "\uD544\uD130",
|
|
5533
5614
|
resultSummary,
|
|
5534
5615
|
clearAction,
|
|
5535
5616
|
actions,
|
|
5617
|
+
layout = "flow",
|
|
5618
|
+
appliedFilters,
|
|
5536
5619
|
...props
|
|
5537
5620
|
}, ref) => {
|
|
5538
5621
|
const [rootElement, setRootElement] = React31.useState(
|
|
@@ -5543,6 +5626,10 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5543
5626
|
);
|
|
5544
5627
|
const [overlayOpen, setOverlayOpen] = React31.useState(false);
|
|
5545
5628
|
const triggerRef = React31.useRef(null);
|
|
5629
|
+
const rowRef = React31.useRef(null);
|
|
5630
|
+
const chipsRef = React31.useRef(null);
|
|
5631
|
+
const chipRemoveRefs = React31.useRef(/* @__PURE__ */ new Map());
|
|
5632
|
+
const pendingFocusRef = React31.useRef(null);
|
|
5546
5633
|
const setRootRefs = React31.useCallback(
|
|
5547
5634
|
(element) => {
|
|
5548
5635
|
setRootElement(element);
|
|
@@ -5566,13 +5653,49 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5566
5653
|
setOverlayOpen(open);
|
|
5567
5654
|
if (!open) queueMicrotask(() => triggerRef.current?.focus());
|
|
5568
5655
|
}, []);
|
|
5656
|
+
const isGrid = layout === "grid";
|
|
5657
|
+
const gridCells = isGrid ? filterCells(filters) : [];
|
|
5658
|
+
const filterCellCount = gridCells.length;
|
|
5659
|
+
React31.useEffect(() => {
|
|
5660
|
+
if (filterCellCount > MAX_GRID_FILTERS) warnGridFilters(filterCellCount);
|
|
5661
|
+
}, [filterCellCount]);
|
|
5662
|
+
React31.useEffect(() => {
|
|
5663
|
+
const ownerDocument = rootElement?.ownerDocument;
|
|
5664
|
+
if (!ownerDocument) return;
|
|
5665
|
+
const dropOutside = (event) => {
|
|
5666
|
+
if (!chipsRef.current?.contains(event.target)) pendingFocusRef.current = null;
|
|
5667
|
+
};
|
|
5668
|
+
ownerDocument.addEventListener("focusin", dropOutside);
|
|
5669
|
+
ownerDocument.addEventListener("pointerdown", dropOutside, true);
|
|
5670
|
+
return () => {
|
|
5671
|
+
ownerDocument.removeEventListener("focusin", dropOutside);
|
|
5672
|
+
ownerDocument.removeEventListener("pointerdown", dropOutside, true);
|
|
5673
|
+
};
|
|
5674
|
+
}, [rootElement]);
|
|
5675
|
+
React31.useEffect(() => {
|
|
5676
|
+
const request = pendingFocusRef.current;
|
|
5677
|
+
if (!request) return;
|
|
5678
|
+
const present = new Set(appliedFilters?.map((filter) => filter.key));
|
|
5679
|
+
if (request.removed.some((key) => present.has(key))) return;
|
|
5680
|
+
pendingFocusRef.current = null;
|
|
5681
|
+
const active = rootElement?.ownerDocument.activeElement;
|
|
5682
|
+
if (active && active !== rootElement.ownerDocument.body) return;
|
|
5683
|
+
const candidates = [
|
|
5684
|
+
...request.next.map((key) => chipRemoveRefs.current.get(key)),
|
|
5685
|
+
triggerRef.current,
|
|
5686
|
+
...rowRef.current?.querySelectorAll(focusableSelector) ?? []
|
|
5687
|
+
];
|
|
5688
|
+
candidates.find(canTakeFocus)?.focus();
|
|
5689
|
+
}, [appliedFilters, rootElement]);
|
|
5569
5690
|
const hasControls = Boolean(search || filters || collapsible);
|
|
5570
5691
|
const hasMeta = Boolean(
|
|
5571
5692
|
resultSummary || clearAction || actions && !hasControls
|
|
5572
5693
|
);
|
|
5694
|
+
const activeFilterCount = activeFilterCountProp ?? appliedFilters?.length ?? 0;
|
|
5573
5695
|
const hasAppliedFilters = activeFilterCount > 0;
|
|
5696
|
+
const hasAppliedChips = Boolean(appliedFilters && appliedFilters.length > 0);
|
|
5574
5697
|
const usesSheet = containerWidth !== null && containerWidth < 640;
|
|
5575
|
-
const collapseClasses = collapsibleClassNames[collapseBelow];
|
|
5698
|
+
const collapseClasses = (isGrid ? gridCollapsibleClassNames : collapsibleClassNames)[collapseBelow];
|
|
5576
5699
|
const collapseTriggerLabel = hasAppliedFilters ? `${collapsedLabel}, ${activeFilterCount}\uAC1C \uC801\uC6A9` : collapsedLabel;
|
|
5577
5700
|
const clearFiltersButton = onClearFilters ? /* @__PURE__ */ jsx32(
|
|
5578
5701
|
"button",
|
|
@@ -5643,14 +5766,18 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5643
5766
|
hasControls ? /* @__PURE__ */ jsxs28(
|
|
5644
5767
|
"div",
|
|
5645
5768
|
{
|
|
5769
|
+
ref: rowRef,
|
|
5646
5770
|
"data-slot": "filter-toolbar-row",
|
|
5647
|
-
className:
|
|
5771
|
+
className: cn(
|
|
5772
|
+
"flex min-h-[32px] w-full flex-wrap items-center justify-start gap-x-[var(--space-2)] gap-y-[var(--space-2)]",
|
|
5773
|
+
isGrid && "@[640px]:flex-nowrap"
|
|
5774
|
+
),
|
|
5648
5775
|
children: [
|
|
5649
5776
|
search ? /* @__PURE__ */ jsx32(
|
|
5650
5777
|
"div",
|
|
5651
5778
|
{
|
|
5652
5779
|
"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]",
|
|
5780
|
+
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
5781
|
children: search
|
|
5655
5782
|
}
|
|
5656
5783
|
) : null,
|
|
@@ -5677,8 +5804,16 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5677
5804
|
"div",
|
|
5678
5805
|
{
|
|
5679
5806
|
"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:
|
|
5807
|
+
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]",
|
|
5808
|
+
children: isGrid ? gridCells.map(({ key, cell }) => /* @__PURE__ */ jsx32(
|
|
5809
|
+
"div",
|
|
5810
|
+
{
|
|
5811
|
+
"data-slot": "filter-toolbar-cell",
|
|
5812
|
+
className: gridCellClassName,
|
|
5813
|
+
children: cell
|
|
5814
|
+
},
|
|
5815
|
+
key
|
|
5816
|
+
)) : filters
|
|
5682
5817
|
}
|
|
5683
5818
|
) : null,
|
|
5684
5819
|
collapsible && !overlayOpen ? /* @__PURE__ */ jsx32(
|
|
@@ -5713,18 +5848,72 @@ var FilterToolbar = React31.forwardRef(
|
|
|
5713
5848
|
children: collapsedContent
|
|
5714
5849
|
}
|
|
5715
5850
|
) : null,
|
|
5851
|
+
hasAppliedChips ? /* @__PURE__ */ jsxs28(
|
|
5852
|
+
"div",
|
|
5853
|
+
{
|
|
5854
|
+
ref: chipsRef,
|
|
5855
|
+
role: "group",
|
|
5856
|
+
"aria-label": collapsedLabel,
|
|
5857
|
+
"data-slot": "filter-toolbar-applied-chips",
|
|
5858
|
+
className: "hidden flex-wrap items-center gap-[var(--space-2)] @[640px]:flex",
|
|
5859
|
+
children: [
|
|
5860
|
+
appliedFilters.map((filter, index) => /* @__PURE__ */ jsx32(
|
|
5861
|
+
Chip,
|
|
5862
|
+
{
|
|
5863
|
+
ref: (button) => {
|
|
5864
|
+
if (button) chipRemoveRefs.current.set(filter.key, button);
|
|
5865
|
+
else chipRemoveRefs.current.delete(filter.key);
|
|
5866
|
+
},
|
|
5867
|
+
variant: "removable",
|
|
5868
|
+
size: "md",
|
|
5869
|
+
removeLabel: `${filter.label} \uC81C\uAC70`,
|
|
5870
|
+
onClick: () => {
|
|
5871
|
+
pendingFocusRef.current = {
|
|
5872
|
+
removed: [filter.key],
|
|
5873
|
+
next: [appliedFilters[index + 1]?.key, appliedFilters[index - 1]?.key].filter(
|
|
5874
|
+
(key) => key !== void 0
|
|
5875
|
+
)
|
|
5876
|
+
};
|
|
5877
|
+
filter.onRemove();
|
|
5878
|
+
},
|
|
5879
|
+
children: filter.label
|
|
5880
|
+
},
|
|
5881
|
+
filter.key
|
|
5882
|
+
)),
|
|
5883
|
+
onClearFilters ? /* @__PURE__ */ jsx32(
|
|
5884
|
+
"button",
|
|
5885
|
+
{
|
|
5886
|
+
type: "button",
|
|
5887
|
+
"data-slot": "filter-toolbar-clear-filters",
|
|
5888
|
+
className: "cursor-pointer border-0 bg-transparent p-0 text-body-sm font-medium text-text-secondary no-underline",
|
|
5889
|
+
onClick: () => {
|
|
5890
|
+
pendingFocusRef.current = {
|
|
5891
|
+
removed: appliedFilters.map((filter) => filter.key),
|
|
5892
|
+
next: []
|
|
5893
|
+
};
|
|
5894
|
+
onClearFilters();
|
|
5895
|
+
},
|
|
5896
|
+
children: "\uD574\uC81C"
|
|
5897
|
+
}
|
|
5898
|
+
) : null
|
|
5899
|
+
]
|
|
5900
|
+
}
|
|
5901
|
+
) : null,
|
|
5716
5902
|
hasAppliedFilters ? /* @__PURE__ */ jsxs28(
|
|
5717
5903
|
"div",
|
|
5718
5904
|
{
|
|
5719
5905
|
"data-slot": "filter-toolbar-applied",
|
|
5720
|
-
className:
|
|
5906
|
+
className: cn(
|
|
5907
|
+
"flex items-center gap-[var(--space-1)] text-[11px] text-text-tertiary",
|
|
5908
|
+
hasAppliedChips && "@[640px]:hidden"
|
|
5909
|
+
),
|
|
5721
5910
|
children: [
|
|
5722
5911
|
/* @__PURE__ */ jsxs28("span", { children: [
|
|
5723
5912
|
"\uD544\uD130 ",
|
|
5724
5913
|
activeFilterCount,
|
|
5725
5914
|
"\uAC1C \uC801\uC6A9"
|
|
5726
5915
|
] }),
|
|
5727
|
-
onClearFilters ? /* @__PURE__ */ jsxs28(
|
|
5916
|
+
onClearFilters ? /* @__PURE__ */ jsxs28(Fragment14, { children: [
|
|
5728
5917
|
/* @__PURE__ */ jsx32("span", { "aria-hidden": "true", children: " \xB7 " }),
|
|
5729
5918
|
/* @__PURE__ */ jsx32(
|
|
5730
5919
|
"button",
|
|
@@ -6032,16 +6221,19 @@ function DropdownMenuSubContent({
|
|
|
6032
6221
|
}
|
|
6033
6222
|
|
|
6034
6223
|
// src/components/ui/action-menu.tsx
|
|
6035
|
-
import { Fragment as
|
|
6224
|
+
import { Fragment as Fragment16, jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
6036
6225
|
var sheetRowClassName = cn(
|
|
6037
6226
|
"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
6227
|
"border-t border-[var(--border-subtle)] text-[13px] font-medium leading-normal text-text-primary",
|
|
6039
6228
|
"transition-colors motion-reduce:transition-none hover:bg-[var(--action-hover)]",
|
|
6040
6229
|
"focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[var(--focus-ring)]",
|
|
6041
6230
|
"enabled:data-[destructive]:text-[var(--semantic-error-fg)]",
|
|
6042
|
-
"disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled"
|
|
6231
|
+
"disabled:cursor-not-allowed disabled:bg-[var(--action-disabled-bg)] disabled:text-text-disabled",
|
|
6232
|
+
"aria-disabled:cursor-not-allowed"
|
|
6043
6233
|
);
|
|
6044
6234
|
var sheetRowDescriptionClassName = "block text-[12px] font-normal text-text-secondary group-disabled:text-text-disabled";
|
|
6235
|
+
var unavailableClassName = "text-text-disabled";
|
|
6236
|
+
var reasonClassName = "block text-[12px] font-normal leading-normal text-text-tertiary";
|
|
6045
6237
|
var sheetGroupLabelClassName = "px-[var(--space-4)] pt-[var(--space-3)] pb-[var(--space-2)] text-[12px] font-semibold leading-normal text-text-tertiary";
|
|
6046
6238
|
var sheetGroupSeparatorClassName = "h-[var(--space-2)] bg-[var(--bg-inset)]";
|
|
6047
6239
|
function ActionMenuSheet({
|
|
@@ -6111,23 +6303,34 @@ function ActionMenuSheet({
|
|
|
6111
6303
|
index > 0 ? /* @__PURE__ */ jsx34("div", { role: "separator", className: sheetGroupSeparatorClassName }) : null,
|
|
6112
6304
|
/* @__PURE__ */ jsxs30("div", { role: "group", "aria-labelledby": group.label ? `${labelId}-${index}` : void 0, children: [
|
|
6113
6305
|
group.label ? /* @__PURE__ */ jsx34("div", { id: `${labelId}-${index}`, className: sheetGroupLabelClassName, children: group.label }) : null,
|
|
6114
|
-
group.items.map((item) => {
|
|
6306
|
+
group.items.map((item, itemIndex) => {
|
|
6115
6307
|
const Icon = item.icon;
|
|
6308
|
+
const reason = item.disabledReason || void 0;
|
|
6309
|
+
const reasonId = `${labelId}-${index}-${itemIndex}-reason`;
|
|
6310
|
+
const itemLabelId = `${labelId}-${index}-${itemIndex}-label`;
|
|
6116
6311
|
return /* @__PURE__ */ jsxs30(
|
|
6117
6312
|
"button",
|
|
6118
6313
|
{
|
|
6119
6314
|
type: "button",
|
|
6120
6315
|
"data-slot": "action-menu-item",
|
|
6121
|
-
"data-destructive": item.destructive ? "" : void 0,
|
|
6316
|
+
"data-destructive": item.destructive && !reason ? "" : void 0,
|
|
6122
6317
|
className: sheetRowClassName,
|
|
6123
|
-
disabled: item.disabled,
|
|
6124
|
-
|
|
6318
|
+
disabled: item.disabled && !reason,
|
|
6319
|
+
"aria-disabled": reason ? true : void 0,
|
|
6320
|
+
"aria-labelledby": reason ? itemLabelId : void 0,
|
|
6321
|
+
"aria-describedby": reason ? reasonId : void 0,
|
|
6322
|
+
onClick: () => {
|
|
6323
|
+
if (!reason) handleSelect(item);
|
|
6324
|
+
},
|
|
6125
6325
|
children: [
|
|
6126
|
-
Icon ? /* @__PURE__ */ jsx34(Icon, { "aria-hidden": true, size: 17, strokeWidth: 1.75, className: "shrink-0" }) : null,
|
|
6127
|
-
/* @__PURE__ */
|
|
6326
|
+
Icon ? /* @__PURE__ */ jsx34(Icon, { "aria-hidden": true, size: 17, strokeWidth: 1.75, className: cn("shrink-0", reason && unavailableClassName) }) : null,
|
|
6327
|
+
/* @__PURE__ */ jsx34("span", { className: "min-w-0 flex-1 break-keep", children: reason ? /* @__PURE__ */ jsxs30(Fragment16, { children: [
|
|
6328
|
+
/* @__PURE__ */ jsx34("span", { id: itemLabelId, className: unavailableClassName, children: item.label }),
|
|
6329
|
+
/* @__PURE__ */ jsx34("span", { id: reasonId, className: reasonClassName, children: reason })
|
|
6330
|
+
] }) : /* @__PURE__ */ jsxs30(Fragment16, { children: [
|
|
6128
6331
|
item.label,
|
|
6129
6332
|
item.description ? /* @__PURE__ */ jsx34("span", { className: sheetRowDescriptionClassName, children: item.description }) : null
|
|
6130
|
-
] })
|
|
6333
|
+
] }) })
|
|
6131
6334
|
]
|
|
6132
6335
|
},
|
|
6133
6336
|
item.id
|
|
@@ -6140,6 +6343,48 @@ function ActionMenuSheet({
|
|
|
6140
6343
|
)
|
|
6141
6344
|
] }) }) });
|
|
6142
6345
|
}
|
|
6346
|
+
function ActionMenuDropdownItem({
|
|
6347
|
+
item,
|
|
6348
|
+
onPick
|
|
6349
|
+
}) {
|
|
6350
|
+
const id = React32.useId();
|
|
6351
|
+
const labelId = `${id}-label`;
|
|
6352
|
+
const reasonId = `${id}-reason`;
|
|
6353
|
+
const Icon = item.icon;
|
|
6354
|
+
const reason = item.disabledReason || void 0;
|
|
6355
|
+
if (!reason) {
|
|
6356
|
+
return /* @__PURE__ */ jsxs30(
|
|
6357
|
+
DropdownMenuItem,
|
|
6358
|
+
{
|
|
6359
|
+
variant: item.destructive ? "destructive" : "default",
|
|
6360
|
+
disabled: item.disabled,
|
|
6361
|
+
onSelect: () => onPick(item),
|
|
6362
|
+
children: [
|
|
6363
|
+
Icon ? /* @__PURE__ */ jsx34(Icon, { "aria-hidden": true, size: 16, strokeWidth: 1.75 }) : null,
|
|
6364
|
+
item.label
|
|
6365
|
+
]
|
|
6366
|
+
}
|
|
6367
|
+
);
|
|
6368
|
+
}
|
|
6369
|
+
return /* @__PURE__ */ jsxs30(
|
|
6370
|
+
DropdownMenuItem,
|
|
6371
|
+
{
|
|
6372
|
+
"aria-disabled": true,
|
|
6373
|
+
"aria-labelledby": labelId,
|
|
6374
|
+
"aria-describedby": reasonId,
|
|
6375
|
+
textValue: item.label,
|
|
6376
|
+
className: "aria-disabled:cursor-not-allowed",
|
|
6377
|
+
onSelect: (event) => event.preventDefault(),
|
|
6378
|
+
children: [
|
|
6379
|
+
Icon ? /* @__PURE__ */ jsx34(Icon, { "aria-hidden": true, size: 16, strokeWidth: 1.75, className: unavailableClassName }) : null,
|
|
6380
|
+
/* @__PURE__ */ jsxs30("span", { className: "min-w-0 flex-1 break-keep", children: [
|
|
6381
|
+
/* @__PURE__ */ jsx34("span", { id: labelId, className: unavailableClassName, children: item.label }),
|
|
6382
|
+
/* @__PURE__ */ jsx34("span", { id: reasonId, className: cn(reasonClassName, "max-w-64"), children: reason })
|
|
6383
|
+
] })
|
|
6384
|
+
]
|
|
6385
|
+
}
|
|
6386
|
+
);
|
|
6387
|
+
}
|
|
6143
6388
|
var readPresentation = () => window.matchMedia?.(OVERLAY_DESKTOP_QUERY).matches ?? true ? "dropdown" : "sheet";
|
|
6144
6389
|
var subscribeNothing = () => () => void 0;
|
|
6145
6390
|
var useHydrated = () => React32.useSyncExternalStore(
|
|
@@ -6190,31 +6435,23 @@ function ActionMenu({
|
|
|
6190
6435
|
triggerRef.current?.focus();
|
|
6191
6436
|
};
|
|
6192
6437
|
const triggerLabel = trigger.props["aria-label"];
|
|
6193
|
-
return /* @__PURE__ */ jsxs30(
|
|
6438
|
+
return /* @__PURE__ */ jsxs30(Fragment16, { children: [
|
|
6194
6439
|
/* @__PURE__ */ jsxs30(DropdownMenu, { open: open && presentation === "dropdown", onOpenChange: setOpen, children: [
|
|
6195
6440
|
/* @__PURE__ */ jsx34(DropdownMenuTrigger, { asChild: true, "aria-expanded": open, children: /* @__PURE__ */ jsx34(Slot3.Root, { ref: triggerRef, children: trigger }) }),
|
|
6196
6441
|
/* @__PURE__ */ jsx34(DropdownMenuContent, { align: "end", onCloseAutoFocus: handleDropdownCloseAutoFocus, children: menuGroups.map((group, index) => /* @__PURE__ */ jsxs30(React32.Fragment, { children: [
|
|
6197
6442
|
index > 0 ? /* @__PURE__ */ jsx34(DropdownMenuSeparator, {}) : null,
|
|
6198
6443
|
/* @__PURE__ */ jsxs30(DropdownMenuGroup, { children: [
|
|
6199
6444
|
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
|
-
})
|
|
6445
|
+
group.items.map((item) => /* @__PURE__ */ jsx34(
|
|
6446
|
+
ActionMenuDropdownItem,
|
|
6447
|
+
{
|
|
6448
|
+
item,
|
|
6449
|
+
onPick: (picked) => {
|
|
6450
|
+
pendingRef.current = picked;
|
|
6451
|
+
}
|
|
6452
|
+
},
|
|
6453
|
+
item.id
|
|
6454
|
+
))
|
|
6218
6455
|
] })
|
|
6219
6456
|
] }, group.id)) })
|
|
6220
6457
|
] }),
|
|
@@ -6610,7 +6847,7 @@ function ContextMenu({
|
|
|
6610
6847
|
// src/components/ui/list-card.tsx
|
|
6611
6848
|
import * as React34 from "react";
|
|
6612
6849
|
import { ChevronRight as ChevronRight2, MoreVertical } from "lucide-react";
|
|
6613
|
-
import { Fragment as
|
|
6850
|
+
import { Fragment as Fragment17, jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
6614
6851
|
function lineTokens(value) {
|
|
6615
6852
|
return React34.Children.toArray(value).filter((token) => token !== "");
|
|
6616
6853
|
}
|
|
@@ -6697,7 +6934,7 @@ function ListCard({
|
|
|
6697
6934
|
children: overlay && href != null ? React34.createElement(linkComponent ?? "a", { ...linkProps, href, className: overlayClassName }, title) : title
|
|
6698
6935
|
}
|
|
6699
6936
|
);
|
|
6700
|
-
const content = /* @__PURE__ */ jsxs33(
|
|
6937
|
+
const content = /* @__PURE__ */ jsxs33(Fragment17, { children: [
|
|
6701
6938
|
leading != null ? /* @__PURE__ */ jsx37("span", { className: "flex min-h-[18px] items-center", children: leading }) : null,
|
|
6702
6939
|
/* @__PURE__ */ jsxs33("span", { className: "min-w-0", children: [
|
|
6703
6940
|
overlay && href == null ? (
|
|
@@ -6728,7 +6965,7 @@ function ListCard({
|
|
|
6728
6965
|
),
|
|
6729
6966
|
children: [
|
|
6730
6967
|
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(
|
|
6968
|
+
actions != null ? /* @__PURE__ */ jsx37("span", { "data-slot": `${slot}-actions`, className: "relative z-[1] flex", children: /* @__PURE__ */ jsx37(
|
|
6732
6969
|
ActionMenu,
|
|
6733
6970
|
{
|
|
6734
6971
|
title: typeof title === "string" ? title : void 0,
|
|
@@ -6762,7 +6999,7 @@ function ListCard({
|
|
|
6762
6999
|
}
|
|
6763
7000
|
|
|
6764
7001
|
// src/components/ui/data-table.tsx
|
|
6765
|
-
import { Fragment as
|
|
7002
|
+
import { Fragment as Fragment19, jsx as jsx38, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
6766
7003
|
var dataTableVariants = cva13(
|
|
6767
7004
|
[
|
|
6768
7005
|
"relative overflow-hidden rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
|
|
@@ -6885,25 +7122,24 @@ function RowActionsCell({
|
|
|
6885
7122
|
);
|
|
6886
7123
|
}
|
|
6887
7124
|
function RowContextMenu({
|
|
6888
|
-
|
|
7125
|
+
menuKey,
|
|
6889
7126
|
position,
|
|
6890
7127
|
groups,
|
|
7128
|
+
cards,
|
|
6891
7129
|
onClose
|
|
6892
7130
|
}) {
|
|
6893
|
-
const [open, setOpen] = React35.useState(
|
|
6894
|
-
const
|
|
6895
|
-
const
|
|
7131
|
+
const [open, setOpen] = React35.useState(true);
|
|
7132
|
+
const closeRef = React35.useRef(null);
|
|
7133
|
+
const pressedOutside = React35.useRef(false);
|
|
7134
|
+
const close = (reason) => {
|
|
7135
|
+
closeRef.current ??= reason;
|
|
7136
|
+
setOpen(false);
|
|
7137
|
+
};
|
|
6896
7138
|
const shownGroups = React35.useRef([]);
|
|
6897
7139
|
if (groups) shownGroups.current = groups;
|
|
6898
|
-
const gone =
|
|
7140
|
+
const gone = groups === null;
|
|
6899
7141
|
const contentRef = React35.useRef(null);
|
|
6900
7142
|
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
7143
|
useIsomorphicLayoutEffect(() => {
|
|
6908
7144
|
const content = contentRef.current;
|
|
6909
7145
|
if (!open || !focusInsideRef.current || !content?.isConnected) return;
|
|
@@ -6913,13 +7149,20 @@ function RowContextMenu({
|
|
|
6913
7149
|
next.focus();
|
|
6914
7150
|
});
|
|
6915
7151
|
React35.useEffect(() => {
|
|
6916
|
-
if (gone)
|
|
7152
|
+
if (gone) close({ by: "dismiss", outside: false });
|
|
6917
7153
|
}, [gone]);
|
|
7154
|
+
useIsomorphicLayoutEffect(() => {
|
|
7155
|
+
if (!cards || !open || closeRef.current) return;
|
|
7156
|
+
const active = document.activeElement;
|
|
7157
|
+
close({ by: "layout", focusInside: Boolean(active && contentRef.current?.contains(active)) });
|
|
7158
|
+
}, [cards, open]);
|
|
6918
7159
|
return /* @__PURE__ */ jsx38(
|
|
6919
7160
|
ContextMenu,
|
|
6920
7161
|
{
|
|
6921
7162
|
open: open && !gone,
|
|
6922
|
-
onOpenChange:
|
|
7163
|
+
onOpenChange: (next) => {
|
|
7164
|
+
if (!next) close({ by: "dismiss", outside: false });
|
|
7165
|
+
},
|
|
6923
7166
|
position,
|
|
6924
7167
|
contentProps: {
|
|
6925
7168
|
align: "start",
|
|
@@ -6933,37 +7176,31 @@ function RowContextMenu({
|
|
|
6933
7176
|
}
|
|
6934
7177
|
},
|
|
6935
7178
|
onInteractOutside: () => {
|
|
6936
|
-
|
|
7179
|
+
pressedOutside.current = true;
|
|
7180
|
+
close({ by: "dismiss", outside: true });
|
|
6937
7181
|
},
|
|
6938
7182
|
onCloseAutoFocus: (event) => {
|
|
6939
7183
|
event.preventDefault();
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
7184
|
+
let reason = closeRef.current ?? { by: "dismiss", outside: false };
|
|
7185
|
+
if (pressedOutside.current && reason.by === "dismiss") reason = { by: "dismiss", outside: true };
|
|
7186
|
+
if (pressedOutside.current && reason.by === "layout") reason = { by: "layout", focusInside: false };
|
|
7187
|
+
onClose(menuKey, reason);
|
|
6943
7188
|
}
|
|
6944
7189
|
},
|
|
6945
7190
|
children: shownGroups.current.map((group, index) => /* @__PURE__ */ jsxs34(React35.Fragment, { children: [
|
|
6946
7191
|
index > 0 ? /* @__PURE__ */ jsx38(DropdownMenuSeparator, {}) : null,
|
|
6947
7192
|
/* @__PURE__ */ jsxs34(DropdownMenuGroup, { children: [
|
|
6948
7193
|
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
|
-
})
|
|
7194
|
+
group.items.map((item) => /* @__PURE__ */ jsx38(
|
|
7195
|
+
ActionMenuDropdownItem,
|
|
7196
|
+
{
|
|
7197
|
+
item,
|
|
7198
|
+
onPick: (picked) => {
|
|
7199
|
+
closeRef.current ??= { by: "item", item: picked };
|
|
7200
|
+
}
|
|
7201
|
+
},
|
|
7202
|
+
item.id
|
|
7203
|
+
))
|
|
6967
7204
|
] })
|
|
6968
7205
|
] }, group.id))
|
|
6969
7206
|
}
|
|
@@ -7044,7 +7281,7 @@ function MobileSortMenu({
|
|
|
7044
7281
|
size: "sm",
|
|
7045
7282
|
className: "ml-auto min-w-0",
|
|
7046
7283
|
children: [
|
|
7047
|
-
active && sortBy ? /* @__PURE__ */ jsxs34(
|
|
7284
|
+
active && sortBy ? /* @__PURE__ */ jsxs34(Fragment19, { children: [
|
|
7048
7285
|
/* @__PURE__ */ jsx38("span", { className: "sr-only", children: "\uC815\uB82C " }),
|
|
7049
7286
|
/* @__PURE__ */ jsx38("span", { className: "truncate", children: active.header }),
|
|
7050
7287
|
/* @__PURE__ */ jsxs34("span", { className: "sr-only", children: [
|
|
@@ -7317,7 +7554,7 @@ function DataTableRowView({
|
|
|
7317
7554
|
if (!expand) {
|
|
7318
7555
|
return dataRow;
|
|
7319
7556
|
}
|
|
7320
|
-
return /* @__PURE__ */ jsxs34(
|
|
7557
|
+
return /* @__PURE__ */ jsxs34(Fragment19, { children: [
|
|
7321
7558
|
dataRow,
|
|
7322
7559
|
/* @__PURE__ */ jsx38(
|
|
7323
7560
|
"div",
|
|
@@ -7929,15 +8166,22 @@ function DataTableInner({
|
|
|
7929
8166
|
contextMenuKey.current += 1;
|
|
7930
8167
|
setContextMenu({ rowId, position: { x: event.clientX, y: event.clientY }, key: contextMenuKey.current });
|
|
7931
8168
|
};
|
|
7932
|
-
const closeRowContextMenu = (
|
|
8169
|
+
const closeRowContextMenu = (key, close) => {
|
|
8170
|
+
if (key !== contextMenuKey.current) {
|
|
8171
|
+
return;
|
|
8172
|
+
}
|
|
7933
8173
|
const rowId = contextMenu?.rowId;
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
const
|
|
7937
|
-
|
|
8174
|
+
const refocus = close.by === "item" || (close.by === "dismiss" ? !close.outside : close.focusInside);
|
|
8175
|
+
if (rowId !== void 0 && refocus) {
|
|
8176
|
+
const cards = readLayout(desktopRef.current) === "mobile";
|
|
8177
|
+
const list = cards ? mobileListRef.current : desktopListRef.current;
|
|
8178
|
+
const row = Array.from(
|
|
8179
|
+
list?.querySelectorAll(cards ? '[data-slot="data-table-mobile-card"]' : '[data-slot="data-table-row"]') ?? []
|
|
8180
|
+
).find((node) => node.getAttribute("data-row-id") === rowId);
|
|
8181
|
+
const trigger = row?.querySelector(
|
|
8182
|
+
cards ? '[data-slot="list-card-actions"] button' : '[data-slot="data-table-row-actions"] button'
|
|
7938
8183
|
);
|
|
7939
|
-
const
|
|
7940
|
-
const target = trigger ?? (row?.hasAttribute("tabindex") ? row : null) ?? list ?? desktopRef.current;
|
|
8184
|
+
const target = trigger ?? (row && (cards || row.hasAttribute("tabindex")) ? row : null) ?? list ?? (cards ? mobileRef : desktopRef).current;
|
|
7941
8185
|
if (target) {
|
|
7942
8186
|
if (!target.hasAttribute("tabindex") && !target.matches("a[href],button,input")) {
|
|
7943
8187
|
target.tabIndex = -1;
|
|
@@ -7946,7 +8190,7 @@ function DataTableInner({
|
|
|
7946
8190
|
}
|
|
7947
8191
|
}
|
|
7948
8192
|
setContextMenu(null);
|
|
7949
|
-
item
|
|
8193
|
+
if (close.by === "item") close.item.onSelect();
|
|
7950
8194
|
};
|
|
7951
8195
|
const handleRowContextMenu = rowActions ? openRowContextMenu : onRowContextMenu;
|
|
7952
8196
|
const latestHandlers = React35.useRef({ toggleRow, activateRow, onRowContextMenu, handleRowContextMenu });
|
|
@@ -8198,14 +8442,16 @@ function DataTableInner({
|
|
|
8198
8442
|
)
|
|
8199
8443
|
] }),
|
|
8200
8444
|
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(
|
|
8445
|
+
hasRowActions && contextMenu ? /* @__PURE__ */ jsx38(
|
|
8202
8446
|
RowContextMenu,
|
|
8203
8447
|
{
|
|
8204
|
-
|
|
8205
|
-
position: contextMenu
|
|
8448
|
+
menuKey: contextMenu.key,
|
|
8449
|
+
position: contextMenu.position,
|
|
8206
8450
|
groups: contextGroups,
|
|
8451
|
+
cards: activeLayout === "mobile",
|
|
8207
8452
|
onClose: closeRowContextMenu
|
|
8208
|
-
}
|
|
8453
|
+
},
|
|
8454
|
+
contextMenu.key
|
|
8209
8455
|
) : null
|
|
8210
8456
|
]
|
|
8211
8457
|
}
|
|
@@ -8263,6 +8509,35 @@ function ActionButton({ action }) {
|
|
|
8263
8509
|
}
|
|
8264
8510
|
);
|
|
8265
8511
|
}
|
|
8512
|
+
function CardActionButton({ action }) {
|
|
8513
|
+
const Icon = action.icon;
|
|
8514
|
+
return /* @__PURE__ */ jsxs35(
|
|
8515
|
+
Button,
|
|
8516
|
+
{
|
|
8517
|
+
appearance: "outline",
|
|
8518
|
+
tone: action.variant === "destructive" ? "danger" : "neutral",
|
|
8519
|
+
size: "sm",
|
|
8520
|
+
className: "before:-inset-y-[5px]",
|
|
8521
|
+
"data-slot": "bulk-action-bar-action",
|
|
8522
|
+
"data-variant": action.variant ?? "default",
|
|
8523
|
+
disabled: action.disabled,
|
|
8524
|
+
title: action.title,
|
|
8525
|
+
onClick: action.onClick,
|
|
8526
|
+
children: [
|
|
8527
|
+
Icon ? /* @__PURE__ */ jsx39(
|
|
8528
|
+
Icon,
|
|
8529
|
+
{
|
|
8530
|
+
"aria-hidden": "true",
|
|
8531
|
+
"data-slot": "bulk-action-bar-action-icon",
|
|
8532
|
+
size: 16,
|
|
8533
|
+
strokeWidth: 1.75
|
|
8534
|
+
}
|
|
8535
|
+
) : null,
|
|
8536
|
+
action.label
|
|
8537
|
+
]
|
|
8538
|
+
}
|
|
8539
|
+
);
|
|
8540
|
+
}
|
|
8266
8541
|
function Divider() {
|
|
8267
8542
|
return /* @__PURE__ */ jsx39(
|
|
8268
8543
|
"span",
|
|
@@ -8305,24 +8580,24 @@ function ClearButton({ onClear }) {
|
|
|
8305
8580
|
}
|
|
8306
8581
|
);
|
|
8307
8582
|
}
|
|
8583
|
+
var CLEAR_CLEARANCE = 32;
|
|
8308
8584
|
var INLINE_HEIGHT = 40;
|
|
8309
8585
|
var HIT_AREA = 44;
|
|
8310
8586
|
var HIT_INSET = 8;
|
|
8587
|
+
var FLOATING_BOTTOM = "calc(var(--space-4) + env(safe-area-inset-bottom))";
|
|
8311
8588
|
var floatingStyle = {
|
|
8312
8589
|
position: "sticky",
|
|
8313
|
-
bottom:
|
|
8590
|
+
bottom: FLOATING_BOTTOM,
|
|
8314
8591
|
zIndex: 1100,
|
|
8315
8592
|
margin: "0 auto",
|
|
8316
8593
|
display: "flex",
|
|
8317
|
-
|
|
8318
|
-
width: "
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
gap: "var(--space-2)",
|
|
8322
|
-
borderRadius: 9999,
|
|
8594
|
+
boxSizing: "border-box",
|
|
8595
|
+
width: "min(360px, calc(100% - var(--space-8)))",
|
|
8596
|
+
flexDirection: "column",
|
|
8597
|
+
borderRadius: "var(--radius-xl)",
|
|
8323
8598
|
border: "1px solid var(--border)",
|
|
8324
8599
|
background: "var(--bg-raised)",
|
|
8325
|
-
padding: "var(--space-
|
|
8600
|
+
padding: "var(--space-2) var(--space-4) var(--space-3)",
|
|
8326
8601
|
boxShadow: "var(--shadow-8)"
|
|
8327
8602
|
};
|
|
8328
8603
|
var inlineStyle = {
|
|
@@ -8364,7 +8639,117 @@ function warnInlineOnce() {
|
|
|
8364
8639
|
warnedInline = true;
|
|
8365
8640
|
console.warn('BulkActionBar: placement="inline" is deprecated and removed in the next minor. Use "floating".');
|
|
8366
8641
|
}
|
|
8642
|
+
var warnedTrailing = false;
|
|
8643
|
+
function warnTrailingOnce() {
|
|
8644
|
+
if (warnedTrailing || typeof process === "undefined" || process.env.NODE_ENV === "production") {
|
|
8645
|
+
return;
|
|
8646
|
+
}
|
|
8647
|
+
warnedTrailing = true;
|
|
8648
|
+
console.warn("BulkActionBar: the floating card ignores `trailing`. Put edit-mode controls at the right end of the toolbar.");
|
|
8649
|
+
}
|
|
8650
|
+
var OFFSET_PROPERTY = "--olun-bulk-bar-offset";
|
|
8651
|
+
var LIFT_ZONE = 204;
|
|
8652
|
+
var cardOffsets = /* @__PURE__ */ new Map();
|
|
8653
|
+
function writeOffset() {
|
|
8654
|
+
const root = document.documentElement;
|
|
8655
|
+
const offset = Math.max(0, ...cardOffsets.values());
|
|
8656
|
+
const value = offset > 0 ? `${offset}px` : "";
|
|
8657
|
+
if (root.style.getPropertyValue(OFFSET_PROPERTY) === value) return;
|
|
8658
|
+
if (value) root.style.setProperty(OFFSET_PROPERTY, value);
|
|
8659
|
+
else root.style.removeProperty(OFFSET_PROPERTY);
|
|
8660
|
+
}
|
|
8661
|
+
function reportOffset(key, card) {
|
|
8662
|
+
let offset = 0;
|
|
8663
|
+
if (card.offsetHeight > 0) {
|
|
8664
|
+
const { top, bottom } = card.getBoundingClientRect();
|
|
8665
|
+
if (window.innerHeight - bottom <= LIFT_ZONE) offset = Math.max(0, Math.round(window.innerHeight - top));
|
|
8666
|
+
}
|
|
8667
|
+
if (offset === (cardOffsets.get(key) ?? 0)) return;
|
|
8668
|
+
if (offset > 0) cardOffsets.set(key, offset);
|
|
8669
|
+
else cardOffsets.delete(key);
|
|
8670
|
+
writeOffset();
|
|
8671
|
+
}
|
|
8367
8672
|
var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React36.useEffect : React36.useLayoutEffect;
|
|
8673
|
+
function useBottomOffset(card) {
|
|
8674
|
+
const [key] = React36.useState(() => ({}));
|
|
8675
|
+
React36.useEffect(() => {
|
|
8676
|
+
if (!card) return;
|
|
8677
|
+
let frame = 0;
|
|
8678
|
+
let stopped = false;
|
|
8679
|
+
let listening = false;
|
|
8680
|
+
const schedule = () => {
|
|
8681
|
+
if (frame || stopped) return;
|
|
8682
|
+
frame = requestAnimationFrame(measure);
|
|
8683
|
+
};
|
|
8684
|
+
const listen = (on) => {
|
|
8685
|
+
if (on === listening) return;
|
|
8686
|
+
listening = on;
|
|
8687
|
+
if (on) {
|
|
8688
|
+
window.addEventListener("resize", schedule);
|
|
8689
|
+
window.addEventListener("scroll", schedule, { capture: true, passive: true });
|
|
8690
|
+
} else {
|
|
8691
|
+
window.removeEventListener("resize", schedule);
|
|
8692
|
+
window.removeEventListener("scroll", schedule, { capture: true });
|
|
8693
|
+
}
|
|
8694
|
+
};
|
|
8695
|
+
let watcher = null;
|
|
8696
|
+
let watched = "";
|
|
8697
|
+
const arm = (margin, threshold) => {
|
|
8698
|
+
let first = true;
|
|
8699
|
+
watcher = new IntersectionObserver(
|
|
8700
|
+
([entry]) => {
|
|
8701
|
+
if (stopped) return;
|
|
8702
|
+
if (first) {
|
|
8703
|
+
first = false;
|
|
8704
|
+
if (entry.intersectionRatio === threshold) return;
|
|
8705
|
+
watcher?.disconnect();
|
|
8706
|
+
arm(margin, entry.intersectionRatio);
|
|
8707
|
+
}
|
|
8708
|
+
schedule();
|
|
8709
|
+
},
|
|
8710
|
+
{ root: document, rootMargin: margin, threshold }
|
|
8711
|
+
);
|
|
8712
|
+
watcher.observe(card);
|
|
8713
|
+
};
|
|
8714
|
+
const watch = (on) => {
|
|
8715
|
+
let margin = "";
|
|
8716
|
+
if (on && typeof IntersectionObserver !== "undefined") {
|
|
8717
|
+
const { top, right, bottom, left } = card.getBoundingClientRect();
|
|
8718
|
+
const { clientWidth, clientHeight } = document.documentElement;
|
|
8719
|
+
margin = [top, clientWidth - right, clientHeight - bottom, left].map((inset) => `${-Math.floor(inset)}px`).join(" ");
|
|
8720
|
+
}
|
|
8721
|
+
if (margin === watched) return;
|
|
8722
|
+
watched = margin;
|
|
8723
|
+
watcher?.disconnect();
|
|
8724
|
+
watcher = null;
|
|
8725
|
+
if (margin) arm(margin, 1);
|
|
8726
|
+
};
|
|
8727
|
+
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(() => schedule());
|
|
8728
|
+
const measure = () => {
|
|
8729
|
+
frame = 0;
|
|
8730
|
+
reportOffset(key, card);
|
|
8731
|
+
const shown = card.offsetHeight > 0;
|
|
8732
|
+
listen(shown || !observer);
|
|
8733
|
+
watch(shown);
|
|
8734
|
+
};
|
|
8735
|
+
measure();
|
|
8736
|
+
observer?.observe(card);
|
|
8737
|
+
card.addEventListener("animationend", schedule);
|
|
8738
|
+
return () => {
|
|
8739
|
+
stopped = true;
|
|
8740
|
+
cancelAnimationFrame(frame);
|
|
8741
|
+
listen(false);
|
|
8742
|
+
watcher?.disconnect();
|
|
8743
|
+
observer?.disconnect();
|
|
8744
|
+
card.removeEventListener("animationend", schedule);
|
|
8745
|
+
cardOffsets.delete(key);
|
|
8746
|
+
writeOffset();
|
|
8747
|
+
};
|
|
8748
|
+
}, [key, card]);
|
|
8749
|
+
useIsomorphicLayoutEffect2(() => {
|
|
8750
|
+
if (card && typeof ResizeObserver === "undefined") reportOffset(key, card);
|
|
8751
|
+
});
|
|
8752
|
+
}
|
|
8368
8753
|
function useCompactSummary(slot, enabled) {
|
|
8369
8754
|
const [fullWidth, setFullWidth] = React36.useState(null);
|
|
8370
8755
|
const measure = React36.useCallback(() => {
|
|
@@ -8402,7 +8787,9 @@ function BulkActionBar({
|
|
|
8402
8787
|
}) {
|
|
8403
8788
|
const inline = placement === "inline";
|
|
8404
8789
|
if (inline) warnInlineOnce();
|
|
8405
|
-
const
|
|
8790
|
+
const hasTrailing = trailing !== void 0 && trailing !== null;
|
|
8791
|
+
if (!inline && hasTrailing) warnTrailingOnce();
|
|
8792
|
+
const trailingSlot = inline && hasTrailing ? /* @__PURE__ */ jsx39(
|
|
8406
8793
|
"div",
|
|
8407
8794
|
{
|
|
8408
8795
|
"data-slot": "bulk-action-bar-trailing",
|
|
@@ -8420,6 +8807,8 @@ function BulkActionBar({
|
|
|
8420
8807
|
summaryElement,
|
|
8421
8808
|
inline && compactSummary !== void 0 && compactSummary !== null
|
|
8422
8809
|
);
|
|
8810
|
+
const [card, setCard] = React36.useState(null);
|
|
8811
|
+
useBottomOffset(card);
|
|
8423
8812
|
if (count === 0 && idleContent !== void 0 && trailingSlot) {
|
|
8424
8813
|
return /* @__PURE__ */ jsxs35(
|
|
8425
8814
|
"div",
|
|
@@ -8474,16 +8863,31 @@ function BulkActionBar({
|
|
|
8474
8863
|
"span",
|
|
8475
8864
|
{
|
|
8476
8865
|
"data-slot": "bulk-action-bar-count",
|
|
8477
|
-
style: {
|
|
8478
|
-
paddingLeft: inline ? void 0 : "var(--space-2)",
|
|
8866
|
+
style: inline ? {
|
|
8479
8867
|
paddingRight: "var(--space-1)",
|
|
8480
8868
|
fontFamily: "var(--font-sans)",
|
|
8481
8869
|
fontSize: 13,
|
|
8482
|
-
fontWeight:
|
|
8870
|
+
fontWeight: 600,
|
|
8483
8871
|
fontVariantNumeric: "tabular-nums",
|
|
8484
8872
|
color: "var(--text-primary)",
|
|
8485
8873
|
whiteSpace: "nowrap"
|
|
8486
|
-
}
|
|
8874
|
+
} : (
|
|
8875
|
+
// First row, 32px like the ✕ beside it; the right padding keeps text clear of it,
|
|
8876
|
+
// and a long unbroken unit or hint breaks instead of running under it.
|
|
8877
|
+
{
|
|
8878
|
+
display: "flex",
|
|
8879
|
+
minHeight: 32,
|
|
8880
|
+
alignItems: "center",
|
|
8881
|
+
paddingRight: CLEAR_CLEARANCE,
|
|
8882
|
+
fontFamily: "var(--font-sans)",
|
|
8883
|
+
fontSize: 13,
|
|
8884
|
+
fontWeight: 500,
|
|
8885
|
+
fontVariantNumeric: "tabular-nums",
|
|
8886
|
+
color: "var(--text-primary)",
|
|
8887
|
+
wordBreak: "keep-all",
|
|
8888
|
+
overflowWrap: "anywhere"
|
|
8889
|
+
}
|
|
8890
|
+
),
|
|
8487
8891
|
children: count > 0 ? `${count.toLocaleString("ko-KR")}${unit} \uC120\uD0DD\uB428` : emptyHint
|
|
8488
8892
|
}
|
|
8489
8893
|
);
|
|
@@ -8493,7 +8897,7 @@ function BulkActionBar({
|
|
|
8493
8897
|
ref: setSummaryElement,
|
|
8494
8898
|
"data-slot": "bulk-action-bar-summary",
|
|
8495
8899
|
style: {
|
|
8496
|
-
display:
|
|
8900
|
+
display: "flex",
|
|
8497
8901
|
minWidth: 0,
|
|
8498
8902
|
alignItems: "center",
|
|
8499
8903
|
columnGap: "var(--space-3)",
|
|
@@ -8516,27 +8920,30 @@ function BulkActionBar({
|
|
|
8516
8920
|
whiteSpace: "nowrap",
|
|
8517
8921
|
contain: "inline-size"
|
|
8518
8922
|
}
|
|
8519
|
-
) :
|
|
8923
|
+
) : (
|
|
8924
|
+
// Its own row at the card's full inner width; wraps, never clips.
|
|
8925
|
+
{ flexWrap: "wrap", lineHeight: 1.5, wordBreak: "keep-all", overflowWrap: "anywhere" }
|
|
8926
|
+
)
|
|
8520
8927
|
},
|
|
8521
8928
|
children: compact ? compactSummary : summary
|
|
8522
8929
|
}
|
|
8523
8930
|
) : 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
8931
|
if (inline) {
|
|
8932
|
+
const actionGroup = /* @__PURE__ */ jsx39(
|
|
8933
|
+
"div",
|
|
8934
|
+
{
|
|
8935
|
+
"data-slot": "bulk-action-bar-actions",
|
|
8936
|
+
style: {
|
|
8937
|
+
display: "flex",
|
|
8938
|
+
minWidth: 0,
|
|
8939
|
+
flexWrap: "nowrap",
|
|
8940
|
+
alignItems: "center",
|
|
8941
|
+
justifyContent: "flex-end",
|
|
8942
|
+
gap: 2
|
|
8943
|
+
},
|
|
8944
|
+
children: actions.map((action) => /* @__PURE__ */ jsx39(ActionButton, { action }, action.key))
|
|
8945
|
+
}
|
|
8946
|
+
);
|
|
8540
8947
|
return /* @__PURE__ */ jsxs35(
|
|
8541
8948
|
"div",
|
|
8542
8949
|
{
|
|
@@ -8601,6 +9008,7 @@ function BulkActionBar({
|
|
|
8601
9008
|
"animate-[olun-bulk-action-bar-in_var(--dur-fast)_var(--ease-out)_both] motion-reduce:animate-none",
|
|
8602
9009
|
className
|
|
8603
9010
|
),
|
|
9011
|
+
ref: setCard,
|
|
8604
9012
|
style: { ...floatingStyle, ...style },
|
|
8605
9013
|
...props,
|
|
8606
9014
|
children: [
|
|
@@ -8612,8 +9020,8 @@ function BulkActionBar({
|
|
|
8612
9020
|
style: {
|
|
8613
9021
|
display: "flex",
|
|
8614
9022
|
minWidth: 0,
|
|
8615
|
-
|
|
8616
|
-
|
|
9023
|
+
flexDirection: "column",
|
|
9024
|
+
rowGap: "var(--space-2)"
|
|
8617
9025
|
},
|
|
8618
9026
|
children: [
|
|
8619
9027
|
countLabel,
|
|
@@ -8621,11 +9029,29 @@ function BulkActionBar({
|
|
|
8621
9029
|
]
|
|
8622
9030
|
}
|
|
8623
9031
|
),
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
9032
|
+
actions.length > 0 ? /* @__PURE__ */ jsx39(
|
|
9033
|
+
"div",
|
|
9034
|
+
{
|
|
9035
|
+
"data-slot": "bulk-action-bar-actions",
|
|
9036
|
+
style: {
|
|
9037
|
+
display: "flex",
|
|
9038
|
+
flexWrap: "wrap",
|
|
9039
|
+
justifyContent: "flex-end",
|
|
9040
|
+
gap: "var(--space-2)",
|
|
9041
|
+
marginTop: "var(--space-3)"
|
|
9042
|
+
},
|
|
9043
|
+
children: actions.map((action) => /* @__PURE__ */ jsx39(CardActionButton, { action }, action.key))
|
|
9044
|
+
}
|
|
9045
|
+
) : null,
|
|
9046
|
+
/* @__PURE__ */ jsx39(
|
|
9047
|
+
IconButton,
|
|
9048
|
+
{
|
|
9049
|
+
icon: X4,
|
|
9050
|
+
"aria-label": "\uC120\uD0DD \uD574\uC81C",
|
|
9051
|
+
onClick: onClear,
|
|
9052
|
+
style: { position: "absolute", top: "var(--space-2)", right: "var(--space-2)" }
|
|
9053
|
+
}
|
|
9054
|
+
)
|
|
8629
9055
|
]
|
|
8630
9056
|
}
|
|
8631
9057
|
);
|
|
@@ -9957,7 +10383,7 @@ function TablePagination({
|
|
|
9957
10383
|
|
|
9958
10384
|
// src/components/ui/mode-toggle.tsx
|
|
9959
10385
|
import { cva as cva19 } from "class-variance-authority";
|
|
9960
|
-
import { jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
10386
|
+
import { Fragment as Fragment20, jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
9961
10387
|
var modeToggleVariants = cva19(
|
|
9962
10388
|
[
|
|
9963
10389
|
"inline-flex items-center rounded-[var(--radius-md)] border border-[var(--border-subtle)]",
|
|
@@ -9980,6 +10406,17 @@ var modeToggleItemVariants = cva19(
|
|
|
9980
10406
|
"[&_svg]:pointer-events-none [&_svg]:size-[14px] [&_svg]:shrink-0 [&_svg]:stroke-[1.75]"
|
|
9981
10407
|
].join(" ")
|
|
9982
10408
|
);
|
|
10409
|
+
function formatModeToggleCount(value) {
|
|
10410
|
+
return value > 99 ? "99+" : String(value);
|
|
10411
|
+
}
|
|
10412
|
+
function isShownModeToggleCount(value) {
|
|
10413
|
+
if (value === void 0) return false;
|
|
10414
|
+
if (Number.isInteger(value) && value >= 0) return true;
|
|
10415
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
|
|
10416
|
+
console.warn(`ModeToggle: count must be an integer 0 or greater (got ${value}). The count is not shown.`);
|
|
10417
|
+
}
|
|
10418
|
+
return false;
|
|
10419
|
+
}
|
|
9983
10420
|
function ModeToggle({
|
|
9984
10421
|
className,
|
|
9985
10422
|
itemClassName,
|
|
@@ -10020,7 +10457,11 @@ function ModeToggle({
|
|
|
10020
10457
|
},
|
|
10021
10458
|
children: [
|
|
10022
10459
|
Icon ? /* @__PURE__ */ jsx56(Icon, { "aria-hidden": "true", "data-slot": "mode-toggle-icon" }) : null,
|
|
10023
|
-
/* @__PURE__ */ jsx56("span", { children: option.label })
|
|
10460
|
+
/* @__PURE__ */ jsx56("span", { children: option.label }),
|
|
10461
|
+
isShownModeToggleCount(option.count) ? /* @__PURE__ */ jsxs45(Fragment20, { children: [
|
|
10462
|
+
/* @__PURE__ */ jsx56("span", { "aria-hidden": "true", "data-slot": "mode-toggle-count", className: tabsBadgeVariants(), children: formatModeToggleCount(option.count) }),
|
|
10463
|
+
/* @__PURE__ */ jsx56("span", { className: "sr-only", children: ` ${option.count}` })
|
|
10464
|
+
] }) : null
|
|
10024
10465
|
]
|
|
10025
10466
|
},
|
|
10026
10467
|
option.value
|
|
@@ -10236,7 +10677,8 @@ var toastVariants = cva21(
|
|
|
10236
10677
|
);
|
|
10237
10678
|
var toastViewportVariants = cva21(
|
|
10238
10679
|
[
|
|
10239
|
-
|
|
10680
|
+
// A floating BulkActionBar publishes --olun-bulk-bar-offset while it is up; sit 8px above it.
|
|
10681
|
+
"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
10682
|
"flex w-[min(420px,calc(100vw-var(--space-12)))] list-none flex-col gap-[var(--space-2)]",
|
|
10241
10683
|
"pointer-events-none outline-none"
|
|
10242
10684
|
].join(" ")
|
|
@@ -10468,7 +10910,7 @@ function ToastProvider({ children, maxToasts = 3, className, ...props }) {
|
|
|
10468
10910
|
import * as React48 from "react";
|
|
10469
10911
|
import { cva as cva22 } from "class-variance-authority";
|
|
10470
10912
|
import { AlertCircle as AlertCircle4 } from "lucide-react";
|
|
10471
|
-
import { Fragment as
|
|
10913
|
+
import { Fragment as Fragment21, jsx as jsx59, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
10472
10914
|
var otpFieldVariants = cva22("flex w-full min-w-0 flex-col gap-[var(--space-3)]", {
|
|
10473
10915
|
variants: {
|
|
10474
10916
|
size: {
|
|
@@ -10798,7 +11240,7 @@ var OTPField = React48.forwardRef(
|
|
|
10798
11240
|
"data-slot": "otp-field-message",
|
|
10799
11241
|
"data-kind": errorText ? "error" : "helper",
|
|
10800
11242
|
className: otpFieldMessageVariants({ state: resolvedState }),
|
|
10801
|
-
children: errorText ? /* @__PURE__ */ jsxs48(
|
|
11243
|
+
children: errorText ? /* @__PURE__ */ jsxs48(Fragment21, { children: [
|
|
10802
11244
|
/* @__PURE__ */ jsx59(
|
|
10803
11245
|
AlertCircle4,
|
|
10804
11246
|
{
|
|
@@ -11686,7 +12128,7 @@ function TreeView({
|
|
|
11686
12128
|
|
|
11687
12129
|
// src/components/branding/olun-logo.tsx
|
|
11688
12130
|
import { OLUN_MASTER, OLUN_SYMBOL, OLUN_WORDMARK } from "@olundot/tokens/brand";
|
|
11689
|
-
import { Fragment as
|
|
12131
|
+
import { Fragment as Fragment22, jsx as jsx66, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
11690
12132
|
var ACCENT_FILL = "var(--accent-pop)";
|
|
11691
12133
|
var INK = { color: "var(--text-primary)" };
|
|
11692
12134
|
var INK_TIGHT = { ...INK, display: "block", overflow: "visible" };
|
|
@@ -11696,7 +12138,7 @@ function symbolGeometry(size) {
|
|
|
11696
12138
|
function SymbolCircles({ size }) {
|
|
11697
12139
|
const { ring } = OLUN_SYMBOL;
|
|
11698
12140
|
const g = symbolGeometry(size);
|
|
11699
|
-
return /* @__PURE__ */ jsxs53(
|
|
12141
|
+
return /* @__PURE__ */ jsxs53(Fragment22, { children: [
|
|
11700
12142
|
/* @__PURE__ */ jsx66(
|
|
11701
12143
|
"circle",
|
|
11702
12144
|
{
|