sellmate-design-system-react 9.0.0-beta.91 → 9.0.0-beta.92
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 +7 -0
- package/dist/components/SGnbSystem/README.md +6 -2
- package/dist/components/SGnbSystem/SGnbSystem.d.ts +3 -3
- package/dist/components/SGnbSystem/gnbSystem.config.d.ts +5 -3
- package/dist/components/STimePicker/README.md +1 -1
- package/dist/components/STimePicker/STimePicker.d.ts +3 -7
- package/dist/components/STimePicker/TimeListbox.d.ts +21 -0
- package/dist/components/STimeRangePicker/README.md +2 -2
- package/dist/components/STimeRangePicker/STimeRangePicker.d.ts +5 -1
- package/dist/index.cjs +215 -459
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +215 -459
- package/dist/index.js.map +1 -1
- package/dist/lib/mode-listbox.d.ts +10 -0
- package/dist/llms-full.txt +15 -5
- package/dist/llms.txt +7 -0
- package/dist/styles.css +3 -29
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -13423,9 +13423,20 @@ var SystemButton = /* @__PURE__ */ react.forwardRef(function SystemButton2({
|
|
|
13423
13423
|
}
|
|
13424
13424
|
),
|
|
13425
13425
|
label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-semibold min-w-0 truncate", children: label }),
|
|
13426
|
-
count != null && count > 0 && //
|
|
13426
|
+
count != null && count > 0 && // 개수는 채운 배지로 단다 — 배경·글자색·치수는 xs deep 태그 토큰이 쥔다(시안).
|
|
13427
|
+
// 배지 색은 고정이다: 흰 면은 파랑, 어두운 면(dark·darker)은 노랑 바탕에 검은 글자.
|
|
13428
|
+
// 배지 오른쪽은 버튼 여백(alertButton.paddingX)만으로는 좁다 — 시안이 4px 을 더 준다.
|
|
13427
13429
|
// 대응 토큰이 없어 디자인 값을 그대로 쓴다.
|
|
13428
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13430
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13431
|
+
STag,
|
|
13432
|
+
{
|
|
13433
|
+
size: "xs",
|
|
13434
|
+
deep: true,
|
|
13435
|
+
color: color === "light" ? "blue" : "yellow",
|
|
13436
|
+
label: count.toLocaleString(),
|
|
13437
|
+
className: "me-[4px] shrink-0"
|
|
13438
|
+
}
|
|
13439
|
+
)
|
|
13429
13440
|
]
|
|
13430
13441
|
}
|
|
13431
13442
|
);
|
|
@@ -14304,7 +14315,7 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
|
|
|
14304
14315
|
items.findIndex((item4, index) => getItemValue(item4, index) === value)
|
|
14305
14316
|
);
|
|
14306
14317
|
const lastCompletedIndex = items.reduce(
|
|
14307
|
-
(
|
|
14318
|
+
(lastIndex2, item4, index) => item4.completed === true ? index : lastIndex2,
|
|
14308
14319
|
-1
|
|
14309
14320
|
);
|
|
14310
14321
|
const resolvedClickableIndex = lastCompletedIndex + 1;
|
|
@@ -19403,13 +19414,21 @@ function SCalendar({
|
|
|
19403
19414
|
}
|
|
19404
19415
|
);
|
|
19405
19416
|
}
|
|
19417
|
+
|
|
19418
|
+
// src/lib/mode-listbox.ts
|
|
19419
|
+
var MODE_LIST_HEIGHT = 240;
|
|
19420
|
+
var MODE_ITEM_HEIGHT = 28;
|
|
19421
|
+
var modeListItemClass = (selected, disabled) => cn(
|
|
19422
|
+
"flex w-full items-center justify-center gap-[var(--cmp-datepicker-mode-item-gap)] border-0 px-[var(--cmp-datepicker-mode-item-paddingX)] py-[var(--cmp-datepicker-mode-item-paddingY)] text-center font-base text-12 leading-[20px]",
|
|
19423
|
+
disabled && "cursor-not-allowed bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-disabled)]",
|
|
19424
|
+
!disabled && !selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-default)] hover:bg-[var(--cmp-datepicker-mode-item-bg-hover)] hover:text-[color:var(--cmp-datepicker-mode-item-content-hover)]",
|
|
19425
|
+
!disabled && selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-bold text-[color:var(--cmp-datepicker-mode-item-content-selected)]"
|
|
19426
|
+
);
|
|
19406
19427
|
var MODE_NOUN = {
|
|
19407
19428
|
date: "\uB0A0\uC9DC",
|
|
19408
19429
|
month: "\uC6D4",
|
|
19409
19430
|
year: "\uC5F0\uB3C4"
|
|
19410
19431
|
};
|
|
19411
|
-
var DATEPICKER_MODE_LIST_HEIGHT = 240;
|
|
19412
|
-
var DATEPICKER_MODE_ITEM_HEIGHT = 28;
|
|
19413
19432
|
var YEAR_LIST_EDGE_BUFFER = 24;
|
|
19414
19433
|
var YEAR_LIST_EXPAND_SIZE = 80;
|
|
19415
19434
|
var MONTHS = Array.from({ length: 12 }, (_, i) => i + 1);
|
|
@@ -19460,7 +19479,7 @@ function YearWheel({ value, anchorYear, selectable, onCommit }) {
|
|
|
19460
19479
|
if (!list) return;
|
|
19461
19480
|
const index = anchorYearRef.current - rangeStartRef.current;
|
|
19462
19481
|
syncingScrollRef.current = true;
|
|
19463
|
-
list.scrollTop = index *
|
|
19482
|
+
list.scrollTop = index * MODE_ITEM_HEIGHT;
|
|
19464
19483
|
requestAnimationFrame(() => {
|
|
19465
19484
|
syncingScrollRef.current = false;
|
|
19466
19485
|
});
|
|
@@ -19469,7 +19488,7 @@ function YearWheel({ value, anchorYear, selectable, onCommit }) {
|
|
|
19469
19488
|
const list = listRef.current;
|
|
19470
19489
|
if (!list) return;
|
|
19471
19490
|
if (syncingScrollRef.current) return;
|
|
19472
|
-
if (list.scrollTop <
|
|
19491
|
+
if (list.scrollTop < MODE_ITEM_HEIGHT * YEAR_LIST_EDGE_BUFFER) {
|
|
19473
19492
|
const previousHeight = list.scrollHeight;
|
|
19474
19493
|
setRange((current) => ({
|
|
19475
19494
|
start: current.start - YEAR_LIST_EXPAND_SIZE,
|
|
@@ -19485,7 +19504,7 @@ function YearWheel({ value, anchorYear, selectable, onCommit }) {
|
|
|
19485
19504
|
});
|
|
19486
19505
|
return;
|
|
19487
19506
|
}
|
|
19488
|
-
if (list.scrollHeight - list.scrollTop - list.clientHeight <
|
|
19507
|
+
if (list.scrollHeight - list.scrollTop - list.clientHeight < MODE_ITEM_HEIGHT * YEAR_LIST_EDGE_BUFFER) {
|
|
19489
19508
|
setRange((current) => ({
|
|
19490
19509
|
start: current.start,
|
|
19491
19510
|
end: current.end + YEAR_LIST_EXPAND_SIZE
|
|
@@ -19500,8 +19519,8 @@ function YearWheel({ value, anchorYear, selectable, onCommit }) {
|
|
|
19500
19519
|
"aria-label": "year",
|
|
19501
19520
|
className: "h-full overflow-y-auto overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
19502
19521
|
style: {
|
|
19503
|
-
paddingTop: `calc((${
|
|
19504
|
-
paddingBottom: `calc((${
|
|
19522
|
+
paddingTop: `calc((${MODE_LIST_HEIGHT}px - ${MODE_ITEM_HEIGHT}px) / 2)`,
|
|
19523
|
+
paddingBottom: `calc((${MODE_LIST_HEIGHT}px - ${MODE_ITEM_HEIGHT}px) / 2)`
|
|
19505
19524
|
},
|
|
19506
19525
|
onScroll: handleScroll,
|
|
19507
19526
|
children: years.map((year) => {
|
|
@@ -19514,12 +19533,7 @@ function YearWheel({ value, anchorYear, selectable, onCommit }) {
|
|
|
19514
19533
|
role: "option",
|
|
19515
19534
|
"aria-selected": selected,
|
|
19516
19535
|
disabled,
|
|
19517
|
-
className:
|
|
19518
|
-
"flex w-full items-center justify-center gap-[var(--cmp-datepicker-mode-item-gap)] border-0 px-[var(--cmp-datepicker-mode-item-paddingX)] py-[var(--cmp-datepicker-mode-item-paddingY)] text-center font-base text-12 leading-[20px]",
|
|
19519
|
-
disabled && "cursor-not-allowed bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-disabled)]",
|
|
19520
|
-
!disabled && !selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-default)] hover:bg-[var(--cmp-datepicker-mode-item-bg-hover)] hover:text-[color:var(--cmp-datepicker-mode-item-content-hover)]",
|
|
19521
|
-
!disabled && selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-bold text-[color:var(--cmp-datepicker-mode-item-content-selected)]"
|
|
19522
|
-
),
|
|
19536
|
+
className: modeListItemClass(selected, disabled),
|
|
19523
19537
|
onClick: () => !disabled && onCommit(year),
|
|
19524
19538
|
children: year
|
|
19525
19539
|
},
|
|
@@ -19575,7 +19589,7 @@ function MonthWheel({ year, value, selectable, onCommit }) {
|
|
|
19575
19589
|
if (!list) return;
|
|
19576
19590
|
list.scrollTop = Math.max(
|
|
19577
19591
|
0,
|
|
19578
|
-
(initialValueRef.current - 1) *
|
|
19592
|
+
(initialValueRef.current - 1) * MODE_ITEM_HEIGHT - (list.clientHeight - MODE_ITEM_HEIGHT) / 2
|
|
19579
19593
|
);
|
|
19580
19594
|
}, []);
|
|
19581
19595
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full overflow-hidden bg-[var(--cmp-datepicker-mode-bg)]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -19595,12 +19609,7 @@ function MonthWheel({ year, value, selectable, onCommit }) {
|
|
|
19595
19609
|
role: "option",
|
|
19596
19610
|
"aria-selected": selected,
|
|
19597
19611
|
disabled,
|
|
19598
|
-
className:
|
|
19599
|
-
"flex w-full items-center justify-center gap-[var(--cmp-datepicker-mode-item-gap)] border-0 px-[var(--cmp-datepicker-mode-item-paddingX)] py-[var(--cmp-datepicker-mode-item-paddingY)] text-center font-base text-12 leading-[20px]",
|
|
19600
|
-
disabled && "cursor-not-allowed bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-disabled)]",
|
|
19601
|
-
!disabled && !selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-default)] hover:bg-[var(--cmp-datepicker-mode-item-bg-hover)] hover:text-[color:var(--cmp-datepicker-mode-item-content-hover)]",
|
|
19602
|
-
!disabled && selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-bold text-[color:var(--cmp-datepicker-mode-item-content-selected)]"
|
|
19603
|
-
),
|
|
19612
|
+
className: modeListItemClass(selected, disabled),
|
|
19604
19613
|
onClick: () => !disabled && onCommit(month),
|
|
19605
19614
|
children: [
|
|
19606
19615
|
month,
|
|
@@ -28687,212 +28696,171 @@ function formatTimeDisplay(value, type) {
|
|
|
28687
28696
|
const displayHour = hour % 12 === 0 ? 12 : hour % 12;
|
|
28688
28697
|
return `${meridiem} ${padTimePart(displayHour)}:${padTimePart(minute)}`;
|
|
28689
28698
|
}
|
|
28690
|
-
|
|
28691
|
-
|
|
28692
|
-
|
|
28699
|
+
function scrollSelectedIntoView(list, index, center) {
|
|
28700
|
+
const top = index * MODE_ITEM_HEIGHT;
|
|
28701
|
+
if (center) {
|
|
28702
|
+
list.scrollTop = Math.max(0, top - (list.clientHeight - MODE_ITEM_HEIGHT) / 2);
|
|
28703
|
+
return;
|
|
28704
|
+
}
|
|
28705
|
+
if (top < list.scrollTop) list.scrollTop = top;
|
|
28706
|
+
else if (top + MODE_ITEM_HEIGHT > list.scrollTop + list.clientHeight)
|
|
28707
|
+
list.scrollTop = top + MODE_ITEM_HEIGHT - list.clientHeight;
|
|
28708
|
+
}
|
|
28709
|
+
function lastIndex(arr, pred) {
|
|
28710
|
+
for (let i = arr.length - 1; i >= 0; i--) if (pred(arr[i], i)) return i;
|
|
28711
|
+
return -1;
|
|
28712
|
+
}
|
|
28713
|
+
function ListColumn({ ariaLabel, items }) {
|
|
28714
|
+
const listRef = react.useRef(null);
|
|
28715
|
+
const mountedRef = react.useRef(false);
|
|
28716
|
+
const selectedIndex = items.findIndex((item4) => item4.selected);
|
|
28717
|
+
const tabIndexTarget = selectedIndex >= 0 ? selectedIndex : items.findIndex((item4) => !item4.disabled);
|
|
28718
|
+
react.useLayoutEffect(() => {
|
|
28719
|
+
const list = listRef.current;
|
|
28720
|
+
if (!list || selectedIndex < 0) return;
|
|
28721
|
+
scrollSelectedIntoView(list, selectedIndex, !mountedRef.current);
|
|
28722
|
+
mountedRef.current = true;
|
|
28723
|
+
}, [selectedIndex]);
|
|
28724
|
+
const onKeyDown = (event) => {
|
|
28725
|
+
const buttons = [...listRef.current?.querySelectorAll("button") ?? []];
|
|
28726
|
+
const current = buttons.indexOf(document.activeElement);
|
|
28727
|
+
if (current < 0) return;
|
|
28728
|
+
const enabled = (item4, i) => !item4.disabled && i !== current;
|
|
28729
|
+
let next;
|
|
28730
|
+
if (event.key === "ArrowDown") next = items.findIndex((it, i) => i > current && enabled(it, i));
|
|
28731
|
+
else if (event.key === "ArrowUp")
|
|
28732
|
+
next = lastIndex(items, (it, i) => i < current && enabled(it, i));
|
|
28733
|
+
else if (event.key === "Home") next = items.findIndex((it) => !it.disabled);
|
|
28734
|
+
else if (event.key === "End") next = lastIndex(items, (it) => !it.disabled);
|
|
28735
|
+
else return;
|
|
28736
|
+
event.preventDefault();
|
|
28737
|
+
if (next < 0) return;
|
|
28738
|
+
buttons[next]?.focus({ preventScroll: true });
|
|
28739
|
+
if (listRef.current) scrollSelectedIntoView(listRef.current, next, false);
|
|
28740
|
+
};
|
|
28741
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-[var(--cmp-datepicker-mode-yearMonth-column-width)] min-w-0 overflow-hidden bg-[var(--cmp-datepicker-mode-bg)]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28742
|
+
"div",
|
|
28743
|
+
{
|
|
28744
|
+
ref: listRef,
|
|
28745
|
+
role: "listbox",
|
|
28746
|
+
"aria-label": ariaLabel,
|
|
28747
|
+
tabIndex: -1,
|
|
28748
|
+
className: "h-full overflow-y-auto overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
28749
|
+
onKeyDown,
|
|
28750
|
+
children: items.map((item4, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
28751
|
+
"button",
|
|
28752
|
+
{
|
|
28753
|
+
type: "button",
|
|
28754
|
+
role: "option",
|
|
28755
|
+
"aria-selected": item4.selected,
|
|
28756
|
+
disabled: item4.disabled,
|
|
28757
|
+
tabIndex: index === tabIndexTarget ? 0 : -1,
|
|
28758
|
+
className: cn(modeListItemClass(item4.selected, item4.disabled), "outline-offset-[-2px]"),
|
|
28759
|
+
onClick: () => !item4.disabled && item4.onSelect(),
|
|
28760
|
+
children: item4.label
|
|
28761
|
+
},
|
|
28762
|
+
item4.key
|
|
28763
|
+
))
|
|
28764
|
+
}
|
|
28765
|
+
) });
|
|
28766
|
+
}
|
|
28767
|
+
var HOURS_24 = Array.from({ length: 24 }, (_, i) => i);
|
|
28768
|
+
var HOURS_12 = [12, ...Array.from({ length: 11 }, (_, i) => i + 1)];
|
|
28769
|
+
function TimeListbox({
|
|
28693
28770
|
value,
|
|
28694
28771
|
showMeridiem,
|
|
28695
28772
|
minuteStep,
|
|
28696
|
-
|
|
28773
|
+
isDisabled,
|
|
28774
|
+
onChange,
|
|
28775
|
+
labelPrefix,
|
|
28776
|
+
elevated = true
|
|
28697
28777
|
}) {
|
|
28698
|
-
const
|
|
28699
|
-
const [
|
|
28700
|
-
const [minute, setMinute] = react.useState(parsed.minute);
|
|
28701
|
-
const [editingPart, setEditingPart] = react.useState(null);
|
|
28702
|
-
const [inputDraft, setInputDraft] = react.useState({});
|
|
28778
|
+
const toState = (v) => v ? parseTimeValue(v) : null;
|
|
28779
|
+
const [time, setTime] = react.useState(() => toState(value));
|
|
28703
28780
|
react.useEffect(() => {
|
|
28704
|
-
|
|
28705
|
-
|
|
28706
|
-
|
|
28707
|
-
const
|
|
28708
|
-
const
|
|
28709
|
-
const
|
|
28710
|
-
|
|
28711
|
-
|
|
28712
|
-
|
|
28713
|
-
|
|
28714
|
-
|
|
28715
|
-
|
|
28716
|
-
|
|
28717
|
-
if (next
|
|
28718
|
-
|
|
28719
|
-
|
|
28720
|
-
const changeMinute = (delta) => {
|
|
28721
|
-
const next = minute + delta;
|
|
28722
|
-
if (next > 59) {
|
|
28723
|
-
commit((hour + 1) % 24, next - 60);
|
|
28724
|
-
return;
|
|
28725
|
-
}
|
|
28726
|
-
if (next < 0) {
|
|
28727
|
-
commit((hour + 23) % 24, next + 60);
|
|
28728
|
-
return;
|
|
28729
|
-
}
|
|
28730
|
-
commit(hour, next);
|
|
28731
|
-
};
|
|
28732
|
-
const changeHour = (delta) => commit((hour + delta + 24) % 24, minute);
|
|
28733
|
-
const sanitizeInput = (next) => next.replace(/\D/g, "").slice(0, 2);
|
|
28734
|
-
const beginEdit = (part, currentValue) => {
|
|
28735
|
-
setEditingPart(part);
|
|
28736
|
-
setInputDraft((prev) => ({ ...prev, [part]: String(currentValue).padStart(2, "0") }));
|
|
28737
|
-
};
|
|
28738
|
-
const commitHourDraft = (draft) => {
|
|
28739
|
-
const clamped = clampTimePart(Number(draft), showMeridiem ? 1 : 0, showMeridiem ? 12 : 23);
|
|
28740
|
-
const nextHour = showMeridiem ? meridiem === "PM" ? clamped === 12 ? 12 : clamped + 12 : clamped === 12 ? 0 : clamped : clamped;
|
|
28741
|
-
commit(nextHour, minute);
|
|
28742
|
-
return clamped;
|
|
28743
|
-
};
|
|
28744
|
-
const commitMinuteDraft = (draft) => {
|
|
28745
|
-
const clamped = clampTimePart(Number(draft), 0, 59);
|
|
28746
|
-
commit(hour, clamped);
|
|
28747
|
-
return clamped;
|
|
28748
|
-
};
|
|
28749
|
-
const endEdit = (part) => {
|
|
28750
|
-
const draft = inputDraft[part];
|
|
28751
|
-
if (part === "hour" && draft != null && draft !== "") {
|
|
28752
|
-
commitHourDraft(draft);
|
|
28753
|
-
}
|
|
28754
|
-
if (part === "minute" && draft != null && draft !== "") {
|
|
28755
|
-
commitMinuteDraft(draft);
|
|
28756
|
-
}
|
|
28757
|
-
setEditingPart(null);
|
|
28758
|
-
setInputDraft({});
|
|
28759
|
-
};
|
|
28760
|
-
const inputStyle = {
|
|
28761
|
-
width: "var(--cmp-timepicker-selector-time-input-width)",
|
|
28762
|
-
height: "var(--cmp-textinput-sm-height)",
|
|
28763
|
-
borderRadius: "var(--cmp-textinput-sm-radius)",
|
|
28764
|
-
border: "var(--cmp-textinput-borderWidth) solid var(--cmp-textinput-border-default)",
|
|
28765
|
-
color: "var(--cmp-textinput-text-default)",
|
|
28766
|
-
fontSize: 12,
|
|
28767
|
-
lineHeight: "20px"
|
|
28781
|
+
setTime(toState(value));
|
|
28782
|
+
}, [value]);
|
|
28783
|
+
const step = Math.max(1, Math.floor(minuteStep));
|
|
28784
|
+
const minutes = Array.from({ length: Math.ceil(60 / step) }, (_, i) => i * step);
|
|
28785
|
+
const blocked = (h, m) => isDisabled?.(h * 60 + m) ?? false;
|
|
28786
|
+
const hourBlocked = (h) => minutes.every((m) => blocked(h, m));
|
|
28787
|
+
const commit = (hours, preferred, part) => {
|
|
28788
|
+
let next = blocked(preferred.hour, preferred.minute) ? null : preferred;
|
|
28789
|
+
for (const h of hours) {
|
|
28790
|
+
if (next) break;
|
|
28791
|
+
const m = minutes.find((mm) => !blocked(h, mm));
|
|
28792
|
+
if (m !== void 0) next = { hour: h, minute: m };
|
|
28793
|
+
}
|
|
28794
|
+
if (!next) return;
|
|
28795
|
+
setTime(next);
|
|
28796
|
+
onChange(formatTimeValue(next.hour, next.minute), part);
|
|
28768
28797
|
};
|
|
28769
|
-
const
|
|
28770
|
-
|
|
28771
|
-
|
|
28772
|
-
|
|
28773
|
-
|
|
28774
|
-
|
|
28775
|
-
|
|
28776
|
-
|
|
28777
|
-
|
|
28778
|
-
|
|
28779
|
-
|
|
28780
|
-
|
|
28781
|
-
|
|
28782
|
-
|
|
28783
|
-
|
|
28784
|
-
|
|
28785
|
-
onClick: () => isHour ? changeHour(1) : changeMinute(minuteStep)
|
|
28786
|
-
}
|
|
28787
|
-
),
|
|
28788
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
28789
|
-
"input",
|
|
28790
|
-
{
|
|
28791
|
-
"aria-label": isHour ? "\uC2DC" : "\uBD84",
|
|
28792
|
-
inputMode: "numeric",
|
|
28793
|
-
value: displayValue2,
|
|
28794
|
-
placeholder: "-",
|
|
28795
|
-
onFocus: () => beginEdit(type, val),
|
|
28796
|
-
onBlur: () => endEdit(type),
|
|
28797
|
-
onChange: (event) => {
|
|
28798
|
-
const draft = sanitizeInput(event.target.value);
|
|
28799
|
-
setInputDraft((prev) => ({ ...prev, [type]: draft }));
|
|
28800
|
-
if (draft === "") return;
|
|
28801
|
-
const raw = Number(draft);
|
|
28802
|
-
if (isHour) {
|
|
28803
|
-
if (draft.length < 2) return;
|
|
28804
|
-
const clamped2 = commitHourDraft(draft);
|
|
28805
|
-
const displayDraft2 = raw === clamped2 ? draft : String(clamped2);
|
|
28806
|
-
setInputDraft((prev) => ({ ...prev, [type]: displayDraft2 }));
|
|
28807
|
-
return;
|
|
28808
|
-
}
|
|
28809
|
-
if (draft.length < 2) return;
|
|
28810
|
-
const clamped = commitMinuteDraft(draft);
|
|
28811
|
-
const displayDraft = raw === clamped ? draft : String(clamped);
|
|
28812
|
-
setInputDraft((prev) => ({ ...prev, [type]: displayDraft }));
|
|
28813
|
-
},
|
|
28814
|
-
className: "box-border bg-white text-center outline-none",
|
|
28815
|
-
style: inputStyle
|
|
28816
|
-
}
|
|
28817
|
-
),
|
|
28818
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
28819
|
-
SGhostButton,
|
|
28820
|
-
{
|
|
28821
|
-
icon: "chevronDown",
|
|
28822
|
-
size: "xs",
|
|
28823
|
-
ariaLabel: `${isHour ? "\uC2DC" : "\uBD84"} \uAC10\uC18C`,
|
|
28824
|
-
onClick: () => isHour ? changeHour(-1) : changeMinute(-minuteStep)
|
|
28825
|
-
}
|
|
28826
|
-
)
|
|
28827
|
-
]
|
|
28798
|
+
const hour = time?.hour;
|
|
28799
|
+
const minute = time?.minute ?? 0;
|
|
28800
|
+
const meridiem = hour === void 0 ? void 0 : hour >= 12 ? "PM" : "AM";
|
|
28801
|
+
const prefix = labelPrefix ? `${labelPrefix} ` : "";
|
|
28802
|
+
const meridiemItems = ["AM", "PM"].map((item4) => {
|
|
28803
|
+
const base = item4 === "AM" ? 0 : 12;
|
|
28804
|
+
const range = HOURS_24.slice(base, base + 12);
|
|
28805
|
+
return {
|
|
28806
|
+
key: item4,
|
|
28807
|
+
label: item4 === "AM" ? "\uC624\uC804" : "\uC624\uD6C4",
|
|
28808
|
+
selected: meridiem === item4,
|
|
28809
|
+
disabled: range.every(hourBlocked),
|
|
28810
|
+
onSelect: () => {
|
|
28811
|
+
if (meridiem === item4) return;
|
|
28812
|
+
const h = hour === void 0 ? base : hour % 12 + base;
|
|
28813
|
+
commit(range, { hour: h, minute }, "meridiem");
|
|
28828
28814
|
}
|
|
28829
|
-
|
|
28830
|
-
};
|
|
28815
|
+
};
|
|
28816
|
+
});
|
|
28817
|
+
const hourItems = showMeridiem ? HOURS_12.map((display) => {
|
|
28818
|
+
const h = display % 12 + (meridiem === "PM" ? 12 : 0);
|
|
28819
|
+
return {
|
|
28820
|
+
key: String(display),
|
|
28821
|
+
label: `${padTimePart(display)}\uC2DC`,
|
|
28822
|
+
selected: hour === h,
|
|
28823
|
+
disabled: hourBlocked(h),
|
|
28824
|
+
onSelect: () => commit([h], { hour: h, minute }, "hour")
|
|
28825
|
+
};
|
|
28826
|
+
}) : HOURS_24.map((h) => ({
|
|
28827
|
+
key: String(h),
|
|
28828
|
+
label: `${padTimePart(h)}\uC2DC`,
|
|
28829
|
+
selected: hour === h,
|
|
28830
|
+
disabled: hourBlocked(h),
|
|
28831
|
+
onSelect: () => commit([h], { hour: h, minute }, "hour")
|
|
28832
|
+
}));
|
|
28833
|
+
const minuteHour = hour ?? (meridiem === "PM" ? 12 : 0);
|
|
28834
|
+
const minuteItems = minutes.map((m) => ({
|
|
28835
|
+
key: String(m),
|
|
28836
|
+
label: `${padTimePart(m)}\uBD84`,
|
|
28837
|
+
selected: time != null && minute === m,
|
|
28838
|
+
disabled: blocked(minuteHour, m),
|
|
28839
|
+
onSelect: () => commit([minuteHour], { hour: minuteHour, minute: m }, "minute")
|
|
28840
|
+
}));
|
|
28841
|
+
const divider = /* @__PURE__ */ jsxRuntime.jsx(
|
|
28842
|
+
"div",
|
|
28843
|
+
{
|
|
28844
|
+
"aria-hidden": true,
|
|
28845
|
+
className: "w-[var(--border-width-1)] self-stretch bg-[var(--sys-color-divider-default)]"
|
|
28846
|
+
}
|
|
28847
|
+
);
|
|
28831
28848
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28832
28849
|
"div",
|
|
28833
28850
|
{
|
|
28834
|
-
className:
|
|
28835
|
-
|
|
28836
|
-
|
|
28837
|
-
|
|
28838
|
-
|
|
28839
|
-
},
|
|
28851
|
+
className: cn(
|
|
28852
|
+
"inline-flex gap-[var(--cmp-datepicker-mode-yearMonth-gap)] overflow-hidden bg-[var(--cmp-datepicker-mode-bg)]",
|
|
28853
|
+
elevated && "rounded-[var(--cmp-datepicker-mode-radius)] shadow-normal-sm"
|
|
28854
|
+
),
|
|
28855
|
+
style: { height: MODE_LIST_HEIGHT },
|
|
28840
28856
|
children: [
|
|
28841
|
-
showMeridiem && /* @__PURE__ */ jsxRuntime.
|
|
28842
|
-
|
|
28843
|
-
|
|
28844
|
-
|
|
28845
|
-
|
|
28846
|
-
|
|
28847
|
-
|
|
28848
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "isolate flex", children: ["AM", "PM"].map((item4, index) => {
|
|
28849
|
-
const selected = item4 === meridiem;
|
|
28850
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
28851
|
-
"button",
|
|
28852
|
-
{
|
|
28853
|
-
type: "button",
|
|
28854
|
-
onClick: () => setMeridiem(item4),
|
|
28855
|
-
className: cn(
|
|
28856
|
-
"box-border h-[var(--cmp-textinput-sm-height)] w-[61px] cursor-pointer border border-solid bg-white text-center text-[12px] font-medium leading-[20px]",
|
|
28857
|
-
index === 0 ? "rounded-l-[var(--cmp-select-sm-radius)]" : "rounded-r-[var(--cmp-select-sm-radius)]",
|
|
28858
|
-
index === 0 ? "-mr-px" : "",
|
|
28859
|
-
selected ? "z-[1] border-[var(--cmp-timepicker-border-focus)] text-[var(--cmp-timepicker-border-focus)]" : "border-[var(--cmp-timepicker-border-default)] text-[var(--cmp-field-hint-color)]"
|
|
28860
|
-
),
|
|
28861
|
-
children: item4 === "AM" ? "\uC624\uC804" : "\uC624\uD6C4"
|
|
28862
|
-
},
|
|
28863
|
-
item4
|
|
28864
|
-
);
|
|
28865
|
-
}) })
|
|
28866
|
-
}
|
|
28867
|
-
),
|
|
28868
|
-
showMeridiem && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px w-full bg-[var(--sys-color-divider-default)]" }),
|
|
28869
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
28870
|
-
"div",
|
|
28871
|
-
{
|
|
28872
|
-
className: "flex items-center justify-center",
|
|
28873
|
-
style: {
|
|
28874
|
-
gap: "var(--cmp-timepicker-selector-time-gap)",
|
|
28875
|
-
padding: "var(--cmp-timepicker-selector-section-paddingY) var(--cmp-timepicker-selector-section-paddingX)"
|
|
28876
|
-
},
|
|
28877
|
-
children: [
|
|
28878
|
-
renderColumn("hour"),
|
|
28879
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
28880
|
-
"span",
|
|
28881
|
-
{
|
|
28882
|
-
className: "text-center",
|
|
28883
|
-
style: {
|
|
28884
|
-
width: "var(--cmp-timepicker-selector-colon-size)",
|
|
28885
|
-
color: "var(--cmp-field-hint-color)",
|
|
28886
|
-
fontSize: "var(--cmp-timepicker-selector-colon-size)",
|
|
28887
|
-
lineHeight: "var(--cmp-timepicker-selector-colon-size)"
|
|
28888
|
-
},
|
|
28889
|
-
children: ":"
|
|
28890
|
-
}
|
|
28891
|
-
),
|
|
28892
|
-
renderColumn("minute")
|
|
28893
|
-
]
|
|
28894
|
-
}
|
|
28895
|
-
)
|
|
28857
|
+
showMeridiem && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
28858
|
+
/* @__PURE__ */ jsxRuntime.jsx(ListColumn, { ariaLabel: `${prefix}\uC624\uC804/\uC624\uD6C4`, items: meridiemItems }),
|
|
28859
|
+
divider
|
|
28860
|
+
] }),
|
|
28861
|
+
/* @__PURE__ */ jsxRuntime.jsx(ListColumn, { ariaLabel: `${prefix}\uC2DC`, items: hourItems }),
|
|
28862
|
+
divider,
|
|
28863
|
+
/* @__PURE__ */ jsxRuntime.jsx(ListColumn, { ariaLabel: `${prefix}\uBD84`, items: minuteItems })
|
|
28896
28864
|
]
|
|
28897
28865
|
}
|
|
28898
28866
|
);
|
|
@@ -28930,11 +28898,9 @@ function STimePicker({
|
|
|
28930
28898
|
style
|
|
28931
28899
|
}) {
|
|
28932
28900
|
const portalContainer = usePortalContainer();
|
|
28933
|
-
const triggerRef = react.useRef(null);
|
|
28934
28901
|
const [open, setOpen] = react.useState(false);
|
|
28935
28902
|
const triggerId = useFieldControlId();
|
|
28936
28903
|
const triggerTextId = `${triggerId}-text`;
|
|
28937
|
-
const [popoverAlignOffset, setPopoverAlignOffset] = react.useState(0);
|
|
28938
28904
|
const [focused, setFocused] = react.useState(false);
|
|
28939
28905
|
const [ruleError, setRuleError] = react.useState("");
|
|
28940
28906
|
const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
|
|
@@ -28955,11 +28921,6 @@ function STimePicker({
|
|
|
28955
28921
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
28956
28922
|
const commitOpen = (next) => {
|
|
28957
28923
|
if (disabled) return;
|
|
28958
|
-
if (next) {
|
|
28959
|
-
const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
|
|
28960
|
-
const selectorWidth = effectiveShowMeridiem ? MERIDIEM_TIME_SELECTOR_WIDTH : TIME_SELECTOR_WIDTH;
|
|
28961
|
-
setPopoverAlignOffset(Math.max(0, (triggerWidth - selectorWidth) / 2));
|
|
28962
|
-
}
|
|
28963
28924
|
setOpen(next);
|
|
28964
28925
|
onOpenChange?.(next);
|
|
28965
28926
|
if (!next && rules && rules.length > 0) setRuleError(runRules(value, rules));
|
|
@@ -28998,7 +28959,6 @@ function STimePicker({
|
|
|
28998
28959
|
/* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28999
28960
|
"div",
|
|
29000
28961
|
{
|
|
29001
|
-
ref: triggerRef,
|
|
29002
28962
|
id: triggerId,
|
|
29003
28963
|
role: "button",
|
|
29004
28964
|
"aria-disabled": disabled,
|
|
@@ -29062,20 +29022,22 @@ function STimePicker({
|
|
|
29062
29022
|
RPopover13__namespace.Content,
|
|
29063
29023
|
{
|
|
29064
29024
|
side: "bottom",
|
|
29065
|
-
align: "
|
|
29025
|
+
align: "center",
|
|
29066
29026
|
sideOffset: 4,
|
|
29067
|
-
alignOffset: popoverAlignOffset,
|
|
29068
29027
|
className: cn(
|
|
29069
29028
|
"z-50 max-w-[var(--radix-popover-content-available-width)]",
|
|
29070
29029
|
FLOATING_SLIDE_ANIM
|
|
29071
29030
|
),
|
|
29072
29031
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29073
|
-
|
|
29032
|
+
TimeListbox,
|
|
29074
29033
|
{
|
|
29075
29034
|
value: normalized,
|
|
29076
29035
|
showMeridiem: effectiveShowMeridiem,
|
|
29077
29036
|
minuteStep,
|
|
29078
|
-
onChange:
|
|
29037
|
+
onChange: (time, part) => {
|
|
29038
|
+
commitValue(time);
|
|
29039
|
+
if (part === "minute") commitOpen(false);
|
|
29040
|
+
}
|
|
29079
29041
|
}
|
|
29080
29042
|
)
|
|
29081
29043
|
}
|
|
@@ -29105,7 +29067,6 @@ function formatTimeRangeDisplay(value, type) {
|
|
|
29105
29067
|
if (value == null || value[0] === "" || value[1] === "") return "";
|
|
29106
29068
|
return `${formatTimeDisplay(value[0], type)} ~ ${formatTimeDisplay(value[1], type)}`;
|
|
29107
29069
|
}
|
|
29108
|
-
var TIME_RANGE_SELECTOR_WIDTH = 345;
|
|
29109
29070
|
var MIDDAY_FIELD_MIN_WIDTH = {
|
|
29110
29071
|
sm: 178,
|
|
29111
29072
|
md: 216
|
|
@@ -29114,6 +29075,10 @@ var MIDDAY_FIELD_MAX_WIDTH = {
|
|
|
29114
29075
|
sm: "lg",
|
|
29115
29076
|
md: "lg"
|
|
29116
29077
|
};
|
|
29078
|
+
var toMinutes = (time) => {
|
|
29079
|
+
const { hour, minute } = parseTimeValue(time);
|
|
29080
|
+
return hour * 60 + minute;
|
|
29081
|
+
};
|
|
29117
29082
|
function RangeTimeSelector({
|
|
29118
29083
|
value,
|
|
29119
29084
|
showMeridiem,
|
|
@@ -29121,233 +29086,32 @@ function RangeTimeSelector({
|
|
|
29121
29086
|
rangeOrder,
|
|
29122
29087
|
onChange
|
|
29123
29088
|
}) {
|
|
29124
|
-
const range =
|
|
29125
|
-
const
|
|
29126
|
-
const
|
|
29127
|
-
|
|
29128
|
-
|
|
29129
|
-
const getMeridiem = (side) => getParts(side).hour >= 12 ? "PM" : "AM";
|
|
29130
|
-
const getDisplayHour = (side) => {
|
|
29131
|
-
const { hour } = getParts(side);
|
|
29132
|
-
if (!showMeridiem) return hour;
|
|
29133
|
-
const displayHour = hour % 12;
|
|
29134
|
-
return displayHour === 0 ? 12 : displayHour;
|
|
29135
|
-
};
|
|
29136
|
-
const commit = (side, hour, minute, direction = "unknown") => {
|
|
29137
|
-
const next = formatTimeValue(hour, minute);
|
|
29138
|
-
onChange(
|
|
29139
|
-
normalizeNextRange(side === "start" ? [next, range[1]] : [range[0], next], side, direction)
|
|
29140
|
-
);
|
|
29141
|
-
};
|
|
29142
|
-
const getTimeMinutes2 = (time) => {
|
|
29143
|
-
const { hour, minute } = parseTimeValue(time);
|
|
29144
|
-
return hour * 60 + minute;
|
|
29145
|
-
};
|
|
29146
|
-
const normalizeNextRange = (nextRange, changedSide, direction) => {
|
|
29147
|
-
if (rangeOrder === "allow-cross-day") return nextRange;
|
|
29148
|
-
const [start, end] = nextRange;
|
|
29149
|
-
const [currentStart, currentEnd] = range;
|
|
29150
|
-
if (getTimeMinutes2(start) <= getTimeMinutes2(end)) {
|
|
29151
|
-
const shouldKeepSynced = autoAdjustedRef.current?.side === changedSide && currentStart === currentEnd && start !== end && (direction === "unknown" || autoAdjustedRef.current.direction === direction);
|
|
29152
|
-
if (shouldKeepSynced) {
|
|
29153
|
-
return changedSide === "start" ? [start, start] : [end, end];
|
|
29154
|
-
}
|
|
29155
|
-
autoAdjustedRef.current = null;
|
|
29156
|
-
return nextRange;
|
|
29157
|
-
}
|
|
29158
|
-
autoAdjustedRef.current = {
|
|
29159
|
-
side: changedSide,
|
|
29160
|
-
direction: changedSide === "start" ? "increase" : "decrease"
|
|
29161
|
-
};
|
|
29162
|
-
return changedSide === "start" ? [start, start] : [end, end];
|
|
29163
|
-
};
|
|
29164
|
-
const changeHour = (side, delta) => {
|
|
29165
|
-
const { hour, minute } = getParts(side);
|
|
29166
|
-
commit(side, (hour + delta + 24) % 24, minute, delta > 0 ? "increase" : "decrease");
|
|
29167
|
-
};
|
|
29168
|
-
const changeMinute = (side, delta) => {
|
|
29169
|
-
const { hour, minute } = getParts(side);
|
|
29170
|
-
const next = minute + delta;
|
|
29171
|
-
if (next > 59) {
|
|
29172
|
-
commit(side, (hour + 1) % 24, next - 60, delta > 0 ? "increase" : "decrease");
|
|
29089
|
+
const range = value ?? ["00:00", "23:59"];
|
|
29090
|
+
const strict = rangeOrder !== "allow-cross-day";
|
|
29091
|
+
const change = (side, time) => {
|
|
29092
|
+
if (side === "end") {
|
|
29093
|
+
onChange([range[0], time]);
|
|
29173
29094
|
return;
|
|
29174
29095
|
}
|
|
29175
|
-
|
|
29176
|
-
commit(side, (hour + 23) % 24, next + 60, delta > 0 ? "increase" : "decrease");
|
|
29177
|
-
return;
|
|
29178
|
-
}
|
|
29179
|
-
commit(side, hour, next, delta > 0 ? "increase" : "decrease");
|
|
29180
|
-
};
|
|
29181
|
-
const setMeridiem = (side, next) => {
|
|
29182
|
-
const current = getMeridiem(side);
|
|
29183
|
-
if (current === next) return;
|
|
29184
|
-
const { hour, minute } = getParts(side);
|
|
29185
|
-
commit(side, next === "AM" ? hour - 12 : hour + 12, minute);
|
|
29186
|
-
};
|
|
29187
|
-
const getEditingKey = (side, part) => `${side}-${part}`;
|
|
29188
|
-
const sanitizeInput = (next) => next.replace(/\D/g, "").slice(0, 2);
|
|
29189
|
-
const beginEdit = (side, part, currentValue) => {
|
|
29190
|
-
const key = getEditingKey(side, part);
|
|
29191
|
-
setEditingKey(key);
|
|
29192
|
-
setInputDraft((prev) => ({ ...prev, [key]: String(currentValue).padStart(2, "0") }));
|
|
29193
|
-
};
|
|
29194
|
-
const commitHourDraft = (side, draft) => {
|
|
29195
|
-
const clamped = clampTimePart(Number(draft), showMeridiem ? 1 : 0, showMeridiem ? 12 : 23);
|
|
29196
|
-
const parts = getParts(side);
|
|
29197
|
-
const meridiem = getMeridiem(side);
|
|
29198
|
-
const nextHour = showMeridiem ? meridiem === "PM" ? clamped === 12 ? 12 : clamped + 12 : clamped === 12 ? 0 : clamped : clamped;
|
|
29199
|
-
commit(side, nextHour, parts.minute);
|
|
29200
|
-
return clamped;
|
|
29201
|
-
};
|
|
29202
|
-
const commitMinuteDraft = (side, draft) => {
|
|
29203
|
-
const { hour } = getParts(side);
|
|
29204
|
-
const clamped = clampTimePart(Number(draft), 0, 59);
|
|
29205
|
-
commit(side, hour, clamped);
|
|
29206
|
-
return clamped;
|
|
29207
|
-
};
|
|
29208
|
-
const endEdit = (side, part) => {
|
|
29209
|
-
const key = getEditingKey(side, part);
|
|
29210
|
-
const draft = inputDraft[key];
|
|
29211
|
-
if (part === "hour" && draft != null && draft !== "") {
|
|
29212
|
-
commitHourDraft(side, draft);
|
|
29213
|
-
}
|
|
29214
|
-
if (part === "minute" && draft != null && draft !== "") {
|
|
29215
|
-
commitMinuteDraft(side, draft);
|
|
29216
|
-
}
|
|
29217
|
-
setEditingKey(null);
|
|
29218
|
-
setInputDraft({});
|
|
29219
|
-
};
|
|
29220
|
-
const inputStyle = {
|
|
29221
|
-
width: "var(--cmp-timepicker-selector-time-input-width)",
|
|
29222
|
-
height: "var(--cmp-textinput-sm-height)",
|
|
29223
|
-
borderRadius: "var(--cmp-textinput-sm-radius)",
|
|
29224
|
-
border: "var(--cmp-textinput-borderWidth) solid var(--cmp-textinput-border-default)",
|
|
29225
|
-
color: "var(--cmp-textinput-text-default)",
|
|
29226
|
-
fontSize: 12,
|
|
29227
|
-
lineHeight: "20px"
|
|
29228
|
-
};
|
|
29229
|
-
const renderColumn = (side, kind) => {
|
|
29230
|
-
const isHour = kind === "hour";
|
|
29231
|
-
const { minute } = getParts(side);
|
|
29232
|
-
const val = isHour ? getDisplayHour(side) : minute;
|
|
29233
|
-
const currentEditingKey = getEditingKey(side, kind);
|
|
29234
|
-
const displayValue2 = editingKey === currentEditingKey ? inputDraft[currentEditingKey] ?? "" : String(val).padStart(2, "0");
|
|
29235
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29236
|
-
"div",
|
|
29237
|
-
{
|
|
29238
|
-
className: "flex flex-col items-center justify-center",
|
|
29239
|
-
style: { gap: "var(--cmp-timepicker-selector-time-column-gap)" },
|
|
29240
|
-
children: [
|
|
29241
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29242
|
-
SGhostButton,
|
|
29243
|
-
{
|
|
29244
|
-
icon: "chevronUp",
|
|
29245
|
-
size: "xs",
|
|
29246
|
-
ariaLabel: `${side === "start" ? "\uC2DC\uC791" : "\uC885\uB8CC"} ${isHour ? "\uC2DC" : "\uBD84"} \uC99D\uAC00`,
|
|
29247
|
-
onClick: () => isHour ? changeHour(side, 1) : changeMinute(side, minuteStep)
|
|
29248
|
-
}
|
|
29249
|
-
),
|
|
29250
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29251
|
-
"input",
|
|
29252
|
-
{
|
|
29253
|
-
"aria-label": `${side === "start" ? "\uC2DC\uC791" : "\uC885\uB8CC"} ${isHour ? "\uC2DC" : "\uBD84"}`,
|
|
29254
|
-
inputMode: "numeric",
|
|
29255
|
-
value: displayValue2,
|
|
29256
|
-
placeholder: "-",
|
|
29257
|
-
onFocus: () => beginEdit(side, kind, val),
|
|
29258
|
-
onBlur: () => endEdit(side, kind),
|
|
29259
|
-
onChange: (event) => {
|
|
29260
|
-
const draft = sanitizeInput(event.target.value);
|
|
29261
|
-
setInputDraft((prev) => ({ ...prev, [currentEditingKey]: draft }));
|
|
29262
|
-
if (draft === "") return;
|
|
29263
|
-
const raw = Number(draft);
|
|
29264
|
-
if (isHour) {
|
|
29265
|
-
if (draft.length < 2) return;
|
|
29266
|
-
const clamped2 = commitHourDraft(side, draft);
|
|
29267
|
-
const displayDraft2 = raw === clamped2 ? draft : String(clamped2);
|
|
29268
|
-
setInputDraft((prev) => ({ ...prev, [currentEditingKey]: displayDraft2 }));
|
|
29269
|
-
return;
|
|
29270
|
-
}
|
|
29271
|
-
if (draft.length < 2) return;
|
|
29272
|
-
const clamped = commitMinuteDraft(side, draft);
|
|
29273
|
-
const displayDraft = raw === clamped ? draft : String(clamped);
|
|
29274
|
-
setInputDraft((prev) => ({ ...prev, [currentEditingKey]: displayDraft }));
|
|
29275
|
-
},
|
|
29276
|
-
className: "box-border bg-white text-center outline-none",
|
|
29277
|
-
style: inputStyle
|
|
29278
|
-
}
|
|
29279
|
-
),
|
|
29280
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29281
|
-
SGhostButton,
|
|
29282
|
-
{
|
|
29283
|
-
icon: "chevronDown",
|
|
29284
|
-
size: "xs",
|
|
29285
|
-
ariaLabel: `${side === "start" ? "\uC2DC\uC791" : "\uC885\uB8CC"} ${isHour ? "\uC2DC" : "\uBD84"} \uAC10\uC18C`,
|
|
29286
|
-
onClick: () => isHour ? changeHour(side, -1) : changeMinute(side, -minuteStep)
|
|
29287
|
-
}
|
|
29288
|
-
)
|
|
29289
|
-
]
|
|
29290
|
-
}
|
|
29291
|
-
);
|
|
29096
|
+
onChange([time, strict && toMinutes(time) > toMinutes(range[1]) ? time : range[1]]);
|
|
29292
29097
|
};
|
|
29293
29098
|
const renderPanel = (side, title) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29294
29099
|
"div",
|
|
29295
29100
|
{
|
|
29296
|
-
className: "flex flex-col items-center
|
|
29297
|
-
style: { gap: "var(--cmp-timepicker-selector-range-
|
|
29101
|
+
className: "flex flex-col items-center",
|
|
29102
|
+
style: { gap: "var(--cmp-timepicker-selector-range-heading-gap)" },
|
|
29298
29103
|
children: [
|
|
29299
|
-
/* @__PURE__ */ jsxRuntime.
|
|
29300
|
-
|
|
29301
|
-
|
|
29302
|
-
className: "flex flex-col items-center",
|
|
29303
|
-
style: { gap: "var(--cmp-timepicker-selector-range-heading-gap)" },
|
|
29304
|
-
children: [
|
|
29305
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-nowrap text-center text-[12px] font-bold leading-[20px] text-[var(--cmp-timepicker-selector-range-heading-color)]", children: title }),
|
|
29306
|
-
showMeridiem && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "isolate flex", children: ["AM", "PM"].map((item4, index) => {
|
|
29307
|
-
const selected = item4 === getMeridiem(side);
|
|
29308
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29309
|
-
"button",
|
|
29310
|
-
{
|
|
29311
|
-
type: "button",
|
|
29312
|
-
onClick: () => setMeridiem(side, item4),
|
|
29313
|
-
className: cn(
|
|
29314
|
-
"box-border h-[var(--cmp-textinput-sm-height)] w-[61px] cursor-pointer border border-solid bg-white text-center text-[12px] font-medium leading-[20px]",
|
|
29315
|
-
index === 0 ? "rounded-l-[var(--cmp-select-sm-radius)] -mr-px" : "rounded-r-[var(--cmp-select-sm-radius)]",
|
|
29316
|
-
selected ? "z-[1] border-[var(--cmp-timepicker-border-focus)] text-[var(--cmp-timepicker-border-focus)]" : "border-[var(--cmp-timepicker-border-default)] text-[var(--cmp-field-hint-color)]"
|
|
29317
|
-
),
|
|
29318
|
-
children: item4 === "AM" ? "\uC624\uC804" : "\uC624\uD6C4"
|
|
29319
|
-
},
|
|
29320
|
-
item4
|
|
29321
|
-
);
|
|
29322
|
-
}) })
|
|
29323
|
-
]
|
|
29324
|
-
}
|
|
29325
|
-
),
|
|
29326
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
29327
|
-
"div",
|
|
29104
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-nowrap text-center text-[12px] font-bold leading-[20px] text-[var(--cmp-timepicker-selector-range-heading-color)]", children: title }),
|
|
29105
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29106
|
+
TimeListbox,
|
|
29328
29107
|
{
|
|
29329
|
-
|
|
29330
|
-
|
|
29331
|
-
|
|
29332
|
-
|
|
29333
|
-
|
|
29334
|
-
|
|
29335
|
-
|
|
29336
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29337
|
-
"span",
|
|
29338
|
-
{
|
|
29339
|
-
className: "text-center",
|
|
29340
|
-
style: {
|
|
29341
|
-
width: "var(--cmp-timepicker-selector-colon-size)",
|
|
29342
|
-
color: "var(--cmp-field-hint-color)",
|
|
29343
|
-
fontSize: "var(--cmp-timepicker-selector-colon-size)",
|
|
29344
|
-
lineHeight: "var(--cmp-timepicker-selector-colon-size)"
|
|
29345
|
-
},
|
|
29346
|
-
children: ":"
|
|
29347
|
-
}
|
|
29348
|
-
),
|
|
29349
|
-
renderColumn(side, "minute")
|
|
29350
|
-
]
|
|
29108
|
+
value: side === "start" ? range[0] : range[1],
|
|
29109
|
+
showMeridiem,
|
|
29110
|
+
minuteStep,
|
|
29111
|
+
labelPrefix: side === "start" ? "\uC2DC\uC791" : "\uC885\uB8CC",
|
|
29112
|
+
elevated: false,
|
|
29113
|
+
isDisabled: strict && side === "end" ? (minutes) => minutes < toMinutes(range[0]) : void 0,
|
|
29114
|
+
onChange: (time) => change(side, time)
|
|
29351
29115
|
}
|
|
29352
29116
|
)
|
|
29353
29117
|
]
|
|
@@ -29406,11 +29170,9 @@ function STimeRangePicker({
|
|
|
29406
29170
|
style
|
|
29407
29171
|
}) {
|
|
29408
29172
|
const portalContainer = usePortalContainer();
|
|
29409
|
-
const triggerRef = react.useRef(null);
|
|
29410
29173
|
const [open, setOpen] = react.useState(false);
|
|
29411
29174
|
const triggerId = useFieldControlId();
|
|
29412
29175
|
const triggerTextId = `${triggerId}-text`;
|
|
29413
|
-
const [popoverAlignOffset, setPopoverAlignOffset] = react.useState(0);
|
|
29414
29176
|
const [focused, setFocused] = react.useState(false);
|
|
29415
29177
|
const [ruleError, setRuleError] = react.useState("");
|
|
29416
29178
|
const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
|
|
@@ -29434,10 +29196,6 @@ function STimeRangePicker({
|
|
|
29434
29196
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
29435
29197
|
const commitOpen = (next) => {
|
|
29436
29198
|
if (disabled) return;
|
|
29437
|
-
if (next) {
|
|
29438
|
-
const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
|
|
29439
|
-
setPopoverAlignOffset(Math.max(0, (triggerWidth - TIME_RANGE_SELECTOR_WIDTH) / 2));
|
|
29440
|
-
}
|
|
29441
29199
|
setOpen(next);
|
|
29442
29200
|
onOpenChange?.(next);
|
|
29443
29201
|
if (!next && rules && rules.length > 0) setRuleError(runRules(value, rules));
|
|
@@ -29476,7 +29234,6 @@ function STimeRangePicker({
|
|
|
29476
29234
|
/* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29477
29235
|
"div",
|
|
29478
29236
|
{
|
|
29479
|
-
ref: triggerRef,
|
|
29480
29237
|
id: triggerId,
|
|
29481
29238
|
role: "button",
|
|
29482
29239
|
"aria-disabled": disabled,
|
|
@@ -29540,9 +29297,8 @@ function STimeRangePicker({
|
|
|
29540
29297
|
RPopover13__namespace.Content,
|
|
29541
29298
|
{
|
|
29542
29299
|
side: "bottom",
|
|
29543
|
-
align: "
|
|
29300
|
+
align: "center",
|
|
29544
29301
|
sideOffset: 4,
|
|
29545
|
-
alignOffset: popoverAlignOffset,
|
|
29546
29302
|
className: cn(
|
|
29547
29303
|
"z-50 max-w-[var(--radix-popover-content-available-width)]",
|
|
29548
29304
|
FLOATING_SLIDE_ANIM
|