sellmate-design-system-react 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs +180 -37
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +6 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.js +180 -37
- package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
- package/dist/components/SGnb/SGnb.cjs +329 -100
- package/dist/components/SGnb/SGnb.cjs.map +1 -1
- package/dist/components/SGnb/SGnb.d.ts +24 -5
- package/dist/components/SGnb/SGnb.js +330 -101
- package/dist/components/SGnb/SGnb.js.map +1 -1
- package/dist/components/SGnb/gnb.config.d.ts +46 -12
- package/dist/components/SGnb/index.d.ts +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs +180 -37
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.js +180 -37
- package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
- package/dist/components/SLayout/SLayout.cjs +37 -21
- package/dist/components/SLayout/SLayout.cjs.map +1 -1
- package/dist/components/SLayout/SLayout.d.ts +20 -1
- package/dist/components/SLayout/SLayout.js +37 -21
- package/dist/components/SLayout/SLayout.js.map +1 -1
- package/dist/components/SPage/SPage.cjs +38 -22
- package/dist/components/SPage/SPage.cjs.map +1 -1
- package/dist/components/SPage/SPage.js +38 -22
- package/dist/components/SPage/SPage.js.map +1 -1
- package/dist/components/STabs/STabs.cjs +15 -26
- package/dist/components/STabs/STabs.cjs.map +1 -1
- package/dist/components/STabs/STabs.d.ts +1 -1
- package/dist/components/STabs/STabs.js +15 -26
- package/dist/components/STabs/STabs.js.map +1 -1
- package/dist/components/STimePicker/STimePicker.cjs.map +1 -1
- package/dist/components/STimePicker/STimePicker.js.map +1 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.cjs +3 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.cjs.map +1 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.js +3 -1
- package/dist/components/STimeRangePicker/STimeRangePicker.js.map +1 -1
- package/dist/index.cjs +531 -164
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +528 -165
- package/dist/index.js.map +1 -1
- package/dist/styles.css +73 -4
- package/dist/theme.css +1 -1
- package/package.json +3 -1
|
@@ -20,6 +20,11 @@ export interface SDateRangePickerProps {
|
|
|
20
20
|
selectable?: [string, string];
|
|
21
21
|
/** 최대 선택 일수 */
|
|
22
22
|
maxRange?: number;
|
|
23
|
+
/**
|
|
24
|
+
* 시간(시:분) 선택 푸터 사용 여부.
|
|
25
|
+
* true이면 value는 "YYYY-MM-DD HH:mm" 형식이 되고, 캘린더 하단에 시작·종료 시간 입력이 표시된다.
|
|
26
|
+
*/
|
|
27
|
+
useTimePicker?: boolean;
|
|
23
28
|
disabled?: boolean;
|
|
24
29
|
width?: number | string;
|
|
25
30
|
name?: string;
|
|
@@ -40,4 +45,4 @@ export interface SDateRangePickerProps {
|
|
|
40
45
|
style?: CSSProperties;
|
|
41
46
|
}
|
|
42
47
|
/** SDateRangePicker — sd-date-range-picker 포팅. SField + SPopover(범위 캘린더). */
|
|
43
|
-
export declare function SDateRangePicker({ value, onValueChange, onViewChange, size, placeholder, selectable, maxRange, disabled, width, name, rules, status, label, labelWidth, icon, iconColor, labelTooltip, labelTooltipProps, addonLabel, addonAlign, hint, error, errorMessage, className, style, }: SDateRangePickerProps): import("react").JSX.Element;
|
|
48
|
+
export declare function SDateRangePicker({ value, onValueChange, onViewChange, size, placeholder, selectable, maxRange, useTimePicker, disabled, width, name, rules, status, label, labelWidth, icon, iconColor, labelTooltip, labelTooltipProps, addonLabel, addonAlign, hint, error, errorMessage, className, style, }: SDateRangePickerProps): import("react").JSX.Element;
|
|
@@ -3426,25 +3426,45 @@ function monthCells(year, month) {
|
|
|
3426
3426
|
return cells;
|
|
3427
3427
|
}
|
|
3428
3428
|
var WEEK_LABELS = ["\uC77C", "\uC6D4", "\uD654", "\uC218", "\uBAA9", "\uAE08", "\uD1A0"];
|
|
3429
|
+
function splitDateTime(v) {
|
|
3430
|
+
if (!v) return { date: null, hour: "00", minute: "00" };
|
|
3431
|
+
const [date = "", time = ""] = v.split(" ");
|
|
3432
|
+
const [hour = "00", minute = "00"] = time.split(":");
|
|
3433
|
+
return { date: date || null, hour, minute };
|
|
3434
|
+
}
|
|
3429
3435
|
function RangeCalendar({
|
|
3430
3436
|
value,
|
|
3431
3437
|
selectable,
|
|
3432
3438
|
maxRange,
|
|
3439
|
+
useTimePicker = false,
|
|
3433
3440
|
onSelect,
|
|
3434
3441
|
onPendingStartChange,
|
|
3435
3442
|
onViewChange
|
|
3436
3443
|
}) {
|
|
3437
3444
|
const today = todayStr();
|
|
3438
|
-
const
|
|
3445
|
+
const initial = splitDateTime(value?.[0]);
|
|
3446
|
+
const base = initial.date || today;
|
|
3439
3447
|
const [y, setY] = useState(Number(base.split("-")[0]));
|
|
3440
3448
|
const [m, setM] = useState(Number(base.split("-")[1]));
|
|
3441
|
-
const [start, setStart] = useState(
|
|
3442
|
-
const [end, setEnd] = useState(value?.[1]
|
|
3449
|
+
const [start, setStart] = useState(initial.date);
|
|
3450
|
+
const [end, setEnd] = useState(splitDateTime(value?.[1]).date);
|
|
3443
3451
|
const [hover, setHover] = useState(null);
|
|
3452
|
+
const [sH, setSH] = useState(initial.hour);
|
|
3453
|
+
const [sM, setSM] = useState(initial.minute);
|
|
3454
|
+
const [eH, setEH] = useState(splitDateTime(value?.[1]).hour);
|
|
3455
|
+
const [eM, setEM] = useState(splitDateTime(value?.[1]).minute);
|
|
3456
|
+
const lastEmitted = useRef("");
|
|
3444
3457
|
useEffect(() => {
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3458
|
+
if (useTimePicker && JSON.stringify(value) === lastEmitted.current) return;
|
|
3459
|
+
const s = splitDateTime(value?.[0]);
|
|
3460
|
+
const e = splitDateTime(value?.[1]);
|
|
3461
|
+
setStart(s.date);
|
|
3462
|
+
setEnd(e.date);
|
|
3463
|
+
setSH(s.hour);
|
|
3464
|
+
setSM(s.minute);
|
|
3465
|
+
setEH(e.hour);
|
|
3466
|
+
setEM(e.minute);
|
|
3467
|
+
}, [value, useTimePicker]);
|
|
3448
3468
|
const setBase = (ny, nm) => {
|
|
3449
3469
|
setY(ny);
|
|
3450
3470
|
setM(nm);
|
|
@@ -3488,18 +3508,53 @@ function RangeCalendar({
|
|
|
3488
3508
|
const hasRange = !!(rStart && rEnd && rStart !== rEnd);
|
|
3489
3509
|
const inRange = (d) => !!(rStart && rEnd && d > rStart && d < rEnd);
|
|
3490
3510
|
const RANGE_BG = "var(--cmp-datepicker-calendar-range-bg)";
|
|
3511
|
+
const pad = (v) => String(Number(v) || 0).padStart(2, "0");
|
|
3512
|
+
const emit = (dateStart, dateEnd, time) => {
|
|
3513
|
+
const t = time ?? { sH, sM, eH, eM };
|
|
3514
|
+
const range = useTimePicker ? [`${dateStart} ${pad(t.sH)}:${pad(t.sM)}`, `${dateEnd} ${pad(t.eH)}:${pad(t.eM)}`] : [dateStart, dateEnd];
|
|
3515
|
+
lastEmitted.current = JSON.stringify(range);
|
|
3516
|
+
onSelect(range);
|
|
3517
|
+
};
|
|
3491
3518
|
const click = (d) => {
|
|
3492
3519
|
if (isDisabled(d)) return;
|
|
3493
3520
|
if (!start || complete || d < start) {
|
|
3494
3521
|
setStart(d);
|
|
3495
3522
|
setEnd(null);
|
|
3496
3523
|
setHover(null);
|
|
3524
|
+
if (useTimePicker) {
|
|
3525
|
+
setSH("00");
|
|
3526
|
+
setSM("00");
|
|
3527
|
+
setEH("23");
|
|
3528
|
+
setEM("59");
|
|
3529
|
+
}
|
|
3497
3530
|
onPendingStartChange?.(d);
|
|
3498
3531
|
return;
|
|
3499
3532
|
}
|
|
3500
3533
|
setEnd(d);
|
|
3501
3534
|
onPendingStartChange?.(null);
|
|
3502
|
-
|
|
3535
|
+
emit(start, d, useTimePicker ? { sH, sM, eH: "23", eM: "59" } : void 0);
|
|
3536
|
+
};
|
|
3537
|
+
const changeTime = (which, part, raw) => {
|
|
3538
|
+
const digits = raw.replace(/\D/g, "").slice(0, 2);
|
|
3539
|
+
const max = part === "h" ? 23 : 59;
|
|
3540
|
+
const next = digits !== "" && Number(digits) > max ? String(max) : digits;
|
|
3541
|
+
const nextTime = { sH, sM, eH, eM };
|
|
3542
|
+
if (which === "start") nextTime[part === "h" ? "sH" : "sM"] = next;
|
|
3543
|
+
else nextTime[part === "h" ? "eH" : "eM"] = next;
|
|
3544
|
+
setSH(nextTime.sH);
|
|
3545
|
+
setSM(nextTime.sM);
|
|
3546
|
+
setEH(nextTime.eH);
|
|
3547
|
+
setEM(nextTime.eM);
|
|
3548
|
+
if (start && end) emit(start, end, nextTime);
|
|
3549
|
+
};
|
|
3550
|
+
const blurTime = (which, part) => {
|
|
3551
|
+
if (which === "start") {
|
|
3552
|
+
if (part === "h") setSH(pad(sH));
|
|
3553
|
+
else setSM(pad(sM));
|
|
3554
|
+
} else {
|
|
3555
|
+
if (part === "h") setEH(pad(eH));
|
|
3556
|
+
else setEM(pad(eM));
|
|
3557
|
+
}
|
|
3503
3558
|
};
|
|
3504
3559
|
const GRID_COLS = "grid grid-cols-[repeat(7,var(--cmp-datepicker-calendar-day-width))]";
|
|
3505
3560
|
const renderPanel = (gy, gm, isLeft) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-[var(--cmp-datepicker-calendar-gap)]", children: [
|
|
@@ -3574,35 +3629,120 @@ function RangeCalendar({
|
|
|
3574
3629
|
);
|
|
3575
3630
|
}) })
|
|
3576
3631
|
] });
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3632
|
+
const renderTimeSection = (which, date, suffix) => {
|
|
3633
|
+
const active = !!date;
|
|
3634
|
+
const [yy = "", mm = "", dd = ""] = date ? date.split("-") : [];
|
|
3635
|
+
const hour = which === "start" ? sH : eH;
|
|
3636
|
+
const minute = which === "start" ? sM : eM;
|
|
3637
|
+
const num = (n, strip) => active && n !== "" ? strip ? String(Number(n)) : n : "-";
|
|
3638
|
+
const INPUT_CLS = "h-[var(--cmp-datepicker-sm-height)] w-[40px] rounded-[var(--cmp-datepicker-sm-radius)] border border-solid border-[color:var(--cmp-datepicker-border-default)] bg-[var(--cmp-datepicker-bg-default)] text-center text-[12px] font-medium leading-[20px] text-[color:var(--cmp-datepicker-text-default)] outline-none placeholder:text-[color:var(--cmp-datepicker-text-disabled)] focus:border-[color:var(--cmp-datepicker-border-focus)] disabled:cursor-not-allowed";
|
|
3639
|
+
const LABEL = "text-[color:var(--cmp-datepicker-calendar-time-date-label)]";
|
|
3640
|
+
const UNIT = "text-[color:var(--cmp-datepicker-calendar-time-date-unit)]";
|
|
3641
|
+
return /* @__PURE__ */ jsxs(
|
|
3642
|
+
"div",
|
|
3643
|
+
{
|
|
3644
|
+
className: cn(
|
|
3645
|
+
"flex flex-1 items-center justify-center gap-[var(--cmp-datepicker-calendar-time-section-gap)] rounded-[var(--cmp-datepicker-calendar-time-radius)] px-[var(--cmp-datepicker-calendar-time-paddingX)] py-[var(--cmp-datepicker-calendar-time-paddingY)] text-[12px] font-medium leading-[20px]",
|
|
3646
|
+
active ? "bg-[var(--cmp-datepicker-calendar-time-bg-selected)]" : "bg-[var(--cmp-datepicker-calendar-time-bg-default)]"
|
|
3647
|
+
),
|
|
3648
|
+
children: [
|
|
3649
|
+
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-[var(--cmp-datepicker-calendar-time-date-gap)]", children: [
|
|
3650
|
+
/* @__PURE__ */ jsx("span", { className: LABEL, children: num(yy, false) }),
|
|
3651
|
+
/* @__PURE__ */ jsx("span", { className: UNIT, children: "\uB144" }),
|
|
3652
|
+
/* @__PURE__ */ jsx("span", { className: LABEL, children: num(mm, true) }),
|
|
3653
|
+
/* @__PURE__ */ jsx("span", { className: UNIT, children: "\uC6D4" }),
|
|
3654
|
+
/* @__PURE__ */ jsx("span", { className: LABEL, children: num(dd, true) }),
|
|
3655
|
+
/* @__PURE__ */ jsx("span", { className: UNIT, children: "\uC77C" })
|
|
3656
|
+
] }),
|
|
3657
|
+
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-[var(--cmp-datepicker-calendar-time-unit-gap)]", children: [
|
|
3658
|
+
/* @__PURE__ */ jsx(
|
|
3659
|
+
"input",
|
|
3660
|
+
{
|
|
3661
|
+
type: "text",
|
|
3662
|
+
inputMode: "numeric",
|
|
3663
|
+
maxLength: 2,
|
|
3664
|
+
"aria-label": `${suffix} \uC2DC`,
|
|
3665
|
+
disabled: !active,
|
|
3666
|
+
value: active ? hour : "",
|
|
3667
|
+
placeholder: "--",
|
|
3668
|
+
onChange: (e) => changeTime(which, "h", e.target.value),
|
|
3669
|
+
onBlur: () => blurTime(which, "h"),
|
|
3670
|
+
className: INPUT_CLS
|
|
3671
|
+
}
|
|
3672
|
+
),
|
|
3673
|
+
/* @__PURE__ */ jsx("span", { className: LABEL, children: ":" }),
|
|
3674
|
+
/* @__PURE__ */ jsx(
|
|
3675
|
+
"input",
|
|
3676
|
+
{
|
|
3677
|
+
type: "text",
|
|
3678
|
+
inputMode: "numeric",
|
|
3679
|
+
maxLength: 2,
|
|
3680
|
+
"aria-label": `${suffix} \uBD84`,
|
|
3681
|
+
disabled: !active,
|
|
3682
|
+
value: active ? minute : "",
|
|
3683
|
+
placeholder: "--",
|
|
3684
|
+
onChange: (e) => changeTime(which, "m", e.target.value),
|
|
3685
|
+
onBlur: () => blurTime(which, "m"),
|
|
3686
|
+
className: INPUT_CLS
|
|
3687
|
+
}
|
|
3688
|
+
)
|
|
3689
|
+
] }),
|
|
3690
|
+
/* @__PURE__ */ jsx("span", { className: UNIT, children: suffix })
|
|
3691
|
+
]
|
|
3692
|
+
}
|
|
3693
|
+
);
|
|
3694
|
+
};
|
|
3695
|
+
return /* @__PURE__ */ jsxs(
|
|
3696
|
+
"div",
|
|
3697
|
+
{
|
|
3698
|
+
className: cn(
|
|
3699
|
+
"inline-flex flex-col gap-[var(--cmp-datepicker-calendar-gap)] rounded-[var(--cmp-datepicker-calendar-radius)] bg-[var(--cmp-datepicker-calendar-bg)] p-[var(--cmp-datepicker-calendar-paddingXY)] shadow-[2px_2px_12px_2px_rgba(0,0,0,0.2)] select-none",
|
|
3700
|
+
useTimePicker ? "h-auto" : "h-[364px]"
|
|
3602
3701
|
),
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3702
|
+
children: [
|
|
3703
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
|
|
3704
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-[var(--cmp-datepicker-calendar-gap)] text-[14px] font-medium leading-[24px]", children: [
|
|
3705
|
+
/* @__PURE__ */ jsx(SGhostButton, { icon: "chevronLeft", size: "xxs", ariaLabel: "prevYear", onClick: goPrevYear }),
|
|
3706
|
+
/* @__PURE__ */ jsx("span", { className: "inline-flex min-w-[40px] items-center justify-center text-center", children: y }),
|
|
3707
|
+
/* @__PURE__ */ jsx(SGhostButton, { icon: "chevronRight", size: "xxs", ariaLabel: "nextYear", onClick: goNextYear })
|
|
3708
|
+
] }),
|
|
3709
|
+
/* @__PURE__ */ jsx(
|
|
3710
|
+
"button",
|
|
3711
|
+
{
|
|
3712
|
+
type: "button",
|
|
3713
|
+
onClick: goToday,
|
|
3714
|
+
className: "absolute right-0 h-[24px] min-w-[37px] cursor-pointer bg-transparent text-center text-[12px] font-medium leading-[24px] text-[color:var(--cmp-datepicker-calendar-day-default-text)] hover:underline",
|
|
3715
|
+
children: "\uC624\uB298"
|
|
3716
|
+
}
|
|
3717
|
+
)
|
|
3718
|
+
] }),
|
|
3719
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-[var(--cmp-datepicker-calendar-range-panelGap)]", children: [
|
|
3720
|
+
renderPanel(y, m, true),
|
|
3721
|
+
/* @__PURE__ */ jsx(
|
|
3722
|
+
"span",
|
|
3723
|
+
{
|
|
3724
|
+
className: "w-px shrink-0 self-stretch bg-[var(--cmp-datepicker-calendar-range-divider)]",
|
|
3725
|
+
"aria-hidden": true
|
|
3726
|
+
}
|
|
3727
|
+
),
|
|
3728
|
+
renderPanel(nextMonthYM.year, nextMonthYM.month, false)
|
|
3729
|
+
] }),
|
|
3730
|
+
useTimePicker && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3731
|
+
/* @__PURE__ */ jsx(
|
|
3732
|
+
"span",
|
|
3733
|
+
{
|
|
3734
|
+
className: "h-px w-full bg-[var(--cmp-datepicker-calendar-range-divider)]",
|
|
3735
|
+
"aria-hidden": true
|
|
3736
|
+
}
|
|
3737
|
+
),
|
|
3738
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-[var(--cmp-datepicker-calendar-time-gap)]", children: [
|
|
3739
|
+
renderTimeSection("start", start, "\uBD80\uD130"),
|
|
3740
|
+
renderTimeSection("end", end, "\uAE4C\uC9C0")
|
|
3741
|
+
] })
|
|
3742
|
+
] })
|
|
3743
|
+
]
|
|
3744
|
+
}
|
|
3745
|
+
);
|
|
3606
3746
|
}
|
|
3607
3747
|
function SDateRangePicker({
|
|
3608
3748
|
value,
|
|
@@ -3612,6 +3752,7 @@ function SDateRangePicker({
|
|
|
3612
3752
|
placeholder = "YYYY-MM-DD ~ YYYY-MM-DD",
|
|
3613
3753
|
selectable,
|
|
3614
3754
|
maxRange,
|
|
3755
|
+
useTimePicker = false,
|
|
3615
3756
|
disabled = false,
|
|
3616
3757
|
width,
|
|
3617
3758
|
name,
|
|
@@ -3655,8 +3796,9 @@ function SDateRangePicker({
|
|
|
3655
3796
|
setPendingStart(null);
|
|
3656
3797
|
onValueChange?.(r);
|
|
3657
3798
|
if (rules && rules.length > 0) setRuleError(runRules(r, rules));
|
|
3658
|
-
setOpen(false);
|
|
3799
|
+
if (!useTimePicker) setOpen(false);
|
|
3659
3800
|
};
|
|
3801
|
+
const resolvedPlaceholder = useTimePicker && placeholder === "YYYY-MM-DD ~ YYYY-MM-DD" ? "YYYY-MM-DD HH:mm ~ YYYY-MM-DD HH:mm" : placeholder;
|
|
3660
3802
|
return /* @__PURE__ */ jsx(
|
|
3661
3803
|
SField,
|
|
3662
3804
|
{
|
|
@@ -3723,7 +3865,7 @@ function SDateRangePicker({
|
|
|
3723
3865
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-right", children: startText }),
|
|
3724
3866
|
/* @__PURE__ */ jsx("span", { className: "px-[4px]", children: "~" }),
|
|
3725
3867
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: endText })
|
|
3726
|
-
] }) :
|
|
3868
|
+
] }) : resolvedPlaceholder
|
|
3727
3869
|
}
|
|
3728
3870
|
)
|
|
3729
3871
|
]
|
|
@@ -3742,6 +3884,7 @@ function SDateRangePicker({
|
|
|
3742
3884
|
value: value ?? null,
|
|
3743
3885
|
selectable,
|
|
3744
3886
|
maxRange,
|
|
3887
|
+
useTimePicker,
|
|
3745
3888
|
onSelect: select,
|
|
3746
3889
|
onPendingStartChange: setPendingStart,
|
|
3747
3890
|
onViewChange
|