@hivcd-printshop/design-system 1.3.1 → 1.3.3

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/dist/index.d.mts CHANGED
@@ -424,6 +424,31 @@ interface SideRadioAccordionProps {
424
424
  }
425
425
  declare const SideRadioAccordion: react.ForwardRefExoticComponent<SideRadioAccordionProps & react.RefAttributes<HTMLDivElement>>;
426
426
 
427
+ type TabSwitchItem = {
428
+ label: string;
429
+ /**
430
+ * 선택 상태를 식별할 값. 표시 텍스트(label)와 분리하고 싶을 때 사용한다.
431
+ * 생략하면 label이 식별자로 쓰인다.
432
+ */
433
+ value?: string;
434
+ };
435
+ interface TabSwitchProps {
436
+ items: TabSwitchItem[];
437
+ /** controlled: 현재 선택된 항목의 value(없으면 label). */
438
+ selected?: string;
439
+ /** uncontrolled 초기 선택값. `selected`를 함께 주면 무시된다. 기본은 첫 항목. */
440
+ defaultSelected?: string;
441
+ /** 선택이 바뀔 때 호출. 인자는 항목의 value(없으면 label). */
442
+ onSelect?: (value: string) => void;
443
+ className?: string;
444
+ }
445
+ /**
446
+ * 두 개 이상의 항목을 가로로 나열하고 선택된 항목 아래에 밑줄을 그리는 탭 전환 UI.
447
+ * 예: "나의 예약"의 "진행중인 예약" / "완료된 예약" 전환.
448
+ * (Figma "카테고리" 컴포넌트 — CategorySegmentedControl과는 별개의, 필터가 아닌 탭 전환용 컴포넌트.)
449
+ */
450
+ declare const TabSwitch: react.ForwardRefExoticComponent<TabSwitchProps & react.RefAttributes<HTMLDivElement>>;
451
+
427
452
  type Week = "thisWeek" | "nextWeek" | "twoWeeksLater";
428
453
  interface WeekNavigationProps {
429
454
  /** 표시 중인 주의 월요일(ISO "YYYY-MM-DD"). 범위 라벨(~금요일)을 여기서 계산한다. */
@@ -577,4 +602,4 @@ interface ToastProps {
577
602
  }
578
603
  declare const Toast: react.ForwardRefExoticComponent<ToastProps & react.RefAttributes<HTMLDivElement>>;
579
604
 
580
- export { Accordion, type AccordionProps, BackButton, type BackButtonProps, BasicFormField, type BasicFormFieldProps, CTA, type CTAProps, CategorySegment, type CategorySegmentProps, CategorySegmentedControl, type CategorySegmentedControlProps, Column, ColumnContentContainer, type ColumnContentContainerProps, ColumnDescription, ColumnDescriptionList, type ColumnDescriptionListProps, type ColumnDescriptionProps, ColumnLabel, type ColumnLabelProps, type ColumnProps, ColumnSubTitle, type ColumnSubTitleProps, ColumnText, type ColumnTextProps, ColumnTextStyle, type DayColumn, Dropdown, type DropdownProps, FormCheckBox, type FormCheckBoxProps, FormColor, type FormColorProps, FormFile, type FormFileProps, FormNumber, type FormNumberProps, FormPassword, type FormPasswordProps, FormSelectBox, type FormSelectBoxProps, FormTel, type FormTelProps, FormText, FormTextArea, type FormTextAreaProps, type FormTextProps, IconCheck, IconChevronDownXS, IconClose, IconCompass, IconExclamation, IconInfo, IconRadioSelected, IconRadioUnselected, type LinkComponent, List, type ListProps, type LowerPartItem, Modal, type ModalProps, ModalText, type ModalTextProps, ModalTextStyle, MultiColumn, type NavIcon, NoticeBadge, type NoticeBadgeProps, type NoticeBadgeVariable, NoticeBar, type NoticeBarBadgeVariable, type NoticeBarProps, type NoticeBarVariable, type RadioToggle, SearchBar, type SearchBarProps, SelectBoxOption, type SelectBoxOptionProps, SideRadioAccordion, type PrintColor$1 as SideRadioAccordionPrintColor, type SideRadioAccordionProps, TNB, type TNBProps, Tag, type TagProps, TextButton, type TextButtonProps, type TimeSlot, type TimeSlotState, Timetable, type PrintColor as TimetablePrintColor, type TimetableProps, TitleInput, type TitleInputProps, Toast, type ToastProps, type UpperPartItem, type Week, WeekNavigation, type WeekNavigationProps, getInputStyles };
605
+ export { Accordion, type AccordionProps, BackButton, type BackButtonProps, BasicFormField, type BasicFormFieldProps, CTA, type CTAProps, CategorySegment, type CategorySegmentProps, CategorySegmentedControl, type CategorySegmentedControlProps, Column, ColumnContentContainer, type ColumnContentContainerProps, ColumnDescription, ColumnDescriptionList, type ColumnDescriptionListProps, type ColumnDescriptionProps, ColumnLabel, type ColumnLabelProps, type ColumnProps, ColumnSubTitle, type ColumnSubTitleProps, ColumnText, type ColumnTextProps, ColumnTextStyle, type DayColumn, Dropdown, type DropdownProps, FormCheckBox, type FormCheckBoxProps, FormColor, type FormColorProps, FormFile, type FormFileProps, FormNumber, type FormNumberProps, FormPassword, type FormPasswordProps, FormSelectBox, type FormSelectBoxProps, FormTel, type FormTelProps, FormText, FormTextArea, type FormTextAreaProps, type FormTextProps, IconCheck, IconChevronDownXS, IconClose, IconCompass, IconExclamation, IconInfo, IconRadioSelected, IconRadioUnselected, type LinkComponent, List, type ListProps, type LowerPartItem, Modal, type ModalProps, ModalText, type ModalTextProps, ModalTextStyle, MultiColumn, type NavIcon, NoticeBadge, type NoticeBadgeProps, type NoticeBadgeVariable, NoticeBar, type NoticeBarBadgeVariable, type NoticeBarProps, type NoticeBarVariable, type RadioToggle, SearchBar, type SearchBarProps, SelectBoxOption, type SelectBoxOptionProps, SideRadioAccordion, type PrintColor$1 as SideRadioAccordionPrintColor, type SideRadioAccordionProps, TNB, type TNBProps, TabSwitch, type TabSwitchItem, type TabSwitchProps, Tag, type TagProps, TextButton, type TextButtonProps, type TimeSlot, type TimeSlotState, Timetable, type PrintColor as TimetablePrintColor, type TimetableProps, TitleInput, type TitleInputProps, Toast, type ToastProps, type UpperPartItem, type Week, WeekNavigation, type WeekNavigationProps, getInputStyles };
package/dist/index.d.ts CHANGED
@@ -424,6 +424,31 @@ interface SideRadioAccordionProps {
424
424
  }
425
425
  declare const SideRadioAccordion: react.ForwardRefExoticComponent<SideRadioAccordionProps & react.RefAttributes<HTMLDivElement>>;
426
426
 
427
+ type TabSwitchItem = {
428
+ label: string;
429
+ /**
430
+ * 선택 상태를 식별할 값. 표시 텍스트(label)와 분리하고 싶을 때 사용한다.
431
+ * 생략하면 label이 식별자로 쓰인다.
432
+ */
433
+ value?: string;
434
+ };
435
+ interface TabSwitchProps {
436
+ items: TabSwitchItem[];
437
+ /** controlled: 현재 선택된 항목의 value(없으면 label). */
438
+ selected?: string;
439
+ /** uncontrolled 초기 선택값. `selected`를 함께 주면 무시된다. 기본은 첫 항목. */
440
+ defaultSelected?: string;
441
+ /** 선택이 바뀔 때 호출. 인자는 항목의 value(없으면 label). */
442
+ onSelect?: (value: string) => void;
443
+ className?: string;
444
+ }
445
+ /**
446
+ * 두 개 이상의 항목을 가로로 나열하고 선택된 항목 아래에 밑줄을 그리는 탭 전환 UI.
447
+ * 예: "나의 예약"의 "진행중인 예약" / "완료된 예약" 전환.
448
+ * (Figma "카테고리" 컴포넌트 — CategorySegmentedControl과는 별개의, 필터가 아닌 탭 전환용 컴포넌트.)
449
+ */
450
+ declare const TabSwitch: react.ForwardRefExoticComponent<TabSwitchProps & react.RefAttributes<HTMLDivElement>>;
451
+
427
452
  type Week = "thisWeek" | "nextWeek" | "twoWeeksLater";
428
453
  interface WeekNavigationProps {
429
454
  /** 표시 중인 주의 월요일(ISO "YYYY-MM-DD"). 범위 라벨(~금요일)을 여기서 계산한다. */
@@ -577,4 +602,4 @@ interface ToastProps {
577
602
  }
578
603
  declare const Toast: react.ForwardRefExoticComponent<ToastProps & react.RefAttributes<HTMLDivElement>>;
579
604
 
580
- export { Accordion, type AccordionProps, BackButton, type BackButtonProps, BasicFormField, type BasicFormFieldProps, CTA, type CTAProps, CategorySegment, type CategorySegmentProps, CategorySegmentedControl, type CategorySegmentedControlProps, Column, ColumnContentContainer, type ColumnContentContainerProps, ColumnDescription, ColumnDescriptionList, type ColumnDescriptionListProps, type ColumnDescriptionProps, ColumnLabel, type ColumnLabelProps, type ColumnProps, ColumnSubTitle, type ColumnSubTitleProps, ColumnText, type ColumnTextProps, ColumnTextStyle, type DayColumn, Dropdown, type DropdownProps, FormCheckBox, type FormCheckBoxProps, FormColor, type FormColorProps, FormFile, type FormFileProps, FormNumber, type FormNumberProps, FormPassword, type FormPasswordProps, FormSelectBox, type FormSelectBoxProps, FormTel, type FormTelProps, FormText, FormTextArea, type FormTextAreaProps, type FormTextProps, IconCheck, IconChevronDownXS, IconClose, IconCompass, IconExclamation, IconInfo, IconRadioSelected, IconRadioUnselected, type LinkComponent, List, type ListProps, type LowerPartItem, Modal, type ModalProps, ModalText, type ModalTextProps, ModalTextStyle, MultiColumn, type NavIcon, NoticeBadge, type NoticeBadgeProps, type NoticeBadgeVariable, NoticeBar, type NoticeBarBadgeVariable, type NoticeBarProps, type NoticeBarVariable, type RadioToggle, SearchBar, type SearchBarProps, SelectBoxOption, type SelectBoxOptionProps, SideRadioAccordion, type PrintColor$1 as SideRadioAccordionPrintColor, type SideRadioAccordionProps, TNB, type TNBProps, Tag, type TagProps, TextButton, type TextButtonProps, type TimeSlot, type TimeSlotState, Timetable, type PrintColor as TimetablePrintColor, type TimetableProps, TitleInput, type TitleInputProps, Toast, type ToastProps, type UpperPartItem, type Week, WeekNavigation, type WeekNavigationProps, getInputStyles };
605
+ export { Accordion, type AccordionProps, BackButton, type BackButtonProps, BasicFormField, type BasicFormFieldProps, CTA, type CTAProps, CategorySegment, type CategorySegmentProps, CategorySegmentedControl, type CategorySegmentedControlProps, Column, ColumnContentContainer, type ColumnContentContainerProps, ColumnDescription, ColumnDescriptionList, type ColumnDescriptionListProps, type ColumnDescriptionProps, ColumnLabel, type ColumnLabelProps, type ColumnProps, ColumnSubTitle, type ColumnSubTitleProps, ColumnText, type ColumnTextProps, ColumnTextStyle, type DayColumn, Dropdown, type DropdownProps, FormCheckBox, type FormCheckBoxProps, FormColor, type FormColorProps, FormFile, type FormFileProps, FormNumber, type FormNumberProps, FormPassword, type FormPasswordProps, FormSelectBox, type FormSelectBoxProps, FormTel, type FormTelProps, FormText, FormTextArea, type FormTextAreaProps, type FormTextProps, IconCheck, IconChevronDownXS, IconClose, IconCompass, IconExclamation, IconInfo, IconRadioSelected, IconRadioUnselected, type LinkComponent, List, type ListProps, type LowerPartItem, Modal, type ModalProps, ModalText, type ModalTextProps, ModalTextStyle, MultiColumn, type NavIcon, NoticeBadge, type NoticeBadgeProps, type NoticeBadgeVariable, NoticeBar, type NoticeBarBadgeVariable, type NoticeBarProps, type NoticeBarVariable, type RadioToggle, SearchBar, type SearchBarProps, SelectBoxOption, type SelectBoxOptionProps, SideRadioAccordion, type PrintColor$1 as SideRadioAccordionPrintColor, type SideRadioAccordionProps, TNB, type TNBProps, TabSwitch, type TabSwitchItem, type TabSwitchProps, Tag, type TagProps, TextButton, type TextButtonProps, type TimeSlot, type TimeSlotState, Timetable, type PrintColor as TimetablePrintColor, type TimetableProps, TitleInput, type TitleInputProps, Toast, type ToastProps, type UpperPartItem, type Week, WeekNavigation, type WeekNavigationProps, getInputStyles };
package/dist/index.js CHANGED
@@ -64,6 +64,7 @@ __export(index_exports, {
64
64
  SelectBoxOption: () => SelectBoxOption,
65
65
  SideRadioAccordion: () => SideRadioAccordion,
66
66
  TNB: () => TNB,
67
+ TabSwitch: () => TabSwitch,
67
68
  Tag: () => Tag,
68
69
  TextButton: () => TextButton,
69
70
  Timetable: () => Timetable,
@@ -1625,11 +1626,56 @@ var Tag = ({
1625
1626
  );
1626
1627
  };
1627
1628
 
1629
+ // src/components/TabSwitch/TabSwitch.tsx
1630
+ var import_react8 = require("react");
1631
+ var import_jsx_runtime36 = require("react/jsx-runtime");
1632
+ var itemKey2 = (item) => item.value ?? item.label;
1633
+ var TabSwitch = (0, import_react8.forwardRef)(function TabSwitch2({ items, selected, defaultSelected, onSelect, className }, ref) {
1634
+ const [selectedValue, setSelectedValue] = useControllableState(
1635
+ selected,
1636
+ defaultSelected ?? itemKey2(items[0])
1637
+ );
1638
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { ref, className: cn("w-full border-b border-gray02", className), children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex items-stretch", children: items.map((item) => {
1639
+ const key = itemKey2(item);
1640
+ const isSelected = key === selectedValue;
1641
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-stretch", children: [
1642
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
1643
+ "button",
1644
+ {
1645
+ type: "button",
1646
+ onClick: () => {
1647
+ setSelectedValue(key);
1648
+ onSelect?.(key);
1649
+ },
1650
+ className: cn(
1651
+ "flex flex-col items-center pt-2.5 cursor-pointer",
1652
+ isSelected ? "gap-2" : "pb-2.5"
1653
+ ),
1654
+ children: [
1655
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1656
+ "span",
1657
+ {
1658
+ className: cn(
1659
+ "px-4 whitespace-nowrap",
1660
+ isSelected ? "text-body1-medium text-strong" : "text-body1-regular text-quaternary"
1661
+ ),
1662
+ children: item.label
1663
+ }
1664
+ ),
1665
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "h-0.5 w-full bg-black" })
1666
+ ]
1667
+ }
1668
+ ),
1669
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" })
1670
+ ] }, key);
1671
+ }) }) });
1672
+ });
1673
+
1628
1674
  // src/components/Timetable/Timetable.tsx
1629
- var import_react9 = require("react");
1675
+ var import_react10 = require("react");
1630
1676
 
1631
1677
  // src/components/Timetable/WeekNavigation.tsx
1632
- var import_react8 = require("react");
1678
+ var import_react9 = require("react");
1633
1679
 
1634
1680
  // src/components/Timetable/dateUtils.ts
1635
1681
  var KOREAN_WEEKDAYS = ["\uC77C", "\uC6D4", "\uD654", "\uC218", "\uBAA9", "\uAE08", "\uD1A0"];
@@ -1662,18 +1708,18 @@ var formatWeekRange = (weekStart) => {
1662
1708
  };
1663
1709
 
1664
1710
  // src/components/Timetable/WeekNavigation.tsx
1665
- var import_jsx_runtime36 = require("react/jsx-runtime");
1711
+ var import_jsx_runtime37 = require("react/jsx-runtime");
1666
1712
  var weekLabel = {
1667
1713
  thisWeek: "\uC774\uBC88 \uC8FC",
1668
1714
  nextWeek: "\uB2E4\uC74C \uC8FC",
1669
1715
  twoWeeksLater: "\uB2E4\uB2E4\uC74C \uC8FC"
1670
1716
  };
1671
- var WeekNavigation = (0, import_react8.forwardRef)(
1717
+ var WeekNavigation = (0, import_react9.forwardRef)(
1672
1718
  function WeekNavigation2({ date, week, label, canPrev, canNext, onPrevWeek, onNextWeek, className }, ref) {
1673
1719
  const showPrev = canPrev ?? (week ? week !== "thisWeek" : true);
1674
1720
  const showNext = canNext ?? (week ? week !== "twoWeeksLater" : true);
1675
1721
  const text = label ?? (week ? `${weekLabel[week]} (${formatWeekRange(date)})` : formatWeekRange(date));
1676
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
1722
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
1677
1723
  "div",
1678
1724
  {
1679
1725
  ref,
@@ -1685,22 +1731,22 @@ var WeekNavigation = (0, import_react8.forwardRef)(
1685
1731
  className
1686
1732
  ),
1687
1733
  children: [
1688
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ArrowButton, { direction: "left", visible: showPrev, onClick: onPrevWeek }),
1689
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "flex flex-1 items-center justify-center text-center", children: text }),
1690
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ArrowButton, { direction: "right", visible: showNext, onClick: onNextWeek })
1734
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ArrowButton, { direction: "left", visible: showPrev, onClick: onPrevWeek }),
1735
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "flex flex-1 items-center justify-center text-center", children: text }),
1736
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ArrowButton, { direction: "right", visible: showNext, onClick: onNextWeek })
1691
1737
  ]
1692
1738
  }
1693
1739
  );
1694
1740
  }
1695
1741
  );
1696
1742
  var ArrowButton = ({ direction, visible, onClick }) => {
1697
- const divider = /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" });
1743
+ const divider = /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" });
1698
1744
  if (!visible) {
1699
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { "aria-hidden": true, className: "w-[43px]" });
1745
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { "aria-hidden": true, className: "w-[43px]" });
1700
1746
  }
1701
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-stretch", children: [
1747
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-stretch", children: [
1702
1748
  direction === "right" && divider,
1703
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1749
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1704
1750
  "button",
1705
1751
  {
1706
1752
  type: "button",
@@ -1710,7 +1756,7 @@ var ArrowButton = ({ direction, visible, onClick }) => {
1710
1756
  "text-gray06 cursor-pointer transition-colors",
1711
1757
  "hover:bg-gray00 active:bg-gray01"
1712
1758
  ),
1713
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1759
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1714
1760
  IconChevronDownXS,
1715
1761
  {
1716
1762
  className: direction === "left" ? "rotate-90" : "-rotate-90",
@@ -1724,7 +1770,7 @@ var ArrowButton = ({ direction, visible, onClick }) => {
1724
1770
  };
1725
1771
 
1726
1772
  // src/components/Timetable/Timetable.tsx
1727
- var import_jsx_runtime37 = require("react/jsx-runtime");
1773
+ var import_jsx_runtime38 = require("react/jsx-runtime");
1728
1774
  var printColorHoverClass = {
1729
1775
  Plotter: "hover:bg-print-plotter",
1730
1776
  Printer: "hover:bg-print-printer",
@@ -1734,7 +1780,7 @@ var printColorHoverClass = {
1734
1780
  "Seet Cutting": "hover:bg-print-seet-cutting",
1735
1781
  "Laser Cutting": "hover:bg-print-laser-cutting"
1736
1782
  };
1737
- var Timetable = (0, import_react9.forwardRef)(function Timetable2({
1783
+ var Timetable = (0, import_react10.forwardRef)(function Timetable2({
1738
1784
  weekStart,
1739
1785
  week,
1740
1786
  days,
@@ -1747,8 +1793,8 @@ var Timetable = (0, import_react9.forwardRef)(function Timetable2({
1747
1793
  canNextWeek,
1748
1794
  className
1749
1795
  }, ref) {
1750
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { ref, className: cn(fluid && "w-full", className), children: [
1751
- !hideWeekNavigation && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1796
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { ref, className: cn(fluid && "w-full", className), children: [
1797
+ !hideWeekNavigation && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1752
1798
  WeekNavigation,
1753
1799
  {
1754
1800
  date: weekStart,
@@ -1759,7 +1805,7 @@ var Timetable = (0, import_react9.forwardRef)(function Timetable2({
1759
1805
  onNextWeek
1760
1806
  }
1761
1807
  ),
1762
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cn("flex divide-x divide-gray02", fluid && "w-full"), children: days.map((day) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1808
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: cn("flex divide-x divide-gray02", fluid && "w-full"), children: days.map((day) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1763
1809
  DailyTimetable,
1764
1810
  {
1765
1811
  date: day.date,
@@ -1772,21 +1818,26 @@ var Timetable = (0, import_react9.forwardRef)(function Timetable2({
1772
1818
  ] });
1773
1819
  });
1774
1820
  var DailyTimetable = ({ date, slots, fluid, onSelectTime, className }) => {
1775
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cn("flex flex-col", fluid ? "flex-1 min-w-0" : "w-18", className), children: [
1776
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "h-12 flex items-center justify-center border-b border-gray02 text-body1-regular text-secondary", children: formatDayLabel(date) }),
1777
- slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1778
- TimeItem,
1779
- {
1780
- state: slot.state,
1781
- label: slot.time,
1782
- printColor: slot.printColor,
1783
- color: slot.color,
1784
- fluid,
1785
- className: slot.className,
1786
- onClick: onSelectTime ? () => onSelectTime(slot.time) : void 0
1787
- },
1788
- slot.time
1789
- ))
1821
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: cn("flex flex-col", fluid ? "flex-1 min-w-0" : "w-18", className), children: [
1822
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "h-12 flex items-center justify-center border-b border-gray02 text-body1-regular text-secondary", children: formatDayLabel(date) }),
1823
+ slots.map((slot, index) => {
1824
+ const prevState = index > 0 ? slots[index - 1].state : void 0;
1825
+ const withTopBorder = slot.state !== "none" && prevState === "none";
1826
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1827
+ TimeItem,
1828
+ {
1829
+ state: slot.state,
1830
+ label: slot.time,
1831
+ printColor: slot.printColor,
1832
+ color: slot.color,
1833
+ fluid,
1834
+ withTopBorder,
1835
+ className: slot.className,
1836
+ onClick: onSelectTime ? () => onSelectTime(slot.time) : void 0
1837
+ },
1838
+ slot.time
1839
+ );
1840
+ })
1790
1841
  ] });
1791
1842
  };
1792
1843
  var TimeItem = ({
@@ -1795,12 +1846,13 @@ var TimeItem = ({
1795
1846
  printColor,
1796
1847
  color,
1797
1848
  fluid,
1849
+ withTopBorder = false,
1798
1850
  onClick,
1799
1851
  className
1800
1852
  }) => {
1801
1853
  const clickable = (state === "default" || state === "selected") && !!onClick;
1802
1854
  const style = state === "default" && color ? { "--tt-hover": color } : void 0;
1803
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1855
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1804
1856
  "div",
1805
1857
  {
1806
1858
  onClick: clickable ? onClick : void 0,
@@ -1811,6 +1863,7 @@ var TimeItem = ({
1811
1863
  "text-body1-medium text-center bg-white text-primary",
1812
1864
  // "none"(일정 없음)은 구분선을 그리지 않아 연속된 빈 칸이 하나의 덩어리로 보이게 한다.
1813
1865
  state === "none" ? "bg-gray00 text-transparent" : "border-b border-gray02",
1866
+ withTopBorder && "border-t border-gray02",
1814
1867
  state === "selected" && "bg-black text-white hover:cursor-pointer",
1815
1868
  state === "disabled" && "bg-gray00 text-gray03",
1816
1869
  state === "default" && [
@@ -1825,13 +1878,13 @@ var TimeItem = ({
1825
1878
  };
1826
1879
 
1827
1880
  // src/components/TNB/TNB.tsx
1828
- var import_react10 = require("react");
1829
- var import_jsx_runtime38 = require("react/jsx-runtime");
1881
+ var import_react11 = require("react");
1882
+ var import_jsx_runtime39 = require("react/jsx-runtime");
1830
1883
  function useControllableState2(controlled, defaultValue) {
1831
1884
  const isControlled = controlled !== void 0;
1832
- const [uncontrolled, setUncontrolled] = (0, import_react10.useState)(defaultValue);
1885
+ const [uncontrolled, setUncontrolled] = (0, import_react11.useState)(defaultValue);
1833
1886
  const value = isControlled ? controlled : uncontrolled;
1834
- const setValue = (0, import_react10.useCallback)(
1887
+ const setValue = (0, import_react11.useCallback)(
1835
1888
  (next) => {
1836
1889
  if (!isControlled) setUncontrolled(next);
1837
1890
  },
@@ -1839,7 +1892,7 @@ function useControllableState2(controlled, defaultValue) {
1839
1892
  );
1840
1893
  return [value, setValue, isControlled];
1841
1894
  }
1842
- var TNB = (0, import_react10.forwardRef)(function TNB2({
1895
+ var TNB = (0, import_react11.forwardRef)(function TNB2({
1843
1896
  logo,
1844
1897
  upperPartItemList,
1845
1898
  upperPartIconList,
@@ -1878,8 +1931,8 @@ var TNB = (0, import_react10.forwardRef)(function TNB2({
1878
1931
  setLowerValue(label);
1879
1932
  onSelectedLowerChange?.(label);
1880
1933
  };
1881
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("nav", { ref, "aria-label": ariaLabel, className: cn("w-full bg-white", className), children: [
1882
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1934
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("nav", { ref, "aria-label": ariaLabel, className: cn("w-full bg-white", className), children: [
1935
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
1883
1936
  UpperPart,
1884
1937
  {
1885
1938
  logo,
@@ -1890,7 +1943,7 @@ var TNB = (0, import_react10.forwardRef)(function TNB2({
1890
1943
  linkComponent
1891
1944
  }
1892
1945
  ),
1893
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1946
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
1894
1947
  LowerPart,
1895
1948
  {
1896
1949
  lowerPartItemList: currentLowerItemList,
@@ -1901,11 +1954,11 @@ var TNB = (0, import_react10.forwardRef)(function TNB2({
1901
1954
  )
1902
1955
  ] });
1903
1956
  });
1904
- var NavClickable = (0, import_react10.forwardRef)(function NavClickable2({ href, onClick, linkComponent: Link, current, disabled, className, children }, ref) {
1957
+ var NavClickable = (0, import_react11.forwardRef)(function NavClickable2({ href, onClick, linkComponent: Link, current, disabled, className, children }, ref) {
1905
1958
  const ariaCurrent = current ? "page" : void 0;
1906
1959
  if (href && !disabled) {
1907
1960
  if (Link) {
1908
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1961
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
1909
1962
  Link,
1910
1963
  {
1911
1964
  href,
@@ -1917,7 +1970,7 @@ var NavClickable = (0, import_react10.forwardRef)(function NavClickable2({ href,
1917
1970
  }
1918
1971
  );
1919
1972
  }
1920
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1973
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
1921
1974
  "a",
1922
1975
  {
1923
1976
  href,
@@ -1929,7 +1982,7 @@ var NavClickable = (0, import_react10.forwardRef)(function NavClickable2({ href,
1929
1982
  }
1930
1983
  );
1931
1984
  }
1932
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1985
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
1933
1986
  "button",
1934
1987
  {
1935
1988
  type: "button",
@@ -1951,7 +2004,7 @@ var UpperPart = ({
1951
2004
  linkComponent,
1952
2005
  className
1953
2006
  }) => {
1954
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2007
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
1955
2008
  "div",
1956
2009
  {
1957
2010
  className: cn(
@@ -1959,12 +2012,12 @@ var UpperPart = ({
1959
2012
  className
1960
2013
  ),
1961
2014
  children: [
1962
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-stretch", children: [
1963
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "flex w-14 shrink-0 items-center justify-center px-3", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(NavIconButton, { ...logo, linkComponent }) }),
1964
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-stretch", children: [
1965
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" }),
1966
- upperPartItemList.map((item) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react10.Fragment, { children: [
1967
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2015
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-stretch", children: [
2016
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "flex w-14 shrink-0 items-center justify-center px-3", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(NavIconButton, { ...logo, linkComponent }) }),
2017
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-stretch", children: [
2018
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" }),
2019
+ upperPartItemList.map((item) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_react11.Fragment, { children: [
2020
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
1968
2021
  UpperPartTab,
1969
2022
  {
1970
2023
  label: item.label,
@@ -1977,15 +2030,15 @@ var UpperPart = ({
1977
2030
  }
1978
2031
  }
1979
2032
  ),
1980
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" })
2033
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" })
1981
2034
  ] }, item.id ?? item.label))
1982
2035
  ] })
1983
2036
  ] }),
1984
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-stretch", children: [
1985
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" }),
1986
- upperPartIconList.map((icon, index) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react10.Fragment, { children: [
1987
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(NavIconButton, { ...icon, linkComponent }),
1988
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" })
2037
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-stretch", children: [
2038
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" }),
2039
+ upperPartIconList.map((icon, index) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_react11.Fragment, { children: [
2040
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(NavIconButton, { ...icon, linkComponent }),
2041
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" })
1989
2042
  ] }, icon.id ?? icon.src ?? icon.label ?? index))
1990
2043
  ] })
1991
2044
  ]
@@ -2000,7 +2053,7 @@ var UpperPartTab = ({
2000
2053
  linkComponent,
2001
2054
  className
2002
2055
  }) => {
2003
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2056
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2004
2057
  NavClickable,
2005
2058
  {
2006
2059
  href,
@@ -2015,17 +2068,17 @@ var UpperPartTab = ({
2015
2068
  className
2016
2069
  ),
2017
2070
  children: [
2018
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: cn("px-5 text-head1-medium", selected ? "text-strong" : "text-quaternary"), children: label }),
2019
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: cn("h-0.5 w-full", selected ? "bg-black" : "bg-transparent") })
2071
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn("px-5 text-head1-medium", selected ? "text-strong" : "text-quaternary"), children: label }),
2072
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn("h-0.5 w-full", selected ? "bg-black" : "bg-transparent") })
2020
2073
  ]
2021
2074
  }
2022
2075
  );
2023
2076
  };
2024
- var NavIconButton = (0, import_react10.forwardRef)(
2077
+ var NavIconButton = (0, import_react11.forwardRef)(
2025
2078
  function NavIconButton2({ src, icon, alt, label, href, onClick, selected, badge, className, linkComponent }, forwardedRef) {
2026
2079
  const interactive = Boolean(onClick || href);
2027
2080
  const showBadge = badge !== void 0 && badge !== null && badge !== false;
2028
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2081
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2029
2082
  NavClickable,
2030
2083
  {
2031
2084
  ref: forwardedRef,
@@ -2041,9 +2094,9 @@ var NavIconButton = (0, import_react10.forwardRef)(
2041
2094
  className
2042
2095
  ),
2043
2096
  children: [
2044
- icon ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "inline-flex h-6 w-6 items-center justify-center", children: icon }) : src ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("img", { src, alt: alt ?? label ?? "", className: "h-6 w-6" }) : null,
2045
- label ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: cn("text-body2-regular", selected ? "text-white" : "text-secondary"), children: label }) : null,
2046
- showBadge ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2097
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "inline-flex h-6 w-6 items-center justify-center", children: icon }) : src ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("img", { src, alt: alt ?? label ?? "", className: "h-6 w-6" }) : null,
2098
+ label ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn("text-body2-regular", selected ? "text-white" : "text-secondary"), children: label }) : null,
2099
+ showBadge ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2047
2100
  "span",
2048
2101
  {
2049
2102
  "aria-hidden": badge === true,
@@ -2069,14 +2122,14 @@ var LowerPart = ({
2069
2122
  if (lowerPartItemList.length === 0) {
2070
2123
  return null;
2071
2124
  }
2072
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2125
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2073
2126
  "div",
2074
2127
  {
2075
2128
  className: cn("w-full h-[42px] pl-14 flex items-stretch border-b border-gray02", className),
2076
2129
  children: [
2077
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" }),
2078
- lowerPartItemList.map((item) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react10.Fragment, { children: [
2079
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2130
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" }),
2131
+ lowerPartItemList.map((item) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_react11.Fragment, { children: [
2132
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2080
2133
  LowerPartItemButton,
2081
2134
  {
2082
2135
  label: item.label,
@@ -2089,7 +2142,7 @@ var LowerPart = ({
2089
2142
  }
2090
2143
  }
2091
2144
  ),
2092
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" })
2145
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { "aria-hidden": true, className: "w-px self-stretch bg-gray02" })
2093
2146
  ] }, item.id ?? item.label))
2094
2147
  ]
2095
2148
  }
@@ -2103,7 +2156,7 @@ var LowerPartItemButton = ({
2103
2156
  linkComponent,
2104
2157
  className
2105
2158
  }) => {
2106
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2159
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2107
2160
  NavClickable,
2108
2161
  {
2109
2162
  href,
@@ -2122,14 +2175,14 @@ var LowerPartItemButton = ({
2122
2175
  };
2123
2176
 
2124
2177
  // src/components/Toast/Toast.tsx
2125
- var import_react11 = require("react");
2126
- var import_jsx_runtime39 = require("react/jsx-runtime");
2178
+ var import_react12 = require("react");
2179
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2127
2180
  var EXIT_MS = 300;
2128
- var Toast = (0, import_react11.forwardRef)(function Toast2({ message, open, duration = 3e3, onClose, position = "none", className }, ref) {
2181
+ var Toast = (0, import_react12.forwardRef)(function Toast2({ message, open, duration = 3e3, onClose, position = "none", className }, ref) {
2129
2182
  const controlled = open !== void 0;
2130
- const [mounted, setMounted] = (0, import_react11.useState)(!controlled || open);
2131
- const [visible, setVisible] = (0, import_react11.useState)(!controlled || open);
2132
- (0, import_react11.useEffect)(() => {
2183
+ const [mounted, setMounted] = (0, import_react12.useState)(!controlled || open);
2184
+ const [visible, setVisible] = (0, import_react12.useState)(!controlled || open);
2185
+ (0, import_react12.useEffect)(() => {
2133
2186
  if (!controlled) return;
2134
2187
  if (open) {
2135
2188
  setMounted(true);
@@ -2140,13 +2193,13 @@ var Toast = (0, import_react11.forwardRef)(function Toast2({ message, open, dura
2140
2193
  const timer = setTimeout(() => setMounted(false), EXIT_MS);
2141
2194
  return () => clearTimeout(timer);
2142
2195
  }, [controlled, open]);
2143
- (0, import_react11.useEffect)(() => {
2196
+ (0, import_react12.useEffect)(() => {
2144
2197
  if (!controlled || !open || !duration) return;
2145
2198
  const timer = setTimeout(() => onClose?.(), duration);
2146
2199
  return () => clearTimeout(timer);
2147
2200
  }, [controlled, open, duration, onClose]);
2148
2201
  if (!mounted) return null;
2149
- const banner = /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2202
+ const banner = /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2150
2203
  "div",
2151
2204
  {
2152
2205
  ref,
@@ -2164,7 +2217,7 @@ var Toast = (0, import_react11.forwardRef)(function Toast2({ message, open, dura
2164
2217
  }
2165
2218
  );
2166
2219
  if (position === "none") return banner;
2167
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2220
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2168
2221
  "div",
2169
2222
  {
2170
2223
  className: cn(
@@ -2220,6 +2273,7 @@ var Toast = (0, import_react11.forwardRef)(function Toast2({ message, open, dura
2220
2273
  SelectBoxOption,
2221
2274
  SideRadioAccordion,
2222
2275
  TNB,
2276
+ TabSwitch,
2223
2277
  Tag,
2224
2278
  TextButton,
2225
2279
  Timetable,