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.
Files changed (44) hide show
  1. package/README.md +20 -0
  2. package/dist/components/SDateRangePicker/SDateRangePicker.cjs +180 -37
  3. package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
  4. package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +6 -1
  5. package/dist/components/SDateRangePicker/SDateRangePicker.js +180 -37
  6. package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
  7. package/dist/components/SGnb/SGnb.cjs +329 -100
  8. package/dist/components/SGnb/SGnb.cjs.map +1 -1
  9. package/dist/components/SGnb/SGnb.d.ts +24 -5
  10. package/dist/components/SGnb/SGnb.js +330 -101
  11. package/dist/components/SGnb/SGnb.js.map +1 -1
  12. package/dist/components/SGnb/gnb.config.d.ts +46 -12
  13. package/dist/components/SGnb/index.d.ts +1 -1
  14. package/dist/components/SKeyValueTable/SKeyValueTable.cjs +180 -37
  15. package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
  16. package/dist/components/SKeyValueTable/SKeyValueTable.js +180 -37
  17. package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
  18. package/dist/components/SLayout/SLayout.cjs +37 -21
  19. package/dist/components/SLayout/SLayout.cjs.map +1 -1
  20. package/dist/components/SLayout/SLayout.d.ts +20 -1
  21. package/dist/components/SLayout/SLayout.js +37 -21
  22. package/dist/components/SLayout/SLayout.js.map +1 -1
  23. package/dist/components/SPage/SPage.cjs +38 -22
  24. package/dist/components/SPage/SPage.cjs.map +1 -1
  25. package/dist/components/SPage/SPage.js +38 -22
  26. package/dist/components/SPage/SPage.js.map +1 -1
  27. package/dist/components/STabs/STabs.cjs +15 -26
  28. package/dist/components/STabs/STabs.cjs.map +1 -1
  29. package/dist/components/STabs/STabs.d.ts +1 -1
  30. package/dist/components/STabs/STabs.js +15 -26
  31. package/dist/components/STabs/STabs.js.map +1 -1
  32. package/dist/components/STimePicker/STimePicker.cjs.map +1 -1
  33. package/dist/components/STimePicker/STimePicker.js.map +1 -1
  34. package/dist/components/STimeRangePicker/STimeRangePicker.cjs +3 -1
  35. package/dist/components/STimeRangePicker/STimeRangePicker.cjs.map +1 -1
  36. package/dist/components/STimeRangePicker/STimeRangePicker.js +3 -1
  37. package/dist/components/STimeRangePicker/STimeRangePicker.js.map +1 -1
  38. package/dist/index.cjs +531 -164
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.js +528 -165
  41. package/dist/index.js.map +1 -1
  42. package/dist/styles.css +73 -4
  43. package/dist/theme.css +1 -1
  44. package/package.json +3 -1
@@ -5400,25 +5400,45 @@ function SDatePicker({
5400
5400
  }
5401
5401
  );
5402
5402
  }
5403
+ function splitDateTime(v) {
5404
+ if (!v) return { date: null, hour: "00", minute: "00" };
5405
+ const [date = "", time = ""] = v.split(" ");
5406
+ const [hour = "00", minute = "00"] = time.split(":");
5407
+ return { date: date || null, hour, minute };
5408
+ }
5403
5409
  function RangeCalendar({
5404
5410
  value,
5405
5411
  selectable,
5406
5412
  maxRange,
5413
+ useTimePicker = false,
5407
5414
  onSelect,
5408
5415
  onPendingStartChange,
5409
5416
  onViewChange
5410
5417
  }) {
5411
5418
  const today = todayStr();
5412
- const base = value?.[0] || today;
5419
+ const initial = splitDateTime(value?.[0]);
5420
+ const base = initial.date || today;
5413
5421
  const [y, setY] = useState(Number(base.split("-")[0]));
5414
5422
  const [m, setM] = useState(Number(base.split("-")[1]));
5415
- const [start, setStart] = useState(value?.[0] ?? null);
5416
- const [end, setEnd] = useState(value?.[1] ?? null);
5423
+ const [start, setStart] = useState(initial.date);
5424
+ const [end, setEnd] = useState(splitDateTime(value?.[1]).date);
5417
5425
  const [hover, setHover] = useState(null);
5426
+ const [sH, setSH] = useState(initial.hour);
5427
+ const [sM, setSM] = useState(initial.minute);
5428
+ const [eH, setEH] = useState(splitDateTime(value?.[1]).hour);
5429
+ const [eM, setEM] = useState(splitDateTime(value?.[1]).minute);
5430
+ const lastEmitted = useRef("");
5418
5431
  useEffect(() => {
5419
- setStart(value?.[0] ?? null);
5420
- setEnd(value?.[1] ?? null);
5421
- }, [value]);
5432
+ if (useTimePicker && JSON.stringify(value) === lastEmitted.current) return;
5433
+ const s = splitDateTime(value?.[0]);
5434
+ const e = splitDateTime(value?.[1]);
5435
+ setStart(s.date);
5436
+ setEnd(e.date);
5437
+ setSH(s.hour);
5438
+ setSM(s.minute);
5439
+ setEH(e.hour);
5440
+ setEM(e.minute);
5441
+ }, [value, useTimePicker]);
5422
5442
  const setBase = (ny, nm) => {
5423
5443
  setY(ny);
5424
5444
  setM(nm);
@@ -5462,18 +5482,53 @@ function RangeCalendar({
5462
5482
  const hasRange = !!(rStart && rEnd && rStart !== rEnd);
5463
5483
  const inRange = (d) => !!(rStart && rEnd && d > rStart && d < rEnd);
5464
5484
  const RANGE_BG = "var(--cmp-datepicker-calendar-range-bg)";
5485
+ const pad = (v) => String(Number(v) || 0).padStart(2, "0");
5486
+ const emit = (dateStart, dateEnd, time) => {
5487
+ const t = time ?? { sH, sM, eH, eM };
5488
+ const range = useTimePicker ? [`${dateStart} ${pad(t.sH)}:${pad(t.sM)}`, `${dateEnd} ${pad(t.eH)}:${pad(t.eM)}`] : [dateStart, dateEnd];
5489
+ lastEmitted.current = JSON.stringify(range);
5490
+ onSelect(range);
5491
+ };
5465
5492
  const click = (d) => {
5466
5493
  if (isDisabled(d)) return;
5467
5494
  if (!start || complete || d < start) {
5468
5495
  setStart(d);
5469
5496
  setEnd(null);
5470
5497
  setHover(null);
5498
+ if (useTimePicker) {
5499
+ setSH("00");
5500
+ setSM("00");
5501
+ setEH("23");
5502
+ setEM("59");
5503
+ }
5471
5504
  onPendingStartChange?.(d);
5472
5505
  return;
5473
5506
  }
5474
5507
  setEnd(d);
5475
5508
  onPendingStartChange?.(null);
5476
- onSelect([start, d]);
5509
+ emit(start, d, useTimePicker ? { sH, sM, eH: "23", eM: "59" } : void 0);
5510
+ };
5511
+ const changeTime = (which, part, raw) => {
5512
+ const digits = raw.replace(/\D/g, "").slice(0, 2);
5513
+ const max = part === "h" ? 23 : 59;
5514
+ const next = digits !== "" && Number(digits) > max ? String(max) : digits;
5515
+ const nextTime = { sH, sM, eH, eM };
5516
+ if (which === "start") nextTime[part === "h" ? "sH" : "sM"] = next;
5517
+ else nextTime[part === "h" ? "eH" : "eM"] = next;
5518
+ setSH(nextTime.sH);
5519
+ setSM(nextTime.sM);
5520
+ setEH(nextTime.eH);
5521
+ setEM(nextTime.eM);
5522
+ if (start && end) emit(start, end, nextTime);
5523
+ };
5524
+ const blurTime = (which, part) => {
5525
+ if (which === "start") {
5526
+ if (part === "h") setSH(pad(sH));
5527
+ else setSM(pad(sM));
5528
+ } else {
5529
+ if (part === "h") setEH(pad(eH));
5530
+ else setEM(pad(eM));
5531
+ }
5477
5532
  };
5478
5533
  const GRID_COLS = "grid grid-cols-[repeat(7,var(--cmp-datepicker-calendar-day-width))]";
5479
5534
  const renderPanel = (gy, gm, isLeft) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-[var(--cmp-datepicker-calendar-gap)]", children: [
@@ -5548,35 +5603,120 @@ function RangeCalendar({
5548
5603
  );
5549
5604
  }) })
5550
5605
  ] });
5551
- return /* @__PURE__ */ jsxs("div", { className: "inline-flex h-[364px] 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", children: [
5552
- /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
5553
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-[var(--cmp-datepicker-calendar-gap)] text-[14px] font-medium leading-[24px]", children: [
5554
- /* @__PURE__ */ jsx(SGhostButton, { icon: "chevronLeft", size: "xxs", ariaLabel: "prevYear", onClick: goPrevYear }),
5555
- /* @__PURE__ */ jsx("span", { className: "inline-flex min-w-[40px] items-center justify-center text-center", children: y }),
5556
- /* @__PURE__ */ jsx(SGhostButton, { icon: "chevronRight", size: "xxs", ariaLabel: "nextYear", onClick: goNextYear })
5557
- ] }),
5558
- /* @__PURE__ */ jsx(
5559
- "button",
5560
- {
5561
- type: "button",
5562
- onClick: goToday,
5563
- 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",
5564
- children: "\uC624\uB298"
5565
- }
5566
- )
5567
- ] }),
5568
- /* @__PURE__ */ jsxs("div", { className: "flex gap-[var(--cmp-datepicker-calendar-range-panelGap)]", children: [
5569
- renderPanel(y, m, true),
5570
- /* @__PURE__ */ jsx(
5571
- "span",
5572
- {
5573
- className: "w-px shrink-0 self-stretch bg-[var(--cmp-datepicker-calendar-range-divider)]",
5574
- "aria-hidden": true
5575
- }
5606
+ const renderTimeSection = (which, date, suffix) => {
5607
+ const active = !!date;
5608
+ const [yy = "", mm = "", dd = ""] = date ? date.split("-") : [];
5609
+ const hour = which === "start" ? sH : eH;
5610
+ const minute = which === "start" ? sM : eM;
5611
+ const num = (n, strip) => active && n !== "" ? strip ? String(Number(n)) : n : "-";
5612
+ 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";
5613
+ const LABEL = "text-[color:var(--cmp-datepicker-calendar-time-date-label)]";
5614
+ const UNIT = "text-[color:var(--cmp-datepicker-calendar-time-date-unit)]";
5615
+ return /* @__PURE__ */ jsxs(
5616
+ "div",
5617
+ {
5618
+ className: cn(
5619
+ "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]",
5620
+ active ? "bg-[var(--cmp-datepicker-calendar-time-bg-selected)]" : "bg-[var(--cmp-datepicker-calendar-time-bg-default)]"
5621
+ ),
5622
+ children: [
5623
+ /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-[var(--cmp-datepicker-calendar-time-date-gap)]", children: [
5624
+ /* @__PURE__ */ jsx("span", { className: LABEL, children: num(yy, false) }),
5625
+ /* @__PURE__ */ jsx("span", { className: UNIT, children: "\uB144" }),
5626
+ /* @__PURE__ */ jsx("span", { className: LABEL, children: num(mm, true) }),
5627
+ /* @__PURE__ */ jsx("span", { className: UNIT, children: "\uC6D4" }),
5628
+ /* @__PURE__ */ jsx("span", { className: LABEL, children: num(dd, true) }),
5629
+ /* @__PURE__ */ jsx("span", { className: UNIT, children: "\uC77C" })
5630
+ ] }),
5631
+ /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-[var(--cmp-datepicker-calendar-time-unit-gap)]", children: [
5632
+ /* @__PURE__ */ jsx(
5633
+ "input",
5634
+ {
5635
+ type: "text",
5636
+ inputMode: "numeric",
5637
+ maxLength: 2,
5638
+ "aria-label": `${suffix} \uC2DC`,
5639
+ disabled: !active,
5640
+ value: active ? hour : "",
5641
+ placeholder: "--",
5642
+ onChange: (e) => changeTime(which, "h", e.target.value),
5643
+ onBlur: () => blurTime(which, "h"),
5644
+ className: INPUT_CLS
5645
+ }
5646
+ ),
5647
+ /* @__PURE__ */ jsx("span", { className: LABEL, children: ":" }),
5648
+ /* @__PURE__ */ jsx(
5649
+ "input",
5650
+ {
5651
+ type: "text",
5652
+ inputMode: "numeric",
5653
+ maxLength: 2,
5654
+ "aria-label": `${suffix} \uBD84`,
5655
+ disabled: !active,
5656
+ value: active ? minute : "",
5657
+ placeholder: "--",
5658
+ onChange: (e) => changeTime(which, "m", e.target.value),
5659
+ onBlur: () => blurTime(which, "m"),
5660
+ className: INPUT_CLS
5661
+ }
5662
+ )
5663
+ ] }),
5664
+ /* @__PURE__ */ jsx("span", { className: UNIT, children: suffix })
5665
+ ]
5666
+ }
5667
+ );
5668
+ };
5669
+ return /* @__PURE__ */ jsxs(
5670
+ "div",
5671
+ {
5672
+ className: cn(
5673
+ "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",
5674
+ useTimePicker ? "h-auto" : "h-[364px]"
5576
5675
  ),
5577
- renderPanel(nextMonthYM.year, nextMonthYM.month, false)
5578
- ] })
5579
- ] });
5676
+ children: [
5677
+ /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
5678
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-[var(--cmp-datepicker-calendar-gap)] text-[14px] font-medium leading-[24px]", children: [
5679
+ /* @__PURE__ */ jsx(SGhostButton, { icon: "chevronLeft", size: "xxs", ariaLabel: "prevYear", onClick: goPrevYear }),
5680
+ /* @__PURE__ */ jsx("span", { className: "inline-flex min-w-[40px] items-center justify-center text-center", children: y }),
5681
+ /* @__PURE__ */ jsx(SGhostButton, { icon: "chevronRight", size: "xxs", ariaLabel: "nextYear", onClick: goNextYear })
5682
+ ] }),
5683
+ /* @__PURE__ */ jsx(
5684
+ "button",
5685
+ {
5686
+ type: "button",
5687
+ onClick: goToday,
5688
+ 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",
5689
+ children: "\uC624\uB298"
5690
+ }
5691
+ )
5692
+ ] }),
5693
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-[var(--cmp-datepicker-calendar-range-panelGap)]", children: [
5694
+ renderPanel(y, m, true),
5695
+ /* @__PURE__ */ jsx(
5696
+ "span",
5697
+ {
5698
+ className: "w-px shrink-0 self-stretch bg-[var(--cmp-datepicker-calendar-range-divider)]",
5699
+ "aria-hidden": true
5700
+ }
5701
+ ),
5702
+ renderPanel(nextMonthYM.year, nextMonthYM.month, false)
5703
+ ] }),
5704
+ useTimePicker && /* @__PURE__ */ jsxs(Fragment, { children: [
5705
+ /* @__PURE__ */ jsx(
5706
+ "span",
5707
+ {
5708
+ className: "h-px w-full bg-[var(--cmp-datepicker-calendar-range-divider)]",
5709
+ "aria-hidden": true
5710
+ }
5711
+ ),
5712
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-[var(--cmp-datepicker-calendar-time-gap)]", children: [
5713
+ renderTimeSection("start", start, "\uBD80\uD130"),
5714
+ renderTimeSection("end", end, "\uAE4C\uC9C0")
5715
+ ] })
5716
+ ] })
5717
+ ]
5718
+ }
5719
+ );
5580
5720
  }
5581
5721
  function SDateRangePicker({
5582
5722
  value,
@@ -5586,6 +5726,7 @@ function SDateRangePicker({
5586
5726
  placeholder = "YYYY-MM-DD ~ YYYY-MM-DD",
5587
5727
  selectable,
5588
5728
  maxRange,
5729
+ useTimePicker = false,
5589
5730
  disabled = false,
5590
5731
  width,
5591
5732
  name,
@@ -5629,8 +5770,9 @@ function SDateRangePicker({
5629
5770
  setPendingStart(null);
5630
5771
  onValueChange?.(r);
5631
5772
  if (rules && rules.length > 0) setRuleError(runRules(r, rules));
5632
- setOpen(false);
5773
+ if (!useTimePicker) setOpen(false);
5633
5774
  };
5775
+ const resolvedPlaceholder = useTimePicker && placeholder === "YYYY-MM-DD ~ YYYY-MM-DD" ? "YYYY-MM-DD HH:mm ~ YYYY-MM-DD HH:mm" : placeholder;
5634
5776
  return /* @__PURE__ */ jsx(
5635
5777
  SField,
5636
5778
  {
@@ -5697,7 +5839,7 @@ function SDateRangePicker({
5697
5839
  /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-right", children: startText }),
5698
5840
  /* @__PURE__ */ jsx("span", { className: "px-[4px]", children: "~" }),
5699
5841
  /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: endText })
5700
- ] }) : placeholder
5842
+ ] }) : resolvedPlaceholder
5701
5843
  }
5702
5844
  )
5703
5845
  ]
@@ -5716,6 +5858,7 @@ function SDateRangePicker({
5716
5858
  value: value ?? null,
5717
5859
  selectable,
5718
5860
  maxRange,
5861
+ useTimePicker,
5719
5862
  onSelect: select,
5720
5863
  onPendingStartChange: setPendingStart,
5721
5864
  onViewChange