sellmate-design-system-react 8.1.0 → 9.0.0-beta.2
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/AGENTS.md +176 -111
- package/README.md +38 -8
- package/dist/components/SChipFilter/README.md +69 -0
- package/dist/components/SChipFilter/SChipFilter.d.ts +160 -0
- package/dist/components/SChipFilter/index.d.ts +1 -0
- package/dist/components/SCircleProgress/README.md +3 -0
- package/dist/components/SCircleProgress/SCircleProgress.d.ts +7 -1
- package/dist/components/SDatePicker/README.md +2 -0
- package/dist/components/SDateRangePicker/README.md +21 -0
- package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +16 -0
- package/dist/components/SDateRangePicker/index.d.ts +1 -1
- package/dist/components/SGhostButton/README.md +4 -0
- package/dist/components/SGuide/README.md +1 -1
- package/dist/components/SGuide/SGuide.d.ts +1 -1
- package/dist/components/SIcon/README.md +4 -0
- package/dist/components/SIcon/icons.gen.d.ts +1 -0
- package/dist/components/SImage/README.md +44 -0
- package/dist/components/SImage/SImage.d.ts +41 -0
- package/dist/components/SImage/index.d.ts +1 -0
- package/dist/components/SList/README.md +1 -0
- package/dist/components/SList/SList.d.ts +2 -0
- package/dist/components/SListItem/README.md +2 -2
- package/dist/components/SListItem/SListItem.d.ts +2 -2
- package/dist/components/SPage/README.md +21 -0
- package/dist/components/SPage/SPage.d.ts +10 -0
- package/dist/components/SPage/SPageHeader.d.ts +32 -0
- package/dist/components/SPage/index.d.ts +1 -0
- package/dist/components/SPortal/README.md +1 -1
- package/dist/components/SPortal/SPortal.d.ts +7 -1
- package/dist/components/SRadio/README.md +2 -0
- package/dist/components/SRadioButton/README.md +13 -0
- package/dist/components/SSelect/README.md +2 -2
- package/dist/components/SSelect/SSelect.d.ts +2 -2
- package/dist/components/STag/README.md +2 -0
- package/dist/components/STextLink/README.md +2 -0
- package/dist/components/SToggle/README.md +1 -0
- package/dist/components/SToggle/SToggle.d.ts +4 -1
- package/dist/components/STooltip/README.md +2 -0
- package/dist/index.cjs +1830 -319
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1826 -319
- package/dist/index.js.map +1 -1
- package/dist/lib/floating-width.d.ts +22 -0
- package/dist/llms-full.txt +343 -118
- package/dist/llms.txt +180 -114
- package/dist/styles.css +218 -16
- package/dist/theme.css +12 -5
- package/eslint/scale.gen.mjs +1 -1
- package/package.json +7 -4
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { forwardRef, useState, useRef, useEffect, createContext, useContext, use
|
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import { createPortal } from 'react-dom';
|
|
7
7
|
import * as RCheckbox from '@radix-ui/react-checkbox';
|
|
8
|
-
import * as
|
|
8
|
+
import * as RPopover9 from '@radix-ui/react-popover';
|
|
9
9
|
import { createRoot } from 'react-dom/client';
|
|
10
10
|
import * as RTooltip from '@radix-ui/react-tooltip';
|
|
11
11
|
import * as RDropdown from '@radix-ui/react-dropdown-menu';
|
|
@@ -2565,6 +2565,27 @@ var Icon_sidebar = (p) => {
|
|
|
2565
2565
|
}
|
|
2566
2566
|
);
|
|
2567
2567
|
};
|
|
2568
|
+
var Icon_star = (p) => {
|
|
2569
|
+
const { size = 24, ...rest } = p;
|
|
2570
|
+
return /* @__PURE__ */ jsx(
|
|
2571
|
+
"svg",
|
|
2572
|
+
{
|
|
2573
|
+
width: size,
|
|
2574
|
+
height: size,
|
|
2575
|
+
viewBox: "0 0 24 24",
|
|
2576
|
+
fill: "none",
|
|
2577
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2578
|
+
...rest,
|
|
2579
|
+
children: /* @__PURE__ */ jsx(
|
|
2580
|
+
"path",
|
|
2581
|
+
{
|
|
2582
|
+
d: "M12.3358 3.45335C12.0755 2.84888 11.2185 2.84888 10.9582 3.45335L8.78136 8.50811C8.67278 8.76024 8.43512 8.93291 8.16178 8.95826L2.68175 9.46652C2.02642 9.5273 1.76157 10.3424 2.25602 10.7768L6.39071 14.409C6.59695 14.5902 6.68773 14.8696 6.62737 15.1374L5.41733 20.5063C5.27263 21.1483 5.966 21.6521 6.5319 21.3161L11.2641 18.5062C11.5001 18.366 11.7939 18.366 12.0299 18.5062L16.7621 21.3161C17.328 21.6521 18.0214 21.1483 17.8767 20.5063L16.6666 15.1374C16.6063 14.8696 16.6971 14.5902 16.9033 14.409L21.038 10.7768C21.5324 10.3424 21.2676 9.5273 20.6123 9.46652L15.1322 8.95826C14.8589 8.93291 14.6212 8.76024 14.5126 8.50811L12.3358 3.45335Z",
|
|
2583
|
+
fill: "currentColor"
|
|
2584
|
+
}
|
|
2585
|
+
)
|
|
2586
|
+
}
|
|
2587
|
+
);
|
|
2588
|
+
};
|
|
2568
2589
|
var Icon_store = (p) => {
|
|
2569
2590
|
const { size = 24, ...rest } = p;
|
|
2570
2591
|
return /* @__PURE__ */ jsxs(
|
|
@@ -3059,6 +3080,7 @@ var ICONS = {
|
|
|
3059
3080
|
settingOutline: Icon_settingOutline,
|
|
3060
3081
|
shield: Icon_shield,
|
|
3061
3082
|
sidebar: Icon_sidebar,
|
|
3083
|
+
star: Icon_star,
|
|
3062
3084
|
store: Icon_store,
|
|
3063
3085
|
synchronize: Icon_synchronize,
|
|
3064
3086
|
thumbsDown: Icon_thumbsDown,
|
|
@@ -3091,6 +3113,209 @@ var SIcon = /* @__PURE__ */ forwardRef(function SIcon2({ name, size = 24, color,
|
|
|
3091
3113
|
}
|
|
3092
3114
|
);
|
|
3093
3115
|
});
|
|
3116
|
+
var VIEWBOX = 80;
|
|
3117
|
+
var RADIUS = 34;
|
|
3118
|
+
var STROKE = 12;
|
|
3119
|
+
var CIRCUMFERENCE = 2 * Math.PI * RADIUS;
|
|
3120
|
+
var COLOR_MAP = {
|
|
3121
|
+
primary: { arc: "var(--cmp-progress-color-active)", track: "var(--cmp-progress-color-track)" },
|
|
3122
|
+
// inverse: 어두운 배경용 — arc 흰색, track 은 흰색 40%(회색 링)
|
|
3123
|
+
inverse: { arc: "var(--color-white)", track: "rgba(255,255,255,0.4)" },
|
|
3124
|
+
error: { arc: "var(--color-red-75)", track: "var(--cmp-progress-color-track)" },
|
|
3125
|
+
complete: { arc: "#01BB4B", track: "var(--cmp-progress-color-track)" },
|
|
3126
|
+
// neutral: 콘텐츠가 아직 없는 자리를 채우는 용도 — arc 도 회색이라 진행률보다 "대기"로 읽힌다
|
|
3127
|
+
neutral: { arc: "var(--color-grey-35)", track: "var(--cmp-progress-color-track)" }
|
|
3128
|
+
};
|
|
3129
|
+
var DEFAULT_SIZE = 80;
|
|
3130
|
+
var clamp = (v) => Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0;
|
|
3131
|
+
var SCircleProgress = /* @__PURE__ */ forwardRef(
|
|
3132
|
+
function SCircleProgress2({
|
|
3133
|
+
value = 0,
|
|
3134
|
+
type = "primary",
|
|
3135
|
+
indeterminate = false,
|
|
3136
|
+
size = DEFAULT_SIZE,
|
|
3137
|
+
label,
|
|
3138
|
+
innerValue = false,
|
|
3139
|
+
className,
|
|
3140
|
+
style
|
|
3141
|
+
}, ref) {
|
|
3142
|
+
const v = clamp(value);
|
|
3143
|
+
const dimension = typeof size === "number" ? `${size}px` : size;
|
|
3144
|
+
const colors = COLOR_MAP[type];
|
|
3145
|
+
const c = VIEWBOX / 2;
|
|
3146
|
+
const percentColor = v === 0 ? "var(--sys-color-fg-tertiary, #888888)" : colors.arc;
|
|
3147
|
+
const filled = v / 100 * CIRCUMFERENCE;
|
|
3148
|
+
const showPercent = !indeterminate;
|
|
3149
|
+
const percentNode = /* @__PURE__ */ jsxs(
|
|
3150
|
+
"span",
|
|
3151
|
+
{
|
|
3152
|
+
className: cn(
|
|
3153
|
+
"text-center text-[16px] font-bold",
|
|
3154
|
+
innerValue ? (
|
|
3155
|
+
// leading-[normal]: 26px leading 은 폰트 content(19px) 위아래로 홀수(7px)만큼 남아
|
|
3156
|
+
// 3px/4px 로 쪼개지고 글자가 링 중심보다 위로 뜬다. (leading-normal 은 1.5 라 동일 문제)
|
|
3157
|
+
"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 leading-[normal]"
|
|
3158
|
+
) : "leading-[26px]"
|
|
3159
|
+
),
|
|
3160
|
+
style: { color: percentColor },
|
|
3161
|
+
children: [
|
|
3162
|
+
Math.round(v),
|
|
3163
|
+
"%"
|
|
3164
|
+
]
|
|
3165
|
+
}
|
|
3166
|
+
);
|
|
3167
|
+
return /* @__PURE__ */ jsxs(
|
|
3168
|
+
"div",
|
|
3169
|
+
{
|
|
3170
|
+
ref,
|
|
3171
|
+
className: cn(
|
|
3172
|
+
"inline-flex flex-col items-center gap-[var(--cmp-progress-circular-gap)]",
|
|
3173
|
+
className
|
|
3174
|
+
),
|
|
3175
|
+
style,
|
|
3176
|
+
children: [
|
|
3177
|
+
/* @__PURE__ */ jsxs("div", { className: cn(innerValue && "relative"), children: [
|
|
3178
|
+
/* @__PURE__ */ jsxs(
|
|
3179
|
+
"svg",
|
|
3180
|
+
{
|
|
3181
|
+
viewBox: `0 0 ${VIEWBOX} ${VIEWBOX}`,
|
|
3182
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3183
|
+
className: cn(indeterminate && "origin-center animate-circle-spin"),
|
|
3184
|
+
style: { width: dimension, height: dimension },
|
|
3185
|
+
children: [
|
|
3186
|
+
/* @__PURE__ */ jsx(
|
|
3187
|
+
"circle",
|
|
3188
|
+
{
|
|
3189
|
+
cx: c,
|
|
3190
|
+
cy: c,
|
|
3191
|
+
r: RADIUS,
|
|
3192
|
+
fill: "none",
|
|
3193
|
+
strokeWidth: STROKE,
|
|
3194
|
+
style: { stroke: colors.track }
|
|
3195
|
+
}
|
|
3196
|
+
),
|
|
3197
|
+
/* @__PURE__ */ jsx(
|
|
3198
|
+
"circle",
|
|
3199
|
+
{
|
|
3200
|
+
cx: c,
|
|
3201
|
+
cy: c,
|
|
3202
|
+
r: RADIUS,
|
|
3203
|
+
fill: "none",
|
|
3204
|
+
strokeWidth: STROKE,
|
|
3205
|
+
strokeLinecap: "round",
|
|
3206
|
+
className: cn(
|
|
3207
|
+
"origin-center",
|
|
3208
|
+
indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
|
|
3209
|
+
),
|
|
3210
|
+
style: {
|
|
3211
|
+
stroke: colors.arc,
|
|
3212
|
+
...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
)
|
|
3216
|
+
]
|
|
3217
|
+
}
|
|
3218
|
+
),
|
|
3219
|
+
showPercent && innerValue && percentNode
|
|
3220
|
+
] }),
|
|
3221
|
+
showPercent && !innerValue && percentNode,
|
|
3222
|
+
label && /* @__PURE__ */ jsx("span", { className: "text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]", children: label })
|
|
3223
|
+
]
|
|
3224
|
+
}
|
|
3225
|
+
);
|
|
3226
|
+
}
|
|
3227
|
+
);
|
|
3228
|
+
var IMAGE_FITS = ["cover", "contain", "fill", "none", "scale-down"];
|
|
3229
|
+
var EMPTY_ICON_SIZE = "60cqh";
|
|
3230
|
+
var SPINNER_SIZE = "45cqh";
|
|
3231
|
+
var SImage = /* @__PURE__ */ forwardRef(function SImage2({
|
|
3232
|
+
src,
|
|
3233
|
+
alt = "",
|
|
3234
|
+
ratio = 1,
|
|
3235
|
+
fit = "cover",
|
|
3236
|
+
position = "50% 50%",
|
|
3237
|
+
loading: loading2 = "lazy",
|
|
3238
|
+
loadingShowDelay = 0,
|
|
3239
|
+
noSpinner = false,
|
|
3240
|
+
loadingSlot,
|
|
3241
|
+
errorSlot,
|
|
3242
|
+
imgProps,
|
|
3243
|
+
onLoad,
|
|
3244
|
+
onError,
|
|
3245
|
+
className,
|
|
3246
|
+
style,
|
|
3247
|
+
...rest
|
|
3248
|
+
}, ref) {
|
|
3249
|
+
const [status, setStatus] = useState("loading");
|
|
3250
|
+
const [spinnerVisible, setSpinnerVisible] = useState(loadingShowDelay <= 0);
|
|
3251
|
+
const [trackedSrc, setTrackedSrc] = useState(src);
|
|
3252
|
+
const imgRef = useRef(null);
|
|
3253
|
+
if (src !== trackedSrc) {
|
|
3254
|
+
setTrackedSrc(src);
|
|
3255
|
+
setStatus("loading");
|
|
3256
|
+
}
|
|
3257
|
+
useEffect(() => {
|
|
3258
|
+
if (!src) return;
|
|
3259
|
+
const node = imgRef.current;
|
|
3260
|
+
if (node?.complete && node.naturalWidth > 0) {
|
|
3261
|
+
setStatus((current) => current === "loading" ? "loaded" : current);
|
|
3262
|
+
}
|
|
3263
|
+
}, [src]);
|
|
3264
|
+
useEffect(() => {
|
|
3265
|
+
if (status !== "loading" || loadingShowDelay <= 0) {
|
|
3266
|
+
setSpinnerVisible(status === "loading");
|
|
3267
|
+
return;
|
|
3268
|
+
}
|
|
3269
|
+
setSpinnerVisible(false);
|
|
3270
|
+
const timer = setTimeout(() => setSpinnerVisible(true), loadingShowDelay);
|
|
3271
|
+
return () => clearTimeout(timer);
|
|
3272
|
+
}, [status, loadingShowDelay, src]);
|
|
3273
|
+
const isEmpty = !src;
|
|
3274
|
+
const showFallback = isEmpty || status === "error";
|
|
3275
|
+
const showSpinner = !isEmpty && status === "loading" && !noSpinner && spinnerVisible;
|
|
3276
|
+
return /* @__PURE__ */ jsxs(
|
|
3277
|
+
"div",
|
|
3278
|
+
{
|
|
3279
|
+
ref,
|
|
3280
|
+
className: cn("relative overflow-hidden bg-(--cmp-image-bg)", className),
|
|
3281
|
+
style: { containerType: "size", aspectRatio: ratio, ...style },
|
|
3282
|
+
...rest,
|
|
3283
|
+
children: [
|
|
3284
|
+
!isEmpty && /* @__PURE__ */ jsx(
|
|
3285
|
+
"img",
|
|
3286
|
+
{
|
|
3287
|
+
...imgProps,
|
|
3288
|
+
ref: imgRef,
|
|
3289
|
+
src,
|
|
3290
|
+
alt,
|
|
3291
|
+
loading: loading2,
|
|
3292
|
+
onLoad: () => {
|
|
3293
|
+
setStatus("loaded");
|
|
3294
|
+
onLoad?.(src);
|
|
3295
|
+
},
|
|
3296
|
+
onError: (event) => {
|
|
3297
|
+
setStatus("error");
|
|
3298
|
+
onError?.(event);
|
|
3299
|
+
},
|
|
3300
|
+
className: cn(
|
|
3301
|
+
"h-full w-full",
|
|
3302
|
+
// 로딩 중에도 자리를 지켜야 브라우저가 계속 받아온다 — 숨기되 없애지 않는다
|
|
3303
|
+
status === "loaded" ? "visible" : "invisible",
|
|
3304
|
+
imgProps?.className
|
|
3305
|
+
),
|
|
3306
|
+
style: {
|
|
3307
|
+
objectFit: fit,
|
|
3308
|
+
objectPosition: position,
|
|
3309
|
+
...imgProps?.style
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
),
|
|
3313
|
+
showFallback && /* @__PURE__ */ jsx("span", { className: "absolute inset-0 flex items-center justify-center", children: errorSlot ?? /* @__PURE__ */ jsx(SIcon, { name: "image", size: EMPTY_ICON_SIZE, color: "var(--cmp-image-icon)" }) }),
|
|
3314
|
+
showSpinner && /* @__PURE__ */ jsx("span", { className: "absolute inset-0 flex items-center justify-center", children: loadingSlot ?? /* @__PURE__ */ jsx(SCircleProgress, { indeterminate: true, type: "neutral", size: SPINNER_SIZE }) })
|
|
3315
|
+
]
|
|
3316
|
+
}
|
|
3317
|
+
);
|
|
3318
|
+
});
|
|
3094
3319
|
var BADGE_COLORS = [
|
|
3095
3320
|
"red",
|
|
3096
3321
|
"orange",
|
|
@@ -3192,12 +3417,13 @@ var SDraggableItemView = /* @__PURE__ */ forwardRef(
|
|
|
3192
3417
|
!disabled && !selected && !dragging && "hover:bg-(--cmp-listDraggableItem-bg-hover)",
|
|
3193
3418
|
hasSupportingText && supportingTextPosition === "bottom" ? dense ? "min-h-[52px]" : "min-h-[60px]" : dense ? "h-[32px]" : "h-[40px]",
|
|
3194
3419
|
paddingYClass,
|
|
3195
|
-
|
|
3420
|
+
// 항목 사이 구분선은 리스트가 그린다 — SDraggableList 의 separator (SList.tsx)
|
|
3421
|
+
bordered && cn(
|
|
3196
3422
|
"rounded-(--cmp-listDraggableItem-radius-bordered) border border-(--cmp-listDraggableItem-border-default)",
|
|
3197
3423
|
!disabled && !selected && !dragging && "hover:border-(--cmp-listDraggableItem-bordered-border-hover)",
|
|
3198
3424
|
!disabled && selected && !dragging && "border-(--cmp-listDraggableItem-bordered-border-selected) bg-(--cmp-listDraggableItem-bordered-bg-selected)",
|
|
3199
3425
|
!disabled && selected && dragging && "border-[length:var(--cmp-listDraggableItem-bordered-dragging-border-width)] border-(--cmp-listDraggableItem-bordered-dragging-border-color) bg-(--cmp-listDraggableItem-bordered-dragging-bg)"
|
|
3200
|
-
)
|
|
3426
|
+
),
|
|
3201
3427
|
disabled && "cursor-not-allowed",
|
|
3202
3428
|
className
|
|
3203
3429
|
),
|
|
@@ -3399,7 +3625,7 @@ var SDraggableItemImpl = /* @__PURE__ */ forwardRef(function SDraggableItem({
|
|
|
3399
3625
|
] });
|
|
3400
3626
|
});
|
|
3401
3627
|
var SDraggableItem2 = /* @__PURE__ */ withDisplayName(SDraggableItemImpl, "SDraggableItem");
|
|
3402
|
-
var SListImpl = /* @__PURE__ */ forwardRef(function SList({ className, children, useGap = false, usePadding = false, ...rest }, ref) {
|
|
3628
|
+
var SListImpl = /* @__PURE__ */ forwardRef(function SList({ className, children, useGap = false, usePadding = false, separator = false, ...rest }, ref) {
|
|
3403
3629
|
return /* @__PURE__ */ jsx(
|
|
3404
3630
|
"div",
|
|
3405
3631
|
{
|
|
@@ -3407,6 +3633,7 @@ var SListImpl = /* @__PURE__ */ forwardRef(function SList({ className, children,
|
|
|
3407
3633
|
className: cn(
|
|
3408
3634
|
useGap && "flex flex-col gap-(--cmp-list-group-gap)",
|
|
3409
3635
|
usePadding && "p-(--cmp-list-group-padding)",
|
|
3636
|
+
separator && "[&>*]:border-b [&>*]:border-(--cmp-listItem-border-default)",
|
|
3410
3637
|
className
|
|
3411
3638
|
),
|
|
3412
3639
|
...rest,
|
|
@@ -3778,7 +4005,7 @@ var SExpansionItem = /* @__PURE__ */ forwardRef(
|
|
|
3778
4005
|
ref,
|
|
3779
4006
|
className: cn(
|
|
3780
4007
|
"group/expansion-item relative overflow-hidden bg-(--cmp-listExpansionItem-title-bg-default)",
|
|
3781
|
-
|
|
4008
|
+
// 항목 사이 구분선은 리스트가 그린다 — SList/SExpansionList 의 separator (SList.tsx)
|
|
3782
4009
|
// 보더 색은 시맨틱 토큰(border-default → hover strong → 펼침 accentLight)을 쓴다.
|
|
3783
4010
|
// TODO: expansionItem/bordered/radius 토큰 생성 후 rounded 고정값도 토큰으로 교체한다.
|
|
3784
4011
|
bordered && "rounded-[8px] border border-border-default hover:border-border-strong [&:has(>button:hover)]:border-border-strong",
|
|
@@ -3888,7 +4115,7 @@ var SListItemImpl = /* @__PURE__ */ forwardRef(function SListItem({
|
|
|
3888
4115
|
trailing,
|
|
3889
4116
|
bordered = false,
|
|
3890
4117
|
selected = false,
|
|
3891
|
-
clickable =
|
|
4118
|
+
clickable = false,
|
|
3892
4119
|
interaction,
|
|
3893
4120
|
accentStripe = false,
|
|
3894
4121
|
dense = false,
|
|
@@ -3941,10 +4168,10 @@ var SListItemImpl = /* @__PURE__ */ forwardRef(function SListItem({
|
|
|
3941
4168
|
"gap-(--cmp-listItem-gap)",
|
|
3942
4169
|
"pr-(--cmp-listItem-paddingX)",
|
|
3943
4170
|
depth === 2 ? "pl-[36px]" : depth === 3 ? "pl-[56px]" : "pl-[16px]",
|
|
3944
|
-
bordered
|
|
4171
|
+
bordered && cn(
|
|
3945
4172
|
"overflow-hidden rounded-(--cmp-listItem-radius-bordered) border border-(--cmp-listItem-border-default)",
|
|
3946
4173
|
isSelected ? "border-(--cmp-listItem-bordered-border-selected)" : isInteractive && "hover:border-(--cmp-listItem-bordered-border-hover)"
|
|
3947
|
-
)
|
|
4174
|
+
),
|
|
3948
4175
|
className
|
|
3949
4176
|
),
|
|
3950
4177
|
...rest,
|
|
@@ -4023,6 +4250,8 @@ var SExpansionListImpl = /* @__PURE__ */ forwardRef(function SExpansionList({ ch
|
|
|
4023
4250
|
const depth2 = child.props.depth ?? 1;
|
|
4024
4251
|
const itemKey2 = String(child.key ?? index);
|
|
4025
4252
|
return cloneElement(child, {
|
|
4253
|
+
// 선택을 리스트가 관리하는 이상 아이템은 클릭 가능해야 한다 — SListItem 의 기본값(false)을 뒤집는다
|
|
4254
|
+
clickable: child.props.clickable ?? true,
|
|
4026
4255
|
selected: selectedKeys[depth2] === itemKey2,
|
|
4027
4256
|
onClick: (event) => {
|
|
4028
4257
|
setSelectedKeys((current) => ({ ...current, [depth2]: itemKey2 }));
|
|
@@ -4328,8 +4557,8 @@ function SGhostButton({
|
|
|
4328
4557
|
}
|
|
4329
4558
|
);
|
|
4330
4559
|
if (!hasTooltip) return btn;
|
|
4331
|
-
return /* @__PURE__ */ jsxs(
|
|
4332
|
-
/* @__PURE__ */ jsx(
|
|
4560
|
+
return /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: setOpen, children: [
|
|
4561
|
+
/* @__PURE__ */ jsx(RPopover9.Anchor, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
4333
4562
|
"span",
|
|
4334
4563
|
{
|
|
4335
4564
|
className: cn("inline-flex", anchorClassName),
|
|
@@ -4341,8 +4570,8 @@ function SGhostButton({
|
|
|
4341
4570
|
children: btn
|
|
4342
4571
|
}
|
|
4343
4572
|
) }),
|
|
4344
|
-
/* @__PURE__ */ jsx(
|
|
4345
|
-
|
|
4573
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
4574
|
+
RPopover9.Content,
|
|
4346
4575
|
{
|
|
4347
4576
|
side: "top",
|
|
4348
4577
|
sideOffset: 4,
|
|
@@ -4813,7 +5042,7 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
|
|
|
4813
5042
|
...restContentProps
|
|
4814
5043
|
} = contentProps ?? {};
|
|
4815
5044
|
const contentClass = cn(
|
|
4816
|
-
"z-50 w-fit
|
|
5045
|
+
"z-50 w-fit max-w-[var(--radix-popover-content-available-width)] rounded-[6px] px-[16px] py-[12px] text-[12px] leading-[20px] shadow-normal-sm",
|
|
4817
5046
|
FLOATING_SLIDE_ANIM,
|
|
4818
5047
|
className,
|
|
4819
5048
|
contentPropsClassName
|
|
@@ -4825,14 +5054,14 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
|
|
|
4825
5054
|
...style,
|
|
4826
5055
|
...contentPropsStyle
|
|
4827
5056
|
};
|
|
4828
|
-
return /* @__PURE__ */ jsxs(
|
|
5057
|
+
return /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: setOpenState, children: [
|
|
4829
5058
|
isNone ? (
|
|
4830
5059
|
// 트리거 없음: children 을 래퍼 없이 그대로 앵커로 쓴다 (소비자 레이아웃 보존).
|
|
4831
5060
|
// mouse/focus 핸들러가 없으므로 useClose 없이도 자동 닫힘이 발생하지 않는다.
|
|
4832
|
-
/* @__PURE__ */ jsx(
|
|
5061
|
+
/* @__PURE__ */ jsx(RPopover9.Anchor, { asChild: true, children: triggerNode })
|
|
4833
5062
|
) : isHover ? (
|
|
4834
5063
|
// hover: Anchor(위치 기준) + 직접 mouse 핸들러 — 클릭으로 토글되지 않도록 Trigger 미사용
|
|
4835
|
-
/* @__PURE__ */ jsx(
|
|
5064
|
+
/* @__PURE__ */ jsx(RPopover9.Anchor, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
4836
5065
|
"span",
|
|
4837
5066
|
{
|
|
4838
5067
|
className: "inline-flex",
|
|
@@ -4843,9 +5072,9 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
|
|
|
4843
5072
|
children: triggerNode
|
|
4844
5073
|
}
|
|
4845
5074
|
) })
|
|
4846
|
-
) : /* @__PURE__ */ jsx(
|
|
4847
|
-
/* @__PURE__ */ jsx(
|
|
4848
|
-
|
|
5075
|
+
) : /* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: triggerNode }),
|
|
5076
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
|
|
5077
|
+
RPopover9.Content,
|
|
4849
5078
|
{
|
|
4850
5079
|
side: placement,
|
|
4851
5080
|
sideOffset,
|
|
@@ -4879,7 +5108,7 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
|
|
|
4879
5108
|
}
|
|
4880
5109
|
)
|
|
4881
5110
|
] }),
|
|
4882
|
-
/* @__PURE__ */ jsx(
|
|
5111
|
+
/* @__PURE__ */ jsx(RPopover9.Arrow, { width: 16, height: 12, style: { fill: bg } })
|
|
4883
5112
|
]
|
|
4884
5113
|
}
|
|
4885
5114
|
) })
|
|
@@ -5528,14 +5757,14 @@ var SCallout = /* @__PURE__ */ forwardRef(function SCallout2({ type = "default",
|
|
|
5528
5757
|
);
|
|
5529
5758
|
});
|
|
5530
5759
|
var FILL_COLOR = {
|
|
5531
|
-
primary: "var(--cmp-progress-active
|
|
5532
|
-
error: "var(--cmp-progress-error
|
|
5533
|
-
complete: "var(--cmp-progress-success
|
|
5760
|
+
primary: "var(--cmp-progress-color-active)",
|
|
5761
|
+
error: "var(--cmp-progress-color-error)",
|
|
5762
|
+
complete: "var(--cmp-progress-color-success)"
|
|
5534
5763
|
};
|
|
5535
|
-
var
|
|
5764
|
+
var clamp2 = (v) => Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0;
|
|
5536
5765
|
var SLinearProgress = /* @__PURE__ */ forwardRef(
|
|
5537
5766
|
function SLinearProgress2({ value = 0, type = "primary", indeterminate = false, label, className, style }, ref) {
|
|
5538
|
-
const v =
|
|
5767
|
+
const v = clamp2(value);
|
|
5539
5768
|
const fill = FILL_COLOR[type];
|
|
5540
5769
|
const valueColor = v === 0 ? "var(--sys-color-fg-tertiary, #888888)" : fill;
|
|
5541
5770
|
const valueText = `${Math.round(v)}%`;
|
|
@@ -5582,169 +5811,60 @@ var SLinearProgress = /* @__PURE__ */ forwardRef(
|
|
|
5582
5811
|
);
|
|
5583
5812
|
}
|
|
5584
5813
|
);
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
var
|
|
5588
|
-
var
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
const
|
|
5608
|
-
const
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
{
|
|
5616
|
-
className: cn(
|
|
5617
|
-
"text-center text-[16px] font-bold",
|
|
5618
|
-
innerValue ? (
|
|
5619
|
-
// leading-[normal]: 26px leading 은 폰트 content(19px) 위아래로 홀수(7px)만큼 남아
|
|
5620
|
-
// 3px/4px 로 쪼개지고 글자가 링 중심보다 위로 뜬다. (leading-normal 은 1.5 라 동일 문제)
|
|
5621
|
-
"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 leading-[normal]"
|
|
5622
|
-
) : "leading-[26px]"
|
|
5623
|
-
),
|
|
5624
|
-
style: { color: percentColor },
|
|
5625
|
-
children: [
|
|
5626
|
-
Math.round(v),
|
|
5627
|
-
"%"
|
|
5628
|
-
]
|
|
5629
|
-
}
|
|
5814
|
+
|
|
5815
|
+
// src/lib/global-overlay.ts
|
|
5816
|
+
var GLOBAL_OVERLAY_ATTR = "data-s-global-overlay";
|
|
5817
|
+
var globalOverlayProps = { [GLOBAL_OVERLAY_ATTR]: "" };
|
|
5818
|
+
function isFromGlobalOverlay(event) {
|
|
5819
|
+
const detail = event.detail;
|
|
5820
|
+
const target = detail?.originalEvent?.target ?? event.target;
|
|
5821
|
+
const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
|
|
5822
|
+
return !!element?.closest(`[${GLOBAL_OVERLAY_ATTR}]`);
|
|
5823
|
+
}
|
|
5824
|
+
var SLoadingContainer = /* @__PURE__ */ forwardRef(
|
|
5825
|
+
function SLoadingContainer2({ open = false, message, zIndex = Z_INDEX.loading, className, style }, ref) {
|
|
5826
|
+
const [mounted2, setMounted] = useState(false);
|
|
5827
|
+
useEffect(() => setMounted(true), []);
|
|
5828
|
+
useEffect(() => {
|
|
5829
|
+
if (!open) return;
|
|
5830
|
+
const prev = document.body.style.overflow;
|
|
5831
|
+
document.body.style.overflow = "hidden";
|
|
5832
|
+
return () => {
|
|
5833
|
+
document.body.style.overflow = prev;
|
|
5834
|
+
};
|
|
5835
|
+
}, [open]);
|
|
5836
|
+
const innerRef = useRef(null);
|
|
5837
|
+
const setRef = useCallback(
|
|
5838
|
+
(node) => {
|
|
5839
|
+
innerRef.current = node;
|
|
5840
|
+
if (typeof ref === "function") ref(node);
|
|
5841
|
+
else if (ref) ref.current = node;
|
|
5842
|
+
},
|
|
5843
|
+
[ref]
|
|
5630
5844
|
);
|
|
5631
|
-
|
|
5845
|
+
useEffect(() => {
|
|
5846
|
+
const el = innerRef.current;
|
|
5847
|
+
if (!el) return;
|
|
5848
|
+
const stop = (e) => e.stopPropagation();
|
|
5849
|
+
el.addEventListener("pointerdown", stop);
|
|
5850
|
+
el.addEventListener("mousedown", stop);
|
|
5851
|
+
return () => {
|
|
5852
|
+
el.removeEventListener("pointerdown", stop);
|
|
5853
|
+
el.removeEventListener("mousedown", stop);
|
|
5854
|
+
};
|
|
5855
|
+
}, [mounted2]);
|
|
5856
|
+
const overlay = /* @__PURE__ */ jsxs(
|
|
5632
5857
|
"div",
|
|
5633
5858
|
{
|
|
5634
|
-
ref,
|
|
5859
|
+
ref: setRef,
|
|
5860
|
+
...globalOverlayProps,
|
|
5861
|
+
"aria-hidden": !open,
|
|
5635
5862
|
className: cn(
|
|
5636
|
-
"
|
|
5863
|
+
"fixed inset-0 flex items-center justify-center transition-opacity duration-200",
|
|
5864
|
+
open ? "pointer-events-auto visible opacity-100" : "pointer-events-none invisible opacity-0",
|
|
5637
5865
|
className
|
|
5638
5866
|
),
|
|
5639
|
-
style,
|
|
5640
|
-
children: [
|
|
5641
|
-
/* @__PURE__ */ jsxs("div", { className: cn(innerValue && "relative"), children: [
|
|
5642
|
-
/* @__PURE__ */ jsxs(
|
|
5643
|
-
"svg",
|
|
5644
|
-
{
|
|
5645
|
-
viewBox: `0 0 ${VIEWBOX} ${VIEWBOX}`,
|
|
5646
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
5647
|
-
className: cn(
|
|
5648
|
-
"h-[80px] w-[80px]",
|
|
5649
|
-
indeterminate && "origin-center animate-circle-spin"
|
|
5650
|
-
),
|
|
5651
|
-
children: [
|
|
5652
|
-
/* @__PURE__ */ jsx(
|
|
5653
|
-
"circle",
|
|
5654
|
-
{
|
|
5655
|
-
cx: c,
|
|
5656
|
-
cy: c,
|
|
5657
|
-
r: RADIUS,
|
|
5658
|
-
fill: "none",
|
|
5659
|
-
strokeWidth: STROKE,
|
|
5660
|
-
style: { stroke: colors.track }
|
|
5661
|
-
}
|
|
5662
|
-
),
|
|
5663
|
-
/* @__PURE__ */ jsx(
|
|
5664
|
-
"circle",
|
|
5665
|
-
{
|
|
5666
|
-
cx: c,
|
|
5667
|
-
cy: c,
|
|
5668
|
-
r: RADIUS,
|
|
5669
|
-
fill: "none",
|
|
5670
|
-
strokeWidth: STROKE,
|
|
5671
|
-
strokeLinecap: "round",
|
|
5672
|
-
className: cn(
|
|
5673
|
-
"origin-center",
|
|
5674
|
-
indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
|
|
5675
|
-
),
|
|
5676
|
-
style: {
|
|
5677
|
-
stroke: colors.arc,
|
|
5678
|
-
...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
|
|
5679
|
-
}
|
|
5680
|
-
}
|
|
5681
|
-
)
|
|
5682
|
-
]
|
|
5683
|
-
}
|
|
5684
|
-
),
|
|
5685
|
-
showPercent && innerValue && percentNode
|
|
5686
|
-
] }),
|
|
5687
|
-
showPercent && !innerValue && percentNode,
|
|
5688
|
-
label && /* @__PURE__ */ jsx("span", { className: "text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]", children: label })
|
|
5689
|
-
]
|
|
5690
|
-
}
|
|
5691
|
-
);
|
|
5692
|
-
}
|
|
5693
|
-
);
|
|
5694
|
-
|
|
5695
|
-
// src/lib/global-overlay.ts
|
|
5696
|
-
var GLOBAL_OVERLAY_ATTR = "data-s-global-overlay";
|
|
5697
|
-
var globalOverlayProps = { [GLOBAL_OVERLAY_ATTR]: "" };
|
|
5698
|
-
function isFromGlobalOverlay(event) {
|
|
5699
|
-
const detail = event.detail;
|
|
5700
|
-
const target = detail?.originalEvent?.target ?? event.target;
|
|
5701
|
-
const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
|
|
5702
|
-
return !!element?.closest(`[${GLOBAL_OVERLAY_ATTR}]`);
|
|
5703
|
-
}
|
|
5704
|
-
var SLoadingContainer = /* @__PURE__ */ forwardRef(
|
|
5705
|
-
function SLoadingContainer2({ open = false, message, zIndex = Z_INDEX.loading, className, style }, ref) {
|
|
5706
|
-
const [mounted2, setMounted] = useState(false);
|
|
5707
|
-
useEffect(() => setMounted(true), []);
|
|
5708
|
-
useEffect(() => {
|
|
5709
|
-
if (!open) return;
|
|
5710
|
-
const prev = document.body.style.overflow;
|
|
5711
|
-
document.body.style.overflow = "hidden";
|
|
5712
|
-
return () => {
|
|
5713
|
-
document.body.style.overflow = prev;
|
|
5714
|
-
};
|
|
5715
|
-
}, [open]);
|
|
5716
|
-
const innerRef = useRef(null);
|
|
5717
|
-
const setRef = useCallback(
|
|
5718
|
-
(node) => {
|
|
5719
|
-
innerRef.current = node;
|
|
5720
|
-
if (typeof ref === "function") ref(node);
|
|
5721
|
-
else if (ref) ref.current = node;
|
|
5722
|
-
},
|
|
5723
|
-
[ref]
|
|
5724
|
-
);
|
|
5725
|
-
useEffect(() => {
|
|
5726
|
-
const el = innerRef.current;
|
|
5727
|
-
if (!el) return;
|
|
5728
|
-
const stop = (e) => e.stopPropagation();
|
|
5729
|
-
el.addEventListener("pointerdown", stop);
|
|
5730
|
-
el.addEventListener("mousedown", stop);
|
|
5731
|
-
return () => {
|
|
5732
|
-
el.removeEventListener("pointerdown", stop);
|
|
5733
|
-
el.removeEventListener("mousedown", stop);
|
|
5734
|
-
};
|
|
5735
|
-
}, [mounted2]);
|
|
5736
|
-
const overlay = /* @__PURE__ */ jsxs(
|
|
5737
|
-
"div",
|
|
5738
|
-
{
|
|
5739
|
-
ref: setRef,
|
|
5740
|
-
...globalOverlayProps,
|
|
5741
|
-
"aria-hidden": !open,
|
|
5742
|
-
className: cn(
|
|
5743
|
-
"fixed inset-0 flex items-center justify-center transition-opacity duration-200",
|
|
5744
|
-
open ? "pointer-events-auto visible opacity-100" : "pointer-events-none invisible opacity-0",
|
|
5745
|
-
className
|
|
5746
|
-
),
|
|
5747
|
-
style: { zIndex, ...style },
|
|
5867
|
+
style: { zIndex, ...style },
|
|
5748
5868
|
children: [
|
|
5749
5869
|
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/40" }),
|
|
5750
5870
|
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-col items-center gap-[16px]", children: [
|
|
@@ -5887,6 +6007,15 @@ var STextLink = /* @__PURE__ */ forwardRef(function STextLink2({
|
|
|
5887
6007
|
/* @__PURE__ */ jsx(RTooltip.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(RTooltip.Content, { side: "top", sideOffset: 4, className: cn("z-50", FLOATING_SLIDE_ANIM), children: /* @__PURE__ */ jsx(STag, { shape: "square", size: "xs", color: "grey", label: text }) }) })
|
|
5888
6008
|
] }) });
|
|
5889
6009
|
});
|
|
6010
|
+
|
|
6011
|
+
// src/lib/floating-width.ts
|
|
6012
|
+
var POPOVER_AVAILABLE_WIDTH = "var(--radix-popover-content-available-width)";
|
|
6013
|
+
var DROPDOWN_AVAILABLE_WIDTH = "var(--radix-dropdown-menu-content-available-width)";
|
|
6014
|
+
function clampToAvailableWidth(value, availableWidth) {
|
|
6015
|
+
if (value == null || value === "") return availableWidth;
|
|
6016
|
+
const css = typeof value === "number" ? `${value}px` : value;
|
|
6017
|
+
return `min(${css}, ${availableWidth})`;
|
|
6018
|
+
}
|
|
5890
6019
|
var SIZE2 = {
|
|
5891
6020
|
xs: { height: 24, paddingX: 8, gap: 6, arrow: 12, fontSize: 12, minWidth: 64, splitMinWidth: 72 },
|
|
5892
6021
|
sm: {
|
|
@@ -5923,6 +6052,7 @@ function splitDivider(color, outline) {
|
|
|
5923
6052
|
};
|
|
5924
6053
|
return (outline ? outlined : solid)[color];
|
|
5925
6054
|
}
|
|
6055
|
+
var VIEWPORT_PADDING = 12;
|
|
5926
6056
|
var itemClass = cn(
|
|
5927
6057
|
"flex min-h-[28px] cursor-pointer select-none items-center gap-[8px] rounded-[2px] px-[12px] py-[4px] text-[12px] leading-[20px] outline-none",
|
|
5928
6058
|
"text-[color:var(--sys-color-fg-secondary)]",
|
|
@@ -6004,12 +6134,16 @@ var SDropdownButtonImpl = /* @__PURE__ */ forwardRef(
|
|
|
6004
6134
|
sideOffset: 4,
|
|
6005
6135
|
align: "start",
|
|
6006
6136
|
alignOffset: split ? splitAlignOffset : 0,
|
|
6137
|
+
collisionPadding: VIEWPORT_PADDING,
|
|
6007
6138
|
className: cn(
|
|
6008
6139
|
"z-50 overflow-hidden rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] shadow-normal-sm",
|
|
6009
|
-
|
|
6140
|
+
// 창보다 넓은 메뉴는 창 폭에 맞춰 줄인다. 트리거 너비를 따르는 하한도 같은 상한으로
|
|
6141
|
+
// 감싸야 한다 — min-width 가 max-width 를 이기기 때문이다.
|
|
6142
|
+
"max-w-[var(--radix-dropdown-menu-content-available-width)]",
|
|
6143
|
+
!split && "min-w-[min(var(--radix-dropdown-menu-trigger-width),var(--radix-dropdown-menu-content-available-width))]",
|
|
6010
6144
|
FLOATING_SLIDE_ANIM
|
|
6011
6145
|
),
|
|
6012
|
-
style: split ? { minWidth: splitWidth } : void 0,
|
|
6146
|
+
style: split ? { minWidth: clampToAvailableWidth(splitWidth, DROPDOWN_AVAILABLE_WIDTH) } : void 0,
|
|
6013
6147
|
children: items.map((it) => /* @__PURE__ */ jsxs(
|
|
6014
6148
|
RDropdown.Item,
|
|
6015
6149
|
{
|
|
@@ -6021,7 +6155,7 @@ var SDropdownButtonImpl = /* @__PURE__ */ forwardRef(
|
|
|
6021
6155
|
/* @__PURE__ */ jsx(
|
|
6022
6156
|
"span",
|
|
6023
6157
|
{
|
|
6024
|
-
className: "min-w-0
|
|
6158
|
+
className: "min-w-0 break-words",
|
|
6025
6159
|
dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(it.label) }
|
|
6026
6160
|
}
|
|
6027
6161
|
)
|
|
@@ -6162,10 +6296,15 @@ function SSwitch({
|
|
|
6162
6296
|
}
|
|
6163
6297
|
);
|
|
6164
6298
|
}
|
|
6299
|
+
var SIZE_CLASSES = {
|
|
6300
|
+
xs: "h-[24px] px-[8px] text-[12px] font-normal leading-[20px]",
|
|
6301
|
+
sm: "h-[28px] px-[12px] text-[14px] font-medium leading-[24px]"
|
|
6302
|
+
};
|
|
6165
6303
|
function SToggle({
|
|
6166
6304
|
value = false,
|
|
6167
6305
|
label = "",
|
|
6168
6306
|
disabled = false,
|
|
6307
|
+
size = "sm",
|
|
6169
6308
|
onValueChange,
|
|
6170
6309
|
className,
|
|
6171
6310
|
style
|
|
@@ -6181,7 +6320,8 @@ function SToggle({
|
|
|
6181
6320
|
"aria-pressed": value,
|
|
6182
6321
|
onClick: () => !disabled && onValueChange?.(!value),
|
|
6183
6322
|
className: cn(
|
|
6184
|
-
"box-border inline-flex
|
|
6323
|
+
"box-border inline-flex items-center justify-center whitespace-nowrap rounded-full border border-solid transition-colors",
|
|
6324
|
+
SIZE_CLASSES[size],
|
|
6185
6325
|
disabled ? "cursor-not-allowed" : "cursor-pointer",
|
|
6186
6326
|
// 미선택(off) hover 시 파란 채움 + 흰 글자
|
|
6187
6327
|
!disabled && !value && "hover:!bg-[var(--cmp-toggle-bg-hover)] hover:!text-[color:var(--cmp-toggle-content-hover)] hover:!border-[color:var(--cmp-toggle-bg-hover)]",
|
|
@@ -6233,16 +6373,20 @@ function SPopover({
|
|
|
6233
6373
|
const descColor = type === "default" ? "var(--cmp-popover-default-description)" : "var(--cmp-popover-light-description)";
|
|
6234
6374
|
const leftLinkLabelClass = type === "default" ? "text-[color:var(--cmp-popover-default-subAction)]" : "text-[color:var(--cmp-popover-light-subAction)]";
|
|
6235
6375
|
const triggerNode = trigger ?? /* @__PURE__ */ jsx("span", { className: "inline-flex cursor-pointer", "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(SIcon, { name: icon, size: iconSize, color }) });
|
|
6236
|
-
return /* @__PURE__ */ jsxs(
|
|
6237
|
-
/* @__PURE__ */ jsx(
|
|
6238
|
-
/* @__PURE__ */ jsx(
|
|
6239
|
-
|
|
6376
|
+
return /* @__PURE__ */ jsxs(RPopover9.Root, { open: actualOpen, onOpenChange: setOpen, children: [
|
|
6377
|
+
/* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: triggerNode }),
|
|
6378
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
|
|
6379
|
+
RPopover9.Content,
|
|
6240
6380
|
{
|
|
6241
6381
|
side: placement,
|
|
6242
6382
|
sideOffset: 8,
|
|
6243
6383
|
className: cn(
|
|
6244
6384
|
// 닫기 버튼이 항상 있으므로 우측은 close clearance(36px) 로 고정
|
|
6245
|
-
"relative z-50 flex
|
|
6385
|
+
"relative z-50 flex flex-col gap-[var(--cmp-popover-gap)] rounded-[var(--cmp-popover-radius)] py-[var(--cmp-popover-paddingY)] px-[var(--cmp-popover-paddingX)] text-[12px] leading-[20px] shadow-normal-sm",
|
|
6386
|
+
// 창보다 넓어지면 창 폭에 맞춘다. 최소 너비도 같은 상한으로 감싼다 —
|
|
6387
|
+
// min-width 가 max-width 를 이기므로 감싸지 않으면 상한이 무력화된다.
|
|
6388
|
+
"max-w-[var(--radix-popover-content-available-width)]",
|
|
6389
|
+
"min-w-[min(160px,var(--radix-popover-content-available-width))]",
|
|
6246
6390
|
FLOATING_SLIDE_ANIM,
|
|
6247
6391
|
menuClassName
|
|
6248
6392
|
),
|
|
@@ -6298,7 +6442,7 @@ function SPopover({
|
|
|
6298
6442
|
]
|
|
6299
6443
|
}
|
|
6300
6444
|
),
|
|
6301
|
-
/* @__PURE__ */ jsx(
|
|
6445
|
+
/* @__PURE__ */ jsx(RPopover9.Arrow, { width: 16, height: 12, style: { fill: bg } })
|
|
6302
6446
|
]
|
|
6303
6447
|
}
|
|
6304
6448
|
) })
|
|
@@ -6327,8 +6471,9 @@ function SPortal({
|
|
|
6327
6471
|
ariaLabel
|
|
6328
6472
|
}) {
|
|
6329
6473
|
const portalContainer = usePortalContainer();
|
|
6474
|
+
const { minWidth: styleMinWidth, maxWidth: styleMaxWidth, ...restStyle } = style ?? {};
|
|
6330
6475
|
return /* @__PURE__ */ jsxs(
|
|
6331
|
-
|
|
6476
|
+
RPopover9.Root,
|
|
6332
6477
|
{
|
|
6333
6478
|
open,
|
|
6334
6479
|
onOpenChange: (next) => {
|
|
@@ -6336,9 +6481,9 @@ function SPortal({
|
|
|
6336
6481
|
if (!next) onClose?.();
|
|
6337
6482
|
},
|
|
6338
6483
|
children: [
|
|
6339
|
-
/* @__PURE__ */ jsx(
|
|
6340
|
-
/* @__PURE__ */ jsx(
|
|
6341
|
-
|
|
6484
|
+
/* @__PURE__ */ jsx(RPopover9.Anchor, { virtualRef: anchorRef }),
|
|
6485
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
6486
|
+
RPopover9.Content,
|
|
6342
6487
|
{
|
|
6343
6488
|
side: placement,
|
|
6344
6489
|
align,
|
|
@@ -6365,11 +6510,18 @@ function SPortal({
|
|
|
6365
6510
|
className: cn(
|
|
6366
6511
|
"z-50 overflow-hidden rounded-(--cmp-listBox-radius) bg-(--cmp-listBox-bg) shadow-normal-sm",
|
|
6367
6512
|
maxHeight != null && "overflow-y-auto",
|
|
6368
|
-
|
|
6513
|
+
// 앵커가 창보다 넓을 수 있는 자리(가로 스크롤 안의 트리거 등)에서도 하한이 상한을
|
|
6514
|
+
// 이기지 않도록, 앵커 너비 역시 가용 폭으로 가둔다.
|
|
6515
|
+
fit && "min-w-[min(var(--radix-popover-trigger-width),var(--radix-popover-content-available-width))]",
|
|
6369
6516
|
FLOATING_SLIDE_ANIM,
|
|
6370
6517
|
className
|
|
6371
6518
|
),
|
|
6372
|
-
style: {
|
|
6519
|
+
style: {
|
|
6520
|
+
maxHeight,
|
|
6521
|
+
...restStyle,
|
|
6522
|
+
...styleMinWidth != null ? { minWidth: clampToAvailableWidth(styleMinWidth, POPOVER_AVAILABLE_WIDTH) } : {},
|
|
6523
|
+
maxWidth: clampToAvailableWidth(styleMaxWidth, POPOVER_AVAILABLE_WIDTH)
|
|
6524
|
+
},
|
|
6373
6525
|
children
|
|
6374
6526
|
}
|
|
6375
6527
|
) })
|
|
@@ -6529,16 +6681,18 @@ function SGuide({
|
|
|
6529
6681
|
);
|
|
6530
6682
|
if (isNotion)
|
|
6531
6683
|
return /* @__PURE__ */ jsx("span", { className, style, children: trigger });
|
|
6532
|
-
return /* @__PURE__ */ jsxs(
|
|
6533
|
-
/* @__PURE__ */ jsx(
|
|
6534
|
-
/* @__PURE__ */ jsx(
|
|
6535
|
-
|
|
6684
|
+
return /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: setOpen, children: [
|
|
6685
|
+
/* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: trigger }),
|
|
6686
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
|
|
6687
|
+
RPopover9.Content,
|
|
6536
6688
|
{
|
|
6537
6689
|
side: "bottom",
|
|
6538
6690
|
align: "start",
|
|
6539
6691
|
sideOffset: 4,
|
|
6540
6692
|
className: cn(
|
|
6541
6693
|
"relative z-50 rounded-[var(--cmp-guide-contents-radius)] bg-[var(--color-white)]",
|
|
6694
|
+
// popupWidth(기본 426px)가 창보다 넓으면 창 폭에 맞춘다 — max-width 가 width 를 이긴다.
|
|
6695
|
+
"max-w-[var(--radix-popover-content-available-width)]",
|
|
6542
6696
|
FLOATING_SLIDE_ANIM
|
|
6543
6697
|
),
|
|
6544
6698
|
style: {
|
|
@@ -8611,10 +8765,10 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
|
|
|
8611
8765
|
}
|
|
8612
8766
|
),
|
|
8613
8767
|
header === "fix" && menuResizeHandle,
|
|
8614
|
-
/* @__PURE__ */ jsxs(
|
|
8615
|
-
/* @__PURE__ */ jsx(
|
|
8616
|
-
/* @__PURE__ */ jsx(
|
|
8617
|
-
|
|
8768
|
+
/* @__PURE__ */ jsxs(RPopover9.Root, { open: labelTip !== null, onOpenChange: (open) => !open && setLabelTip(null), children: [
|
|
8769
|
+
/* @__PURE__ */ jsx(RPopover9.Anchor, { virtualRef: labelTipAnchorRef }),
|
|
8770
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
8771
|
+
RPopover9.Content,
|
|
8618
8772
|
{
|
|
8619
8773
|
side: "right",
|
|
8620
8774
|
sideOffset: 4,
|
|
@@ -8632,16 +8786,81 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
|
|
|
8632
8786
|
}
|
|
8633
8787
|
);
|
|
8634
8788
|
});
|
|
8789
|
+
var SPageHeader = /* @__PURE__ */ withDisplayName(
|
|
8790
|
+
forwardRef(function SPageHeader2({ title, subText, fix = false, onBack, slot, scrolled = false, className, style, ...rest }, ref) {
|
|
8791
|
+
const hasBack = onBack != null;
|
|
8792
|
+
return /* @__PURE__ */ jsxs(
|
|
8793
|
+
"header",
|
|
8794
|
+
{
|
|
8795
|
+
ref,
|
|
8796
|
+
className: cn(
|
|
8797
|
+
"relative z-10 box-border flex shrink-0 items-center gap-(--cmp-pageHeader-gap) px-(--cmp-pageHeader-paddingX)",
|
|
8798
|
+
fix ? "h-(--cmp-pageHeader-bar-height) border-b border-(--cmp-pageHeader-bar-border) bg-(--cmp-pageHeader-bar-bg) py-(--cmp-pageHeader-bar-paddingY)" : cn(
|
|
8799
|
+
// 배경은 항상 투명 — 페이지 배경을 따라갈지는 fix 가 정하지 scrolled 가 정하지 않는다.
|
|
8800
|
+
// 스크롤되면 그림자만 더해 콘텐츠 위에 뜬 것처럼 보이게 한다.
|
|
8801
|
+
"bg-transparent pt-(--cmp-pageHeader-plain-paddingTop) pb-(--cmp-pageHeader-plain-paddingBottom)",
|
|
8802
|
+
scrolled && "shadow-floating"
|
|
8803
|
+
),
|
|
8804
|
+
className
|
|
8805
|
+
),
|
|
8806
|
+
style,
|
|
8807
|
+
...rest,
|
|
8808
|
+
children: [
|
|
8809
|
+
hasBack && /* @__PURE__ */ jsx(
|
|
8810
|
+
SGhostButton,
|
|
8811
|
+
{
|
|
8812
|
+
icon: "chevronLeft",
|
|
8813
|
+
size: "xs",
|
|
8814
|
+
ariaLabel: "\uB4A4\uB85C\uAC00\uAE30",
|
|
8815
|
+
onClick: onBack,
|
|
8816
|
+
className: "shrink-0"
|
|
8817
|
+
}
|
|
8818
|
+
),
|
|
8819
|
+
/* @__PURE__ */ jsxs(
|
|
8820
|
+
"div",
|
|
8821
|
+
{
|
|
8822
|
+
className: cn(
|
|
8823
|
+
"flex min-w-0 flex-1 items-center",
|
|
8824
|
+
fix ? "flex-row gap-(--cmp-pageHeader-gap)" : "flex-col items-start gap-(--cmp-pageHeader-plain-title-gap)",
|
|
8825
|
+
!hasBack && "pl-(--cmp-pageHeader-title-paddingLeft)"
|
|
8826
|
+
),
|
|
8827
|
+
children: [
|
|
8828
|
+
/* @__PURE__ */ jsx("span", { className: "typo-heading-lg min-w-0 truncate text-(--cmp-pageHeader-title-text)", children: title }),
|
|
8829
|
+
subText && /* @__PURE__ */ jsx("span", { className: "typo-body-md-default min-w-0 truncate text-(--cmp-pageHeader-subtitle-text)", children: subText })
|
|
8830
|
+
]
|
|
8831
|
+
}
|
|
8832
|
+
),
|
|
8833
|
+
slot && /* @__PURE__ */ jsx("div", { className: "ml-auto flex shrink-0 items-center", children: slot })
|
|
8834
|
+
]
|
|
8835
|
+
}
|
|
8836
|
+
);
|
|
8837
|
+
}),
|
|
8838
|
+
"SPageHeader"
|
|
8839
|
+
);
|
|
8635
8840
|
var MIN_CONTENT_WIDTH = `calc(var(${SLAYOUT_MIN_WIDTH_VAR}, 0px) - 100cqw + 100%)`;
|
|
8636
8841
|
var BACKGROUND_CLASS = {
|
|
8637
8842
|
frame: `bg-[var(--sys-color-bg-frame)] ${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_CLASS}`,
|
|
8638
8843
|
neutral: `bg-[var(--sys-color-bg-neutralLight)] ${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_WHITE_CLASS}`,
|
|
8639
8844
|
screen: `bg-[var(--sys-color-bg-screen)] ${SCROLLBAR_TRACK_BORDER_CLASS} ${SCROLLBAR_TRACK_BG_CLASS}`
|
|
8640
8845
|
};
|
|
8641
|
-
var SPage = /* @__PURE__ */ forwardRef(function SPage2({
|
|
8846
|
+
var SPage = /* @__PURE__ */ forwardRef(function SPage2({
|
|
8847
|
+
background = "frame",
|
|
8848
|
+
scrollEndSpacing = true,
|
|
8849
|
+
header,
|
|
8850
|
+
className,
|
|
8851
|
+
style,
|
|
8852
|
+
children,
|
|
8853
|
+
onScroll,
|
|
8854
|
+
...rest
|
|
8855
|
+
}, ref) {
|
|
8642
8856
|
const layout = useContext(SLayoutContext);
|
|
8643
8857
|
const gridStyle = layout?.header === "full" ? { gridArea: "page" } : void 0;
|
|
8644
|
-
|
|
8858
|
+
const [scrolled, setScrolled] = useState(false);
|
|
8859
|
+
const handleScroll = (e) => {
|
|
8860
|
+
onScroll?.(e);
|
|
8861
|
+
if (header != null && !header.fix) setScrolled(e.currentTarget.scrollTop > 0);
|
|
8862
|
+
};
|
|
8863
|
+
const main = /* @__PURE__ */ jsx(
|
|
8645
8864
|
"main",
|
|
8646
8865
|
{
|
|
8647
8866
|
ref,
|
|
@@ -8652,11 +8871,29 @@ var SPage = /* @__PURE__ */ forwardRef(function SPage2({ background = "frame", s
|
|
|
8652
8871
|
BACKGROUND_CLASS[background],
|
|
8653
8872
|
className
|
|
8654
8873
|
),
|
|
8655
|
-
style: { ...gridStyle, ...style },
|
|
8874
|
+
style: header == null ? { ...gridStyle, ...style } : style,
|
|
8875
|
+
onScroll: handleScroll,
|
|
8656
8876
|
...rest,
|
|
8657
8877
|
children: /* @__PURE__ */ jsx("div", { style: { minWidth: MIN_CONTENT_WIDTH }, children })
|
|
8658
8878
|
}
|
|
8659
8879
|
);
|
|
8880
|
+
if (header == null) return main;
|
|
8881
|
+
return (
|
|
8882
|
+
// fix 가 아닌 헤더는 자기 배경이 투명이라(SPageHeader.tsx) 이 배경이 그대로 비친다 —
|
|
8883
|
+
// 그래서 SPage 의 background 를 main 뿐 아니라 여기에도 칠한다(스크롤바 관련 클래스는
|
|
8884
|
+
// 스크롤 요소가 아닌 여기서는 그냥 무시된다). fix 헤더는 자체 흰 배경이 덮으므로 무관하다.
|
|
8885
|
+
/* @__PURE__ */ jsxs(
|
|
8886
|
+
"div",
|
|
8887
|
+
{
|
|
8888
|
+
className: cn("flex min-h-0 min-w-0 flex-1 flex-col", BACKGROUND_CLASS[background]),
|
|
8889
|
+
style: gridStyle,
|
|
8890
|
+
children: [
|
|
8891
|
+
/* @__PURE__ */ jsx(SPageHeader, { ...header, scrolled }),
|
|
8892
|
+
main
|
|
8893
|
+
]
|
|
8894
|
+
}
|
|
8895
|
+
)
|
|
8896
|
+
);
|
|
8660
8897
|
});
|
|
8661
8898
|
|
|
8662
8899
|
// src/components/SPage/page.config.ts
|
|
@@ -11030,7 +11267,7 @@ var SInput = /* @__PURE__ */ forwardRef(function SInput2({
|
|
|
11030
11267
|
lineHeight: `${f.lineHeight}px`
|
|
11031
11268
|
},
|
|
11032
11269
|
children: [
|
|
11033
|
-
prefix != null && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: prefix }),
|
|
11270
|
+
prefix != null && /* @__PURE__ */ jsx("span", { className: "flex flex-shrink-0 items-center", children: prefix }),
|
|
11034
11271
|
/* @__PURE__ */ jsx(
|
|
11035
11272
|
"input",
|
|
11036
11273
|
{
|
|
@@ -11062,7 +11299,7 @@ var SInput = /* @__PURE__ */ forwardRef(function SInput2({
|
|
|
11062
11299
|
...rest
|
|
11063
11300
|
}
|
|
11064
11301
|
),
|
|
11065
|
-
suffix != null && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: suffix }),
|
|
11302
|
+
suffix != null && /* @__PURE__ */ jsx("span", { className: "flex flex-shrink-0 items-center", children: suffix }),
|
|
11066
11303
|
clearable && hasValue && !disabled && !readOnly && /* @__PURE__ */ jsx(
|
|
11067
11304
|
SGhostButton,
|
|
11068
11305
|
{
|
|
@@ -11960,8 +12197,8 @@ function SDatePicker({
|
|
|
11960
12197
|
disabled,
|
|
11961
12198
|
className,
|
|
11962
12199
|
style,
|
|
11963
|
-
children: /* @__PURE__ */ jsxs(
|
|
11964
|
-
/* @__PURE__ */ jsx(
|
|
12200
|
+
children: /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
|
|
12201
|
+
/* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
11965
12202
|
"button",
|
|
11966
12203
|
{
|
|
11967
12204
|
type: "button",
|
|
@@ -11997,13 +12234,16 @@ function SDatePicker({
|
|
|
11997
12234
|
]
|
|
11998
12235
|
}
|
|
11999
12236
|
) }),
|
|
12000
|
-
/* @__PURE__ */ jsx(
|
|
12001
|
-
|
|
12237
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
12238
|
+
RPopover9.Content,
|
|
12002
12239
|
{
|
|
12003
12240
|
side: "bottom",
|
|
12004
12241
|
align: "start",
|
|
12005
12242
|
sideOffset: 4,
|
|
12006
|
-
className: cn(
|
|
12243
|
+
className: cn(
|
|
12244
|
+
"z-50 max-w-[var(--radix-popover-content-available-width)]",
|
|
12245
|
+
FLOATING_SLIDE_ANIM
|
|
12246
|
+
),
|
|
12007
12247
|
children: /* @__PURE__ */ jsx(
|
|
12008
12248
|
SCalendar,
|
|
12009
12249
|
{
|
|
@@ -12151,78 +12391,81 @@ function RangeCalendar({
|
|
|
12151
12391
|
}
|
|
12152
12392
|
};
|
|
12153
12393
|
const GRID_COLS = "grid grid-cols-[repeat(7,var(--cmp-datepicker-calendar-day-width))]";
|
|
12154
|
-
const renderPanel = (gy, gm, isLeft) =>
|
|
12155
|
-
|
|
12156
|
-
|
|
12157
|
-
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
|
|
12161
|
-
|
|
12162
|
-
|
|
12163
|
-
|
|
12164
|
-
|
|
12165
|
-
|
|
12166
|
-
|
|
12167
|
-
|
|
12168
|
-
"
|
|
12169
|
-
|
|
12394
|
+
const renderPanel = (gy, gm, isLeft) => (
|
|
12395
|
+
// 좁은 창에서 눌려 격자가 깨지지 않도록, 줄이는 대신 부모가 가로 스크롤하게 둔다.
|
|
12396
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-col gap-[var(--cmp-datepicker-calendar-gap)]", children: [
|
|
12397
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-[var(--cmp-datepicker-calendar-gap)]", children: [
|
|
12398
|
+
/* @__PURE__ */ jsx(
|
|
12399
|
+
SGhostButton,
|
|
12400
|
+
{
|
|
12401
|
+
icon: "chevronLeft",
|
|
12402
|
+
size: "xxs",
|
|
12403
|
+
ariaLabel: "prevMonth",
|
|
12404
|
+
onClick: goPrevMonth,
|
|
12405
|
+
className: cn(!isLeft && "invisible pointer-events-none")
|
|
12406
|
+
}
|
|
12407
|
+
),
|
|
12408
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-[40px] flex-1 items-center justify-center text-center text-[14px] font-medium leading-[24px]", children: [
|
|
12409
|
+
gy,
|
|
12410
|
+
".",
|
|
12411
|
+
String(gm).padStart(2, "0")
|
|
12412
|
+
] }),
|
|
12413
|
+
/* @__PURE__ */ jsx(
|
|
12414
|
+
SGhostButton,
|
|
12415
|
+
{
|
|
12416
|
+
icon: "chevronRight",
|
|
12417
|
+
size: "xxs",
|
|
12418
|
+
ariaLabel: "nextMonth",
|
|
12419
|
+
onClick: goNextMonth,
|
|
12420
|
+
className: cn(isLeft && "invisible pointer-events-none")
|
|
12421
|
+
}
|
|
12422
|
+
)
|
|
12170
12423
|
] }),
|
|
12171
|
-
/* @__PURE__ */ jsx(
|
|
12172
|
-
|
|
12173
|
-
{
|
|
12174
|
-
icon: "chevronRight",
|
|
12175
|
-
size: "xxs",
|
|
12176
|
-
ariaLabel: "nextMonth",
|
|
12177
|
-
onClick: goNextMonth,
|
|
12178
|
-
className: cn(isLeft && "invisible pointer-events-none")
|
|
12179
|
-
}
|
|
12180
|
-
)
|
|
12181
|
-
] }),
|
|
12182
|
-
/* @__PURE__ */ jsx("div", { className: GRID_COLS, children: WEEK_LABELS.map((l) => /* @__PURE__ */ jsx(
|
|
12183
|
-
"span",
|
|
12184
|
-
{
|
|
12185
|
-
className: "flex h-[20px] items-center justify-center text-[12px] font-normal text-[color:var(--cmp-datepicker-calendar-week-color)]",
|
|
12186
|
-
children: l
|
|
12187
|
-
},
|
|
12188
|
-
l
|
|
12189
|
-
)) }),
|
|
12190
|
-
/* @__PURE__ */ jsx("div", { className: cn(GRID_COLS, "gap-y-[var(--cmp-datepicker-calendar-grid-rowGap)]"), children: monthCells(gy, gm).map((cell) => {
|
|
12191
|
-
const isEdge = cell.inCurrentMonth && (cell.date === rStart || complete && cell.date === rEnd);
|
|
12192
|
-
const between = cell.inCurrentMonth && inRange(cell.date);
|
|
12193
|
-
const disabled = cell.inCurrentMonth && isDisabled(cell.date);
|
|
12194
|
-
const isToday = cell.inCurrentMonth && today === cell.date;
|
|
12195
|
-
let cellBg;
|
|
12196
|
-
if (between) cellBg = RANGE_BG;
|
|
12197
|
-
else if (cell.inCurrentMonth && hasRange && cell.date === rStart)
|
|
12198
|
-
cellBg = `linear-gradient(to right, transparent 50%, ${RANGE_BG} 50%)`;
|
|
12199
|
-
else if (cell.inCurrentMonth && hasRange && cell.date === rEnd) cellBg = RANGE_BG;
|
|
12200
|
-
return /* @__PURE__ */ jsx(
|
|
12201
|
-
"div",
|
|
12424
|
+
/* @__PURE__ */ jsx("div", { className: GRID_COLS, children: WEEK_LABELS.map((l) => /* @__PURE__ */ jsx(
|
|
12425
|
+
"span",
|
|
12202
12426
|
{
|
|
12203
|
-
className: "flex h-[
|
|
12204
|
-
|
|
12205
|
-
children: /* @__PURE__ */ jsx(
|
|
12206
|
-
"button",
|
|
12207
|
-
{
|
|
12208
|
-
type: "button",
|
|
12209
|
-
disabled: !cell.inCurrentMonth || disabled,
|
|
12210
|
-
onMouseEnter: () => setHover(cell.date),
|
|
12211
|
-
onClick: () => cell.inCurrentMonth && click(cell.date),
|
|
12212
|
-
className: cn(
|
|
12213
|
-
"relative z-[1] flex h-[var(--cmp-datepicker-calendar-day-circle-size)] w-[var(--cmp-datepicker-calendar-day-circle-size)] items-center justify-center rounded-[var(--cmp-datepicker-calendar-day-circle-radius)] border border-solid border-transparent bg-transparent text-[14px]",
|
|
12214
|
-
!cell.inCurrentMonth ? "invisible pointer-events-none" : disabled ? "cursor-not-allowed" : "cursor-pointer",
|
|
12215
|
-
isEdge ? "bg-[var(--cmp-datepicker-calendar-day-select-bg)] text-[color:var(--cmp-datepicker-calendar-day-select-text)]" : disabled ? "text-[color:var(--cmp-datepicker-calendar-day-disabled-text)]" : "text-[color:var(--cmp-datepicker-calendar-day-default-text)] hover:border-[color:var(--cmp-datepicker-calendar-day-hover-border)] hover:text-[color:var(--cmp-datepicker-calendar-day-hover-text)]",
|
|
12216
|
-
isToday && !disabled && "font-bold"
|
|
12217
|
-
),
|
|
12218
|
-
children: cell.inCurrentMonth ? cell.day : ""
|
|
12219
|
-
}
|
|
12220
|
-
)
|
|
12427
|
+
className: "flex h-[20px] items-center justify-center text-[12px] font-normal text-[color:var(--cmp-datepicker-calendar-week-color)]",
|
|
12428
|
+
children: l
|
|
12221
12429
|
},
|
|
12222
|
-
|
|
12223
|
-
)
|
|
12224
|
-
|
|
12225
|
-
|
|
12430
|
+
l
|
|
12431
|
+
)) }),
|
|
12432
|
+
/* @__PURE__ */ jsx("div", { className: cn(GRID_COLS, "gap-y-[var(--cmp-datepicker-calendar-grid-rowGap)]"), children: monthCells(gy, gm).map((cell) => {
|
|
12433
|
+
const isEdge = cell.inCurrentMonth && (cell.date === rStart || complete && cell.date === rEnd);
|
|
12434
|
+
const between = cell.inCurrentMonth && inRange(cell.date);
|
|
12435
|
+
const disabled = cell.inCurrentMonth && isDisabled(cell.date);
|
|
12436
|
+
const isToday = cell.inCurrentMonth && today === cell.date;
|
|
12437
|
+
let cellBg;
|
|
12438
|
+
if (between) cellBg = RANGE_BG;
|
|
12439
|
+
else if (cell.inCurrentMonth && hasRange && cell.date === rStart)
|
|
12440
|
+
cellBg = `linear-gradient(to right, transparent 50%, ${RANGE_BG} 50%)`;
|
|
12441
|
+
else if (cell.inCurrentMonth && hasRange && cell.date === rEnd) cellBg = RANGE_BG;
|
|
12442
|
+
return /* @__PURE__ */ jsx(
|
|
12443
|
+
"div",
|
|
12444
|
+
{
|
|
12445
|
+
className: "flex h-[var(--cmp-datepicker-calendar-range-height)] w-[var(--cmp-datepicker-calendar-day-width)] items-center justify-center",
|
|
12446
|
+
style: { background: cellBg },
|
|
12447
|
+
children: /* @__PURE__ */ jsx(
|
|
12448
|
+
"button",
|
|
12449
|
+
{
|
|
12450
|
+
type: "button",
|
|
12451
|
+
disabled: !cell.inCurrentMonth || disabled,
|
|
12452
|
+
onMouseEnter: () => setHover(cell.date),
|
|
12453
|
+
onClick: () => cell.inCurrentMonth && click(cell.date),
|
|
12454
|
+
className: cn(
|
|
12455
|
+
"relative z-[1] flex h-[var(--cmp-datepicker-calendar-day-circle-size)] w-[var(--cmp-datepicker-calendar-day-circle-size)] items-center justify-center rounded-[var(--cmp-datepicker-calendar-day-circle-radius)] border border-solid border-transparent bg-transparent text-[14px]",
|
|
12456
|
+
!cell.inCurrentMonth ? "invisible pointer-events-none" : disabled ? "cursor-not-allowed" : "cursor-pointer",
|
|
12457
|
+
isEdge ? "bg-[var(--cmp-datepicker-calendar-day-select-bg)] text-[color:var(--cmp-datepicker-calendar-day-select-text)]" : disabled ? "text-[color:var(--cmp-datepicker-calendar-day-disabled-text)]" : "text-[color:var(--cmp-datepicker-calendar-day-default-text)] hover:border-[color:var(--cmp-datepicker-calendar-day-hover-border)] hover:text-[color:var(--cmp-datepicker-calendar-day-hover-text)]",
|
|
12458
|
+
isToday && !disabled && "font-bold"
|
|
12459
|
+
),
|
|
12460
|
+
children: cell.inCurrentMonth ? cell.day : ""
|
|
12461
|
+
}
|
|
12462
|
+
)
|
|
12463
|
+
},
|
|
12464
|
+
cell.date
|
|
12465
|
+
);
|
|
12466
|
+
}) })
|
|
12467
|
+
] })
|
|
12468
|
+
);
|
|
12226
12469
|
const renderTimeSection = (which, date, suffix) => {
|
|
12227
12470
|
const active = !!date;
|
|
12228
12471
|
const [yy = "", mm = "", dd = ""] = date ? date.split("-") : [];
|
|
@@ -12290,8 +12533,11 @@ function RangeCalendar({
|
|
|
12290
12533
|
"div",
|
|
12291
12534
|
{
|
|
12292
12535
|
className: cn(
|
|
12293
|
-
"inline-flex flex-col gap-[var(--cmp-datepicker-calendar-gap)] rounded-[var(--cmp-datepicker-calendar-radius)] bg-[var(--cmp-datepicker-calendar-bg)] p-[var(--cmp-datepicker-calendar-paddingXY)] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.2)] select-none",
|
|
12294
|
-
|
|
12536
|
+
"inline-flex max-w-full flex-col gap-[var(--cmp-datepicker-calendar-gap)] rounded-[var(--cmp-datepicker-calendar-radius)] bg-[var(--cmp-datepicker-calendar-bg)] p-[var(--cmp-datepicker-calendar-paddingXY)] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.2)] select-none",
|
|
12537
|
+
// 높이는 고정이 아니라 하한이다 — 5주/6주 달을 오갈 때의 높이 흔들림만 막으면 되고,
|
|
12538
|
+
// 창이 좁아 패널이 가로 스크롤될 때는 스크롤바 높이만큼 늘어날 수 있어야 한다.
|
|
12539
|
+
// (단일 달 SCalendar 도 min-h 를 쓴다)
|
|
12540
|
+
useTimePicker ? "h-auto" : "min-h-[364px]"
|
|
12295
12541
|
),
|
|
12296
12542
|
children: [
|
|
12297
12543
|
/* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
|
|
@@ -12310,11 +12556,20 @@ function RangeCalendar({
|
|
|
12310
12556
|
}
|
|
12311
12557
|
)
|
|
12312
12558
|
] }),
|
|
12313
|
-
/* @__PURE__ */ jsxs(
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12559
|
+
/* @__PURE__ */ jsxs(
|
|
12560
|
+
"div",
|
|
12561
|
+
{
|
|
12562
|
+
className: cn(
|
|
12563
|
+
"flex max-w-full gap-[var(--cmp-datepicker-calendar-range-panelGap)] overflow-x-auto",
|
|
12564
|
+
SCROLLBAR_CLASS
|
|
12565
|
+
),
|
|
12566
|
+
children: [
|
|
12567
|
+
renderPanel(y, m, true),
|
|
12568
|
+
/* @__PURE__ */ jsx(SDivider, { vertical: true }),
|
|
12569
|
+
renderPanel(nextMonthYM.year, nextMonthYM.month, false)
|
|
12570
|
+
]
|
|
12571
|
+
}
|
|
12572
|
+
),
|
|
12318
12573
|
useTimePicker && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12319
12574
|
/* @__PURE__ */ jsx(SDivider, {}),
|
|
12320
12575
|
/* @__PURE__ */ jsxs("div", { className: "flex gap-[var(--cmp-datepicker-calendar-time-gap)]", children: [
|
|
@@ -12373,7 +12628,25 @@ function SDateRangePicker({
|
|
|
12373
12628
|
});
|
|
12374
12629
|
const resolvedError = error || ruleError !== "";
|
|
12375
12630
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
12376
|
-
const dims = size === "md" ? {
|
|
12631
|
+
const dims = size === "md" ? {
|
|
12632
|
+
padX: 16,
|
|
12633
|
+
gap: 12,
|
|
12634
|
+
icon: 20,
|
|
12635
|
+
minW: 104,
|
|
12636
|
+
fieldMinW: 260,
|
|
12637
|
+
fontSize: 14,
|
|
12638
|
+
lineHeight: 24,
|
|
12639
|
+
radius: 6
|
|
12640
|
+
} : {
|
|
12641
|
+
padX: 12,
|
|
12642
|
+
gap: 8,
|
|
12643
|
+
icon: 16,
|
|
12644
|
+
minW: 80,
|
|
12645
|
+
fieldMinW: 216,
|
|
12646
|
+
fontSize: 12,
|
|
12647
|
+
lineHeight: 20,
|
|
12648
|
+
radius: 4
|
|
12649
|
+
};
|
|
12377
12650
|
const select = (r) => {
|
|
12378
12651
|
setPendingStart(null);
|
|
12379
12652
|
onValueChange?.(r);
|
|
@@ -12399,11 +12672,12 @@ function SDateRangePicker({
|
|
|
12399
12672
|
focused: open,
|
|
12400
12673
|
errorMessage: ruleError !== "" ? ruleError : errorMessage,
|
|
12401
12674
|
width,
|
|
12675
|
+
minWidth: dims.fieldMinW,
|
|
12402
12676
|
disabled,
|
|
12403
12677
|
className,
|
|
12404
12678
|
style,
|
|
12405
12679
|
children: /* @__PURE__ */ jsxs(
|
|
12406
|
-
|
|
12680
|
+
RPopover9.Root,
|
|
12407
12681
|
{
|
|
12408
12682
|
open,
|
|
12409
12683
|
onOpenChange: (o) => {
|
|
@@ -12412,7 +12686,7 @@ function SDateRangePicker({
|
|
|
12412
12686
|
if (!o) setPendingStart(null);
|
|
12413
12687
|
},
|
|
12414
12688
|
children: [
|
|
12415
|
-
/* @__PURE__ */ jsx(
|
|
12689
|
+
/* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
12416
12690
|
"button",
|
|
12417
12691
|
{
|
|
12418
12692
|
type: "button",
|
|
@@ -12453,13 +12727,16 @@ function SDateRangePicker({
|
|
|
12453
12727
|
]
|
|
12454
12728
|
}
|
|
12455
12729
|
) }),
|
|
12456
|
-
/* @__PURE__ */ jsx(
|
|
12457
|
-
|
|
12730
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
12731
|
+
RPopover9.Content,
|
|
12458
12732
|
{
|
|
12459
12733
|
side: "bottom",
|
|
12460
12734
|
align: "start",
|
|
12461
12735
|
sideOffset: 4,
|
|
12462
|
-
className: cn(
|
|
12736
|
+
className: cn(
|
|
12737
|
+
"z-50 max-w-[var(--radix-popover-content-available-width)]",
|
|
12738
|
+
FLOATING_SLIDE_ANIM
|
|
12739
|
+
),
|
|
12463
12740
|
children: /* @__PURE__ */ jsx(
|
|
12464
12741
|
RangeCalendar,
|
|
12465
12742
|
{
|
|
@@ -13447,7 +13724,7 @@ function SRadioButton({
|
|
|
13447
13724
|
disabled: od,
|
|
13448
13725
|
onClick: () => !od && !selected && onValueChange?.(o.value),
|
|
13449
13726
|
className: cn(
|
|
13450
|
-
"relative box-border inline-flex items-center justify-center whitespace-nowrap border border-solid text-[12px] font-medium leading-[20px] transition-colors",
|
|
13727
|
+
"relative box-border grow inline-flex items-center justify-center whitespace-nowrap border border-solid text-[12px] font-medium leading-[20px] transition-colors",
|
|
13451
13728
|
i === 0 ? "rounded-l-[var(--cmp-radioButton-radius)]" : "-ml-px",
|
|
13452
13729
|
i === options.length - 1 ? "rounded-r-[var(--cmp-radioButton-radius)]" : "",
|
|
13453
13730
|
selected ? "z-10" : "",
|
|
@@ -13469,12 +13746,1236 @@ function SRadioButton({
|
|
|
13469
13746
|
}
|
|
13470
13747
|
);
|
|
13471
13748
|
}
|
|
13472
|
-
var
|
|
13473
|
-
|
|
13749
|
+
var CHIPFILTER_LISTBOX_WIDTH = 240;
|
|
13750
|
+
var CHIPFILTER_DATE_PRESET_LISTBOX_WIDTH = 246;
|
|
13751
|
+
var CHIPFILTER = {
|
|
13752
|
+
barBg: "var(--cmp-chipFilter-bar-bg)",
|
|
13753
|
+
barBorder: "var(--cmp-chipFilter-bar-border)",
|
|
13754
|
+
barPaddingX: "var(--cmp-chipFilter-bar-paddingX)",
|
|
13755
|
+
barPaddingY: "var(--cmp-chipFilter-bar-paddingY)",
|
|
13756
|
+
barGap: "var(--cmp-chipFilter-bar-gap)",
|
|
13757
|
+
dividerHeight: "var(--cmp-chipFilter-divider-height)",
|
|
13758
|
+
chipHeight: "var(--cmp-chipFilter-chip-height)",
|
|
13759
|
+
chipRadius: "var(--cmp-chipFilter-chip-radius)",
|
|
13760
|
+
chipGap: "var(--cmp-chipFilter-chip-gap)",
|
|
13761
|
+
chipDefaultBg: "var(--cmp-chipFilter-chip-default-bg)",
|
|
13762
|
+
chipDefaultBorder: "var(--cmp-chipFilter-chip-default-border)",
|
|
13763
|
+
chipDefaultText: "var(--cmp-chipFilter-chip-default-text)",
|
|
13764
|
+
chipActiveBorder: "var(--cmp-chipFilter-chip-active-border)",
|
|
13765
|
+
chipWarningBorder: "var(--cmp-chipFilter-chip-warning-border)",
|
|
13766
|
+
chipAppliedBg: "var(--cmp-chipFilter-chip-applied-bg)",
|
|
13767
|
+
chipAppliedBorder: "var(--cmp-chipFilter-chip-applied-border)",
|
|
13768
|
+
chipAppliedLabel: "var(--cmp-chipFilter-chip-applied-text-label)",
|
|
13769
|
+
chipAppliedValue: "var(--color-brilliantblue-80)",
|
|
13770
|
+
chipDisabledBg: "var(--cmp-chipFilter-chip-disabled-bg)",
|
|
13771
|
+
chipDisabledBorder: "var(--cmp-chipFilter-chip-disabled-border)",
|
|
13772
|
+
chipDisabledText: "var(--cmp-chipFilter-chip-disabled-text)",
|
|
13773
|
+
addBorder: "var(--cmp-chipFilter-addButton-border-default)",
|
|
13774
|
+
addBorderDisabled: "var(--cmp-chipFilter-addButton-border-disabled)",
|
|
13775
|
+
addText: "var(--cmp-chipFilter-addButton-text-default)",
|
|
13776
|
+
addTextDisabled: "var(--cmp-chipFilter-addButton-text-disabled)",
|
|
13777
|
+
listboxBg: "var(--cmp-chipFilter-listbox-bg)",
|
|
13778
|
+
listboxBorder: "var(--cmp-chipFilter-listbox-border-color)",
|
|
13779
|
+
listboxRadius: "var(--cmp-chipFilter-listbox-radius)",
|
|
13780
|
+
listboxLabel: "var(--cmp-chipFilter-listbox-top-label-color)",
|
|
13781
|
+
listboxBottomDividerHeight: "var(--cmp-chipFilter-listbox-bottom-divider-height)",
|
|
13782
|
+
itemPaddingLeft: "var(--cmp-chipFilter-item-paddingLeft)",
|
|
13783
|
+
itemPaddingRight: "var(--cmp-chipFilter-item-paddingRight)",
|
|
13784
|
+
itemPaddingY: "var(--cmp-chipFilter-item-paddingY)",
|
|
13785
|
+
itemMultiPaddingX: "var(--cmp-chipFilter-item-multi-paddingX)",
|
|
13786
|
+
itemTextDefault: "var(--cmp-chipFilter-item-text-default)",
|
|
13787
|
+
itemTextSelected: "var(--cmp-chipFilter-item-text-selected)"
|
|
13788
|
+
};
|
|
13789
|
+
var isKeywordValue = (value) => typeof value === "object" && value != null && !Array.isArray(value) && "keywords" in value;
|
|
13790
|
+
var keywordEntries = (value) => {
|
|
13791
|
+
if (isKeywordValue(value)) return value.keywords;
|
|
13792
|
+
if (Array.isArray(value)) {
|
|
13793
|
+
return value.filter((v) => typeof v === "string");
|
|
13794
|
+
}
|
|
13795
|
+
return [];
|
|
13796
|
+
};
|
|
13797
|
+
var isEmptyValue = (value) => {
|
|
13798
|
+
if (value == null) return true;
|
|
13799
|
+
if (Array.isArray(value)) return value.length === 0 || value.every((v) => v == null || v === "");
|
|
13800
|
+
if (isKeywordValue(value)) return value.keywords.length === 0;
|
|
13801
|
+
return value === "";
|
|
13802
|
+
};
|
|
13803
|
+
var normalizeValues = (value) => value ?? {};
|
|
13804
|
+
var toArrayValue = (value) => Array.isArray(value) ? value.filter(
|
|
13805
|
+
(v) => typeof v === "string" || typeof v === "number"
|
|
13806
|
+
) : [];
|
|
13807
|
+
var todayIso = () => {
|
|
13808
|
+
const d = /* @__PURE__ */ new Date();
|
|
13809
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
13810
|
+
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
13811
|
+
};
|
|
13812
|
+
var isInlineDateField = (field) => field.type === "date" && field.radioButton === true && (field.presets?.length ?? 0) > 0;
|
|
13813
|
+
var resolveFieldDefault = (field) => {
|
|
13814
|
+
if (field.defaultValue !== void 0) return field.defaultValue;
|
|
13815
|
+
if (isInlineDateField(field)) return todayIso();
|
|
13816
|
+
if (!field.required) return void 0;
|
|
13817
|
+
if (field.type === "single") return field.options?.[0]?.value;
|
|
13818
|
+
if (field.type === "date") return todayIso();
|
|
13819
|
+
return void 0;
|
|
13820
|
+
};
|
|
13821
|
+
var valuesEqual = (a, b) => {
|
|
13822
|
+
if (isKeywordValue(a) || isKeywordValue(b)) {
|
|
13823
|
+
return isKeywordValue(a) && isKeywordValue(b) && a.mode === b.mode && valuesEqual(a.keywords, b.keywords);
|
|
13824
|
+
}
|
|
13825
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
13826
|
+
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((v, i) => v === b[i]);
|
|
13827
|
+
}
|
|
13828
|
+
return a === b;
|
|
13829
|
+
};
|
|
13830
|
+
var valuesMapEqual = (a, b) => {
|
|
13831
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)]);
|
|
13832
|
+
for (const key of keys) {
|
|
13833
|
+
if (!valuesEqual(a[key], b[key])) return false;
|
|
13834
|
+
}
|
|
13835
|
+
return true;
|
|
13836
|
+
};
|
|
13837
|
+
var isAtDefaultValue = (field, value) => {
|
|
13838
|
+
const def = resolveFieldDefault(field);
|
|
13839
|
+
return def !== void 0 && valuesEqual(value, def);
|
|
13840
|
+
};
|
|
13841
|
+
var isInlineField = (field) => isInlineDateField(field) || field.type === "custom";
|
|
13842
|
+
var isGroupedFields = (fields) => fields.length > 0 && "fields" in fields[0];
|
|
13843
|
+
var isGroupSatisfied = (group, values) => {
|
|
13844
|
+
if (!group.rule) return true;
|
|
13845
|
+
const keys = group.fields.map((f) => f.key);
|
|
13846
|
+
if (group.rule.type === "requireKey") return !isEmptyValue(values[group.rule.key]);
|
|
13847
|
+
if (group.rule.type === "requireAll") return keys.every((k) => !isEmptyValue(values[k]));
|
|
13848
|
+
if (group.rule.type === "requireAny") return keys.some((k) => !isEmptyValue(values[k]));
|
|
13849
|
+
return true;
|
|
13850
|
+
};
|
|
13851
|
+
var koreanParticle = (word, consonant, vowel) => {
|
|
13852
|
+
const code = word.charCodeAt(word.length - 1);
|
|
13853
|
+
if (code < 44032 || code > 55203) return consonant;
|
|
13854
|
+
return (code - 44032) % 28 === 0 ? vowel : consonant;
|
|
13855
|
+
};
|
|
13856
|
+
var defaultGroupTooltipMessage = (rule, fields) => {
|
|
13857
|
+
if (rule.type === "requireAll") return "\uD56D\uBAA9\uC744 \uBAA8\uB450 \uC120\uD0DD\uD574 \uC8FC\uC138\uC694.";
|
|
13858
|
+
if (rule.type === "requireAny") {
|
|
13859
|
+
const name = rule.dataGroupName;
|
|
13860
|
+
if (!name) return "\uCD5C\uC18C 1\uAC1C\uC758 \uD544\uD130\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694.";
|
|
13861
|
+
return `\uCD5C\uC18C 1\uAC1C\uC758 ${name}${koreanParticle(name, "\uC744", "\uB97C")} \uC120\uD0DD\uD574\uC8FC\uC138\uC694.`;
|
|
13862
|
+
}
|
|
13863
|
+
const label = fields.find((f) => f.key === rule.key)?.label ?? "\uD56D\uBAA9";
|
|
13864
|
+
return `${label}${koreanParticle(label, "\uC744", "\uB97C")} \uC120\uD0DD\uD574 \uC8FC\uC138\uC694.`;
|
|
13865
|
+
};
|
|
13866
|
+
var matchPresetId = (presets, value) => {
|
|
13867
|
+
if (isEmptyValue(value)) return null;
|
|
13868
|
+
for (const preset of presets) {
|
|
13869
|
+
if (preset.custom || !preset.resolve) continue;
|
|
13870
|
+
const resolved = preset.resolve();
|
|
13871
|
+
if (Array.isArray(resolved) && Array.isArray(value)) {
|
|
13872
|
+
if (resolved[0] === value[0] && resolved[1] === value[1]) return preset.value;
|
|
13873
|
+
} else if (!Array.isArray(resolved) && !Array.isArray(value) && resolved === value) {
|
|
13874
|
+
return preset.value;
|
|
13875
|
+
}
|
|
13876
|
+
}
|
|
13877
|
+
return presets.find((preset) => preset.custom)?.value ?? null;
|
|
13878
|
+
};
|
|
13879
|
+
var optionLabel = (field, value) => field.options?.find((option) => option.value === value)?.label ?? String(value);
|
|
13880
|
+
var formatValueList = (labels) => {
|
|
13881
|
+
if (labels.length <= 1) return labels[0] ?? "";
|
|
13882
|
+
return `${labels[0]} \uC678 ${labels.length - 1}\uAC1C`;
|
|
13883
|
+
};
|
|
13884
|
+
var displayValue = (field, value) => {
|
|
13885
|
+
if (isEmptyValue(value)) return "";
|
|
13886
|
+
if (field.type === "multi")
|
|
13887
|
+
return formatValueList(toArrayValue(value).map((v) => optionLabel(field, v)));
|
|
13888
|
+
if (field.type === "single") return optionLabel(field, value);
|
|
13889
|
+
if (field.type === "date")
|
|
13890
|
+
return Array.isArray(value) ? `${value[0]} ~ ${value[1]}` : String(value);
|
|
13891
|
+
if (field.type === "keyword") return formatValueList(keywordEntries(value));
|
|
13892
|
+
return String(value);
|
|
13893
|
+
};
|
|
13894
|
+
var chipDisplayValue = (field, value) => {
|
|
13895
|
+
const text = displayValue(field, value);
|
|
13896
|
+
if (field.type !== "date" || isEmptyValue(value)) return text;
|
|
13897
|
+
const presets = field.presets ?? [];
|
|
13898
|
+
if (presets.length === 0) return text;
|
|
13899
|
+
const preset = presets.find((p) => p.value === matchPresetId(presets, value));
|
|
13900
|
+
return preset && !preset.custom ? `${preset.label}(${text})` : text;
|
|
13901
|
+
};
|
|
13902
|
+
var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
|
|
13903
|
+
fields: fieldsProp = [],
|
|
13904
|
+
value,
|
|
13474
13905
|
onValueChange,
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13906
|
+
onFilterChange,
|
|
13907
|
+
onSearch,
|
|
13908
|
+
activeKeys,
|
|
13909
|
+
onActiveKeysChange,
|
|
13910
|
+
onReset,
|
|
13911
|
+
onAddFilter,
|
|
13912
|
+
label = "\uAC80\uC0C9 \uD544\uD130",
|
|
13913
|
+
showLabel = false,
|
|
13914
|
+
showAddButton = true,
|
|
13915
|
+
showReset = true,
|
|
13916
|
+
disabled = false,
|
|
13917
|
+
className,
|
|
13918
|
+
style
|
|
13919
|
+
}, ref) {
|
|
13920
|
+
const usingGroupedFields = isGroupedFields(fieldsProp);
|
|
13921
|
+
const groups = useMemo(
|
|
13922
|
+
() => usingGroupedFields ? fieldsProp : [{ fields: fieldsProp }],
|
|
13923
|
+
[usingGroupedFields, fieldsProp]
|
|
13924
|
+
);
|
|
13925
|
+
const fields = useMemo(() => groups.flatMap((group) => group.fields), [groups]);
|
|
13926
|
+
const values = normalizeValues(value);
|
|
13927
|
+
const portalContainer = usePortalContainer();
|
|
13928
|
+
const [internalActiveKeys, setInternalActiveKeys] = useState(
|
|
13929
|
+
() => fields.filter((field) => field.defaultActive !== false).map((field) => field.key)
|
|
13930
|
+
);
|
|
13931
|
+
const [openKey, setOpenKey] = useState(null);
|
|
13932
|
+
const [addOpen, setAddOpen] = useState(false);
|
|
13933
|
+
const triggerRefs = useRef(/* @__PURE__ */ new Map());
|
|
13934
|
+
const initializedDefaultsRef = useRef(/* @__PURE__ */ new Set());
|
|
13935
|
+
const prevOpenKeyRef = useRef(null);
|
|
13936
|
+
const valuesRef = useRef(values);
|
|
13937
|
+
valuesRef.current = values;
|
|
13938
|
+
const lastSearchedValuesRef = useRef(values);
|
|
13939
|
+
const invalidGroups = useMemo(() => {
|
|
13940
|
+
const invalid = /* @__PURE__ */ new Set();
|
|
13941
|
+
groups.forEach((group, groupIndex) => {
|
|
13942
|
+
if (!isGroupSatisfied(group, values)) invalid.add(groupIndex);
|
|
13943
|
+
});
|
|
13944
|
+
return invalid;
|
|
13945
|
+
}, [groups, values]);
|
|
13946
|
+
const isGroupsValid = useCallback(
|
|
13947
|
+
(current) => groups.every((group) => isGroupSatisfied(group, current)),
|
|
13948
|
+
[groups]
|
|
13949
|
+
);
|
|
13950
|
+
const runSearch = useCallback(
|
|
13951
|
+
(next) => {
|
|
13952
|
+
if (valuesMapEqual(lastSearchedValuesRef.current, next)) return;
|
|
13953
|
+
if (!isGroupsValid(next)) return;
|
|
13954
|
+
lastSearchedValuesRef.current = next;
|
|
13955
|
+
onSearch?.(next);
|
|
13956
|
+
},
|
|
13957
|
+
[isGroupsValid, onSearch]
|
|
13958
|
+
);
|
|
13959
|
+
useEffect(() => {
|
|
13960
|
+
const prevKey = prevOpenKeyRef.current;
|
|
13961
|
+
if (prevKey != null && prevKey !== openKey) {
|
|
13962
|
+
runSearch(valuesRef.current);
|
|
13963
|
+
}
|
|
13964
|
+
prevOpenKeyRef.current = openKey;
|
|
13965
|
+
}, [openKey, runSearch]);
|
|
13966
|
+
useEffect(() => {
|
|
13967
|
+
if (activeKeys) return;
|
|
13968
|
+
setInternalActiveKeys((current) => {
|
|
13969
|
+
const known = new Set(fields.map((field) => field.key));
|
|
13970
|
+
const kept = current.filter((key) => known.has(key));
|
|
13971
|
+
const additions = fields.filter((field) => field.defaultActive !== false && !kept.includes(field.key)).map((field) => field.key);
|
|
13972
|
+
return [...kept, ...additions];
|
|
13973
|
+
});
|
|
13974
|
+
}, [activeKeys, fields]);
|
|
13975
|
+
useEffect(() => {
|
|
13976
|
+
const patch = {};
|
|
13977
|
+
let changed = false;
|
|
13978
|
+
fields.forEach((field) => {
|
|
13979
|
+
if (initializedDefaultsRef.current.has(field.key)) return;
|
|
13980
|
+
if (!isEmptyValue(values[field.key])) {
|
|
13981
|
+
initializedDefaultsRef.current.add(field.key);
|
|
13982
|
+
return;
|
|
13983
|
+
}
|
|
13984
|
+
const def = resolveFieldDefault(field);
|
|
13985
|
+
if (def === void 0) return;
|
|
13986
|
+
patch[field.key] = def;
|
|
13987
|
+
initializedDefaultsRef.current.add(field.key);
|
|
13988
|
+
changed = true;
|
|
13989
|
+
});
|
|
13990
|
+
if (changed) onValueChange?.({ ...values, ...patch });
|
|
13991
|
+
}, [fields, values, onValueChange]);
|
|
13992
|
+
const resolvedActiveKeys = activeKeys ?? internalActiveKeys;
|
|
13993
|
+
const activeFields = fields.filter((field) => resolvedActiveKeys.includes(field.key));
|
|
13994
|
+
const inactiveFields = fields.filter((field) => !resolvedActiveKeys.includes(field.key));
|
|
13995
|
+
const groupIndexByKey = /* @__PURE__ */ new Map();
|
|
13996
|
+
groups.forEach((group, groupIndex) => {
|
|
13997
|
+
group.fields.forEach((field) => groupIndexByKey.set(field.key, groupIndex));
|
|
13998
|
+
});
|
|
13999
|
+
const hasValue = fields.some((field) => !isEmptyValue(values[field.key]));
|
|
14000
|
+
const hasRightActions = showAddButton || showReset;
|
|
14001
|
+
const currentOpenField = fields.find((field) => field.key === openKey);
|
|
14002
|
+
const editorPopoverStyle = useMemo(() => {
|
|
14003
|
+
if (currentOpenField?.type === "keyword") {
|
|
14004
|
+
return { width: CHIPFILTER_LISTBOX_WIDTH };
|
|
14005
|
+
}
|
|
14006
|
+
if (currentOpenField?.type === "date" && (currentOpenField.presets?.length ?? 0) > 0) {
|
|
14007
|
+
return { width: CHIPFILTER_DATE_PRESET_LISTBOX_WIDTH };
|
|
14008
|
+
}
|
|
14009
|
+
return { width: CHIPFILTER_LISTBOX_WIDTH };
|
|
14010
|
+
}, [currentOpenField?.type, currentOpenField?.presets?.length]);
|
|
14011
|
+
const setActive = (next) => {
|
|
14012
|
+
if (!activeKeys) setInternalActiveKeys(next);
|
|
14013
|
+
onActiveKeysChange?.(next);
|
|
14014
|
+
};
|
|
14015
|
+
const emitValue = (key, nextValue) => {
|
|
14016
|
+
const next = { ...values, [key]: nextValue };
|
|
14017
|
+
onValueChange?.(next);
|
|
14018
|
+
onFilterChange?.({ key, value: nextValue, values: next });
|
|
14019
|
+
return next;
|
|
14020
|
+
};
|
|
14021
|
+
const emitValueAndSearch = (key, nextValue) => {
|
|
14022
|
+
runSearch(emitValue(key, nextValue));
|
|
14023
|
+
};
|
|
14024
|
+
const clearValue = (key) => {
|
|
14025
|
+
const field = fields.find((f) => f.key === key);
|
|
14026
|
+
const def = field ? resolveFieldDefault(field) : void 0;
|
|
14027
|
+
runSearch(emitValue(key, def !== void 0 ? def : null));
|
|
14028
|
+
};
|
|
14029
|
+
const reset = useCallback(() => {
|
|
14030
|
+
const next = fields.reduce((acc, field) => {
|
|
14031
|
+
const def = resolveFieldDefault(field);
|
|
14032
|
+
acc[field.key] = def !== void 0 ? def : null;
|
|
14033
|
+
return acc;
|
|
14034
|
+
}, {});
|
|
14035
|
+
onValueChange?.(next);
|
|
14036
|
+
runSearch(next);
|
|
14037
|
+
onReset?.();
|
|
14038
|
+
}, [fields, onReset, onValueChange, runSearch]);
|
|
14039
|
+
const open = useCallback(
|
|
14040
|
+
(key) => {
|
|
14041
|
+
const field = fields.find((f) => f.key === key);
|
|
14042
|
+
if (!field || isInlineField(field)) return;
|
|
14043
|
+
setOpenKey(key);
|
|
14044
|
+
},
|
|
14045
|
+
[fields]
|
|
14046
|
+
);
|
|
14047
|
+
const validate = useCallback(() => invalidGroups.size === 0, [invalidGroups]);
|
|
14048
|
+
useImperativeHandle(ref, () => ({ open, reset, validate }), [open, reset, validate]);
|
|
14049
|
+
const addField = (key) => {
|
|
14050
|
+
const next = [...resolvedActiveKeys, key];
|
|
14051
|
+
setActive(next);
|
|
14052
|
+
onAddFilter?.(key);
|
|
14053
|
+
setAddOpen(false);
|
|
14054
|
+
const field = fields.find((f) => f.key === key);
|
|
14055
|
+
if (field && !isInlineField(field)) requestAnimationFrame(() => setOpenKey(key));
|
|
14056
|
+
};
|
|
14057
|
+
const rootStyle = useMemo(
|
|
14058
|
+
() => ({
|
|
14059
|
+
"--chipfilter-bar-bg": CHIPFILTER.barBg,
|
|
14060
|
+
"--chipfilter-bar-border": CHIPFILTER.barBorder,
|
|
14061
|
+
"--chipfilter-bar-padding-x": CHIPFILTER.barPaddingX,
|
|
14062
|
+
"--chipfilter-bar-padding-y": CHIPFILTER.barPaddingY,
|
|
14063
|
+
"--chipfilter-bar-gap": CHIPFILTER.barGap,
|
|
14064
|
+
"--chipfilter-divider-height": CHIPFILTER.dividerHeight,
|
|
14065
|
+
...style
|
|
14066
|
+
}),
|
|
14067
|
+
[style]
|
|
14068
|
+
);
|
|
14069
|
+
return /* @__PURE__ */ jsxs(
|
|
14070
|
+
"div",
|
|
14071
|
+
{
|
|
14072
|
+
className: cn(
|
|
14073
|
+
"flex w-full items-start gap-[var(--chipfilter-bar-gap)] border-b border-solid bg-[var(--chipfilter-bar-bg)] px-[var(--chipfilter-bar-padding-x)] py-[var(--chipfilter-bar-padding-y)]",
|
|
14074
|
+
className
|
|
14075
|
+
),
|
|
14076
|
+
style: { ...rootStyle, borderColor: "var(--chipfilter-bar-border)" },
|
|
14077
|
+
children: [
|
|
14078
|
+
showLabel && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14079
|
+
/* @__PURE__ */ jsx(STag, { className: "shrink-0", shape: "square", size: "sm", color: "darkblue", label }),
|
|
14080
|
+
/* @__PURE__ */ jsx(Divider, { top: true })
|
|
14081
|
+
] }),
|
|
14082
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-[var(--cmp-chipFilter-chip-group)]", children: [
|
|
14083
|
+
(() => {
|
|
14084
|
+
const nodes = [];
|
|
14085
|
+
let runBuffer = [];
|
|
14086
|
+
let runGroupIndex = null;
|
|
14087
|
+
const flushRun = () => {
|
|
14088
|
+
if (runBuffer.length === 0) return;
|
|
14089
|
+
const group = runGroupIndex != null ? groups[runGroupIndex] : void 0;
|
|
14090
|
+
const message = usingGroupedFields && group?.rule ? group.tooltipMessage ?? defaultGroupTooltipMessage(group.rule, group.fields) : void 0;
|
|
14091
|
+
if (message) {
|
|
14092
|
+
nodes.push(
|
|
14093
|
+
/* @__PURE__ */ jsx(
|
|
14094
|
+
GroupTooltip,
|
|
14095
|
+
{
|
|
14096
|
+
message,
|
|
14097
|
+
open: invalidGroups.has(runGroupIndex),
|
|
14098
|
+
children: runBuffer
|
|
14099
|
+
},
|
|
14100
|
+
`group-${runGroupIndex}`
|
|
14101
|
+
)
|
|
14102
|
+
);
|
|
14103
|
+
} else {
|
|
14104
|
+
nodes.push(...runBuffer);
|
|
14105
|
+
}
|
|
14106
|
+
runBuffer = [];
|
|
14107
|
+
};
|
|
14108
|
+
activeFields.forEach((field, index) => {
|
|
14109
|
+
const inline = isInlineField(field);
|
|
14110
|
+
const groupIndex = groupIndexByKey.get(field.key) ?? 0;
|
|
14111
|
+
const warning = field.warning || invalidGroups.has(groupIndex);
|
|
14112
|
+
const prevField = index > 0 ? activeFields[index - 1] : null;
|
|
14113
|
+
const prevGroupIndex = prevField ? groupIndexByKey.get(prevField.key) ?? 0 : null;
|
|
14114
|
+
const needsLeadingDivider = index === 0 ? false : inline || prevField != null && isInlineField(prevField) || groupIndex !== prevGroupIndex;
|
|
14115
|
+
if (groupIndex !== runGroupIndex) {
|
|
14116
|
+
flushRun();
|
|
14117
|
+
runGroupIndex = groupIndex;
|
|
14118
|
+
}
|
|
14119
|
+
const showClear = !isAtDefaultValue(field, values[field.key]);
|
|
14120
|
+
const node = isInlineDateField(field) ? /* @__PURE__ */ jsx(
|
|
14121
|
+
InlineDatePresetFilter,
|
|
14122
|
+
{
|
|
14123
|
+
field,
|
|
14124
|
+
value: values[field.key],
|
|
14125
|
+
disabled: disabled || field.disabled,
|
|
14126
|
+
warning,
|
|
14127
|
+
showClear,
|
|
14128
|
+
onValueChange: (next) => emitValueAndSearch(field.key, next),
|
|
14129
|
+
onClear: () => clearValue(field.key)
|
|
14130
|
+
},
|
|
14131
|
+
field.key
|
|
14132
|
+
) : field.type === "custom" ? /* @__PURE__ */ jsx(Fragment$1, { children: field.render?.({
|
|
14133
|
+
value: values[field.key],
|
|
14134
|
+
disabled: disabled || field.disabled,
|
|
14135
|
+
warning,
|
|
14136
|
+
onValueChange: (next) => emitValueAndSearch(field.key, next)
|
|
14137
|
+
}) }, field.key) : /* @__PURE__ */ jsx(
|
|
14138
|
+
FilterChip,
|
|
14139
|
+
{
|
|
14140
|
+
field,
|
|
14141
|
+
valueText: chipDisplayValue(field, values[field.key]),
|
|
14142
|
+
active: openKey === field.key,
|
|
14143
|
+
applied: !isEmptyValue(values[field.key]),
|
|
14144
|
+
disabled: disabled || field.disabled,
|
|
14145
|
+
warning,
|
|
14146
|
+
showClear,
|
|
14147
|
+
refCallback: (node2) => triggerRefs.current.set(field.key, node2),
|
|
14148
|
+
onOpen: () => setOpenKey(openKey === field.key ? null : field.key),
|
|
14149
|
+
onClear: () => clearValue(field.key)
|
|
14150
|
+
},
|
|
14151
|
+
field.key
|
|
14152
|
+
);
|
|
14153
|
+
runBuffer.push(
|
|
14154
|
+
needsLeadingDivider ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
14155
|
+
/* @__PURE__ */ jsx(Divider, { inset: true }),
|
|
14156
|
+
node
|
|
14157
|
+
] }, `${field.key}-wrap`) : node
|
|
14158
|
+
);
|
|
14159
|
+
});
|
|
14160
|
+
flushRun();
|
|
14161
|
+
return nodes;
|
|
14162
|
+
})(),
|
|
14163
|
+
(() => {
|
|
14164
|
+
const lastField = activeFields[activeFields.length - 1];
|
|
14165
|
+
const needsTrailingDivider = lastField != null && isInlineField(lastField) && !hasRightActions;
|
|
14166
|
+
return needsTrailingDivider ? /* @__PURE__ */ jsx(Divider, { inset: true }) : null;
|
|
14167
|
+
})(),
|
|
14168
|
+
hasRightActions && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14169
|
+
/* @__PURE__ */ jsx(Divider, { inset: true }),
|
|
14170
|
+
showAddButton && /* @__PURE__ */ jsxs(RPopover9.Root, { open: addOpen, onOpenChange: setAddOpen, children: [
|
|
14171
|
+
/* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
14172
|
+
"button",
|
|
14173
|
+
{
|
|
14174
|
+
type: "button",
|
|
14175
|
+
disabled: disabled || inactiveFields.length === 0,
|
|
14176
|
+
className: "inline-flex shrink-0 cursor-pointer items-center justify-center gap-[var(--cmp-chipFilter-addButton-gap)] whitespace-nowrap border border-solid bg-[var(--cmp-chipFilter-addButton-bg)] px-[var(--cmp-chipFilter-addButton-paddingX)] text-[12px] font-medium leading-[20px] outline-none disabled:cursor-not-allowed",
|
|
14177
|
+
style: {
|
|
14178
|
+
minHeight: "var(--cmp-chipFilter-addButton-height)" ,
|
|
14179
|
+
borderRadius: "var(--cmp-chipFilter-addButton-radius)" ,
|
|
14180
|
+
borderColor: disabled || inactiveFields.length === 0 ? CHIPFILTER.addBorderDisabled : CHIPFILTER.addBorder,
|
|
14181
|
+
color: disabled || inactiveFields.length === 0 ? CHIPFILTER.addTextDisabled : CHIPFILTER.addText
|
|
14182
|
+
},
|
|
14183
|
+
children: [
|
|
14184
|
+
/* @__PURE__ */ jsx(
|
|
14185
|
+
SIcon,
|
|
14186
|
+
{
|
|
14187
|
+
name: "add",
|
|
14188
|
+
size: 12,
|
|
14189
|
+
color: disabled || inactiveFields.length === 0 ? CHIPFILTER.addTextDisabled : CHIPFILTER.addText
|
|
14190
|
+
}
|
|
14191
|
+
),
|
|
14192
|
+
/* @__PURE__ */ jsx("span", { children: "\uD544\uD130 \uCD94\uAC00" })
|
|
14193
|
+
]
|
|
14194
|
+
}
|
|
14195
|
+
) }),
|
|
14196
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
14197
|
+
RPopover9.Content,
|
|
14198
|
+
{
|
|
14199
|
+
side: "bottom",
|
|
14200
|
+
align: "start",
|
|
14201
|
+
sideOffset: 4,
|
|
14202
|
+
className: cn("z-50 min-w-[180px]", FLOATING_SLIDE_ANIM),
|
|
14203
|
+
children: /* @__PURE__ */ jsx(ListBox, { children: inactiveFields.length > 0 ? inactiveFields.map((field) => /* @__PURE__ */ jsx(MenuItem, { onClick: () => addField(field.key), children: field.label }, field.key)) : /* @__PURE__ */ jsx(EmptyItem, { children: "\uCD94\uAC00\uD560 \uD544\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }) })
|
|
14204
|
+
}
|
|
14205
|
+
) })
|
|
14206
|
+
] }),
|
|
14207
|
+
showReset && /* @__PURE__ */ jsxs(
|
|
14208
|
+
"button",
|
|
14209
|
+
{
|
|
14210
|
+
type: "button",
|
|
14211
|
+
disabled: disabled || !hasValue,
|
|
14212
|
+
onClick: reset,
|
|
14213
|
+
className: cn(
|
|
14214
|
+
"inline-flex shrink-0 cursor-pointer items-center gap-[4px] border-none bg-transparent p-0 text-[12px] font-medium leading-[20px] disabled:cursor-not-allowed",
|
|
14215
|
+
// 부모 flex gap(6px)은 칩 사이 간격 기준이라, 필터 추가 버튼과의 12px 간격을 맞추려면
|
|
14216
|
+
// 부족한 만큼(12px - gap)을 추가로 띄운다. 필터 추가가 없을 땐 divider와 이미 12px이라 불필요.
|
|
14217
|
+
showAddButton && "ml-[calc(12px-var(--cmp-chipFilter-chip-group))]"
|
|
14218
|
+
),
|
|
14219
|
+
style: {
|
|
14220
|
+
color: disabled || !hasValue ? "var(--cmp-textLink-content-disabled)" : "var(--cmp-textLink-content-default)"
|
|
14221
|
+
},
|
|
14222
|
+
children: [
|
|
14223
|
+
/* @__PURE__ */ jsx(
|
|
14224
|
+
SIcon,
|
|
14225
|
+
{
|
|
14226
|
+
name: "reset",
|
|
14227
|
+
size: 16,
|
|
14228
|
+
color: disabled || !hasValue ? "var(--cmp-textLink-icon-disabled)" : "var(--cmp-textLink-icon-default)"
|
|
14229
|
+
}
|
|
14230
|
+
),
|
|
14231
|
+
/* @__PURE__ */ jsx("span", { children: "\uAC80\uC0C9 \uCD08\uAE30\uD654" })
|
|
14232
|
+
]
|
|
14233
|
+
}
|
|
14234
|
+
)
|
|
14235
|
+
] })
|
|
14236
|
+
] }),
|
|
14237
|
+
/* @__PURE__ */ jsxs(RPopover9.Root, { open: openKey != null, onOpenChange: (next) => !next && setOpenKey(null), children: [
|
|
14238
|
+
/* @__PURE__ */ jsx(
|
|
14239
|
+
RPopover9.Anchor,
|
|
14240
|
+
{
|
|
14241
|
+
virtualRef: {
|
|
14242
|
+
current: openKey ? triggerRefs.current.get(openKey) : null
|
|
14243
|
+
}
|
|
14244
|
+
}
|
|
14245
|
+
),
|
|
14246
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
14247
|
+
RPopover9.Content,
|
|
14248
|
+
{
|
|
14249
|
+
side: "bottom",
|
|
14250
|
+
align: "start",
|
|
14251
|
+
sideOffset: 4,
|
|
14252
|
+
onOpenAutoFocus: (event) => event.preventDefault(),
|
|
14253
|
+
className: cn("z-50", FLOATING_SLIDE_ANIM),
|
|
14254
|
+
style: editorPopoverStyle,
|
|
14255
|
+
children: currentOpenField && /* @__PURE__ */ jsx(
|
|
14256
|
+
EditorPanel,
|
|
14257
|
+
{
|
|
14258
|
+
field: currentOpenField,
|
|
14259
|
+
value: values[currentOpenField.key],
|
|
14260
|
+
disabled: disabled || currentOpenField.disabled,
|
|
14261
|
+
onValueChange: (next) => emitValue(currentOpenField.key, next),
|
|
14262
|
+
onClose: () => setOpenKey(null)
|
|
14263
|
+
}
|
|
14264
|
+
)
|
|
14265
|
+
}
|
|
14266
|
+
) })
|
|
14267
|
+
] })
|
|
14268
|
+
]
|
|
14269
|
+
}
|
|
14270
|
+
);
|
|
14271
|
+
});
|
|
14272
|
+
function Divider({ inset, top } = {}) {
|
|
14273
|
+
return /* @__PURE__ */ jsx(
|
|
14274
|
+
"span",
|
|
14275
|
+
{
|
|
14276
|
+
"aria-hidden": true,
|
|
14277
|
+
className: cn(
|
|
14278
|
+
"inline-flex w-px shrink-0 bg-[var(--chipfilter-bar-border)]",
|
|
14279
|
+
top ? "mt-[2px] self-start" : "my-auto",
|
|
14280
|
+
inset && "mx-[calc(12px-var(--cmp-chipFilter-chip-group))]"
|
|
14281
|
+
),
|
|
14282
|
+
style: { height: "var(--chipfilter-divider-height)" }
|
|
14283
|
+
}
|
|
14284
|
+
);
|
|
14285
|
+
}
|
|
14286
|
+
function GroupTooltip({
|
|
14287
|
+
message,
|
|
14288
|
+
open,
|
|
14289
|
+
children
|
|
14290
|
+
}) {
|
|
14291
|
+
return /* @__PURE__ */ jsx(STooltip2, { trigger: "none", open, placement: "top", tooltipType: "warning", message: [message], children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-[var(--cmp-chipFilter-chip-group)]", children }) });
|
|
14292
|
+
}
|
|
14293
|
+
function FilterChip({
|
|
14294
|
+
field,
|
|
14295
|
+
valueText,
|
|
14296
|
+
active,
|
|
14297
|
+
applied,
|
|
14298
|
+
disabled,
|
|
14299
|
+
warning,
|
|
14300
|
+
showClear,
|
|
14301
|
+
refCallback,
|
|
14302
|
+
onOpen,
|
|
14303
|
+
onClear
|
|
14304
|
+
}) {
|
|
14305
|
+
const border = disabled ? CHIPFILTER.chipDisabledBorder : warning ? CHIPFILTER.chipWarningBorder : applied ? active ? "var(--color-blue-strong)" : CHIPFILTER.chipAppliedBorder : active ? CHIPFILTER.chipActiveBorder : CHIPFILTER.chipDefaultBorder;
|
|
14306
|
+
const background = disabled ? CHIPFILTER.chipDisabledBg : applied ? CHIPFILTER.chipAppliedBg : CHIPFILTER.chipDefaultBg;
|
|
14307
|
+
const textColor = disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipDefaultText;
|
|
14308
|
+
return /* @__PURE__ */ jsxs(
|
|
14309
|
+
"button",
|
|
14310
|
+
{
|
|
14311
|
+
ref: refCallback,
|
|
14312
|
+
type: "button",
|
|
14313
|
+
disabled,
|
|
14314
|
+
"aria-expanded": active,
|
|
14315
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
14316
|
+
onClick: onOpen,
|
|
14317
|
+
className: "group/chip-filter inline-flex max-w-full shrink-0 cursor-pointer items-center justify-center whitespace-nowrap border border-solid px-[var(--cmp-chipFilter-chip-paddingX)] text-[12px] leading-[20px] outline-none disabled:cursor-not-allowed",
|
|
14318
|
+
style: {
|
|
14319
|
+
minHeight: CHIPFILTER.chipHeight,
|
|
14320
|
+
gap: CHIPFILTER.chipGap,
|
|
14321
|
+
borderRadius: CHIPFILTER.chipRadius,
|
|
14322
|
+
borderColor: border,
|
|
14323
|
+
background,
|
|
14324
|
+
color: textColor
|
|
14325
|
+
},
|
|
14326
|
+
children: [
|
|
14327
|
+
field.required && /* @__PURE__ */ jsx(
|
|
14328
|
+
SIcon,
|
|
14329
|
+
{
|
|
14330
|
+
name: "asterisk",
|
|
14331
|
+
size: 12,
|
|
14332
|
+
color: disabled ? CHIPFILTER.chipDisabledText : "var(--cmp-tag-darkblue-content)"
|
|
14333
|
+
}
|
|
14334
|
+
),
|
|
14335
|
+
applied ? /* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-0 items-center gap-[4px] truncate", children: [
|
|
14336
|
+
/* @__PURE__ */ jsx(
|
|
14337
|
+
"span",
|
|
14338
|
+
{
|
|
14339
|
+
className: "font-bold",
|
|
14340
|
+
style: { color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedLabel },
|
|
14341
|
+
children: field.label
|
|
14342
|
+
}
|
|
14343
|
+
),
|
|
14344
|
+
/* @__PURE__ */ jsx(
|
|
14345
|
+
"span",
|
|
14346
|
+
{
|
|
14347
|
+
style: { color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedLabel },
|
|
14348
|
+
children: ":"
|
|
14349
|
+
}
|
|
14350
|
+
),
|
|
14351
|
+
/* @__PURE__ */ jsx(
|
|
14352
|
+
"span",
|
|
14353
|
+
{
|
|
14354
|
+
className: "min-w-0 truncate font-bold",
|
|
14355
|
+
style: { color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipAppliedValue },
|
|
14356
|
+
children: valueText
|
|
14357
|
+
}
|
|
14358
|
+
)
|
|
14359
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14360
|
+
/* @__PURE__ */ jsx("span", { className: cn("min-w-0 truncate", active && "font-bold"), children: field.label }),
|
|
14361
|
+
/* @__PURE__ */ jsx(
|
|
14362
|
+
SIcon,
|
|
14363
|
+
{
|
|
14364
|
+
name: "caretDown",
|
|
14365
|
+
size: 12,
|
|
14366
|
+
color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.chipDefaultText
|
|
14367
|
+
}
|
|
14368
|
+
)
|
|
14369
|
+
] }),
|
|
14370
|
+
applied && !disabled && showClear && /* @__PURE__ */ jsx(
|
|
14371
|
+
"span",
|
|
14372
|
+
{
|
|
14373
|
+
role: "button",
|
|
14374
|
+
tabIndex: 0,
|
|
14375
|
+
"aria-label": `${field.label} \uD544\uD130 \uC9C0\uC6B0\uAE30`,
|
|
14376
|
+
className: "inline-flex size-[16px] items-center justify-center rounded-[var(--cmp-ghostButton-radius-sm)]",
|
|
14377
|
+
onClick: (event) => {
|
|
14378
|
+
event.preventDefault();
|
|
14379
|
+
event.stopPropagation();
|
|
14380
|
+
onClear();
|
|
14381
|
+
},
|
|
14382
|
+
onKeyDown: (event) => {
|
|
14383
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
14384
|
+
event.preventDefault();
|
|
14385
|
+
event.stopPropagation();
|
|
14386
|
+
onClear();
|
|
14387
|
+
},
|
|
14388
|
+
children: /* @__PURE__ */ jsx(SIcon, { name: "close", size: 12, color: "var(--cmp-ghostButton-default-content)" })
|
|
14389
|
+
}
|
|
14390
|
+
)
|
|
14391
|
+
]
|
|
14392
|
+
}
|
|
14393
|
+
);
|
|
14394
|
+
}
|
|
14395
|
+
function EditorPanel({
|
|
14396
|
+
field,
|
|
14397
|
+
value,
|
|
14398
|
+
disabled,
|
|
14399
|
+
onValueChange,
|
|
14400
|
+
onClose
|
|
14401
|
+
}) {
|
|
14402
|
+
const wrapsInPaddedTop = field.type === "date";
|
|
14403
|
+
const isMulti = field.type === "multi";
|
|
14404
|
+
const selectableValues = isMulti ? (field.options ?? []).filter((option) => !option.disabled).map((option) => option.value) : [];
|
|
14405
|
+
const selectedValues = isMulti ? toArrayValue(value) : [];
|
|
14406
|
+
const allSelected = isMulti && selectableValues.length > 0 && selectableValues.every((v) => selectedValues.includes(v));
|
|
14407
|
+
const toggleSelectAll = () => {
|
|
14408
|
+
onValueChange(
|
|
14409
|
+
allSelected ? selectedValues.filter((v) => !selectableValues.includes(v)) : [...selectedValues, ...selectableValues.filter((v) => !selectedValues.includes(v))]
|
|
14410
|
+
);
|
|
14411
|
+
};
|
|
14412
|
+
return /* @__PURE__ */ jsxs(ListBox, { children: [
|
|
14413
|
+
wrapsInPaddedTop ? /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[var(--cmp-chipFilter-listbox-top-gap)] px-[var(--cmp-chipFilter-listbox-top-paddingX)] py-[var(--cmp-chipFilter-listbox-top-paddingY)]", children: /* @__PURE__ */ jsx(
|
|
14414
|
+
FilterEditor,
|
|
14415
|
+
{
|
|
14416
|
+
field,
|
|
14417
|
+
value,
|
|
14418
|
+
disabled,
|
|
14419
|
+
onValueChange
|
|
14420
|
+
}
|
|
14421
|
+
) }) : /* @__PURE__ */ jsx(
|
|
14422
|
+
FilterEditor,
|
|
14423
|
+
{
|
|
14424
|
+
field,
|
|
14425
|
+
value,
|
|
14426
|
+
disabled,
|
|
14427
|
+
onValueChange
|
|
14428
|
+
}
|
|
14429
|
+
),
|
|
14430
|
+
/* @__PURE__ */ jsxs(
|
|
14431
|
+
"div",
|
|
14432
|
+
{
|
|
14433
|
+
className: "flex items-center justify-end gap-[var(--cmp-chipFilter-listbox-bottom-gap)] border-t border-solid px-[var(--cmp-chipFilter-listbox-bottom-paddingX)] py-[var(--cmp-chipFilter-listbox-bottom-paddingY)]",
|
|
14434
|
+
style: { borderColor: CHIPFILTER.listboxBorder },
|
|
14435
|
+
children: [
|
|
14436
|
+
isMulti && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14437
|
+
/* @__PURE__ */ jsx(
|
|
14438
|
+
STextLink,
|
|
14439
|
+
{
|
|
14440
|
+
size: "sm",
|
|
14441
|
+
label: allSelected ? "\uC120\uD0DD \uD574\uC81C" : "\uC804\uCCB4 \uC120\uD0DD",
|
|
14442
|
+
labelClass: "font-bold",
|
|
14443
|
+
disabled,
|
|
14444
|
+
onClick: toggleSelectAll,
|
|
14445
|
+
style: { color: "var(--sys-color-fg-secondary)" }
|
|
14446
|
+
}
|
|
14447
|
+
),
|
|
14448
|
+
/* @__PURE__ */ jsx(
|
|
14449
|
+
"span",
|
|
14450
|
+
{
|
|
14451
|
+
"aria-hidden": true,
|
|
14452
|
+
className: "inline-flex w-px shrink-0",
|
|
14453
|
+
style: {
|
|
14454
|
+
height: CHIPFILTER.listboxBottomDividerHeight,
|
|
14455
|
+
background: CHIPFILTER.listboxBorder
|
|
14456
|
+
}
|
|
14457
|
+
}
|
|
14458
|
+
)
|
|
14459
|
+
] }),
|
|
14460
|
+
/* @__PURE__ */ jsx(
|
|
14461
|
+
STextLink,
|
|
14462
|
+
{
|
|
14463
|
+
size: "sm",
|
|
14464
|
+
label: "\uAC80\uC0C9",
|
|
14465
|
+
labelClass: "font-bold",
|
|
14466
|
+
onClick: onClose,
|
|
14467
|
+
style: { color: CHIPFILTER.chipAppliedValue }
|
|
14468
|
+
}
|
|
14469
|
+
)
|
|
14470
|
+
]
|
|
14471
|
+
}
|
|
14472
|
+
)
|
|
14473
|
+
] });
|
|
14474
|
+
}
|
|
14475
|
+
function FilterEditor({
|
|
14476
|
+
field,
|
|
14477
|
+
value,
|
|
14478
|
+
disabled,
|
|
14479
|
+
onValueChange
|
|
14480
|
+
}) {
|
|
14481
|
+
if (field.type === "date") {
|
|
14482
|
+
return /* @__PURE__ */ jsx(
|
|
14483
|
+
DatePresetEditor,
|
|
14484
|
+
{
|
|
14485
|
+
field,
|
|
14486
|
+
value,
|
|
14487
|
+
disabled,
|
|
14488
|
+
onValueChange
|
|
14489
|
+
}
|
|
14490
|
+
);
|
|
14491
|
+
}
|
|
14492
|
+
if (field.type === "keyword") {
|
|
14493
|
+
return /* @__PURE__ */ jsx(
|
|
14494
|
+
KeywordEditor,
|
|
14495
|
+
{
|
|
14496
|
+
field,
|
|
14497
|
+
value: isKeywordValue(value) ? value : keywordEntries(value),
|
|
14498
|
+
disabled,
|
|
14499
|
+
onValueChange
|
|
14500
|
+
}
|
|
14501
|
+
);
|
|
14502
|
+
}
|
|
14503
|
+
return /* @__PURE__ */ jsx(
|
|
14504
|
+
OptionList,
|
|
14505
|
+
{
|
|
14506
|
+
field,
|
|
14507
|
+
value: field.type === "multi" ? toArrayValue(value) : value,
|
|
14508
|
+
multiple: field.type === "multi",
|
|
14509
|
+
disabled,
|
|
14510
|
+
onValueChange
|
|
14511
|
+
}
|
|
14512
|
+
);
|
|
14513
|
+
}
|
|
14514
|
+
function DatePresetEditor({
|
|
14515
|
+
field,
|
|
14516
|
+
value,
|
|
14517
|
+
disabled,
|
|
14518
|
+
onValueChange
|
|
14519
|
+
}) {
|
|
14520
|
+
const presets = field.presets ?? [];
|
|
14521
|
+
const [selectedId, setSelectedId] = useState(() => matchPresetId(presets, value));
|
|
14522
|
+
const syncedInitialValueRef = useRef(!isEmptyValue(value));
|
|
14523
|
+
useEffect(() => {
|
|
14524
|
+
if (syncedInitialValueRef.current || isEmptyValue(value)) return;
|
|
14525
|
+
syncedInitialValueRef.current = true;
|
|
14526
|
+
setSelectedId(matchPresetId(presets, value));
|
|
14527
|
+
}, [value, presets]);
|
|
14528
|
+
const selectedPreset = presets.find((preset) => preset.value === selectedId);
|
|
14529
|
+
const selectPreset = (preset) => {
|
|
14530
|
+
setSelectedId(preset.value);
|
|
14531
|
+
if (!preset.custom) onValueChange(preset.resolve ? preset.resolve() : null);
|
|
14532
|
+
};
|
|
14533
|
+
if (presets.length === 0) {
|
|
14534
|
+
return /* @__PURE__ */ jsx(
|
|
14535
|
+
SDatePicker,
|
|
14536
|
+
{
|
|
14537
|
+
value: typeof value === "string" ? value : null,
|
|
14538
|
+
onValueChange,
|
|
14539
|
+
selectable: field.selectable,
|
|
14540
|
+
disabled,
|
|
14541
|
+
placeholder: field.placeholder
|
|
14542
|
+
}
|
|
14543
|
+
);
|
|
14544
|
+
}
|
|
14545
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-[var(--cmp-chipFilter-listbox-top-gap)]", children: [
|
|
14546
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[8px]", children: presets.map((preset) => /* @__PURE__ */ jsx(
|
|
14547
|
+
SRadio,
|
|
14548
|
+
{
|
|
14549
|
+
val: preset.value,
|
|
14550
|
+
value: selectedId,
|
|
14551
|
+
label: preset.label,
|
|
14552
|
+
disabled,
|
|
14553
|
+
onValueChange: () => selectPreset(preset)
|
|
14554
|
+
},
|
|
14555
|
+
preset.value
|
|
14556
|
+
)) }),
|
|
14557
|
+
selectedPreset?.custom && /* @__PURE__ */ jsx(
|
|
14558
|
+
SDateRangePicker,
|
|
14559
|
+
{
|
|
14560
|
+
value: Array.isArray(value) && value.length === 2 ? value : null,
|
|
14561
|
+
onValueChange,
|
|
14562
|
+
selectable: field.selectable,
|
|
14563
|
+
maxRange: field.maxRange,
|
|
14564
|
+
disabled
|
|
14565
|
+
}
|
|
14566
|
+
)
|
|
14567
|
+
] });
|
|
14568
|
+
}
|
|
14569
|
+
function InlineDatePresetFilter({
|
|
14570
|
+
field,
|
|
14571
|
+
value,
|
|
14572
|
+
disabled,
|
|
14573
|
+
warning,
|
|
14574
|
+
showClear,
|
|
14575
|
+
onValueChange,
|
|
14576
|
+
onClear
|
|
14577
|
+
}) {
|
|
14578
|
+
const presets = (field.presets ?? []).filter((preset) => !preset.custom);
|
|
14579
|
+
const [selectedId, setSelectedId] = useState(() => matchPresetId(presets, value));
|
|
14580
|
+
const syncedInitialValueRef = useRef(!isEmptyValue(value));
|
|
14581
|
+
useEffect(() => {
|
|
14582
|
+
if (syncedInitialValueRef.current || isEmptyValue(value)) return;
|
|
14583
|
+
syncedInitialValueRef.current = true;
|
|
14584
|
+
setSelectedId(matchPresetId(presets, value));
|
|
14585
|
+
}, [value, presets]);
|
|
14586
|
+
const applied = !isEmptyValue(value);
|
|
14587
|
+
const rangeValue = Array.isArray(value) ? value : typeof value === "string" && value !== "" ? [value, value] : null;
|
|
14588
|
+
const [pickerOpen, setPickerOpen] = useState(false);
|
|
14589
|
+
const portalContainer = usePortalContainer();
|
|
14590
|
+
const selectPreset = (id) => {
|
|
14591
|
+
const preset = presets.find((p) => p.value === id);
|
|
14592
|
+
if (!preset) return;
|
|
14593
|
+
setSelectedId(preset.value);
|
|
14594
|
+
onValueChange(preset.resolve ? preset.resolve() : null);
|
|
14595
|
+
};
|
|
14596
|
+
const badge = applied && /* @__PURE__ */ jsxs(
|
|
14597
|
+
"span",
|
|
14598
|
+
{
|
|
14599
|
+
className: "inline-flex shrink-0 items-center gap-[4px] whitespace-nowrap border border-solid px-[var(--cmp-chipFilter-chip-paddingX)] text-[12px] leading-[20px]",
|
|
14600
|
+
style: {
|
|
14601
|
+
minHeight: CHIPFILTER.chipHeight,
|
|
14602
|
+
borderRadius: CHIPFILTER.chipRadius,
|
|
14603
|
+
borderColor: warning ? CHIPFILTER.chipWarningBorder : CHIPFILTER.chipAppliedBorder,
|
|
14604
|
+
background: CHIPFILTER.chipAppliedBg,
|
|
14605
|
+
color: CHIPFILTER.chipAppliedLabel,
|
|
14606
|
+
cursor: rangeValue ? "pointer" : void 0
|
|
14607
|
+
},
|
|
14608
|
+
children: [
|
|
14609
|
+
/* @__PURE__ */ jsxs("span", { className: "font-bold", children: [
|
|
14610
|
+
field.label,
|
|
14611
|
+
":"
|
|
14612
|
+
] }),
|
|
14613
|
+
/* @__PURE__ */ jsx("span", { className: "font-bold", style: { color: CHIPFILTER.chipAppliedValue }, children: displayValue(field, value) }),
|
|
14614
|
+
!disabled && showClear && /* @__PURE__ */ jsx(
|
|
14615
|
+
"span",
|
|
14616
|
+
{
|
|
14617
|
+
role: "button",
|
|
14618
|
+
tabIndex: 0,
|
|
14619
|
+
"aria-label": `${field.label} \uD544\uD130 \uC9C0\uC6B0\uAE30`,
|
|
14620
|
+
className: "inline-flex size-[16px] items-center justify-center rounded-[var(--cmp-ghostButton-radius-sm)]",
|
|
14621
|
+
onClick: (event) => {
|
|
14622
|
+
event.stopPropagation();
|
|
14623
|
+
onClear();
|
|
14624
|
+
},
|
|
14625
|
+
onKeyDown: (event) => {
|
|
14626
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
14627
|
+
event.preventDefault();
|
|
14628
|
+
event.stopPropagation();
|
|
14629
|
+
onClear();
|
|
14630
|
+
},
|
|
14631
|
+
children: /* @__PURE__ */ jsx(SIcon, { name: "close", size: 12, color: "var(--cmp-ghostButton-default-content)" })
|
|
14632
|
+
}
|
|
14633
|
+
)
|
|
14634
|
+
]
|
|
14635
|
+
}
|
|
14636
|
+
);
|
|
14637
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-[8px]", children: [
|
|
14638
|
+
/* @__PURE__ */ jsx(
|
|
14639
|
+
SRadioButton,
|
|
14640
|
+
{
|
|
14641
|
+
size: "xs",
|
|
14642
|
+
options: presets.map((preset) => ({ value: preset.value, label: preset.label })),
|
|
14643
|
+
value: selectedId,
|
|
14644
|
+
disabled,
|
|
14645
|
+
onValueChange: (next) => selectPreset(String(next))
|
|
14646
|
+
}
|
|
14647
|
+
),
|
|
14648
|
+
applied && (rangeValue ? (
|
|
14649
|
+
// 뱃지 모양은 그대로 두고, 눌렀을 때 캘린더가 열려 기간을 직접 다시 고를 수 있게 한다.
|
|
14650
|
+
// 직접 고르면 프리셋 선택은 해제된다.
|
|
14651
|
+
/* @__PURE__ */ jsxs(RPopover9.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
|
|
14652
|
+
/* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
14653
|
+
"button",
|
|
14654
|
+
{
|
|
14655
|
+
type: "button",
|
|
14656
|
+
disabled,
|
|
14657
|
+
className: "border-none bg-transparent p-0 outline-none disabled:cursor-not-allowed",
|
|
14658
|
+
children: badge
|
|
14659
|
+
}
|
|
14660
|
+
) }),
|
|
14661
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
14662
|
+
RPopover9.Content,
|
|
14663
|
+
{
|
|
14664
|
+
side: "bottom",
|
|
14665
|
+
align: "start",
|
|
14666
|
+
sideOffset: 4,
|
|
14667
|
+
className: cn("z-50", FLOATING_SLIDE_ANIM),
|
|
14668
|
+
children: /* @__PURE__ */ jsx(
|
|
14669
|
+
RangeCalendar,
|
|
14670
|
+
{
|
|
14671
|
+
value: rangeValue,
|
|
14672
|
+
selectable: field.selectable,
|
|
14673
|
+
maxRange: field.maxRange,
|
|
14674
|
+
onSelect: (range) => {
|
|
14675
|
+
setSelectedId(null);
|
|
14676
|
+
onValueChange(range);
|
|
14677
|
+
setPickerOpen(false);
|
|
14678
|
+
}
|
|
14679
|
+
}
|
|
14680
|
+
)
|
|
14681
|
+
}
|
|
14682
|
+
) })
|
|
14683
|
+
] })
|
|
14684
|
+
) : badge)
|
|
14685
|
+
] });
|
|
14686
|
+
}
|
|
14687
|
+
var MATCH_MODE_OPTIONS = [
|
|
14688
|
+
{ value: "contains", label: "\uD3EC\uD568" },
|
|
14689
|
+
{ value: "exact", label: "\uC77C\uCE58" }
|
|
14690
|
+
];
|
|
14691
|
+
var EXCLUDE_MATCH_MODE_OPTION = {
|
|
14692
|
+
value: "excludes",
|
|
14693
|
+
label: "\uBBF8\uD3EC\uD568"
|
|
14694
|
+
};
|
|
14695
|
+
function KeywordEditor({
|
|
14696
|
+
field,
|
|
14697
|
+
value,
|
|
14698
|
+
disabled,
|
|
14699
|
+
onValueChange
|
|
14700
|
+
}) {
|
|
14701
|
+
const entries3 = keywordEntries(value);
|
|
14702
|
+
const [draft, setDraft] = useState("");
|
|
14703
|
+
const [mode, setMode] = useState(
|
|
14704
|
+
isKeywordValue(value) ? value.mode : "contains"
|
|
14705
|
+
);
|
|
14706
|
+
const emit3 = (nextEntries) => {
|
|
14707
|
+
onValueChange(field.matchModes ? { keywords: nextEntries, mode } : nextEntries);
|
|
14708
|
+
};
|
|
14709
|
+
const addEntry = (raw) => {
|
|
14710
|
+
const next = raw.trim();
|
|
14711
|
+
if (next === "" || entries3.includes(next)) return;
|
|
14712
|
+
emit3([...entries3, next]);
|
|
14713
|
+
setDraft("");
|
|
14714
|
+
};
|
|
14715
|
+
const removeEntry = (entry) => {
|
|
14716
|
+
emit3(entries3.filter((e) => e !== entry));
|
|
14717
|
+
};
|
|
14718
|
+
const onKeyDown = (event) => {
|
|
14719
|
+
if (event.key === "Enter") {
|
|
14720
|
+
if (event.nativeEvent.isComposing) return;
|
|
14721
|
+
event.preventDefault();
|
|
14722
|
+
addEntry(draft);
|
|
14723
|
+
}
|
|
14724
|
+
};
|
|
14725
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14726
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-[var(--cmp-chipFilter-listbox-top-gap)] px-[var(--cmp-chipFilter-listbox-top-paddingX)] py-[var(--cmp-chipFilter-listbox-top-paddingY)]", children: [
|
|
14727
|
+
field.matchModes && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
14728
|
+
/* @__PURE__ */ jsx(
|
|
14729
|
+
"span",
|
|
14730
|
+
{
|
|
14731
|
+
className: "shrink-0 whitespace-nowrap text-[12px] font-medium leading-[20px]",
|
|
14732
|
+
style: { color: CHIPFILTER.listboxLabel },
|
|
14733
|
+
children: "\uAC80\uC0C9 \uC870\uAC74 :"
|
|
14734
|
+
}
|
|
14735
|
+
),
|
|
14736
|
+
/* @__PURE__ */ jsx(
|
|
14737
|
+
SRadioButton,
|
|
14738
|
+
{
|
|
14739
|
+
size: "xs",
|
|
14740
|
+
style: { width: 150 },
|
|
14741
|
+
options: field.excludeMode ? [...MATCH_MODE_OPTIONS, EXCLUDE_MATCH_MODE_OPTION] : MATCH_MODE_OPTIONS,
|
|
14742
|
+
value: mode,
|
|
14743
|
+
disabled,
|
|
14744
|
+
onValueChange: (next) => setMode(next)
|
|
14745
|
+
}
|
|
14746
|
+
)
|
|
14747
|
+
] }),
|
|
14748
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[6px] rounded-[4px] border border-solid border-[color:var(--sys-color-field-border-default)] bg-[var(--sys-color-field-bg-default)] px-[8px] py-[4px] focus-within:border-[color:var(--sys-color-field-border-focus)]", children: [
|
|
14749
|
+
/* @__PURE__ */ jsx(SIcon, { name: "search", size: 16, color: "var(--sys-color-field-icon-default)" }),
|
|
14750
|
+
/* @__PURE__ */ jsx(
|
|
14751
|
+
"input",
|
|
14752
|
+
{
|
|
14753
|
+
value: draft,
|
|
14754
|
+
disabled,
|
|
14755
|
+
placeholder: field.placeholder ?? "\uC785\uB825 \uD6C4 Enter\uB85C \uCD94\uAC00",
|
|
14756
|
+
onChange: (event) => setDraft(event.target.value),
|
|
14757
|
+
onKeyDown,
|
|
14758
|
+
className: "min-w-0 flex-1 border-none bg-transparent text-[12px] leading-[20px] text-[color:var(--sys-color-field-text-default)] outline-none placeholder:text-[color:var(--sys-color-field-text-placeholder)] disabled:cursor-not-allowed"
|
|
14759
|
+
}
|
|
14760
|
+
)
|
|
14761
|
+
] })
|
|
14762
|
+
] }),
|
|
14763
|
+
entries3.length > 0 && /* @__PURE__ */ jsx(
|
|
14764
|
+
"div",
|
|
14765
|
+
{
|
|
14766
|
+
className: "max-h-[220px] overflow-auto border-t border-solid py-[var(--cmp-chipFilter-listbox-list-paddingY)]",
|
|
14767
|
+
style: { borderColor: CHIPFILTER.listboxBorder },
|
|
14768
|
+
children: entries3.map((entry) => /* @__PURE__ */ jsx(
|
|
14769
|
+
KeywordEntryRow,
|
|
14770
|
+
{
|
|
14771
|
+
label: optionLabel(field, entry),
|
|
14772
|
+
disabled,
|
|
14773
|
+
onRemove: () => removeEntry(entry)
|
|
14774
|
+
},
|
|
14775
|
+
entry
|
|
14776
|
+
))
|
|
14777
|
+
}
|
|
14778
|
+
)
|
|
14779
|
+
] });
|
|
14780
|
+
}
|
|
14781
|
+
function KeywordEntryRow({
|
|
14782
|
+
label,
|
|
14783
|
+
disabled,
|
|
14784
|
+
onRemove
|
|
14785
|
+
}) {
|
|
14786
|
+
return /* @__PURE__ */ jsxs(
|
|
14787
|
+
"div",
|
|
14788
|
+
{
|
|
14789
|
+
className: "group flex w-full items-center justify-between gap-[8px] text-[12px] leading-[20px]",
|
|
14790
|
+
style: {
|
|
14791
|
+
paddingTop: CHIPFILTER.itemPaddingY,
|
|
14792
|
+
paddingBottom: CHIPFILTER.itemPaddingY,
|
|
14793
|
+
paddingLeft: CHIPFILTER.itemPaddingLeft,
|
|
14794
|
+
paddingRight: CHIPFILTER.itemPaddingRight,
|
|
14795
|
+
color: disabled ? CHIPFILTER.chipDisabledText : CHIPFILTER.itemTextDefault
|
|
14796
|
+
},
|
|
14797
|
+
children: [
|
|
14798
|
+
/* @__PURE__ */ jsx("span", { className: cn("min-w-0 truncate", !disabled && "group-hover:font-bold"), children: label }),
|
|
14799
|
+
!disabled && /* @__PURE__ */ jsx(
|
|
14800
|
+
"button",
|
|
14801
|
+
{
|
|
14802
|
+
type: "button",
|
|
14803
|
+
"aria-label": `${label} \uC0AD\uC81C`,
|
|
14804
|
+
className: "invisible inline-flex size-[16px] shrink-0 cursor-pointer items-center justify-center group-hover:visible",
|
|
14805
|
+
onClick: onRemove,
|
|
14806
|
+
children: /* @__PURE__ */ jsx(SIcon, { name: "close", size: 12, color: "var(--cmp-ghostButton-default-content)" })
|
|
14807
|
+
}
|
|
14808
|
+
)
|
|
14809
|
+
]
|
|
14810
|
+
}
|
|
14811
|
+
);
|
|
14812
|
+
}
|
|
14813
|
+
var OPTION_SEARCH_THRESHOLD = 11;
|
|
14814
|
+
function OptionList({
|
|
14815
|
+
field,
|
|
14816
|
+
value,
|
|
14817
|
+
multiple,
|
|
14818
|
+
disabled,
|
|
14819
|
+
onValueChange
|
|
14820
|
+
}) {
|
|
14821
|
+
const selected = multiple ? toArrayValue(value) : [];
|
|
14822
|
+
const singleValue = !multiple && (typeof value === "string" || typeof value === "number") ? value : null;
|
|
14823
|
+
const [search, setSearch] = useState("");
|
|
14824
|
+
const options = field.options ?? [];
|
|
14825
|
+
const showSearch = options.length >= OPTION_SEARCH_THRESHOLD;
|
|
14826
|
+
const filteredOptions = useMemo(() => {
|
|
14827
|
+
if (!showSearch || search.trim() === "") return options;
|
|
14828
|
+
const query = search.trim().toLowerCase();
|
|
14829
|
+
return options.filter((option) => option.label.toLowerCase().includes(query));
|
|
14830
|
+
}, [options, search, showSearch]);
|
|
14831
|
+
if (options.length === 0) return /* @__PURE__ */ jsx(EmptyItem, { children: "\uD45C\uC2DC\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." });
|
|
14832
|
+
return /* @__PURE__ */ jsxs(
|
|
14833
|
+
"div",
|
|
14834
|
+
{
|
|
14835
|
+
className: cn(
|
|
14836
|
+
"max-h-[240px] overflow-auto",
|
|
14837
|
+
!showSearch && "pt-[var(--cmp-chipFilter-listbox-list-paddingY)]",
|
|
14838
|
+
"pb-[var(--cmp-chipFilter-listbox-list-paddingY)]"
|
|
14839
|
+
),
|
|
14840
|
+
children: [
|
|
14841
|
+
showSearch && /* @__PURE__ */ jsx(
|
|
14842
|
+
"div",
|
|
14843
|
+
{
|
|
14844
|
+
className: "sticky top-0 z-[1] border-b border-solid px-[8px] pb-[4px] pt-[var(--cmp-chipFilter-listbox-list-paddingY)]",
|
|
14845
|
+
style: { background: CHIPFILTER.listboxBg, borderColor: CHIPFILTER.listboxBorder },
|
|
14846
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[6px] rounded-[4px] border border-solid border-[color:var(--sys-color-field-border-default)] bg-[var(--sys-color-field-bg-default)] px-[8px] py-[4px] focus-within:border-[color:var(--sys-color-field-border-focus)]", children: [
|
|
14847
|
+
/* @__PURE__ */ jsx(SIcon, { name: "search", size: 16, color: "var(--sys-color-field-icon-default)" }),
|
|
14848
|
+
/* @__PURE__ */ jsx(
|
|
14849
|
+
"input",
|
|
14850
|
+
{
|
|
14851
|
+
value: search,
|
|
14852
|
+
disabled,
|
|
14853
|
+
placeholder: "\uAC80\uC0C9",
|
|
14854
|
+
onChange: (event) => setSearch(event.target.value),
|
|
14855
|
+
className: "min-w-0 flex-1 border-none bg-transparent text-[12px] leading-[20px] text-[color:var(--sys-color-field-text-default)] outline-none placeholder:text-[color:var(--sys-color-field-text-placeholder)] disabled:cursor-not-allowed"
|
|
14856
|
+
}
|
|
14857
|
+
),
|
|
14858
|
+
search !== "" && !disabled && /* @__PURE__ */ jsx(
|
|
14859
|
+
SGhostButton,
|
|
14860
|
+
{
|
|
14861
|
+
icon: "close",
|
|
14862
|
+
size: "xxs",
|
|
14863
|
+
ariaLabel: "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30",
|
|
14864
|
+
className: "flex-shrink-0",
|
|
14865
|
+
onClick: () => setSearch("")
|
|
14866
|
+
}
|
|
14867
|
+
)
|
|
14868
|
+
] })
|
|
14869
|
+
}
|
|
14870
|
+
),
|
|
14871
|
+
showSearch && filteredOptions.length === 0 && /* @__PURE__ */ jsx(EmptyItem, { children: "\uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }),
|
|
14872
|
+
filteredOptions.map((option) => {
|
|
14873
|
+
const checked = multiple ? selected.includes(option.value) : singleValue === option.value;
|
|
14874
|
+
return /* @__PURE__ */ jsxs(
|
|
14875
|
+
MenuItem,
|
|
14876
|
+
{
|
|
14877
|
+
selected: checked,
|
|
14878
|
+
disabled: disabled || option.disabled,
|
|
14879
|
+
multi: multiple,
|
|
14880
|
+
onClick: () => {
|
|
14881
|
+
if (multiple) {
|
|
14882
|
+
const next = checked ? selected.filter((v) => v !== option.value) : [...selected, option.value];
|
|
14883
|
+
onValueChange(next);
|
|
14884
|
+
} else {
|
|
14885
|
+
onValueChange(option.value);
|
|
14886
|
+
}
|
|
14887
|
+
},
|
|
14888
|
+
children: [
|
|
14889
|
+
multiple && /* @__PURE__ */ jsx(OptionCheckbox, { checked }),
|
|
14890
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: option.label })
|
|
14891
|
+
]
|
|
14892
|
+
},
|
|
14893
|
+
String(option.value)
|
|
14894
|
+
);
|
|
14895
|
+
})
|
|
14896
|
+
]
|
|
14897
|
+
}
|
|
14898
|
+
);
|
|
14899
|
+
}
|
|
14900
|
+
function OptionCheckbox({ checked }) {
|
|
14901
|
+
return /* @__PURE__ */ jsx(
|
|
14902
|
+
"span",
|
|
14903
|
+
{
|
|
14904
|
+
className: cn(
|
|
14905
|
+
"inline-flex size-[16px] shrink-0 items-center justify-center rounded-[2px] border border-solid",
|
|
14906
|
+
checked ? "border-[color:var(--cmp-checkbox-checked-bg-default)] bg-[var(--cmp-checkbox-checked-bg-default)]" : "border-[color:var(--cmp-checkbox-unchecked-border-default)] bg-[var(--cmp-checkbox-unchecked-bg-default)]"
|
|
14907
|
+
),
|
|
14908
|
+
children: checked && /* @__PURE__ */ jsx(SIcon, { name: "checkboxCheck", size: 12, color: "var(--cmp-checkbox-checked-icon-default)" })
|
|
14909
|
+
}
|
|
14910
|
+
);
|
|
14911
|
+
}
|
|
14912
|
+
function ListBox({ children }) {
|
|
14913
|
+
return /* @__PURE__ */ jsx(
|
|
14914
|
+
"div",
|
|
14915
|
+
{
|
|
14916
|
+
className: "overflow-hidden border border-solid shadow-[var(--shadow-overlay)]",
|
|
14917
|
+
style: {
|
|
14918
|
+
borderRadius: CHIPFILTER.listboxRadius,
|
|
14919
|
+
background: CHIPFILTER.listboxBg,
|
|
14920
|
+
borderColor: CHIPFILTER.listboxBorder
|
|
14921
|
+
},
|
|
14922
|
+
children
|
|
14923
|
+
}
|
|
14924
|
+
);
|
|
14925
|
+
}
|
|
14926
|
+
function MenuItem({
|
|
14927
|
+
children,
|
|
14928
|
+
selected,
|
|
14929
|
+
disabled,
|
|
14930
|
+
multi,
|
|
14931
|
+
onMouseEnter,
|
|
14932
|
+
onClick
|
|
14933
|
+
}) {
|
|
14934
|
+
return /* @__PURE__ */ jsx(
|
|
14935
|
+
"button",
|
|
14936
|
+
{
|
|
14937
|
+
type: "button",
|
|
14938
|
+
disabled,
|
|
14939
|
+
onMouseEnter,
|
|
14940
|
+
onClick,
|
|
14941
|
+
className: cn(
|
|
14942
|
+
"flex w-full min-w-0 cursor-pointer items-center gap-[8px] border-none bg-transparent text-left text-[12px] leading-[20px] outline-none disabled:cursor-not-allowed",
|
|
14943
|
+
selected ? "font-bold" : "font-normal",
|
|
14944
|
+
!disabled && "hover:font-bold"
|
|
14945
|
+
),
|
|
14946
|
+
style: {
|
|
14947
|
+
paddingTop: CHIPFILTER.itemPaddingY,
|
|
14948
|
+
paddingBottom: CHIPFILTER.itemPaddingY,
|
|
14949
|
+
paddingLeft: multi ? CHIPFILTER.itemMultiPaddingX : CHIPFILTER.itemPaddingLeft,
|
|
14950
|
+
paddingRight: multi ? CHIPFILTER.itemMultiPaddingX : CHIPFILTER.itemPaddingRight,
|
|
14951
|
+
color: disabled ? CHIPFILTER.chipDisabledText : selected ? CHIPFILTER.itemTextSelected : CHIPFILTER.itemTextDefault
|
|
14952
|
+
},
|
|
14953
|
+
children
|
|
14954
|
+
}
|
|
14955
|
+
);
|
|
14956
|
+
}
|
|
14957
|
+
function EmptyItem({ children }) {
|
|
14958
|
+
return /* @__PURE__ */ jsx(
|
|
14959
|
+
"div",
|
|
14960
|
+
{
|
|
14961
|
+
className: "text-[12px] leading-[20px]",
|
|
14962
|
+
style: {
|
|
14963
|
+
paddingTop: CHIPFILTER.itemPaddingY,
|
|
14964
|
+
paddingBottom: CHIPFILTER.itemPaddingY,
|
|
14965
|
+
paddingLeft: CHIPFILTER.itemPaddingLeft,
|
|
14966
|
+
paddingRight: CHIPFILTER.itemPaddingRight,
|
|
14967
|
+
color: CHIPFILTER.chipDisabledText
|
|
14968
|
+
},
|
|
14969
|
+
children
|
|
14970
|
+
}
|
|
14971
|
+
);
|
|
14972
|
+
}
|
|
14973
|
+
var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
|
|
14974
|
+
values = [],
|
|
14975
|
+
onValueChange,
|
|
14976
|
+
onInput,
|
|
14977
|
+
onFocus,
|
|
14978
|
+
onBlur,
|
|
13478
14979
|
errors = [],
|
|
13479
14980
|
disabledChips = [],
|
|
13480
14981
|
size = "sm",
|
|
@@ -14192,7 +15693,7 @@ function TimeSelector({
|
|
|
14192
15693
|
const renderColumn = (type) => {
|
|
14193
15694
|
const isHour = type === "hour";
|
|
14194
15695
|
const val = isHour ? displayHour : minute;
|
|
14195
|
-
const
|
|
15696
|
+
const displayValue2 = editingPart === type ? inputDraft[type] ?? "" : String(val).padStart(2, "0");
|
|
14196
15697
|
return /* @__PURE__ */ jsxs(
|
|
14197
15698
|
"div",
|
|
14198
15699
|
{
|
|
@@ -14213,7 +15714,7 @@ function TimeSelector({
|
|
|
14213
15714
|
{
|
|
14214
15715
|
"aria-label": isHour ? "\uC2DC" : "\uBD84",
|
|
14215
15716
|
inputMode: "numeric",
|
|
14216
|
-
value:
|
|
15717
|
+
value: displayValue2,
|
|
14217
15718
|
placeholder: "-",
|
|
14218
15719
|
onFocus: () => beginEdit(type, val),
|
|
14219
15720
|
onBlur: () => endEdit(type),
|
|
@@ -14408,8 +15909,8 @@ function STimePicker({
|
|
|
14408
15909
|
disabled,
|
|
14409
15910
|
className,
|
|
14410
15911
|
style,
|
|
14411
|
-
children: /* @__PURE__ */ jsxs(
|
|
14412
|
-
/* @__PURE__ */ jsx(
|
|
15912
|
+
children: /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: commitOpen, children: [
|
|
15913
|
+
/* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
14413
15914
|
"div",
|
|
14414
15915
|
{
|
|
14415
15916
|
ref: triggerRef,
|
|
@@ -14469,14 +15970,17 @@ function STimePicker({
|
|
|
14469
15970
|
]
|
|
14470
15971
|
}
|
|
14471
15972
|
) }),
|
|
14472
|
-
/* @__PURE__ */ jsx(
|
|
14473
|
-
|
|
15973
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
15974
|
+
RPopover9.Content,
|
|
14474
15975
|
{
|
|
14475
15976
|
side: "bottom",
|
|
14476
15977
|
align: "start",
|
|
14477
15978
|
sideOffset: 4,
|
|
14478
15979
|
alignOffset: popoverAlignOffset,
|
|
14479
|
-
className: cn(
|
|
15980
|
+
className: cn(
|
|
15981
|
+
"z-50 max-w-[var(--radix-popover-content-available-width)]",
|
|
15982
|
+
FLOATING_SLIDE_ANIM
|
|
15983
|
+
),
|
|
14480
15984
|
children: /* @__PURE__ */ jsx(
|
|
14481
15985
|
TimeSelector,
|
|
14482
15986
|
{
|
|
@@ -14635,7 +16139,7 @@ function RangeTimeSelector({
|
|
|
14635
16139
|
const { minute } = getParts(side);
|
|
14636
16140
|
const val = isHour ? getDisplayHour(side) : minute;
|
|
14637
16141
|
const currentEditingKey = getEditingKey(side, kind);
|
|
14638
|
-
const
|
|
16142
|
+
const displayValue2 = editingKey === currentEditingKey ? inputDraft[currentEditingKey] ?? "" : String(val).padStart(2, "0");
|
|
14639
16143
|
return /* @__PURE__ */ jsxs(
|
|
14640
16144
|
"div",
|
|
14641
16145
|
{
|
|
@@ -14656,7 +16160,7 @@ function RangeTimeSelector({
|
|
|
14656
16160
|
{
|
|
14657
16161
|
"aria-label": `${side === "start" ? "\uC2DC\uC791" : "\uC885\uB8CC"} ${isHour ? "\uC2DC" : "\uBD84"}`,
|
|
14658
16162
|
inputMode: "numeric",
|
|
14659
|
-
value:
|
|
16163
|
+
value: displayValue2,
|
|
14660
16164
|
placeholder: "-",
|
|
14661
16165
|
onFocus: () => beginEdit(side, kind, val),
|
|
14662
16166
|
onBlur: () => endEdit(side, kind),
|
|
@@ -14867,8 +16371,8 @@ function STimeRangePicker({
|
|
|
14867
16371
|
disabled,
|
|
14868
16372
|
className,
|
|
14869
16373
|
style,
|
|
14870
|
-
children: /* @__PURE__ */ jsxs(
|
|
14871
|
-
/* @__PURE__ */ jsx(
|
|
16374
|
+
children: /* @__PURE__ */ jsxs(RPopover9.Root, { open, onOpenChange: commitOpen, children: [
|
|
16375
|
+
/* @__PURE__ */ jsx(RPopover9.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
14872
16376
|
"div",
|
|
14873
16377
|
{
|
|
14874
16378
|
ref: triggerRef,
|
|
@@ -14928,14 +16432,17 @@ function STimeRangePicker({
|
|
|
14928
16432
|
]
|
|
14929
16433
|
}
|
|
14930
16434
|
) }),
|
|
14931
|
-
/* @__PURE__ */ jsx(
|
|
14932
|
-
|
|
16435
|
+
/* @__PURE__ */ jsx(RPopover9.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
|
|
16436
|
+
RPopover9.Content,
|
|
14933
16437
|
{
|
|
14934
16438
|
side: "bottom",
|
|
14935
16439
|
align: "start",
|
|
14936
16440
|
sideOffset: 4,
|
|
14937
16441
|
alignOffset: popoverAlignOffset,
|
|
14938
|
-
className: cn(
|
|
16442
|
+
className: cn(
|
|
16443
|
+
"z-50 max-w-[var(--radix-popover-content-available-width)]",
|
|
16444
|
+
FLOATING_SLIDE_ANIM
|
|
16445
|
+
),
|
|
14939
16446
|
children: /* @__PURE__ */ jsx(
|
|
14940
16447
|
RangeTimeSelector,
|
|
14941
16448
|
{
|
|
@@ -14953,6 +16460,6 @@ function STimeRangePicker({
|
|
|
14953
16460
|
);
|
|
14954
16461
|
}
|
|
14955
16462
|
|
|
14956
|
-
export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_FULL_LOGO_WIDTH, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, ICONS, PAGE_BACKGROUNDS, SActionModal, SBadge, SBarcodeInput, SButton, SCROLL_AREA_AXES, SCalendar, SCallout, SCard, SCheckbox, SChip2 as SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDraggableGroup, SDraggableItem2 as SDraggableItem, SDraggableList, SDraggableProvider, SDrawer, SDropdownButton2 as SDropdownButton, SExpansionItem, SExpansionList2 as SExpansionList, SField, SFilePicker, SForm, SGhostButton, SGnb, SGuide, SIcon, SInput, SKeyValueTable, SLAYOUT_MIN_WIDTH, SLayout, SLayoutContext, SLinearProgress, SList2 as SList, SListItem2 as SListItem, SLoadingContainer, SLoadingModal, SLoadingViewport, SModal, SModalOutlet, SNumberInput, SPage, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SSPLITTER_UNITS, SScrollArea, SSectionHeaderCard2 as SSectionHeaderCard, SSelect2 as SSelect, SSplitter2 as SSplitter, SStepper, SSwitch, STEPPER_SIZES, STable, STableBar, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip2 as STooltip, STree2 as STree, STreeItem2 as STreeItem, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, findGnbAncestors, findGnbRailValue, isColorKey, loading, resolveColor, useSLayout };
|
|
16463
|
+
export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_FULL_LOGO_WIDTH, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, ICONS, IMAGE_FITS, PAGE_BACKGROUNDS, RangeCalendar, SActionModal, SBadge, SBarcodeInput, SButton, SCROLL_AREA_AXES, SCalendar, SCallout, SCard, SCheckbox, SChip2 as SChip, SChipFilter, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDraggableGroup, SDraggableItem2 as SDraggableItem, SDraggableList, SDraggableProvider, SDrawer, SDropdownButton2 as SDropdownButton, SExpansionItem, SExpansionList2 as SExpansionList, SField, SFilePicker, SForm, SGhostButton, SGnb, SGuide, SIcon, SImage, SInput, SKeyValueTable, SLAYOUT_MIN_WIDTH, SLayout, SLayoutContext, SLinearProgress, SList2 as SList, SListItem2 as SListItem, SLoadingContainer, SLoadingModal, SLoadingViewport, SModal, SModalOutlet, SNumberInput, SPage, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SSPLITTER_UNITS, SScrollArea, SSectionHeaderCard2 as SSectionHeaderCard, SSelect2 as SSelect, SSplitter2 as SSplitter, SStepper, SSwitch, STEPPER_SIZES, STable, STableBar, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip2 as STooltip, STree2 as STree, STreeItem2 as STreeItem, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, findGnbAncestors, findGnbRailValue, isColorKey, loading, resolveColor, useSLayout };
|
|
14957
16464
|
//# sourceMappingURL=index.js.map
|
|
14958
16465
|
//# sourceMappingURL=index.js.map
|