sellmate-design-system-react 9.0.0-beta.90 → 9.0.0-beta.91
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 +33 -13
- package/dist/components/SChatInput/README.md +8 -2
- package/dist/components/SChatInput/SChatInput.d.ts +54 -4
- package/dist/components/SDatePicker/README.md +1 -0
- package/dist/components/SDatePicker/SDatePicker.d.ts +9 -1
- package/dist/components/SDateRangePicker/README.md +1 -0
- package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +9 -1
- package/dist/components/SExpansionItem/README.md +1 -0
- package/dist/components/SExpansionItem/SExpansionItem.d.ts +10 -0
- package/dist/components/SGhostButton/README.md +3 -1
- package/dist/components/SGhostButton/SGhostButton.d.ts +18 -3
- package/dist/index.cjs +429 -167
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +429 -167
- package/dist/index.js.map +1 -1
- package/dist/lib/date.d.ts +9 -0
- package/dist/llms-full.txt +47 -16
- package/dist/llms.txt +33 -13
- package/dist/styles.css +3 -6
- package/dist/theme.css +0 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4486,6 +4486,8 @@ var SGhostButton = /* @__PURE__ */ forwardRef(function SGhostButton2({
|
|
|
4486
4486
|
ariaExpanded,
|
|
4487
4487
|
tooltipText,
|
|
4488
4488
|
disabled = false,
|
|
4489
|
+
href,
|
|
4490
|
+
target,
|
|
4489
4491
|
onClick,
|
|
4490
4492
|
anchorClassName,
|
|
4491
4493
|
anchorStyle,
|
|
@@ -4509,51 +4511,74 @@ var SGhostButton = /* @__PURE__ */ forwardRef(function SGhostButton2({
|
|
|
4509
4511
|
cancelHide();
|
|
4510
4512
|
hideTimer.current = setTimeout(() => setOpen(false), TOOLTIP_HIDE_DELAY_MS);
|
|
4511
4513
|
};
|
|
4512
|
-
const s = SIZE[size];
|
|
4513
|
-
const contentColor = disabled ? intent === "inverse" ? "var(--cmp-ghostButton-inverse-disabled)" : "var(--cmp-ghostButton-icon-disabled)" : `var(--cmp-ghostButton-${intent}-content)`;
|
|
4514
4514
|
const text = (tooltipText ?? "").trim();
|
|
4515
4515
|
const hasTooltip = text !== "";
|
|
4516
|
-
const
|
|
4516
|
+
const [prevHasTooltip, setPrevHasTooltip] = useState(hasTooltip);
|
|
4517
|
+
if (prevHasTooltip !== hasTooltip) {
|
|
4518
|
+
setPrevHasTooltip(hasTooltip);
|
|
4519
|
+
if (!hasTooltip) setOpen(false);
|
|
4520
|
+
}
|
|
4521
|
+
const s = SIZE[size];
|
|
4522
|
+
const contentColor = disabled ? intent === "inverse" ? "var(--cmp-ghostButton-inverse-disabled)" : "var(--cmp-ghostButton-icon-disabled)" : `var(--cmp-ghostButton-${intent}-content)`;
|
|
4523
|
+
const shared = {
|
|
4524
|
+
"aria-disabled": disabled ? "true" : void 0,
|
|
4525
|
+
"aria-label": ariaLabel.trim() || void 0,
|
|
4526
|
+
"tabIndex": disabled ? -1 : void 0,
|
|
4527
|
+
"onClick": (e) => {
|
|
4528
|
+
if (disabled) {
|
|
4529
|
+
e.preventDefault();
|
|
4530
|
+
return;
|
|
4531
|
+
}
|
|
4532
|
+
onClick?.(e);
|
|
4533
|
+
},
|
|
4534
|
+
"className": cn(
|
|
4535
|
+
"group/ghost-button relative box-border inline-flex items-center justify-center border-none bg-transparent p-0 transition-shadow",
|
|
4536
|
+
disabled ? "cursor-not-allowed" : "cursor-pointer",
|
|
4537
|
+
"focus-visible:outline-none focus-visible:shadow-[0_0_0_2px_var(--cmp-ghostButton-action-hover-bg)]",
|
|
4538
|
+
className
|
|
4539
|
+
),
|
|
4540
|
+
"style": {
|
|
4541
|
+
width: `var(--cmp-ghostButton-${size}-size)`,
|
|
4542
|
+
height: `var(--cmp-ghostButton-${size}-size)`,
|
|
4543
|
+
borderRadius: `var(--cmp-ghostButton-radius-${s.radius})`,
|
|
4544
|
+
...style
|
|
4545
|
+
}
|
|
4546
|
+
};
|
|
4547
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4548
|
+
!disabled && /* @__PURE__ */ jsx(
|
|
4549
|
+
"span",
|
|
4550
|
+
{
|
|
4551
|
+
"aria-hidden": true,
|
|
4552
|
+
className: "pointer-events-none absolute inset-0 rounded-[inherit] opacity-0 transition-opacity duration-200 group-hover/ghost-button:opacity-5",
|
|
4553
|
+
style: { background: `var(--cmp-ghostButton-${intent}-hover-bg)` }
|
|
4554
|
+
}
|
|
4555
|
+
),
|
|
4556
|
+
/* @__PURE__ */ jsx(SIcon, { name: icon, size: s.icon, color: contentColor })
|
|
4557
|
+
] });
|
|
4558
|
+
const btn2 = href != null ? (
|
|
4559
|
+
// 비활성 링크는 주소를 뗀다 — `<a>` 에는 disabled 가 없어서 주소가 남으면 가운데 클릭으로 열린다.
|
|
4560
|
+
/* @__PURE__ */ jsx(
|
|
4561
|
+
"a",
|
|
4562
|
+
{
|
|
4563
|
+
ref,
|
|
4564
|
+
href: disabled ? void 0 : href,
|
|
4565
|
+
target,
|
|
4566
|
+
rel: target === "_blank" ? "noopener noreferrer" : void 0,
|
|
4567
|
+
role: disabled ? "link" : void 0,
|
|
4568
|
+
...shared,
|
|
4569
|
+
children: content
|
|
4570
|
+
}
|
|
4571
|
+
)
|
|
4572
|
+
) : /* @__PURE__ */ jsx(
|
|
4517
4573
|
"button",
|
|
4518
4574
|
{
|
|
4519
4575
|
ref,
|
|
4520
4576
|
type: "button",
|
|
4521
4577
|
disabled,
|
|
4522
|
-
"aria-disabled": disabled ? "true" : void 0,
|
|
4523
|
-
"aria-label": ariaLabel.trim() || void 0,
|
|
4524
4578
|
"aria-pressed": ariaPressed,
|
|
4525
4579
|
"aria-expanded": ariaExpanded,
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
if (disabled) {
|
|
4529
|
-
e.preventDefault();
|
|
4530
|
-
return;
|
|
4531
|
-
}
|
|
4532
|
-
onClick?.(e);
|
|
4533
|
-
},
|
|
4534
|
-
className: cn(
|
|
4535
|
-
"group/ghost-button relative box-border inline-flex items-center justify-center border-none bg-transparent p-0 transition-shadow",
|
|
4536
|
-
disabled ? "cursor-not-allowed" : "cursor-pointer",
|
|
4537
|
-
"focus-visible:outline-none focus-visible:shadow-[0_0_0_2px_var(--cmp-ghostButton-action-hover-bg)]",
|
|
4538
|
-
className
|
|
4539
|
-
),
|
|
4540
|
-
style: {
|
|
4541
|
-
width: `var(--cmp-ghostButton-${size}-size)`,
|
|
4542
|
-
height: `var(--cmp-ghostButton-${size}-size)`,
|
|
4543
|
-
borderRadius: `var(--cmp-ghostButton-radius-${s.radius})`,
|
|
4544
|
-
...style
|
|
4545
|
-
},
|
|
4546
|
-
children: [
|
|
4547
|
-
!disabled && /* @__PURE__ */ jsx(
|
|
4548
|
-
"span",
|
|
4549
|
-
{
|
|
4550
|
-
"aria-hidden": true,
|
|
4551
|
-
className: "pointer-events-none absolute inset-0 rounded-[inherit] opacity-0 transition-opacity duration-200 group-hover/ghost-button:opacity-5",
|
|
4552
|
-
style: { background: `var(--cmp-ghostButton-${intent}-hover-bg)` }
|
|
4553
|
-
}
|
|
4554
|
-
),
|
|
4555
|
-
/* @__PURE__ */ jsx(SIcon, { name: icon, size: s.icon, color: contentColor })
|
|
4556
|
-
]
|
|
4580
|
+
...shared,
|
|
4581
|
+
children: content
|
|
4557
4582
|
}
|
|
4558
4583
|
);
|
|
4559
4584
|
if (!hasTooltip) return btn2;
|
|
@@ -5281,6 +5306,9 @@ var FIELD_BORDER = 1;
|
|
|
5281
5306
|
var TEXTAREA_MIN_HEIGHT = `calc(var(--cmp-chatInput-buttonFrame-height) - ${FIELD_BORDER * 2}px)`;
|
|
5282
5307
|
var BUTTON_BOTTOM_INSET = `calc((var(--cmp-chatInput-buttonFrame-height) - var(--cmp-ghostButton-md-size)) / 2)`;
|
|
5283
5308
|
var DEFAULT_MAX_ROWS = 5;
|
|
5309
|
+
function BarButton(props) {
|
|
5310
|
+
return /* @__PURE__ */ jsx(SGhostButton, { ...props, size: "md", style: { marginBottom: BUTTON_BOTTOM_INSET } });
|
|
5311
|
+
}
|
|
5284
5312
|
var SChatInputImpl = /* @__PURE__ */ forwardRef(function SChatInput({
|
|
5285
5313
|
value = "",
|
|
5286
5314
|
onValueChange,
|
|
@@ -5288,7 +5316,13 @@ var SChatInputImpl = /* @__PURE__ */ forwardRef(function SChatInput({
|
|
|
5288
5316
|
disabled = false,
|
|
5289
5317
|
onSend,
|
|
5290
5318
|
hasAttachments = false,
|
|
5319
|
+
onAttachFiles,
|
|
5320
|
+
attachAccept,
|
|
5321
|
+
attachMultiple = true,
|
|
5291
5322
|
onAttach,
|
|
5323
|
+
attachDisabled = false,
|
|
5324
|
+
attachTooltip,
|
|
5325
|
+
sendDisabled = false,
|
|
5292
5326
|
onPasteFiles,
|
|
5293
5327
|
busy = false,
|
|
5294
5328
|
onStop,
|
|
@@ -5300,11 +5334,23 @@ var SChatInputImpl = /* @__PURE__ */ forwardRef(function SChatInput({
|
|
|
5300
5334
|
...rest
|
|
5301
5335
|
}, ref) {
|
|
5302
5336
|
const hasText = value.trim() !== "";
|
|
5303
|
-
const canSend = !disabled && !busy && (hasText || hasAttachments);
|
|
5304
|
-
const send =
|
|
5337
|
+
const canSend = !disabled && !busy && !sendDisabled && (hasText || hasAttachments);
|
|
5338
|
+
const send = () => {
|
|
5305
5339
|
if (!canSend) return;
|
|
5306
5340
|
onSend?.(hasText ? value : "");
|
|
5307
|
-
}
|
|
5341
|
+
};
|
|
5342
|
+
const fileInputRef = useRef(null);
|
|
5343
|
+
const hasAttachButton = onAttachFiles != null || onAttach != null;
|
|
5344
|
+
const attachLocked = disabled || attachDisabled;
|
|
5345
|
+
const handleAttachClick = () => {
|
|
5346
|
+
if (onAttachFiles != null) fileInputRef.current?.click();
|
|
5347
|
+
else onAttach?.();
|
|
5348
|
+
};
|
|
5349
|
+
const handleFilesPicked = (e) => {
|
|
5350
|
+
const files = Array.from(e.target.files ?? []);
|
|
5351
|
+
e.target.value = "";
|
|
5352
|
+
if (files.length > 0) onAttachFiles?.(files);
|
|
5353
|
+
};
|
|
5308
5354
|
const handleKeyDown = (e) => {
|
|
5309
5355
|
rest.onKeyDown?.(e);
|
|
5310
5356
|
if (e.key !== "Enter" || e.shiftKey || e.nativeEvent.isComposing) return;
|
|
@@ -5317,19 +5363,31 @@ var SChatInputImpl = /* @__PURE__ */ forwardRef(function SChatInput({
|
|
|
5317
5363
|
const files = Array.from(e.clipboardData.files);
|
|
5318
5364
|
if (files.length === 0) return;
|
|
5319
5365
|
e.preventDefault();
|
|
5366
|
+
if (attachDisabled) return;
|
|
5320
5367
|
onPasteFiles(files);
|
|
5321
5368
|
};
|
|
5322
5369
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col bg-(--cmp-chatInput-bg)", className), style, children: [
|
|
5323
5370
|
/* @__PURE__ */ jsxs("div", { className: "flex items-end gap-(--cmp-chatInput-gap) p-(--cmp-chatInput-padding)", children: [
|
|
5324
|
-
|
|
5325
|
-
|
|
5371
|
+
hasAttachButton && /* @__PURE__ */ jsx(
|
|
5372
|
+
BarButton,
|
|
5326
5373
|
{
|
|
5327
5374
|
icon: "attachFile",
|
|
5328
|
-
size: "md",
|
|
5329
5375
|
ariaLabel: "\uD30C\uC77C \uCCA8\uBD80",
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5376
|
+
tooltipText: attachTooltip,
|
|
5377
|
+
disabled: attachLocked,
|
|
5378
|
+
onClick: handleAttachClick
|
|
5379
|
+
}
|
|
5380
|
+
),
|
|
5381
|
+
onAttachFiles != null && /* @__PURE__ */ jsx(
|
|
5382
|
+
"input",
|
|
5383
|
+
{
|
|
5384
|
+
ref: fileInputRef,
|
|
5385
|
+
type: "file",
|
|
5386
|
+
className: "hidden",
|
|
5387
|
+
accept: attachAccept,
|
|
5388
|
+
multiple: attachMultiple,
|
|
5389
|
+
disabled: attachLocked,
|
|
5390
|
+
onChange: handleFilesPicked
|
|
5333
5391
|
}
|
|
5334
5392
|
),
|
|
5335
5393
|
/* @__PURE__ */ jsx(
|
|
@@ -5353,26 +5411,26 @@ var SChatInputImpl = /* @__PURE__ */ forwardRef(function SChatInput({
|
|
|
5353
5411
|
onPaste: handlePaste
|
|
5354
5412
|
}
|
|
5355
5413
|
),
|
|
5356
|
-
busy ?
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5414
|
+
busy ? (
|
|
5415
|
+
// disabled 는 모두 잠근다 — 응답 도중 대화가 끝나면 정지도 할 수 없다
|
|
5416
|
+
/* @__PURE__ */ jsx(
|
|
5417
|
+
BarButton,
|
|
5418
|
+
{
|
|
5419
|
+
icon: "stop",
|
|
5420
|
+
intent: "danger",
|
|
5421
|
+
ariaLabel: "\uC751\uB2F5 \uC911\uC9C0",
|
|
5422
|
+
disabled,
|
|
5423
|
+
onClick: onStop
|
|
5424
|
+
}
|
|
5425
|
+
)
|
|
5366
5426
|
) : /* @__PURE__ */ jsx(
|
|
5367
|
-
|
|
5427
|
+
BarButton,
|
|
5368
5428
|
{
|
|
5369
5429
|
icon: "send",
|
|
5370
|
-
size: "md",
|
|
5371
5430
|
intent: "subAction",
|
|
5372
5431
|
ariaLabel: "\uC804\uC1A1",
|
|
5373
5432
|
disabled: !canSend,
|
|
5374
|
-
onClick: send
|
|
5375
|
-
style: { marginBottom: BUTTON_BOTTOM_INSET }
|
|
5433
|
+
onClick: send
|
|
5376
5434
|
}
|
|
5377
5435
|
)
|
|
5378
5436
|
] }),
|
|
@@ -6613,6 +6671,7 @@ var SExpansionItem = /* @__PURE__ */ forwardRef(
|
|
|
6613
6671
|
depth = 1,
|
|
6614
6672
|
leading,
|
|
6615
6673
|
trailing,
|
|
6674
|
+
headerAction,
|
|
6616
6675
|
bodyPadding = true,
|
|
6617
6676
|
bordered = false,
|
|
6618
6677
|
expanded,
|
|
@@ -6652,12 +6711,92 @@ var SExpansionItem = /* @__PURE__ */ forwardRef(
|
|
|
6652
6711
|
);
|
|
6653
6712
|
const leadingNode = typeof leading === "function" ? leading({ expanded: isExpanded, selected: isSelected, disabled }) : leading;
|
|
6654
6713
|
const hasSupportingText = supportingText != null && supportingText !== "";
|
|
6714
|
+
const hasHeaderAction = headerAction != null && headerAction !== false;
|
|
6655
6715
|
const id = useId();
|
|
6716
|
+
const surfaceClass = cn(
|
|
6717
|
+
isExpanded && "border-b border-(--cmp-listExpansionItem-title-border)",
|
|
6718
|
+
hasChevronInteraction ? "hover:bg-(--sys-color-bg-neutralBright)" : !isExpanded && "hover:bg-(--cmp-listExpansionItem-title-bg-hover)",
|
|
6719
|
+
// 펼침 배경(파랑)은 bordered 일 때만. 카드처럼 테두리로 경계가 잡힌
|
|
6720
|
+
// 아이템에서만 배경이 선택 상태를 나타낸다.
|
|
6721
|
+
// 테두리 없는 리스트에서는 accentStripe 가 그 역할을 하므로,
|
|
6722
|
+
// 배경까지 깔면 항목 경계가 없는 목록에서 선택 표시가 두 겹이 된다.
|
|
6723
|
+
isExpanded && isSelected && bordered && "bg-(--cmp-listExpansionItem-title-bg-expanded)"
|
|
6724
|
+
);
|
|
6725
|
+
const hoverHandlers = {
|
|
6726
|
+
onMouseEnter: () => setHovered(true),
|
|
6727
|
+
onMouseLeave: () => setHovered(false)
|
|
6728
|
+
};
|
|
6656
6729
|
useEffect(() => {
|
|
6657
6730
|
if (!isExpanded) return;
|
|
6658
6731
|
parentDescendantContext?.reportExpandedDescendant(1);
|
|
6659
6732
|
return () => parentDescendantContext?.reportExpandedDescendant(-1);
|
|
6660
6733
|
}, [isExpanded, parentDescendantContext]);
|
|
6734
|
+
const toggleButton = /* @__PURE__ */ jsxs(
|
|
6735
|
+
"button",
|
|
6736
|
+
{
|
|
6737
|
+
type: "button",
|
|
6738
|
+
disabled,
|
|
6739
|
+
"aria-expanded": isExpanded,
|
|
6740
|
+
"aria-controls": id,
|
|
6741
|
+
...hasHeaderAction ? {} : hoverHandlers,
|
|
6742
|
+
onClick: (event) => {
|
|
6743
|
+
if (disabled) return;
|
|
6744
|
+
const next = !isExpanded;
|
|
6745
|
+
if (expanded === void 0) setInternalExpanded(next);
|
|
6746
|
+
onToggle?.(next, event);
|
|
6747
|
+
},
|
|
6748
|
+
className: cn(
|
|
6749
|
+
"group/expansion-item-button flex w-full cursor-pointer items-center justify-between border-0 text-left text-(--cmp-listExpansionItem-title-text-default) focus-visible:outline focus-visible:outline-2 focus-visible:outline-(--sys-color-border-accent) disabled:cursor-not-allowed disabled:text-(--sys-color-disabled-text)",
|
|
6750
|
+
titleTypo,
|
|
6751
|
+
// 헤더 액션이 있으면 면은 바깥 줄이 그린다 — 버튼은 남은 폭만 차지한다
|
|
6752
|
+
hasHeaderAction ? "min-w-0 flex-1" : surfaceClass,
|
|
6753
|
+
// 높이는 세로 패딩과 내용이 정한다 — 제목 줄에 높이를 못 박지 않는다 (SListItem 과 동일)
|
|
6754
|
+
dense ? "py-(--cmp-listExpansionItem-title-paddingY-dense)" : "py-(--cmp-listExpansionItem-title-paddingY-normal)",
|
|
6755
|
+
"gap-(--cmp-listExpansionItem-title-gap)",
|
|
6756
|
+
// 헤더 액션이 있으면 오른쪽 끝 여백은 액션 칸이 갖고, 버튼은 액션과의 간격만 남긴다
|
|
6757
|
+
hasHeaderAction ? "pr-(--cmp-listExpansionItem-title-gap)" : "pr-(--cmp-listExpansionItem-title-paddingX)",
|
|
6758
|
+
depth === 2 ? "pl-[36px]" : depth === 3 ? "pl-[56px]" : "pl-[16px]",
|
|
6759
|
+
isExpanded && "text-(--cmp-listExpansionItem-title-text-expanded)"
|
|
6760
|
+
),
|
|
6761
|
+
children: [
|
|
6762
|
+
!leading && /* @__PURE__ */ jsx(
|
|
6763
|
+
"span",
|
|
6764
|
+
{
|
|
6765
|
+
className: cn(
|
|
6766
|
+
"flex transition-transform duration-200 ease-out motion-reduce:transition-none",
|
|
6767
|
+
isExpanded && "rotate-180"
|
|
6768
|
+
),
|
|
6769
|
+
children: /* @__PURE__ */ jsx(SIcon, { name: "caretDown", size: 12, color: "var(--sys-color-fg-quaternary)" })
|
|
6770
|
+
}
|
|
6771
|
+
),
|
|
6772
|
+
leadingNode,
|
|
6773
|
+
/* @__PURE__ */ jsxs(
|
|
6774
|
+
"span",
|
|
6775
|
+
{
|
|
6776
|
+
className: cn(
|
|
6777
|
+
"min-w-0 flex-1",
|
|
6778
|
+
supportingTextPosition === "bottom" ? "flex flex-col" : "flex items-center gap-[8px] whitespace-nowrap"
|
|
6779
|
+
),
|
|
6780
|
+
children: [
|
|
6781
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: title }),
|
|
6782
|
+
hasSupportingText && /* @__PURE__ */ jsx(
|
|
6783
|
+
"span",
|
|
6784
|
+
{
|
|
6785
|
+
className: cn(
|
|
6786
|
+
"typo-body-sm-default min-w-0 truncate text-(--sys-color-fg-secondary)",
|
|
6787
|
+
supportingTextPosition === "right" && "flex-1"
|
|
6788
|
+
),
|
|
6789
|
+
children: supportingText
|
|
6790
|
+
}
|
|
6791
|
+
)
|
|
6792
|
+
]
|
|
6793
|
+
}
|
|
6794
|
+
),
|
|
6795
|
+
trailing,
|
|
6796
|
+
showInteractionChevron && /* @__PURE__ */ jsx(SIcon, { name: "chevronRight", size: 12, color: interactionChevronColor })
|
|
6797
|
+
]
|
|
6798
|
+
}
|
|
6799
|
+
);
|
|
6661
6800
|
return /* @__PURE__ */ jsxs(
|
|
6662
6801
|
"div",
|
|
6663
6802
|
{
|
|
@@ -6680,79 +6819,13 @@ var SExpansionItem = /* @__PURE__ */ forwardRef(
|
|
|
6680
6819
|
className: "pointer-events-none absolute bottom-[-1px] left-0 top-0 z-[1] w-(--cmp-listItem-accentStripe-width) bg-(--cmp-listItem-accentStripe-color)"
|
|
6681
6820
|
}
|
|
6682
6821
|
),
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
{
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
onMouseEnter: () => setHovered(true),
|
|
6691
|
-
onMouseLeave: () => setHovered(false),
|
|
6692
|
-
onClick: (event) => {
|
|
6693
|
-
if (disabled) return;
|
|
6694
|
-
const next = !isExpanded;
|
|
6695
|
-
if (expanded === void 0) setInternalExpanded(next);
|
|
6696
|
-
onToggle?.(next, event);
|
|
6697
|
-
},
|
|
6698
|
-
className: cn(
|
|
6699
|
-
"group/expansion-item-button flex w-full cursor-pointer items-center justify-between border-0 text-left text-(--cmp-listExpansionItem-title-text-default) focus-visible:outline focus-visible:outline-2 focus-visible:outline-(--sys-color-border-accent) disabled:cursor-not-allowed disabled:text-(--sys-color-disabled-text)",
|
|
6700
|
-
titleTypo,
|
|
6701
|
-
isExpanded && "border-b border-(--cmp-listExpansionItem-title-border)",
|
|
6702
|
-
hasChevronInteraction ? "hover:bg-(--sys-color-bg-neutralBright)" : !isExpanded && "hover:bg-(--cmp-listExpansionItem-title-bg-hover)",
|
|
6703
|
-
// 높이는 세로 패딩과 내용이 정한다 — 제목 줄에 높이를 못 박지 않는다 (SListItem 과 동일)
|
|
6704
|
-
dense ? "py-(--cmp-listExpansionItem-title-paddingY-dense)" : "py-(--cmp-listExpansionItem-title-paddingY-normal)",
|
|
6705
|
-
"gap-(--cmp-listExpansionItem-title-gap)",
|
|
6706
|
-
"pr-(--cmp-listExpansionItem-title-paddingX)",
|
|
6707
|
-
depth === 2 ? "pl-[36px]" : depth === 3 ? "pl-[56px]" : "pl-[16px]",
|
|
6708
|
-
isExpanded && cn(
|
|
6709
|
-
"text-(--cmp-listExpansionItem-title-text-expanded)",
|
|
6710
|
-
// 펼침 배경(파랑)은 bordered 일 때만. 카드처럼 테두리로 경계가 잡힌
|
|
6711
|
-
// 아이템에서만 배경이 선택 상태를 나타낸다.
|
|
6712
|
-
// 테두리 없는 리스트에서는 accentStripe 가 그 역할을 하므로,
|
|
6713
|
-
// 배경까지 깔면 항목 경계가 없는 목록에서 선택 표시가 두 겹이 된다.
|
|
6714
|
-
isSelected && bordered && "bg-(--cmp-listExpansionItem-title-bg-expanded)"
|
|
6715
|
-
)
|
|
6716
|
-
),
|
|
6717
|
-
children: [
|
|
6718
|
-
!leading && /* @__PURE__ */ jsx(
|
|
6719
|
-
"span",
|
|
6720
|
-
{
|
|
6721
|
-
className: cn(
|
|
6722
|
-
"flex transition-transform duration-200 ease-out motion-reduce:transition-none",
|
|
6723
|
-
isExpanded && "rotate-180"
|
|
6724
|
-
),
|
|
6725
|
-
children: /* @__PURE__ */ jsx(SIcon, { name: "caretDown", size: 12, color: "var(--sys-color-fg-quaternary)" })
|
|
6726
|
-
}
|
|
6727
|
-
),
|
|
6728
|
-
leadingNode,
|
|
6729
|
-
/* @__PURE__ */ jsxs(
|
|
6730
|
-
"span",
|
|
6731
|
-
{
|
|
6732
|
-
className: cn(
|
|
6733
|
-
"min-w-0 flex-1",
|
|
6734
|
-
supportingTextPosition === "bottom" ? "flex flex-col" : "flex items-center gap-[8px] whitespace-nowrap"
|
|
6735
|
-
),
|
|
6736
|
-
children: [
|
|
6737
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: title }),
|
|
6738
|
-
hasSupportingText && /* @__PURE__ */ jsx(
|
|
6739
|
-
"span",
|
|
6740
|
-
{
|
|
6741
|
-
className: cn(
|
|
6742
|
-
"typo-body-sm-default min-w-0 truncate text-(--sys-color-fg-secondary)",
|
|
6743
|
-
supportingTextPosition === "right" && "flex-1"
|
|
6744
|
-
),
|
|
6745
|
-
children: supportingText
|
|
6746
|
-
}
|
|
6747
|
-
)
|
|
6748
|
-
]
|
|
6749
|
-
}
|
|
6750
|
-
),
|
|
6751
|
-
trailing,
|
|
6752
|
-
showInteractionChevron && /* @__PURE__ */ jsx(SIcon, { name: "chevronRight", size: 12, color: interactionChevronColor })
|
|
6753
|
-
]
|
|
6754
|
-
}
|
|
6755
|
-
),
|
|
6822
|
+
hasHeaderAction ? (
|
|
6823
|
+
// 헤더 액션은 여닫는 버튼의 형제다 — 안에 넣으면 버튼이 중첩되고 누를 때마다 여닫힌다
|
|
6824
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex items-center", surfaceClass), ...hoverHandlers, children: [
|
|
6825
|
+
toggleButton,
|
|
6826
|
+
/* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-(--cmp-listExpansionItem-title-gap) pr-(--cmp-listExpansionItem-title-paddingX)", children: headerAction })
|
|
6827
|
+
] })
|
|
6828
|
+
) : toggleButton,
|
|
6756
6829
|
/* @__PURE__ */ jsx(SExpansionItemDescendantContext.Provider, { value: descendantContextValue, children: /* @__PURE__ */ jsx(
|
|
6757
6830
|
"div",
|
|
6758
6831
|
{
|
|
@@ -14644,12 +14717,25 @@ function monthCells(year, month) {
|
|
|
14644
14717
|
return cells;
|
|
14645
14718
|
}
|
|
14646
14719
|
var WEEK_LABELS = ["\uC77C", "\uC6D4", "\uD654", "\uC218", "\uBAA9", "\uAE08", "\uD1A0"];
|
|
14720
|
+
var WEEKDAY_SUFFIX_EM = 0.25 + 3 * 1;
|
|
14721
|
+
var weekdaySuffixWidth = (fontSize) => Math.ceil(fontSize * WEEKDAY_SUFFIX_EM);
|
|
14722
|
+
function withWeekday(value) {
|
|
14723
|
+
const [date = "", ...rest] = value.split(" ");
|
|
14724
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date);
|
|
14725
|
+
if (!match) return value;
|
|
14726
|
+
const day = new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3])).getDay();
|
|
14727
|
+
if (Number.isNaN(day)) return value;
|
|
14728
|
+
return [date, `${WEEK_LABELS[day]}\uC694\uC77C`, ...rest].join(" ");
|
|
14729
|
+
}
|
|
14647
14730
|
|
|
14648
14731
|
// src/components/SCalendarBoard/calendar-board-layout.ts
|
|
14649
14732
|
function eventEndDate(event) {
|
|
14650
14733
|
const end = event.endDate;
|
|
14651
14734
|
return end != null && end > event.date ? end : event.date;
|
|
14652
14735
|
}
|
|
14736
|
+
function compareDate(a, b) {
|
|
14737
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
14738
|
+
}
|
|
14653
14739
|
function layoutCalendarBoard({
|
|
14654
14740
|
cells,
|
|
14655
14741
|
events,
|
|
@@ -14695,7 +14781,7 @@ function layoutCalendarBoard({
|
|
|
14695
14781
|
flush(to);
|
|
14696
14782
|
});
|
|
14697
14783
|
runs.sort(
|
|
14698
|
-
(a, b) => a.startIndex - b.startIndex ||
|
|
14784
|
+
(a, b) => a.startIndex - b.startIndex || compareDate(a.event.date, b.event.date) || compareDate(eventEndDate(b.event), eventEndDate(a.event)) || a.order - b.order
|
|
14699
14785
|
);
|
|
14700
14786
|
const weekLanes = Array.from({ length: weekCount }, () => []);
|
|
14701
14787
|
for (const run of runs) {
|
|
@@ -17968,7 +18054,8 @@ var STableBar = /* @__PURE__ */ forwardRef(function STableBar2({ title, total, s
|
|
|
17968
18054
|
);
|
|
17969
18055
|
});
|
|
17970
18056
|
var NO_KEYS = /* @__PURE__ */ new Set();
|
|
17971
|
-
var
|
|
18057
|
+
var EXPAND_MOTION = { duration: 220, easing: "ease-out" };
|
|
18058
|
+
var COLLAPSE_MOTION = { duration: 140, easing: "ease-in" };
|
|
17972
18059
|
function STreeTable({
|
|
17973
18060
|
rows = [],
|
|
17974
18061
|
columns = [],
|
|
@@ -18015,32 +18102,88 @@ function STreeTable({
|
|
|
18015
18102
|
if (expandedKeys === void 0) setInnerExpandedKeys(next);
|
|
18016
18103
|
onExpandedChange?.(next, row);
|
|
18017
18104
|
};
|
|
18018
|
-
const visibleRows = useMemo(
|
|
18019
|
-
|
|
18020
|
-
|
|
18021
|
-
|
|
18022
|
-
|
|
18023
|
-
|
|
18024
|
-
|
|
18025
|
-
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
|
|
18105
|
+
const visibleRows = useMemo(
|
|
18106
|
+
() => flattenRows(rows, (row) => expandedSet.has(keyOf(row)), childrenOf),
|
|
18107
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
18108
|
+
[rows, expandedSet, rowKey, childrenKey]
|
|
18109
|
+
);
|
|
18110
|
+
const tableRef = useRef(null);
|
|
18111
|
+
const [closingKeys, setClosingKeys] = useState(NO_KEYS);
|
|
18112
|
+
const [prevExpand, setPrevExpand] = useState({ rows, expandedSet });
|
|
18113
|
+
if (prevExpand.rows !== rows || prevExpand.expandedSet !== expandedSet) {
|
|
18114
|
+
setPrevExpand({ rows, expandedSet });
|
|
18115
|
+
let nextClosing = NO_KEYS;
|
|
18116
|
+
if (prevExpand.rows === rows && motionAllowed()) {
|
|
18117
|
+
const collapsed = [...prevExpand.expandedSet].filter((key) => !expandedSet.has(key));
|
|
18118
|
+
const expanded = [...expandedSet].filter((key) => !prevExpand.expandedSet.has(key));
|
|
18119
|
+
if (collapsed.length > 0 && expanded.length === 0) nextClosing = new Set(collapsed);
|
|
18120
|
+
}
|
|
18121
|
+
if (nextClosing !== closingKeys) setClosingKeys(nextClosing);
|
|
18122
|
+
}
|
|
18123
|
+
const renderedRows = useMemo(
|
|
18124
|
+
() => closingKeys.size === 0 ? visibleRows : flattenRows(
|
|
18125
|
+
rows,
|
|
18126
|
+
(row) => expandedSet.has(keyOf(row)) || closingKeys.has(keyOf(row)),
|
|
18127
|
+
childrenOf
|
|
18128
|
+
),
|
|
18129
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
18130
|
+
[visibleRows, closingKeys]
|
|
18131
|
+
);
|
|
18132
|
+
const visibleKeys = useMemo(
|
|
18133
|
+
() => new Set(visibleRows.map(keyOf)),
|
|
18134
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
18135
|
+
[visibleRows]
|
|
18136
|
+
);
|
|
18137
|
+
const motionRef = useRef(null);
|
|
18030
18138
|
const prevVisibleRef = useRef(null);
|
|
18031
18139
|
useIsomorphicLayoutEffect(() => {
|
|
18032
|
-
const keys = new Set(visibleRows.map(keyOf));
|
|
18033
18140
|
const prev = prevVisibleRef.current;
|
|
18034
|
-
prevVisibleRef.current = { rows, keys };
|
|
18035
|
-
|
|
18036
|
-
|
|
18037
|
-
|
|
18038
|
-
|
|
18039
|
-
|
|
18040
|
-
if (
|
|
18041
|
-
|
|
18042
|
-
|
|
18043
|
-
|
|
18141
|
+
prevVisibleRef.current = { rows, keys: visibleKeys };
|
|
18142
|
+
const running = motionRef.current;
|
|
18143
|
+
if (running?.done) {
|
|
18144
|
+
running.cancel();
|
|
18145
|
+
motionRef.current = null;
|
|
18146
|
+
}
|
|
18147
|
+
if (!prev || prev.rows !== rows) {
|
|
18148
|
+
motionRef.current?.cancel();
|
|
18149
|
+
motionRef.current = null;
|
|
18150
|
+
return;
|
|
18151
|
+
}
|
|
18152
|
+
const added = new Set([...visibleKeys].filter((key) => !prev.keys.has(key)));
|
|
18153
|
+
const removed = new Set([...prev.keys].filter((key) => !visibleKeys.has(key)));
|
|
18154
|
+
if (added.size === 0 && removed.size === 0) return;
|
|
18155
|
+
let from = added.size > 0 ? 0 : 1;
|
|
18156
|
+
if (motionRef.current) {
|
|
18157
|
+
const current = motionRef.current;
|
|
18158
|
+
const reversing = current.to === 0 && sameKeys(added, current.keys) || current.to === 1 && sameKeys(removed, current.keys);
|
|
18159
|
+
if (reversing) from = current.openness();
|
|
18160
|
+
current.cancel();
|
|
18161
|
+
motionRef.current = null;
|
|
18162
|
+
}
|
|
18163
|
+
const scrollEl = tableRef.current?.getScrollElement();
|
|
18164
|
+
const keys = added.size > 0 ? added : removed;
|
|
18165
|
+
const canAnimate = scrollEl != null && motionAllowed() && (added.size === 0 || removed.size === 0);
|
|
18166
|
+
const motion = canAnimate ? startRowMotion({
|
|
18167
|
+
scrollEl,
|
|
18168
|
+
rowKeys: renderedRows.map(keyOf),
|
|
18169
|
+
blockKeys: keys,
|
|
18170
|
+
from,
|
|
18171
|
+
to: added.size > 0 ? 1 : 0
|
|
18172
|
+
}) : null;
|
|
18173
|
+
if (motion) {
|
|
18174
|
+
motionRef.current = motion;
|
|
18175
|
+
if (motion.to === 0) {
|
|
18176
|
+
void motion.finished.then((completed) => {
|
|
18177
|
+
if (!completed || motionRef.current !== motion) return;
|
|
18178
|
+
motion.done = true;
|
|
18179
|
+
setClosingKeys(NO_KEYS);
|
|
18180
|
+
});
|
|
18181
|
+
}
|
|
18182
|
+
} else if (closingKeys.size > 0) {
|
|
18183
|
+
setClosingKeys(NO_KEYS);
|
|
18184
|
+
}
|
|
18185
|
+
}, [renderedRows]);
|
|
18186
|
+
useEffect(() => () => motionRef.current?.cancel(), []);
|
|
18044
18187
|
const collectSelectable = (row) => canSelectRow(row) ? [row, ...childrenOf(row).flatMap(collectSelectable)] : [];
|
|
18045
18188
|
const selectionOf = (keys) => {
|
|
18046
18189
|
const state2 = /* @__PURE__ */ new Map();
|
|
@@ -18136,8 +18279,9 @@ function STreeTable({
|
|
|
18136
18279
|
STable2,
|
|
18137
18280
|
{
|
|
18138
18281
|
...rest,
|
|
18282
|
+
ref: tableRef,
|
|
18139
18283
|
columns: tableColumns,
|
|
18140
|
-
rows:
|
|
18284
|
+
rows: renderedRows,
|
|
18141
18285
|
rowKey,
|
|
18142
18286
|
resizable,
|
|
18143
18287
|
selectable,
|
|
@@ -18145,14 +18289,113 @@ function STreeTable({
|
|
|
18145
18289
|
isRowIndeterminate: selectionState ? (row) => !!selectionState.get(keyOf(row))?.indeterminate : void 0,
|
|
18146
18290
|
rowClassName: (row) => cn(
|
|
18147
18291
|
rowClassName?.(row),
|
|
18148
|
-
//
|
|
18149
|
-
|
|
18292
|
+
// 접히는 중인 행은 이미 접힌 행이다 — 사라지는 동안 눌리지 않게 한다
|
|
18293
|
+
!visibleKeys.has(keyOf(row)) && "pointer-events-none"
|
|
18150
18294
|
) || void 0,
|
|
18151
18295
|
selected: tableSelected,
|
|
18152
18296
|
onSelectedChange: handleSelectedChange
|
|
18153
18297
|
}
|
|
18154
18298
|
);
|
|
18155
18299
|
}
|
|
18300
|
+
function flattenRows(nodes, isOpen, childrenOf) {
|
|
18301
|
+
const out = [];
|
|
18302
|
+
const walk = (list) => {
|
|
18303
|
+
list.forEach((row) => {
|
|
18304
|
+
out.push(row);
|
|
18305
|
+
if (isOpen(row)) walk(childrenOf(row));
|
|
18306
|
+
});
|
|
18307
|
+
};
|
|
18308
|
+
walk(nodes);
|
|
18309
|
+
return out;
|
|
18310
|
+
}
|
|
18311
|
+
function sameKeys(a, b) {
|
|
18312
|
+
return a.size === b.size && [...a].every((key) => b.has(key));
|
|
18313
|
+
}
|
|
18314
|
+
function motionAllowed() {
|
|
18315
|
+
if (typeof window === "undefined" || typeof Element.prototype.animate !== "function")
|
|
18316
|
+
return false;
|
|
18317
|
+
return !window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
18318
|
+
}
|
|
18319
|
+
function startRowMotion({
|
|
18320
|
+
scrollEl,
|
|
18321
|
+
rowKeys,
|
|
18322
|
+
blockKeys,
|
|
18323
|
+
from,
|
|
18324
|
+
to
|
|
18325
|
+
}) {
|
|
18326
|
+
const spec = to === 1 ? EXPAND_MOTION : COLLAPSE_MOTION;
|
|
18327
|
+
const duration = spec.duration * Math.abs(to - from);
|
|
18328
|
+
if (duration < 1) return null;
|
|
18329
|
+
const trs = [...scrollEl.querySelectorAll("tr[data-row-index]")].map((tr) => {
|
|
18330
|
+
const key = rowKeys[Number(tr.dataset.rowIndex)];
|
|
18331
|
+
return {
|
|
18332
|
+
tr,
|
|
18333
|
+
inBlock: key !== void 0 && blockKeys.has(key),
|
|
18334
|
+
height: tr.getBoundingClientRect().height
|
|
18335
|
+
};
|
|
18336
|
+
});
|
|
18337
|
+
const viewBottom = scrollEl.scrollTop + scrollEl.clientHeight;
|
|
18338
|
+
const openAt = (offset) => from + (to - from) * offset;
|
|
18339
|
+
const translate = (shift2, s) => `translateY(${-shift2 * (1 - s)}px)`;
|
|
18340
|
+
const timing = {
|
|
18341
|
+
duration,
|
|
18342
|
+
easing: spec.easing,
|
|
18343
|
+
// 접힘은 남겨 둔 행이 빠질 때까지 끝 위치를 붙잡는다 — 놓으면 그 사이 한 프레임 제자리로 튄다
|
|
18344
|
+
fill: to === 0 ? "forwards" : "none"
|
|
18345
|
+
};
|
|
18346
|
+
const animations = [];
|
|
18347
|
+
let shift = 0;
|
|
18348
|
+
let blockHeight = 0;
|
|
18349
|
+
let y = 0;
|
|
18350
|
+
trs.forEach(({ tr, inBlock, height }, i) => {
|
|
18351
|
+
if (inBlock && !trs[i - 1]?.inBlock) {
|
|
18352
|
+
blockHeight = 0;
|
|
18353
|
+
for (let j = i; j < trs.length && trs[j].inBlock; j++) blockHeight += trs[j].height;
|
|
18354
|
+
shift += blockHeight;
|
|
18355
|
+
y = 0;
|
|
18356
|
+
}
|
|
18357
|
+
if (shift === 0 || tr.offsetTop - shift > viewBottom) return;
|
|
18358
|
+
if (!inBlock) {
|
|
18359
|
+
animations.push(
|
|
18360
|
+
tr.animate(
|
|
18361
|
+
[{ transform: translate(shift, from) }, { transform: translate(shift, to) }],
|
|
18362
|
+
timing
|
|
18363
|
+
)
|
|
18364
|
+
);
|
|
18365
|
+
return;
|
|
18366
|
+
}
|
|
18367
|
+
const rowY = y;
|
|
18368
|
+
const clipAt = (s) => Math.min(height, Math.max(0, blockHeight * (1 - s) - rowY));
|
|
18369
|
+
const bends = [1 - rowY / blockHeight, 1 - (rowY + height) / blockHeight].map((s) => (s - from) / (to - from)).filter((offset) => offset > 0 && offset < 1);
|
|
18370
|
+
const offsets = [0, ...bends, 1].sort((a, b) => a - b);
|
|
18371
|
+
animations.push(
|
|
18372
|
+
tr.animate(
|
|
18373
|
+
offsets.map((offset) => ({
|
|
18374
|
+
offset,
|
|
18375
|
+
transform: translate(shift, openAt(offset)),
|
|
18376
|
+
clipPath: `inset(${clipAt(openAt(offset))}px 0 0 0)`
|
|
18377
|
+
})),
|
|
18378
|
+
timing
|
|
18379
|
+
)
|
|
18380
|
+
);
|
|
18381
|
+
y += height;
|
|
18382
|
+
});
|
|
18383
|
+
if (animations.length === 0) return null;
|
|
18384
|
+
return {
|
|
18385
|
+
keys: blockKeys,
|
|
18386
|
+
to,
|
|
18387
|
+
done: false,
|
|
18388
|
+
finished: Promise.all(animations.map((animation) => animation.finished)).then(
|
|
18389
|
+
() => true,
|
|
18390
|
+
() => false
|
|
18391
|
+
),
|
|
18392
|
+
openness: () => {
|
|
18393
|
+
const progress = animations[0].effect?.getComputedTiming().progress;
|
|
18394
|
+
return progress == null ? to : openAt(progress);
|
|
18395
|
+
},
|
|
18396
|
+
cancel: () => animations.forEach((animation) => animation.cancel())
|
|
18397
|
+
};
|
|
18398
|
+
}
|
|
18156
18399
|
var OWN_CONTROL_SELECTOR = 'a, button, input, select, textarea, label, [role="button"], [role="checkbox"], [contenteditable="true"]';
|
|
18157
18400
|
function isOwnControl(target, cell) {
|
|
18158
18401
|
if (!(target instanceof Element)) return false;
|
|
@@ -19407,6 +19650,7 @@ function SDatePicker({
|
|
|
19407
19650
|
placeholder,
|
|
19408
19651
|
selectable,
|
|
19409
19652
|
disabled = false,
|
|
19653
|
+
showWeekday = false,
|
|
19410
19654
|
clearable = false,
|
|
19411
19655
|
width,
|
|
19412
19656
|
maxWidth,
|
|
@@ -19436,6 +19680,7 @@ function SDatePicker({
|
|
|
19436
19680
|
const [focused, setFocused] = useState(false);
|
|
19437
19681
|
const [ruleError, setRuleError] = useState("");
|
|
19438
19682
|
const hasValue = value != null && value !== "";
|
|
19683
|
+
const weekday = showWeekday && mode === "date";
|
|
19439
19684
|
const resolvedPlaceholder = placeholder ?? (mode === "year" ? "YYYY" : mode === "month" ? "YYYY-MM" : "YYYY-MM-DD");
|
|
19440
19685
|
useFormField({
|
|
19441
19686
|
name,
|
|
@@ -19448,7 +19693,7 @@ function SDatePicker({
|
|
|
19448
19693
|
});
|
|
19449
19694
|
const resolvedError = error || ruleError !== "";
|
|
19450
19695
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
19451
|
-
const
|
|
19696
|
+
const baseDims = size === "md" ? {
|
|
19452
19697
|
padX: 16,
|
|
19453
19698
|
gap: 12,
|
|
19454
19699
|
icon: 20,
|
|
@@ -19473,6 +19718,13 @@ function SDatePicker({
|
|
|
19473
19718
|
lineHeight: 20,
|
|
19474
19719
|
radius: 4
|
|
19475
19720
|
};
|
|
19721
|
+
const weekdayW = weekday ? weekdaySuffixWidth(baseDims.fontSize) : 0;
|
|
19722
|
+
const dims = {
|
|
19723
|
+
...baseDims,
|
|
19724
|
+
minW: baseDims.minW + weekdayW,
|
|
19725
|
+
fieldMinW: baseDims.fieldMinW + weekdayW,
|
|
19726
|
+
fieldMaxW: weekdayW ? `calc(${fieldWidthValue(baseDims.fieldMaxW)} + ${weekdayW}px)` : baseDims.fieldMaxW
|
|
19727
|
+
};
|
|
19476
19728
|
const select = (date) => {
|
|
19477
19729
|
onValueChange?.(date);
|
|
19478
19730
|
if (rules && rules.length > 0) setRuleError(runRules(date, rules));
|
|
@@ -19557,7 +19809,7 @@ function SDatePicker({
|
|
|
19557
19809
|
lineHeight: `${dims.lineHeight}px`,
|
|
19558
19810
|
color: disabled ? "var(--cmp-datepicker-text-disabled)" : hasValue ? "var(--cmp-datepicker-text-default)" : "var(--cmp-field-hint-color)"
|
|
19559
19811
|
},
|
|
19560
|
-
children: hasValue ? value : resolvedPlaceholder
|
|
19812
|
+
children: hasValue ? weekday ? withWeekday(value) : value : resolvedPlaceholder
|
|
19561
19813
|
}
|
|
19562
19814
|
),
|
|
19563
19815
|
clearable && hasValue && !disabled && /* @__PURE__ */ jsx(
|
|
@@ -19951,6 +20203,7 @@ function SDateRangePicker({
|
|
|
19951
20203
|
selectable,
|
|
19952
20204
|
maxRange,
|
|
19953
20205
|
showTimePicker = false,
|
|
20206
|
+
showWeekday = false,
|
|
19954
20207
|
disabled = false,
|
|
19955
20208
|
clearable = false,
|
|
19956
20209
|
width,
|
|
@@ -19982,8 +20235,10 @@ function SDateRangePicker({
|
|
|
19982
20235
|
const [pendingStart, setPendingStart] = useState(null);
|
|
19983
20236
|
const hasValue = value != null && value[0] !== "" && value[1] !== "";
|
|
19984
20237
|
const hasDisplay = pendingStart != null || hasValue;
|
|
19985
|
-
const
|
|
19986
|
-
const
|
|
20238
|
+
const rawStart = pendingStart ?? (hasValue ? value[0] : "");
|
|
20239
|
+
const rawEnd = pendingStart ? "" : hasValue ? value[1] : "";
|
|
20240
|
+
const startText = showWeekday && rawStart ? withWeekday(rawStart) : rawStart;
|
|
20241
|
+
const endText = showWeekday && rawEnd ? withWeekday(rawEnd) : rawEnd;
|
|
19987
20242
|
useFormField({
|
|
19988
20243
|
name,
|
|
19989
20244
|
validate: () => {
|
|
@@ -19995,7 +20250,7 @@ function SDateRangePicker({
|
|
|
19995
20250
|
});
|
|
19996
20251
|
const resolvedError = error || ruleError !== "";
|
|
19997
20252
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
19998
|
-
const
|
|
20253
|
+
const baseDims = size === "md" ? {
|
|
19999
20254
|
padX: 16,
|
|
20000
20255
|
gap: 12,
|
|
20001
20256
|
icon: 20,
|
|
@@ -20019,6 +20274,13 @@ function SDateRangePicker({
|
|
|
20019
20274
|
lineHeight: 20,
|
|
20020
20275
|
radius: 4
|
|
20021
20276
|
};
|
|
20277
|
+
const weekdayW = showWeekday ? weekdaySuffixWidth(baseDims.fontSize) * 2 : 0;
|
|
20278
|
+
const dims = {
|
|
20279
|
+
...baseDims,
|
|
20280
|
+
minW: baseDims.minW + weekdayW,
|
|
20281
|
+
fieldMinW: baseDims.fieldMinW + weekdayW,
|
|
20282
|
+
fieldMaxW: weekdayW ? `calc(${fieldWidthValue(baseDims.fieldMaxW)} + ${weekdayW}px)` : baseDims.fieldMaxW
|
|
20283
|
+
};
|
|
20022
20284
|
const select = (r3) => {
|
|
20023
20285
|
setPendingStart(null);
|
|
20024
20286
|
onValueChange?.(r3);
|
|
@@ -26020,7 +26282,7 @@ var isAtResetTarget = (field, value) => {
|
|
|
26020
26282
|
var isInlineField = (field) => isInlineDateField(field) || field.type === "custom";
|
|
26021
26283
|
var isFixedField = (field) => field.fixed === true || field.required === true;
|
|
26022
26284
|
var isAddableField = (field) => !isFixedField(field);
|
|
26023
|
-
var
|
|
26285
|
+
var sameKeys2 = (a, b) => a.length === b.length && a.every((key, index) => key === b[index]);
|
|
26024
26286
|
var isGroupSatisfied = (group, values) => {
|
|
26025
26287
|
if (!group.rule) return true;
|
|
26026
26288
|
const keys = group.fields.map((f) => f.key);
|
|
@@ -26203,7 +26465,7 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
|
|
|
26203
26465
|
const kept = current.filter((key) => known.has(key));
|
|
26204
26466
|
const additions = fields.filter((field) => isFixedField(field) && !kept.includes(field.key)).map((field) => field.key);
|
|
26205
26467
|
const next = [...kept, ...additions];
|
|
26206
|
-
return
|
|
26468
|
+
return sameKeys2(current, next) ? current : next;
|
|
26207
26469
|
});
|
|
26208
26470
|
}, [fields, values]);
|
|
26209
26471
|
useEffect(() => {
|