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.js
CHANGED
|
@@ -13394,9 +13394,20 @@ var SystemButton = /* @__PURE__ */ forwardRef(function SystemButton2({
|
|
|
13394
13394
|
}
|
|
13395
13395
|
),
|
|
13396
13396
|
label && /* @__PURE__ */ jsx("span", { className: "typo-body-sm-semibold min-w-0 truncate", children: label }),
|
|
13397
|
-
count != null && count > 0 && //
|
|
13397
|
+
count != null && count > 0 && // 개수는 채운 배지로 단다 — 배경·글자색·치수는 xs deep 태그 토큰이 쥔다(시안).
|
|
13398
|
+
// 배지 색은 고정이다: 흰 면은 파랑, 어두운 면(dark·darker)은 노랑 바탕에 검은 글자.
|
|
13399
|
+
// 배지 오른쪽은 버튼 여백(alertButton.paddingX)만으로는 좁다 — 시안이 4px 을 더 준다.
|
|
13398
13400
|
// 대응 토큰이 없어 디자인 값을 그대로 쓴다.
|
|
13399
|
-
/* @__PURE__ */ jsx(
|
|
13401
|
+
/* @__PURE__ */ jsx(
|
|
13402
|
+
STag,
|
|
13403
|
+
{
|
|
13404
|
+
size: "xs",
|
|
13405
|
+
deep: true,
|
|
13406
|
+
color: color === "light" ? "blue" : "yellow",
|
|
13407
|
+
label: count.toLocaleString(),
|
|
13408
|
+
className: "me-[4px] shrink-0"
|
|
13409
|
+
}
|
|
13410
|
+
)
|
|
13400
13411
|
]
|
|
13401
13412
|
}
|
|
13402
13413
|
);
|
|
@@ -14275,7 +14286,7 @@ var SStepper = /* @__PURE__ */ forwardRef(function SStepper2({
|
|
|
14275
14286
|
items.findIndex((item4, index) => getItemValue(item4, index) === value)
|
|
14276
14287
|
);
|
|
14277
14288
|
const lastCompletedIndex = items.reduce(
|
|
14278
|
-
(
|
|
14289
|
+
(lastIndex2, item4, index) => item4.completed === true ? index : lastIndex2,
|
|
14279
14290
|
-1
|
|
14280
14291
|
);
|
|
14281
14292
|
const resolvedClickableIndex = lastCompletedIndex + 1;
|
|
@@ -19374,13 +19385,21 @@ function SCalendar({
|
|
|
19374
19385
|
}
|
|
19375
19386
|
);
|
|
19376
19387
|
}
|
|
19388
|
+
|
|
19389
|
+
// src/lib/mode-listbox.ts
|
|
19390
|
+
var MODE_LIST_HEIGHT = 240;
|
|
19391
|
+
var MODE_ITEM_HEIGHT = 28;
|
|
19392
|
+
var modeListItemClass = (selected, disabled) => cn(
|
|
19393
|
+
"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]",
|
|
19394
|
+
disabled && "cursor-not-allowed bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-disabled)]",
|
|
19395
|
+
!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)]",
|
|
19396
|
+
!disabled && selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-bold text-[color:var(--cmp-datepicker-mode-item-content-selected)]"
|
|
19397
|
+
);
|
|
19377
19398
|
var MODE_NOUN = {
|
|
19378
19399
|
date: "\uB0A0\uC9DC",
|
|
19379
19400
|
month: "\uC6D4",
|
|
19380
19401
|
year: "\uC5F0\uB3C4"
|
|
19381
19402
|
};
|
|
19382
|
-
var DATEPICKER_MODE_LIST_HEIGHT = 240;
|
|
19383
|
-
var DATEPICKER_MODE_ITEM_HEIGHT = 28;
|
|
19384
19403
|
var YEAR_LIST_EDGE_BUFFER = 24;
|
|
19385
19404
|
var YEAR_LIST_EXPAND_SIZE = 80;
|
|
19386
19405
|
var MONTHS = Array.from({ length: 12 }, (_, i) => i + 1);
|
|
@@ -19431,7 +19450,7 @@ function YearWheel({ value, anchorYear, selectable, onCommit }) {
|
|
|
19431
19450
|
if (!list) return;
|
|
19432
19451
|
const index = anchorYearRef.current - rangeStartRef.current;
|
|
19433
19452
|
syncingScrollRef.current = true;
|
|
19434
|
-
list.scrollTop = index *
|
|
19453
|
+
list.scrollTop = index * MODE_ITEM_HEIGHT;
|
|
19435
19454
|
requestAnimationFrame(() => {
|
|
19436
19455
|
syncingScrollRef.current = false;
|
|
19437
19456
|
});
|
|
@@ -19440,7 +19459,7 @@ function YearWheel({ value, anchorYear, selectable, onCommit }) {
|
|
|
19440
19459
|
const list = listRef.current;
|
|
19441
19460
|
if (!list) return;
|
|
19442
19461
|
if (syncingScrollRef.current) return;
|
|
19443
|
-
if (list.scrollTop <
|
|
19462
|
+
if (list.scrollTop < MODE_ITEM_HEIGHT * YEAR_LIST_EDGE_BUFFER) {
|
|
19444
19463
|
const previousHeight = list.scrollHeight;
|
|
19445
19464
|
setRange((current) => ({
|
|
19446
19465
|
start: current.start - YEAR_LIST_EXPAND_SIZE,
|
|
@@ -19456,7 +19475,7 @@ function YearWheel({ value, anchorYear, selectable, onCommit }) {
|
|
|
19456
19475
|
});
|
|
19457
19476
|
return;
|
|
19458
19477
|
}
|
|
19459
|
-
if (list.scrollHeight - list.scrollTop - list.clientHeight <
|
|
19478
|
+
if (list.scrollHeight - list.scrollTop - list.clientHeight < MODE_ITEM_HEIGHT * YEAR_LIST_EDGE_BUFFER) {
|
|
19460
19479
|
setRange((current) => ({
|
|
19461
19480
|
start: current.start,
|
|
19462
19481
|
end: current.end + YEAR_LIST_EXPAND_SIZE
|
|
@@ -19471,8 +19490,8 @@ function YearWheel({ value, anchorYear, selectable, onCommit }) {
|
|
|
19471
19490
|
"aria-label": "year",
|
|
19472
19491
|
className: "h-full overflow-y-auto overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
19473
19492
|
style: {
|
|
19474
|
-
paddingTop: `calc((${
|
|
19475
|
-
paddingBottom: `calc((${
|
|
19493
|
+
paddingTop: `calc((${MODE_LIST_HEIGHT}px - ${MODE_ITEM_HEIGHT}px) / 2)`,
|
|
19494
|
+
paddingBottom: `calc((${MODE_LIST_HEIGHT}px - ${MODE_ITEM_HEIGHT}px) / 2)`
|
|
19476
19495
|
},
|
|
19477
19496
|
onScroll: handleScroll,
|
|
19478
19497
|
children: years.map((year) => {
|
|
@@ -19485,12 +19504,7 @@ function YearWheel({ value, anchorYear, selectable, onCommit }) {
|
|
|
19485
19504
|
role: "option",
|
|
19486
19505
|
"aria-selected": selected,
|
|
19487
19506
|
disabled,
|
|
19488
|
-
className:
|
|
19489
|
-
"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]",
|
|
19490
|
-
disabled && "cursor-not-allowed bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-disabled)]",
|
|
19491
|
-
!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)]",
|
|
19492
|
-
!disabled && selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-bold text-[color:var(--cmp-datepicker-mode-item-content-selected)]"
|
|
19493
|
-
),
|
|
19507
|
+
className: modeListItemClass(selected, disabled),
|
|
19494
19508
|
onClick: () => !disabled && onCommit(year),
|
|
19495
19509
|
children: year
|
|
19496
19510
|
},
|
|
@@ -19546,7 +19560,7 @@ function MonthWheel({ year, value, selectable, onCommit }) {
|
|
|
19546
19560
|
if (!list) return;
|
|
19547
19561
|
list.scrollTop = Math.max(
|
|
19548
19562
|
0,
|
|
19549
|
-
(initialValueRef.current - 1) *
|
|
19563
|
+
(initialValueRef.current - 1) * MODE_ITEM_HEIGHT - (list.clientHeight - MODE_ITEM_HEIGHT) / 2
|
|
19550
19564
|
);
|
|
19551
19565
|
}, []);
|
|
19552
19566
|
return /* @__PURE__ */ jsx("div", { className: "h-full w-full overflow-hidden bg-[var(--cmp-datepicker-mode-bg)]", children: /* @__PURE__ */ jsx(
|
|
@@ -19566,12 +19580,7 @@ function MonthWheel({ year, value, selectable, onCommit }) {
|
|
|
19566
19580
|
role: "option",
|
|
19567
19581
|
"aria-selected": selected,
|
|
19568
19582
|
disabled,
|
|
19569
|
-
className:
|
|
19570
|
-
"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]",
|
|
19571
|
-
disabled && "cursor-not-allowed bg-[var(--cmp-datepicker-mode-item-bg-default)] font-medium text-[color:var(--cmp-datepicker-mode-item-content-disabled)]",
|
|
19572
|
-
!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)]",
|
|
19573
|
-
!disabled && selected && "cursor-pointer bg-[var(--cmp-datepicker-mode-item-bg-default)] font-bold text-[color:var(--cmp-datepicker-mode-item-content-selected)]"
|
|
19574
|
-
),
|
|
19583
|
+
className: modeListItemClass(selected, disabled),
|
|
19575
19584
|
onClick: () => !disabled && onCommit(month),
|
|
19576
19585
|
children: [
|
|
19577
19586
|
month,
|
|
@@ -28658,212 +28667,171 @@ function formatTimeDisplay(value, type) {
|
|
|
28658
28667
|
const displayHour = hour % 12 === 0 ? 12 : hour % 12;
|
|
28659
28668
|
return `${meridiem} ${padTimePart(displayHour)}:${padTimePart(minute)}`;
|
|
28660
28669
|
}
|
|
28661
|
-
|
|
28662
|
-
|
|
28663
|
-
|
|
28670
|
+
function scrollSelectedIntoView(list, index, center) {
|
|
28671
|
+
const top = index * MODE_ITEM_HEIGHT;
|
|
28672
|
+
if (center) {
|
|
28673
|
+
list.scrollTop = Math.max(0, top - (list.clientHeight - MODE_ITEM_HEIGHT) / 2);
|
|
28674
|
+
return;
|
|
28675
|
+
}
|
|
28676
|
+
if (top < list.scrollTop) list.scrollTop = top;
|
|
28677
|
+
else if (top + MODE_ITEM_HEIGHT > list.scrollTop + list.clientHeight)
|
|
28678
|
+
list.scrollTop = top + MODE_ITEM_HEIGHT - list.clientHeight;
|
|
28679
|
+
}
|
|
28680
|
+
function lastIndex(arr, pred) {
|
|
28681
|
+
for (let i = arr.length - 1; i >= 0; i--) if (pred(arr[i], i)) return i;
|
|
28682
|
+
return -1;
|
|
28683
|
+
}
|
|
28684
|
+
function ListColumn({ ariaLabel, items }) {
|
|
28685
|
+
const listRef = useRef(null);
|
|
28686
|
+
const mountedRef = useRef(false);
|
|
28687
|
+
const selectedIndex = items.findIndex((item4) => item4.selected);
|
|
28688
|
+
const tabIndexTarget = selectedIndex >= 0 ? selectedIndex : items.findIndex((item4) => !item4.disabled);
|
|
28689
|
+
useLayoutEffect(() => {
|
|
28690
|
+
const list = listRef.current;
|
|
28691
|
+
if (!list || selectedIndex < 0) return;
|
|
28692
|
+
scrollSelectedIntoView(list, selectedIndex, !mountedRef.current);
|
|
28693
|
+
mountedRef.current = true;
|
|
28694
|
+
}, [selectedIndex]);
|
|
28695
|
+
const onKeyDown = (event) => {
|
|
28696
|
+
const buttons = [...listRef.current?.querySelectorAll("button") ?? []];
|
|
28697
|
+
const current = buttons.indexOf(document.activeElement);
|
|
28698
|
+
if (current < 0) return;
|
|
28699
|
+
const enabled = (item4, i) => !item4.disabled && i !== current;
|
|
28700
|
+
let next;
|
|
28701
|
+
if (event.key === "ArrowDown") next = items.findIndex((it, i) => i > current && enabled(it, i));
|
|
28702
|
+
else if (event.key === "ArrowUp")
|
|
28703
|
+
next = lastIndex(items, (it, i) => i < current && enabled(it, i));
|
|
28704
|
+
else if (event.key === "Home") next = items.findIndex((it) => !it.disabled);
|
|
28705
|
+
else if (event.key === "End") next = lastIndex(items, (it) => !it.disabled);
|
|
28706
|
+
else return;
|
|
28707
|
+
event.preventDefault();
|
|
28708
|
+
if (next < 0) return;
|
|
28709
|
+
buttons[next]?.focus({ preventScroll: true });
|
|
28710
|
+
if (listRef.current) scrollSelectedIntoView(listRef.current, next, false);
|
|
28711
|
+
};
|
|
28712
|
+
return /* @__PURE__ */ 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__ */ jsx(
|
|
28713
|
+
"div",
|
|
28714
|
+
{
|
|
28715
|
+
ref: listRef,
|
|
28716
|
+
role: "listbox",
|
|
28717
|
+
"aria-label": ariaLabel,
|
|
28718
|
+
tabIndex: -1,
|
|
28719
|
+
className: "h-full overflow-y-auto overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
28720
|
+
onKeyDown,
|
|
28721
|
+
children: items.map((item4, index) => /* @__PURE__ */ jsx(
|
|
28722
|
+
"button",
|
|
28723
|
+
{
|
|
28724
|
+
type: "button",
|
|
28725
|
+
role: "option",
|
|
28726
|
+
"aria-selected": item4.selected,
|
|
28727
|
+
disabled: item4.disabled,
|
|
28728
|
+
tabIndex: index === tabIndexTarget ? 0 : -1,
|
|
28729
|
+
className: cn(modeListItemClass(item4.selected, item4.disabled), "outline-offset-[-2px]"),
|
|
28730
|
+
onClick: () => !item4.disabled && item4.onSelect(),
|
|
28731
|
+
children: item4.label
|
|
28732
|
+
},
|
|
28733
|
+
item4.key
|
|
28734
|
+
))
|
|
28735
|
+
}
|
|
28736
|
+
) });
|
|
28737
|
+
}
|
|
28738
|
+
var HOURS_24 = Array.from({ length: 24 }, (_, i) => i);
|
|
28739
|
+
var HOURS_12 = [12, ...Array.from({ length: 11 }, (_, i) => i + 1)];
|
|
28740
|
+
function TimeListbox({
|
|
28664
28741
|
value,
|
|
28665
28742
|
showMeridiem,
|
|
28666
28743
|
minuteStep,
|
|
28667
|
-
|
|
28744
|
+
isDisabled,
|
|
28745
|
+
onChange,
|
|
28746
|
+
labelPrefix,
|
|
28747
|
+
elevated = true
|
|
28668
28748
|
}) {
|
|
28669
|
-
const
|
|
28670
|
-
const [
|
|
28671
|
-
const [minute, setMinute] = useState(parsed.minute);
|
|
28672
|
-
const [editingPart, setEditingPart] = useState(null);
|
|
28673
|
-
const [inputDraft, setInputDraft] = useState({});
|
|
28749
|
+
const toState = (v) => v ? parseTimeValue(v) : null;
|
|
28750
|
+
const [time, setTime] = useState(() => toState(value));
|
|
28674
28751
|
useEffect(() => {
|
|
28675
|
-
|
|
28676
|
-
|
|
28677
|
-
|
|
28678
|
-
const
|
|
28679
|
-
const
|
|
28680
|
-
const
|
|
28681
|
-
|
|
28682
|
-
|
|
28683
|
-
|
|
28684
|
-
|
|
28685
|
-
|
|
28686
|
-
|
|
28687
|
-
|
|
28688
|
-
if (next
|
|
28689
|
-
|
|
28690
|
-
|
|
28691
|
-
const changeMinute = (delta) => {
|
|
28692
|
-
const next = minute + delta;
|
|
28693
|
-
if (next > 59) {
|
|
28694
|
-
commit((hour + 1) % 24, next - 60);
|
|
28695
|
-
return;
|
|
28696
|
-
}
|
|
28697
|
-
if (next < 0) {
|
|
28698
|
-
commit((hour + 23) % 24, next + 60);
|
|
28699
|
-
return;
|
|
28700
|
-
}
|
|
28701
|
-
commit(hour, next);
|
|
28702
|
-
};
|
|
28703
|
-
const changeHour = (delta) => commit((hour + delta + 24) % 24, minute);
|
|
28704
|
-
const sanitizeInput = (next) => next.replace(/\D/g, "").slice(0, 2);
|
|
28705
|
-
const beginEdit = (part, currentValue) => {
|
|
28706
|
-
setEditingPart(part);
|
|
28707
|
-
setInputDraft((prev) => ({ ...prev, [part]: String(currentValue).padStart(2, "0") }));
|
|
28708
|
-
};
|
|
28709
|
-
const commitHourDraft = (draft) => {
|
|
28710
|
-
const clamped = clampTimePart(Number(draft), showMeridiem ? 1 : 0, showMeridiem ? 12 : 23);
|
|
28711
|
-
const nextHour = showMeridiem ? meridiem === "PM" ? clamped === 12 ? 12 : clamped + 12 : clamped === 12 ? 0 : clamped : clamped;
|
|
28712
|
-
commit(nextHour, minute);
|
|
28713
|
-
return clamped;
|
|
28714
|
-
};
|
|
28715
|
-
const commitMinuteDraft = (draft) => {
|
|
28716
|
-
const clamped = clampTimePart(Number(draft), 0, 59);
|
|
28717
|
-
commit(hour, clamped);
|
|
28718
|
-
return clamped;
|
|
28719
|
-
};
|
|
28720
|
-
const endEdit = (part) => {
|
|
28721
|
-
const draft = inputDraft[part];
|
|
28722
|
-
if (part === "hour" && draft != null && draft !== "") {
|
|
28723
|
-
commitHourDraft(draft);
|
|
28724
|
-
}
|
|
28725
|
-
if (part === "minute" && draft != null && draft !== "") {
|
|
28726
|
-
commitMinuteDraft(draft);
|
|
28727
|
-
}
|
|
28728
|
-
setEditingPart(null);
|
|
28729
|
-
setInputDraft({});
|
|
28730
|
-
};
|
|
28731
|
-
const inputStyle = {
|
|
28732
|
-
width: "var(--cmp-timepicker-selector-time-input-width)",
|
|
28733
|
-
height: "var(--cmp-textinput-sm-height)",
|
|
28734
|
-
borderRadius: "var(--cmp-textinput-sm-radius)",
|
|
28735
|
-
border: "var(--cmp-textinput-borderWidth) solid var(--cmp-textinput-border-default)",
|
|
28736
|
-
color: "var(--cmp-textinput-text-default)",
|
|
28737
|
-
fontSize: 12,
|
|
28738
|
-
lineHeight: "20px"
|
|
28752
|
+
setTime(toState(value));
|
|
28753
|
+
}, [value]);
|
|
28754
|
+
const step = Math.max(1, Math.floor(minuteStep));
|
|
28755
|
+
const minutes = Array.from({ length: Math.ceil(60 / step) }, (_, i) => i * step);
|
|
28756
|
+
const blocked = (h, m) => isDisabled?.(h * 60 + m) ?? false;
|
|
28757
|
+
const hourBlocked = (h) => minutes.every((m) => blocked(h, m));
|
|
28758
|
+
const commit = (hours, preferred, part) => {
|
|
28759
|
+
let next = blocked(preferred.hour, preferred.minute) ? null : preferred;
|
|
28760
|
+
for (const h of hours) {
|
|
28761
|
+
if (next) break;
|
|
28762
|
+
const m = minutes.find((mm) => !blocked(h, mm));
|
|
28763
|
+
if (m !== void 0) next = { hour: h, minute: m };
|
|
28764
|
+
}
|
|
28765
|
+
if (!next) return;
|
|
28766
|
+
setTime(next);
|
|
28767
|
+
onChange(formatTimeValue(next.hour, next.minute), part);
|
|
28739
28768
|
};
|
|
28740
|
-
const
|
|
28741
|
-
|
|
28742
|
-
|
|
28743
|
-
|
|
28744
|
-
|
|
28745
|
-
|
|
28746
|
-
|
|
28747
|
-
|
|
28748
|
-
|
|
28749
|
-
|
|
28750
|
-
|
|
28751
|
-
|
|
28752
|
-
|
|
28753
|
-
|
|
28754
|
-
|
|
28755
|
-
|
|
28756
|
-
onClick: () => isHour ? changeHour(1) : changeMinute(minuteStep)
|
|
28757
|
-
}
|
|
28758
|
-
),
|
|
28759
|
-
/* @__PURE__ */ jsx(
|
|
28760
|
-
"input",
|
|
28761
|
-
{
|
|
28762
|
-
"aria-label": isHour ? "\uC2DC" : "\uBD84",
|
|
28763
|
-
inputMode: "numeric",
|
|
28764
|
-
value: displayValue2,
|
|
28765
|
-
placeholder: "-",
|
|
28766
|
-
onFocus: () => beginEdit(type, val),
|
|
28767
|
-
onBlur: () => endEdit(type),
|
|
28768
|
-
onChange: (event) => {
|
|
28769
|
-
const draft = sanitizeInput(event.target.value);
|
|
28770
|
-
setInputDraft((prev) => ({ ...prev, [type]: draft }));
|
|
28771
|
-
if (draft === "") return;
|
|
28772
|
-
const raw = Number(draft);
|
|
28773
|
-
if (isHour) {
|
|
28774
|
-
if (draft.length < 2) return;
|
|
28775
|
-
const clamped2 = commitHourDraft(draft);
|
|
28776
|
-
const displayDraft2 = raw === clamped2 ? draft : String(clamped2);
|
|
28777
|
-
setInputDraft((prev) => ({ ...prev, [type]: displayDraft2 }));
|
|
28778
|
-
return;
|
|
28779
|
-
}
|
|
28780
|
-
if (draft.length < 2) return;
|
|
28781
|
-
const clamped = commitMinuteDraft(draft);
|
|
28782
|
-
const displayDraft = raw === clamped ? draft : String(clamped);
|
|
28783
|
-
setInputDraft((prev) => ({ ...prev, [type]: displayDraft }));
|
|
28784
|
-
},
|
|
28785
|
-
className: "box-border bg-white text-center outline-none",
|
|
28786
|
-
style: inputStyle
|
|
28787
|
-
}
|
|
28788
|
-
),
|
|
28789
|
-
/* @__PURE__ */ jsx(
|
|
28790
|
-
SGhostButton,
|
|
28791
|
-
{
|
|
28792
|
-
icon: "chevronDown",
|
|
28793
|
-
size: "xs",
|
|
28794
|
-
ariaLabel: `${isHour ? "\uC2DC" : "\uBD84"} \uAC10\uC18C`,
|
|
28795
|
-
onClick: () => isHour ? changeHour(-1) : changeMinute(-minuteStep)
|
|
28796
|
-
}
|
|
28797
|
-
)
|
|
28798
|
-
]
|
|
28769
|
+
const hour = time?.hour;
|
|
28770
|
+
const minute = time?.minute ?? 0;
|
|
28771
|
+
const meridiem = hour === void 0 ? void 0 : hour >= 12 ? "PM" : "AM";
|
|
28772
|
+
const prefix = labelPrefix ? `${labelPrefix} ` : "";
|
|
28773
|
+
const meridiemItems = ["AM", "PM"].map((item4) => {
|
|
28774
|
+
const base = item4 === "AM" ? 0 : 12;
|
|
28775
|
+
const range = HOURS_24.slice(base, base + 12);
|
|
28776
|
+
return {
|
|
28777
|
+
key: item4,
|
|
28778
|
+
label: item4 === "AM" ? "\uC624\uC804" : "\uC624\uD6C4",
|
|
28779
|
+
selected: meridiem === item4,
|
|
28780
|
+
disabled: range.every(hourBlocked),
|
|
28781
|
+
onSelect: () => {
|
|
28782
|
+
if (meridiem === item4) return;
|
|
28783
|
+
const h = hour === void 0 ? base : hour % 12 + base;
|
|
28784
|
+
commit(range, { hour: h, minute }, "meridiem");
|
|
28799
28785
|
}
|
|
28800
|
-
|
|
28801
|
-
};
|
|
28786
|
+
};
|
|
28787
|
+
});
|
|
28788
|
+
const hourItems = showMeridiem ? HOURS_12.map((display) => {
|
|
28789
|
+
const h = display % 12 + (meridiem === "PM" ? 12 : 0);
|
|
28790
|
+
return {
|
|
28791
|
+
key: String(display),
|
|
28792
|
+
label: `${padTimePart(display)}\uC2DC`,
|
|
28793
|
+
selected: hour === h,
|
|
28794
|
+
disabled: hourBlocked(h),
|
|
28795
|
+
onSelect: () => commit([h], { hour: h, minute }, "hour")
|
|
28796
|
+
};
|
|
28797
|
+
}) : HOURS_24.map((h) => ({
|
|
28798
|
+
key: String(h),
|
|
28799
|
+
label: `${padTimePart(h)}\uC2DC`,
|
|
28800
|
+
selected: hour === h,
|
|
28801
|
+
disabled: hourBlocked(h),
|
|
28802
|
+
onSelect: () => commit([h], { hour: h, minute }, "hour")
|
|
28803
|
+
}));
|
|
28804
|
+
const minuteHour = hour ?? (meridiem === "PM" ? 12 : 0);
|
|
28805
|
+
const minuteItems = minutes.map((m) => ({
|
|
28806
|
+
key: String(m),
|
|
28807
|
+
label: `${padTimePart(m)}\uBD84`,
|
|
28808
|
+
selected: time != null && minute === m,
|
|
28809
|
+
disabled: blocked(minuteHour, m),
|
|
28810
|
+
onSelect: () => commit([minuteHour], { hour: minuteHour, minute: m }, "minute")
|
|
28811
|
+
}));
|
|
28812
|
+
const divider = /* @__PURE__ */ jsx(
|
|
28813
|
+
"div",
|
|
28814
|
+
{
|
|
28815
|
+
"aria-hidden": true,
|
|
28816
|
+
className: "w-[var(--border-width-1)] self-stretch bg-[var(--sys-color-divider-default)]"
|
|
28817
|
+
}
|
|
28818
|
+
);
|
|
28802
28819
|
return /* @__PURE__ */ jsxs(
|
|
28803
28820
|
"div",
|
|
28804
28821
|
{
|
|
28805
|
-
className:
|
|
28806
|
-
|
|
28807
|
-
|
|
28808
|
-
|
|
28809
|
-
|
|
28810
|
-
},
|
|
28822
|
+
className: cn(
|
|
28823
|
+
"inline-flex gap-[var(--cmp-datepicker-mode-yearMonth-gap)] overflow-hidden bg-[var(--cmp-datepicker-mode-bg)]",
|
|
28824
|
+
elevated && "rounded-[var(--cmp-datepicker-mode-radius)] shadow-normal-sm"
|
|
28825
|
+
),
|
|
28826
|
+
style: { height: MODE_LIST_HEIGHT },
|
|
28811
28827
|
children: [
|
|
28812
|
-
showMeridiem && /* @__PURE__ */
|
|
28813
|
-
|
|
28814
|
-
|
|
28815
|
-
|
|
28816
|
-
|
|
28817
|
-
|
|
28818
|
-
|
|
28819
|
-
children: /* @__PURE__ */ jsx("div", { className: "isolate flex", children: ["AM", "PM"].map((item4, index) => {
|
|
28820
|
-
const selected = item4 === meridiem;
|
|
28821
|
-
return /* @__PURE__ */ jsx(
|
|
28822
|
-
"button",
|
|
28823
|
-
{
|
|
28824
|
-
type: "button",
|
|
28825
|
-
onClick: () => setMeridiem(item4),
|
|
28826
|
-
className: cn(
|
|
28827
|
-
"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]",
|
|
28828
|
-
index === 0 ? "rounded-l-[var(--cmp-select-sm-radius)]" : "rounded-r-[var(--cmp-select-sm-radius)]",
|
|
28829
|
-
index === 0 ? "-mr-px" : "",
|
|
28830
|
-
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)]"
|
|
28831
|
-
),
|
|
28832
|
-
children: item4 === "AM" ? "\uC624\uC804" : "\uC624\uD6C4"
|
|
28833
|
-
},
|
|
28834
|
-
item4
|
|
28835
|
-
);
|
|
28836
|
-
}) })
|
|
28837
|
-
}
|
|
28838
|
-
),
|
|
28839
|
-
showMeridiem && /* @__PURE__ */ jsx("div", { className: "h-px w-full bg-[var(--sys-color-divider-default)]" }),
|
|
28840
|
-
/* @__PURE__ */ jsxs(
|
|
28841
|
-
"div",
|
|
28842
|
-
{
|
|
28843
|
-
className: "flex items-center justify-center",
|
|
28844
|
-
style: {
|
|
28845
|
-
gap: "var(--cmp-timepicker-selector-time-gap)",
|
|
28846
|
-
padding: "var(--cmp-timepicker-selector-section-paddingY) var(--cmp-timepicker-selector-section-paddingX)"
|
|
28847
|
-
},
|
|
28848
|
-
children: [
|
|
28849
|
-
renderColumn("hour"),
|
|
28850
|
-
/* @__PURE__ */ jsx(
|
|
28851
|
-
"span",
|
|
28852
|
-
{
|
|
28853
|
-
className: "text-center",
|
|
28854
|
-
style: {
|
|
28855
|
-
width: "var(--cmp-timepicker-selector-colon-size)",
|
|
28856
|
-
color: "var(--cmp-field-hint-color)",
|
|
28857
|
-
fontSize: "var(--cmp-timepicker-selector-colon-size)",
|
|
28858
|
-
lineHeight: "var(--cmp-timepicker-selector-colon-size)"
|
|
28859
|
-
},
|
|
28860
|
-
children: ":"
|
|
28861
|
-
}
|
|
28862
|
-
),
|
|
28863
|
-
renderColumn("minute")
|
|
28864
|
-
]
|
|
28865
|
-
}
|
|
28866
|
-
)
|
|
28828
|
+
showMeridiem && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
28829
|
+
/* @__PURE__ */ jsx(ListColumn, { ariaLabel: `${prefix}\uC624\uC804/\uC624\uD6C4`, items: meridiemItems }),
|
|
28830
|
+
divider
|
|
28831
|
+
] }),
|
|
28832
|
+
/* @__PURE__ */ jsx(ListColumn, { ariaLabel: `${prefix}\uC2DC`, items: hourItems }),
|
|
28833
|
+
divider,
|
|
28834
|
+
/* @__PURE__ */ jsx(ListColumn, { ariaLabel: `${prefix}\uBD84`, items: minuteItems })
|
|
28867
28835
|
]
|
|
28868
28836
|
}
|
|
28869
28837
|
);
|
|
@@ -28901,11 +28869,9 @@ function STimePicker({
|
|
|
28901
28869
|
style
|
|
28902
28870
|
}) {
|
|
28903
28871
|
const portalContainer = usePortalContainer();
|
|
28904
|
-
const triggerRef = useRef(null);
|
|
28905
28872
|
const [open, setOpen] = useState(false);
|
|
28906
28873
|
const triggerId = useFieldControlId();
|
|
28907
28874
|
const triggerTextId = `${triggerId}-text`;
|
|
28908
|
-
const [popoverAlignOffset, setPopoverAlignOffset] = useState(0);
|
|
28909
28875
|
const [focused, setFocused] = useState(false);
|
|
28910
28876
|
const [ruleError, setRuleError] = useState("");
|
|
28911
28877
|
const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
|
|
@@ -28926,11 +28892,6 @@ function STimePicker({
|
|
|
28926
28892
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
28927
28893
|
const commitOpen = (next) => {
|
|
28928
28894
|
if (disabled) return;
|
|
28929
|
-
if (next) {
|
|
28930
|
-
const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
|
|
28931
|
-
const selectorWidth = effectiveShowMeridiem ? MERIDIEM_TIME_SELECTOR_WIDTH : TIME_SELECTOR_WIDTH;
|
|
28932
|
-
setPopoverAlignOffset(Math.max(0, (triggerWidth - selectorWidth) / 2));
|
|
28933
|
-
}
|
|
28934
28895
|
setOpen(next);
|
|
28935
28896
|
onOpenChange?.(next);
|
|
28936
28897
|
if (!next && rules && rules.length > 0) setRuleError(runRules(value, rules));
|
|
@@ -28969,7 +28930,6 @@ function STimePicker({
|
|
|
28969
28930
|
/* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
28970
28931
|
"div",
|
|
28971
28932
|
{
|
|
28972
|
-
ref: triggerRef,
|
|
28973
28933
|
id: triggerId,
|
|
28974
28934
|
role: "button",
|
|
28975
28935
|
"aria-disabled": disabled,
|
|
@@ -29033,20 +28993,22 @@ function STimePicker({
|
|
|
29033
28993
|
RPopover13.Content,
|
|
29034
28994
|
{
|
|
29035
28995
|
side: "bottom",
|
|
29036
|
-
align: "
|
|
28996
|
+
align: "center",
|
|
29037
28997
|
sideOffset: 4,
|
|
29038
|
-
alignOffset: popoverAlignOffset,
|
|
29039
28998
|
className: cn(
|
|
29040
28999
|
"z-50 max-w-[var(--radix-popover-content-available-width)]",
|
|
29041
29000
|
FLOATING_SLIDE_ANIM
|
|
29042
29001
|
),
|
|
29043
29002
|
children: /* @__PURE__ */ jsx(
|
|
29044
|
-
|
|
29003
|
+
TimeListbox,
|
|
29045
29004
|
{
|
|
29046
29005
|
value: normalized,
|
|
29047
29006
|
showMeridiem: effectiveShowMeridiem,
|
|
29048
29007
|
minuteStep,
|
|
29049
|
-
onChange:
|
|
29008
|
+
onChange: (time, part) => {
|
|
29009
|
+
commitValue(time);
|
|
29010
|
+
if (part === "minute") commitOpen(false);
|
|
29011
|
+
}
|
|
29050
29012
|
}
|
|
29051
29013
|
)
|
|
29052
29014
|
}
|
|
@@ -29076,7 +29038,6 @@ function formatTimeRangeDisplay(value, type) {
|
|
|
29076
29038
|
if (value == null || value[0] === "" || value[1] === "") return "";
|
|
29077
29039
|
return `${formatTimeDisplay(value[0], type)} ~ ${formatTimeDisplay(value[1], type)}`;
|
|
29078
29040
|
}
|
|
29079
|
-
var TIME_RANGE_SELECTOR_WIDTH = 345;
|
|
29080
29041
|
var MIDDAY_FIELD_MIN_WIDTH = {
|
|
29081
29042
|
sm: 178,
|
|
29082
29043
|
md: 216
|
|
@@ -29085,6 +29046,10 @@ var MIDDAY_FIELD_MAX_WIDTH = {
|
|
|
29085
29046
|
sm: "lg",
|
|
29086
29047
|
md: "lg"
|
|
29087
29048
|
};
|
|
29049
|
+
var toMinutes = (time) => {
|
|
29050
|
+
const { hour, minute } = parseTimeValue(time);
|
|
29051
|
+
return hour * 60 + minute;
|
|
29052
|
+
};
|
|
29088
29053
|
function RangeTimeSelector({
|
|
29089
29054
|
value,
|
|
29090
29055
|
showMeridiem,
|
|
@@ -29092,233 +29057,32 @@ function RangeTimeSelector({
|
|
|
29092
29057
|
rangeOrder,
|
|
29093
29058
|
onChange
|
|
29094
29059
|
}) {
|
|
29095
|
-
const range =
|
|
29096
|
-
const
|
|
29097
|
-
const
|
|
29098
|
-
|
|
29099
|
-
|
|
29100
|
-
const getMeridiem = (side) => getParts(side).hour >= 12 ? "PM" : "AM";
|
|
29101
|
-
const getDisplayHour = (side) => {
|
|
29102
|
-
const { hour } = getParts(side);
|
|
29103
|
-
if (!showMeridiem) return hour;
|
|
29104
|
-
const displayHour = hour % 12;
|
|
29105
|
-
return displayHour === 0 ? 12 : displayHour;
|
|
29106
|
-
};
|
|
29107
|
-
const commit = (side, hour, minute, direction = "unknown") => {
|
|
29108
|
-
const next = formatTimeValue(hour, minute);
|
|
29109
|
-
onChange(
|
|
29110
|
-
normalizeNextRange(side === "start" ? [next, range[1]] : [range[0], next], side, direction)
|
|
29111
|
-
);
|
|
29112
|
-
};
|
|
29113
|
-
const getTimeMinutes2 = (time) => {
|
|
29114
|
-
const { hour, minute } = parseTimeValue(time);
|
|
29115
|
-
return hour * 60 + minute;
|
|
29116
|
-
};
|
|
29117
|
-
const normalizeNextRange = (nextRange, changedSide, direction) => {
|
|
29118
|
-
if (rangeOrder === "allow-cross-day") return nextRange;
|
|
29119
|
-
const [start, end] = nextRange;
|
|
29120
|
-
const [currentStart, currentEnd] = range;
|
|
29121
|
-
if (getTimeMinutes2(start) <= getTimeMinutes2(end)) {
|
|
29122
|
-
const shouldKeepSynced = autoAdjustedRef.current?.side === changedSide && currentStart === currentEnd && start !== end && (direction === "unknown" || autoAdjustedRef.current.direction === direction);
|
|
29123
|
-
if (shouldKeepSynced) {
|
|
29124
|
-
return changedSide === "start" ? [start, start] : [end, end];
|
|
29125
|
-
}
|
|
29126
|
-
autoAdjustedRef.current = null;
|
|
29127
|
-
return nextRange;
|
|
29128
|
-
}
|
|
29129
|
-
autoAdjustedRef.current = {
|
|
29130
|
-
side: changedSide,
|
|
29131
|
-
direction: changedSide === "start" ? "increase" : "decrease"
|
|
29132
|
-
};
|
|
29133
|
-
return changedSide === "start" ? [start, start] : [end, end];
|
|
29134
|
-
};
|
|
29135
|
-
const changeHour = (side, delta) => {
|
|
29136
|
-
const { hour, minute } = getParts(side);
|
|
29137
|
-
commit(side, (hour + delta + 24) % 24, minute, delta > 0 ? "increase" : "decrease");
|
|
29138
|
-
};
|
|
29139
|
-
const changeMinute = (side, delta) => {
|
|
29140
|
-
const { hour, minute } = getParts(side);
|
|
29141
|
-
const next = minute + delta;
|
|
29142
|
-
if (next > 59) {
|
|
29143
|
-
commit(side, (hour + 1) % 24, next - 60, delta > 0 ? "increase" : "decrease");
|
|
29060
|
+
const range = value ?? ["00:00", "23:59"];
|
|
29061
|
+
const strict = rangeOrder !== "allow-cross-day";
|
|
29062
|
+
const change = (side, time) => {
|
|
29063
|
+
if (side === "end") {
|
|
29064
|
+
onChange([range[0], time]);
|
|
29144
29065
|
return;
|
|
29145
29066
|
}
|
|
29146
|
-
|
|
29147
|
-
commit(side, (hour + 23) % 24, next + 60, delta > 0 ? "increase" : "decrease");
|
|
29148
|
-
return;
|
|
29149
|
-
}
|
|
29150
|
-
commit(side, hour, next, delta > 0 ? "increase" : "decrease");
|
|
29151
|
-
};
|
|
29152
|
-
const setMeridiem = (side, next) => {
|
|
29153
|
-
const current = getMeridiem(side);
|
|
29154
|
-
if (current === next) return;
|
|
29155
|
-
const { hour, minute } = getParts(side);
|
|
29156
|
-
commit(side, next === "AM" ? hour - 12 : hour + 12, minute);
|
|
29157
|
-
};
|
|
29158
|
-
const getEditingKey = (side, part) => `${side}-${part}`;
|
|
29159
|
-
const sanitizeInput = (next) => next.replace(/\D/g, "").slice(0, 2);
|
|
29160
|
-
const beginEdit = (side, part, currentValue) => {
|
|
29161
|
-
const key = getEditingKey(side, part);
|
|
29162
|
-
setEditingKey(key);
|
|
29163
|
-
setInputDraft((prev) => ({ ...prev, [key]: String(currentValue).padStart(2, "0") }));
|
|
29164
|
-
};
|
|
29165
|
-
const commitHourDraft = (side, draft) => {
|
|
29166
|
-
const clamped = clampTimePart(Number(draft), showMeridiem ? 1 : 0, showMeridiem ? 12 : 23);
|
|
29167
|
-
const parts = getParts(side);
|
|
29168
|
-
const meridiem = getMeridiem(side);
|
|
29169
|
-
const nextHour = showMeridiem ? meridiem === "PM" ? clamped === 12 ? 12 : clamped + 12 : clamped === 12 ? 0 : clamped : clamped;
|
|
29170
|
-
commit(side, nextHour, parts.minute);
|
|
29171
|
-
return clamped;
|
|
29172
|
-
};
|
|
29173
|
-
const commitMinuteDraft = (side, draft) => {
|
|
29174
|
-
const { hour } = getParts(side);
|
|
29175
|
-
const clamped = clampTimePart(Number(draft), 0, 59);
|
|
29176
|
-
commit(side, hour, clamped);
|
|
29177
|
-
return clamped;
|
|
29178
|
-
};
|
|
29179
|
-
const endEdit = (side, part) => {
|
|
29180
|
-
const key = getEditingKey(side, part);
|
|
29181
|
-
const draft = inputDraft[key];
|
|
29182
|
-
if (part === "hour" && draft != null && draft !== "") {
|
|
29183
|
-
commitHourDraft(side, draft);
|
|
29184
|
-
}
|
|
29185
|
-
if (part === "minute" && draft != null && draft !== "") {
|
|
29186
|
-
commitMinuteDraft(side, draft);
|
|
29187
|
-
}
|
|
29188
|
-
setEditingKey(null);
|
|
29189
|
-
setInputDraft({});
|
|
29190
|
-
};
|
|
29191
|
-
const inputStyle = {
|
|
29192
|
-
width: "var(--cmp-timepicker-selector-time-input-width)",
|
|
29193
|
-
height: "var(--cmp-textinput-sm-height)",
|
|
29194
|
-
borderRadius: "var(--cmp-textinput-sm-radius)",
|
|
29195
|
-
border: "var(--cmp-textinput-borderWidth) solid var(--cmp-textinput-border-default)",
|
|
29196
|
-
color: "var(--cmp-textinput-text-default)",
|
|
29197
|
-
fontSize: 12,
|
|
29198
|
-
lineHeight: "20px"
|
|
29199
|
-
};
|
|
29200
|
-
const renderColumn = (side, kind) => {
|
|
29201
|
-
const isHour = kind === "hour";
|
|
29202
|
-
const { minute } = getParts(side);
|
|
29203
|
-
const val = isHour ? getDisplayHour(side) : minute;
|
|
29204
|
-
const currentEditingKey = getEditingKey(side, kind);
|
|
29205
|
-
const displayValue2 = editingKey === currentEditingKey ? inputDraft[currentEditingKey] ?? "" : String(val).padStart(2, "0");
|
|
29206
|
-
return /* @__PURE__ */ jsxs(
|
|
29207
|
-
"div",
|
|
29208
|
-
{
|
|
29209
|
-
className: "flex flex-col items-center justify-center",
|
|
29210
|
-
style: { gap: "var(--cmp-timepicker-selector-time-column-gap)" },
|
|
29211
|
-
children: [
|
|
29212
|
-
/* @__PURE__ */ jsx(
|
|
29213
|
-
SGhostButton,
|
|
29214
|
-
{
|
|
29215
|
-
icon: "chevronUp",
|
|
29216
|
-
size: "xs",
|
|
29217
|
-
ariaLabel: `${side === "start" ? "\uC2DC\uC791" : "\uC885\uB8CC"} ${isHour ? "\uC2DC" : "\uBD84"} \uC99D\uAC00`,
|
|
29218
|
-
onClick: () => isHour ? changeHour(side, 1) : changeMinute(side, minuteStep)
|
|
29219
|
-
}
|
|
29220
|
-
),
|
|
29221
|
-
/* @__PURE__ */ jsx(
|
|
29222
|
-
"input",
|
|
29223
|
-
{
|
|
29224
|
-
"aria-label": `${side === "start" ? "\uC2DC\uC791" : "\uC885\uB8CC"} ${isHour ? "\uC2DC" : "\uBD84"}`,
|
|
29225
|
-
inputMode: "numeric",
|
|
29226
|
-
value: displayValue2,
|
|
29227
|
-
placeholder: "-",
|
|
29228
|
-
onFocus: () => beginEdit(side, kind, val),
|
|
29229
|
-
onBlur: () => endEdit(side, kind),
|
|
29230
|
-
onChange: (event) => {
|
|
29231
|
-
const draft = sanitizeInput(event.target.value);
|
|
29232
|
-
setInputDraft((prev) => ({ ...prev, [currentEditingKey]: draft }));
|
|
29233
|
-
if (draft === "") return;
|
|
29234
|
-
const raw = Number(draft);
|
|
29235
|
-
if (isHour) {
|
|
29236
|
-
if (draft.length < 2) return;
|
|
29237
|
-
const clamped2 = commitHourDraft(side, draft);
|
|
29238
|
-
const displayDraft2 = raw === clamped2 ? draft : String(clamped2);
|
|
29239
|
-
setInputDraft((prev) => ({ ...prev, [currentEditingKey]: displayDraft2 }));
|
|
29240
|
-
return;
|
|
29241
|
-
}
|
|
29242
|
-
if (draft.length < 2) return;
|
|
29243
|
-
const clamped = commitMinuteDraft(side, draft);
|
|
29244
|
-
const displayDraft = raw === clamped ? draft : String(clamped);
|
|
29245
|
-
setInputDraft((prev) => ({ ...prev, [currentEditingKey]: displayDraft }));
|
|
29246
|
-
},
|
|
29247
|
-
className: "box-border bg-white text-center outline-none",
|
|
29248
|
-
style: inputStyle
|
|
29249
|
-
}
|
|
29250
|
-
),
|
|
29251
|
-
/* @__PURE__ */ jsx(
|
|
29252
|
-
SGhostButton,
|
|
29253
|
-
{
|
|
29254
|
-
icon: "chevronDown",
|
|
29255
|
-
size: "xs",
|
|
29256
|
-
ariaLabel: `${side === "start" ? "\uC2DC\uC791" : "\uC885\uB8CC"} ${isHour ? "\uC2DC" : "\uBD84"} \uAC10\uC18C`,
|
|
29257
|
-
onClick: () => isHour ? changeHour(side, -1) : changeMinute(side, -minuteStep)
|
|
29258
|
-
}
|
|
29259
|
-
)
|
|
29260
|
-
]
|
|
29261
|
-
}
|
|
29262
|
-
);
|
|
29067
|
+
onChange([time, strict && toMinutes(time) > toMinutes(range[1]) ? time : range[1]]);
|
|
29263
29068
|
};
|
|
29264
29069
|
const renderPanel = (side, title) => /* @__PURE__ */ jsxs(
|
|
29265
29070
|
"div",
|
|
29266
29071
|
{
|
|
29267
|
-
className: "flex flex-col items-center
|
|
29268
|
-
style: { gap: "var(--cmp-timepicker-selector-range-
|
|
29072
|
+
className: "flex flex-col items-center",
|
|
29073
|
+
style: { gap: "var(--cmp-timepicker-selector-range-heading-gap)" },
|
|
29269
29074
|
children: [
|
|
29270
|
-
/* @__PURE__ */
|
|
29271
|
-
|
|
29272
|
-
|
|
29273
|
-
className: "flex flex-col items-center",
|
|
29274
|
-
style: { gap: "var(--cmp-timepicker-selector-range-heading-gap)" },
|
|
29275
|
-
children: [
|
|
29276
|
-
/* @__PURE__ */ jsx("div", { className: "whitespace-nowrap text-center text-[12px] font-bold leading-[20px] text-[var(--cmp-timepicker-selector-range-heading-color)]", children: title }),
|
|
29277
|
-
showMeridiem && /* @__PURE__ */ jsx("div", { className: "isolate flex", children: ["AM", "PM"].map((item4, index) => {
|
|
29278
|
-
const selected = item4 === getMeridiem(side);
|
|
29279
|
-
return /* @__PURE__ */ jsx(
|
|
29280
|
-
"button",
|
|
29281
|
-
{
|
|
29282
|
-
type: "button",
|
|
29283
|
-
onClick: () => setMeridiem(side, item4),
|
|
29284
|
-
className: cn(
|
|
29285
|
-
"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]",
|
|
29286
|
-
index === 0 ? "rounded-l-[var(--cmp-select-sm-radius)] -mr-px" : "rounded-r-[var(--cmp-select-sm-radius)]",
|
|
29287
|
-
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)]"
|
|
29288
|
-
),
|
|
29289
|
-
children: item4 === "AM" ? "\uC624\uC804" : "\uC624\uD6C4"
|
|
29290
|
-
},
|
|
29291
|
-
item4
|
|
29292
|
-
);
|
|
29293
|
-
}) })
|
|
29294
|
-
]
|
|
29295
|
-
}
|
|
29296
|
-
),
|
|
29297
|
-
/* @__PURE__ */ jsxs(
|
|
29298
|
-
"div",
|
|
29075
|
+
/* @__PURE__ */ jsx("div", { className: "whitespace-nowrap text-center text-[12px] font-bold leading-[20px] text-[var(--cmp-timepicker-selector-range-heading-color)]", children: title }),
|
|
29076
|
+
/* @__PURE__ */ jsx(
|
|
29077
|
+
TimeListbox,
|
|
29299
29078
|
{
|
|
29300
|
-
|
|
29301
|
-
|
|
29302
|
-
|
|
29303
|
-
|
|
29304
|
-
|
|
29305
|
-
|
|
29306
|
-
|
|
29307
|
-
/* @__PURE__ */ jsx(
|
|
29308
|
-
"span",
|
|
29309
|
-
{
|
|
29310
|
-
className: "text-center",
|
|
29311
|
-
style: {
|
|
29312
|
-
width: "var(--cmp-timepicker-selector-colon-size)",
|
|
29313
|
-
color: "var(--cmp-field-hint-color)",
|
|
29314
|
-
fontSize: "var(--cmp-timepicker-selector-colon-size)",
|
|
29315
|
-
lineHeight: "var(--cmp-timepicker-selector-colon-size)"
|
|
29316
|
-
},
|
|
29317
|
-
children: ":"
|
|
29318
|
-
}
|
|
29319
|
-
),
|
|
29320
|
-
renderColumn(side, "minute")
|
|
29321
|
-
]
|
|
29079
|
+
value: side === "start" ? range[0] : range[1],
|
|
29080
|
+
showMeridiem,
|
|
29081
|
+
minuteStep,
|
|
29082
|
+
labelPrefix: side === "start" ? "\uC2DC\uC791" : "\uC885\uB8CC",
|
|
29083
|
+
elevated: false,
|
|
29084
|
+
isDisabled: strict && side === "end" ? (minutes) => minutes < toMinutes(range[0]) : void 0,
|
|
29085
|
+
onChange: (time) => change(side, time)
|
|
29322
29086
|
}
|
|
29323
29087
|
)
|
|
29324
29088
|
]
|
|
@@ -29377,11 +29141,9 @@ function STimeRangePicker({
|
|
|
29377
29141
|
style
|
|
29378
29142
|
}) {
|
|
29379
29143
|
const portalContainer = usePortalContainer();
|
|
29380
|
-
const triggerRef = useRef(null);
|
|
29381
29144
|
const [open, setOpen] = useState(false);
|
|
29382
29145
|
const triggerId = useFieldControlId();
|
|
29383
29146
|
const triggerTextId = `${triggerId}-text`;
|
|
29384
|
-
const [popoverAlignOffset, setPopoverAlignOffset] = useState(0);
|
|
29385
29147
|
const [focused, setFocused] = useState(false);
|
|
29386
29148
|
const [ruleError, setRuleError] = useState("");
|
|
29387
29149
|
const dims = TIMEPICKER_SIZE_CONFIG[size] ?? TIMEPICKER_SIZE_CONFIG.sm;
|
|
@@ -29405,10 +29167,6 @@ function STimeRangePicker({
|
|
|
29405
29167
|
const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
|
|
29406
29168
|
const commitOpen = (next) => {
|
|
29407
29169
|
if (disabled) return;
|
|
29408
|
-
if (next) {
|
|
29409
|
-
const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;
|
|
29410
|
-
setPopoverAlignOffset(Math.max(0, (triggerWidth - TIME_RANGE_SELECTOR_WIDTH) / 2));
|
|
29411
|
-
}
|
|
29412
29170
|
setOpen(next);
|
|
29413
29171
|
onOpenChange?.(next);
|
|
29414
29172
|
if (!next && rules && rules.length > 0) setRuleError(runRules(value, rules));
|
|
@@ -29447,7 +29205,6 @@ function STimeRangePicker({
|
|
|
29447
29205
|
/* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
29448
29206
|
"div",
|
|
29449
29207
|
{
|
|
29450
|
-
ref: triggerRef,
|
|
29451
29208
|
id: triggerId,
|
|
29452
29209
|
role: "button",
|
|
29453
29210
|
"aria-disabled": disabled,
|
|
@@ -29511,9 +29268,8 @@ function STimeRangePicker({
|
|
|
29511
29268
|
RPopover13.Content,
|
|
29512
29269
|
{
|
|
29513
29270
|
side: "bottom",
|
|
29514
|
-
align: "
|
|
29271
|
+
align: "center",
|
|
29515
29272
|
sideOffset: 4,
|
|
29516
|
-
alignOffset: popoverAlignOffset,
|
|
29517
29273
|
className: cn(
|
|
29518
29274
|
"z-50 max-w-[var(--radix-popover-content-available-width)]",
|
|
29519
29275
|
FLOATING_SLIDE_ANIM
|