@x-plat/design-system 0.5.2 → 0.5.4

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 (50) hide show
  1. package/dist/components/Accordion/index.cjs +38 -31
  2. package/dist/components/Accordion/index.css +2 -0
  3. package/dist/components/Accordion/index.js +38 -31
  4. package/dist/components/Alert/index.css +1 -0
  5. package/dist/components/Breadcrumb/index.css +3 -0
  6. package/dist/components/Button/index.css +1 -0
  7. package/dist/components/Calendar/index.cjs +103 -62
  8. package/dist/components/Calendar/index.css +2 -0
  9. package/dist/components/Calendar/index.js +103 -62
  10. package/dist/components/Card/index.css +3 -1
  11. package/dist/components/CardTab/index.css +1 -0
  12. package/dist/components/Chart/index.cjs +106 -83
  13. package/dist/components/Chart/index.css +2 -0
  14. package/dist/components/Chart/index.js +106 -83
  15. package/dist/components/DatePicker/index.cjs +36 -15
  16. package/dist/components/DatePicker/index.css +2 -0
  17. package/dist/components/DatePicker/index.js +36 -15
  18. package/dist/components/Dropdown/index.css +1 -0
  19. package/dist/components/EmptyState/index.css +2 -0
  20. package/dist/components/FileUpload/index.css +3 -0
  21. package/dist/components/HtmlTypeWriter/index.css +1 -0
  22. package/dist/components/Pagination/index.css +8 -8
  23. package/dist/components/Select/index.css +1 -0
  24. package/dist/components/Spinner/index.css +7 -2
  25. package/dist/components/Steps/index.cjs +1 -4
  26. package/dist/components/Steps/index.css +15 -36
  27. package/dist/components/Steps/index.js +1 -4
  28. package/dist/components/Swiper/index.cjs +16 -12
  29. package/dist/components/Swiper/index.css +2 -0
  30. package/dist/components/Swiper/index.js +16 -12
  31. package/dist/components/Switch/index.css +20 -19
  32. package/dist/components/Tab/index.css +16 -2
  33. package/dist/components/Table/index.cjs +4 -4
  34. package/dist/components/Table/index.css +2 -0
  35. package/dist/components/Table/index.d.cts +2 -5
  36. package/dist/components/Table/index.d.ts +2 -5
  37. package/dist/components/Table/index.js +4 -4
  38. package/dist/components/Video/index.cjs +32 -43
  39. package/dist/components/Video/index.css +5 -4
  40. package/dist/components/Video/index.d.cts +1 -5
  41. package/dist/components/Video/index.d.ts +1 -5
  42. package/dist/components/Video/index.js +32 -43
  43. package/dist/components/index.cjs +339 -257
  44. package/dist/components/index.css +99 -72
  45. package/dist/components/index.js +339 -257
  46. package/dist/index.cjs +339 -257
  47. package/dist/index.css +99 -72
  48. package/dist/index.js +339 -257
  49. package/guidelines/Guidelines.md +11 -4
  50. package/package.json +1 -2
@@ -1357,38 +1357,45 @@ var clsx_default = clsx;
1357
1357
 
1358
1358
  // src/components/Accordion/Accordion.tsx
1359
1359
  var import_jsx_runtime295 = require("react/jsx-runtime");
1360
- var AccordionItem = ({ item, isOpen, onToggle }) => {
1361
- const bodyRef = import_react.default.useRef(null);
1362
- const [height, setHeight] = import_react.default.useState(0);
1363
- import_react.default.useEffect(() => {
1364
- if (bodyRef.current) {
1365
- setHeight(bodyRef.current.scrollHeight);
1366
- }
1367
- }, [isOpen, item.content]);
1368
- return /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)("div", { className: clsx_default("accordion-item", { open: isOpen }), children: [
1369
- /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)(
1370
- "button",
1371
- {
1372
- className: "accordion-header",
1373
- onClick: onToggle,
1374
- "aria-expanded": isOpen,
1375
- children: [
1376
- /* @__PURE__ */ (0, import_jsx_runtime295.jsx)("span", { className: "title", children: item.title }),
1377
- /* @__PURE__ */ (0, import_jsx_runtime295.jsx)("span", { className: "chevron", children: /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(ChevronDownIcon_default, {}) })
1378
- ]
1379
- }
1380
- ),
1381
- /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(
1382
- "div",
1383
- {
1384
- ref: bodyRef,
1385
- className: "accordion-body",
1386
- style: { maxHeight: isOpen ? height : 0 },
1387
- children: /* @__PURE__ */ (0, import_jsx_runtime295.jsx)("div", { className: "accordion-content", children: item.content })
1360
+ var AccordionItem = import_react.default.memo(
1361
+ ({
1362
+ item,
1363
+ isOpen,
1364
+ onToggle
1365
+ }) => {
1366
+ const bodyRef = import_react.default.useRef(null);
1367
+ const [height, setHeight] = import_react.default.useState(0);
1368
+ import_react.default.useEffect(() => {
1369
+ if (bodyRef.current) {
1370
+ setHeight(bodyRef.current.scrollHeight);
1388
1371
  }
1389
- )
1390
- ] });
1391
- };
1372
+ }, [isOpen, item.content]);
1373
+ return /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)("div", { className: clsx_default("accordion-item", { open: isOpen }), children: [
1374
+ /* @__PURE__ */ (0, import_jsx_runtime295.jsxs)(
1375
+ "button",
1376
+ {
1377
+ className: "accordion-header",
1378
+ onClick: onToggle,
1379
+ "aria-expanded": isOpen,
1380
+ children: [
1381
+ /* @__PURE__ */ (0, import_jsx_runtime295.jsx)("span", { className: "title", children: item.title }),
1382
+ /* @__PURE__ */ (0, import_jsx_runtime295.jsx)("span", { className: "chevron", children: /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(ChevronDownIcon_default, {}) })
1383
+ ]
1384
+ }
1385
+ ),
1386
+ /* @__PURE__ */ (0, import_jsx_runtime295.jsx)(
1387
+ "div",
1388
+ {
1389
+ ref: bodyRef,
1390
+ className: "accordion-body",
1391
+ style: { maxHeight: isOpen ? height : 0 },
1392
+ children: /* @__PURE__ */ (0, import_jsx_runtime295.jsx)("div", { className: "accordion-content", children: item.content })
1393
+ }
1394
+ )
1395
+ ] });
1396
+ }
1397
+ );
1398
+ AccordionItem.displayName = "AccordionItem";
1392
1399
  var Accordion = (props) => {
1393
1400
  const { items } = props;
1394
1401
  const isMultiple = props.multiple === true;
@@ -1643,6 +1650,76 @@ var MONTH_LABELS = {
1643
1650
 
1644
1651
  // src/components/Calendar/Calendar.tsx
1645
1652
  var import_jsx_runtime301 = require("react/jsx-runtime");
1653
+ var DayCell = import_react3.default.memo(
1654
+ ({
1655
+ day,
1656
+ disabled,
1657
+ selected,
1658
+ dayEvents,
1659
+ renderDay,
1660
+ onSelect,
1661
+ onEventClick
1662
+ }) => {
1663
+ if (renderDay) {
1664
+ return /* @__PURE__ */ (0, import_jsx_runtime301.jsx)(
1665
+ "div",
1666
+ {
1667
+ className: clsx_default(
1668
+ "calendar-day",
1669
+ !day.isCurrentMonth && "outside",
1670
+ disabled && "disabled",
1671
+ selected && "selected",
1672
+ day.isToday && "today"
1673
+ ),
1674
+ onClick: () => {
1675
+ if (!disabled && day.isCurrentMonth) onSelect?.(day.date);
1676
+ },
1677
+ children: renderDay(day, dayEvents)
1678
+ }
1679
+ );
1680
+ }
1681
+ return /* @__PURE__ */ (0, import_jsx_runtime301.jsxs)(
1682
+ "div",
1683
+ {
1684
+ className: clsx_default(
1685
+ "calendar-day",
1686
+ !day.isCurrentMonth && "outside",
1687
+ disabled && "disabled",
1688
+ selected && "selected",
1689
+ day.isToday && "today",
1690
+ day.isSunday && "sunday",
1691
+ day.isSaturday && "saturday"
1692
+ ),
1693
+ onClick: () => {
1694
+ if (!disabled && day.isCurrentMonth) onSelect?.(day.date);
1695
+ },
1696
+ children: [
1697
+ /* @__PURE__ */ (0, import_jsx_runtime301.jsx)("span", { className: "calendar-day-number", children: day.day }),
1698
+ dayEvents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime301.jsxs)("div", { className: "calendar-day-events", children: [
1699
+ dayEvents.slice(0, 3).map((event, ei) => /* @__PURE__ */ (0, import_jsx_runtime301.jsx)(
1700
+ "span",
1701
+ {
1702
+ className: "calendar-event-dot",
1703
+ style: { backgroundColor: event.color ?? "var(--xplat-blue-500)" },
1704
+ title: event.label,
1705
+ onClick: (e) => {
1706
+ e.stopPropagation();
1707
+ onEventClick?.(event);
1708
+ }
1709
+ },
1710
+ ei
1711
+ )),
1712
+ dayEvents.length > 3 && /* @__PURE__ */ (0, import_jsx_runtime301.jsxs)("span", { className: "calendar-event-more", children: [
1713
+ "+",
1714
+ dayEvents.length - 3
1715
+ ] })
1716
+ ] })
1717
+ ]
1718
+ }
1719
+ );
1720
+ }
1721
+ );
1722
+ DayCell.displayName = "DayCell";
1646
1723
  var Calendar = (props) => {
1647
1724
  const {
1648
1725
  year: yearProp,
@@ -1728,12 +1805,28 @@ var Calendar = (props) => {
1728
1805
  setPickerMode("months");
1729
1806
  onMonthChange?.(y, month);
1730
1807
  };
1731
- const isDisabled = (date) => {
1732
- if (minDate && date < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) return true;
1733
- if (maxDate && date > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate())) return true;
1734
- return false;
1735
- };
1736
- const getEventsForDay = (date) => events.filter((e) => isSameDay(e.date, date));
1808
+ const minTime = import_react3.default.useMemo(
1809
+ () => minDate ? new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()).getTime() : -Infinity,
1810
+ [minDate]
1811
+ );
1812
+ const maxTime = import_react3.default.useMemo(
1813
+ () => maxDate ? new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate()).getTime() : Infinity,
1814
+ [maxDate]
1815
+ );
1816
+ const eventsMap = import_react3.default.useMemo(() => {
1817
+ const map = /* @__PURE__ */ new Map();
1818
+ for (const e of events) {
1819
+ const key = `${e.date.getFullYear()}-${e.date.getMonth()}-${e.date.getDate()}`;
1820
+ const arr = map.get(key);
1821
+ if (arr) arr.push(e);
1822
+ else map.set(key, [e]);
1823
+ }
1824
+ return map;
1825
+ }, [events]);
1826
+ const getEventsForDay = import_react3.default.useCallback(
1827
+ (date) => eventsMap.get(`${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`) ?? [],
1828
+ [eventsMap]
1829
+ );
1737
1830
  const weekdays = WEEKDAY_LABELS[locale];
1738
1831
  const monthLabels = MONTH_LABELS[locale];
1739
1832
  const titleText = pickerMode === "days" ? locale === "ko" ? `${year}\uB144 ${monthLabels[month]}` : `${monthLabels[month]} ${year}` : pickerMode === "months" ? `${year}` : `${yearRangeStart} - ${yearRangeStart + 11}`;
@@ -1787,64 +1880,19 @@ var Calendar = (props) => {
1787
1880
  )) }),
1788
1881
  /* @__PURE__ */ (0, import_jsx_runtime301.jsx)("div", { className: "calendar-grid", children: days.map((day, idx) => {
1789
1882
  const dayEvents = getEventsForDay(day.date);
1790
- const disabled = isDisabled(day.date);
1883
+ const t = day.date.getTime();
1884
+ const disabled = t < minTime || t > maxTime;
1791
1885
  const isSelected = selectedDate ? isSameDay(day.date, selectedDate) : false;
1792
- if (renderDay) {
1793
- return /* @__PURE__ */ (0, import_jsx_runtime301.jsx)(
1794
- "div",
1795
- {
1796
- className: clsx_default(
1797
- "calendar-day",
1798
- !day.isCurrentMonth && "outside",
1799
- disabled && "disabled",
1800
- isSelected && "selected",
1801
- day.isToday && "today"
1802
- ),
1803
- onClick: () => {
1804
- if (!disabled && day.isCurrentMonth) onSelect?.(day.date);
1805
- },
1806
- children: renderDay(day, dayEvents)
1807
- },
1808
- idx
1809
- );
1810
- }
1811
- return /* @__PURE__ */ (0, import_jsx_runtime301.jsxs)(
1812
- "div",
1886
+ return /* @__PURE__ */ (0, import_jsx_runtime301.jsx)(
1887
+ DayCell,
1813
1888
  {
1814
- className: clsx_default(
1815
- "calendar-day",
1816
- !day.isCurrentMonth && "outside",
1817
- disabled && "disabled",
1818
- isSelected && "selected",
1819
- day.isToday && "today",
1820
- day.isSunday && "sunday",
1821
- day.isSaturday && "saturday"
1822
- ),
1823
- onClick: () => {
1824
- if (!disabled && day.isCurrentMonth) onSelect?.(day.date);
1825
- },
1826
- children: [
1827
- /* @__PURE__ */ (0, import_jsx_runtime301.jsx)("span", { className: "calendar-day-number", children: day.day }),
1828
- dayEvents.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime301.jsxs)("div", { className: "calendar-day-events", children: [
1829
- dayEvents.slice(0, 3).map((event, ei) => /* @__PURE__ */ (0, import_jsx_runtime301.jsx)(
1830
- "span",
1831
- {
1832
- className: "calendar-event-dot",
1833
- style: { backgroundColor: event.color ?? "var(--xplat-blue-500)" },
1834
- title: event.label,
1835
- onClick: (e) => {
1836
- e.stopPropagation();
1837
- onEventClick?.(event);
1838
- }
1839
- },
1840
- ei
1841
- )),
1842
- dayEvents.length > 3 && /* @__PURE__ */ (0, import_jsx_runtime301.jsxs)("span", { className: "calendar-event-more", children: [
1843
- "+",
1844
- dayEvents.length - 3
1845
- ] })
1846
- ] })
1847
- ]
1889
+ day,
1890
+ disabled,
1891
+ selected: isSelected,
1892
+ dayEvents,
1893
+ renderDay,
1894
+ onSelect,
1895
+ onEventClick
1848
1896
  },
1849
1897
  idx
1850
1898
  );
@@ -1992,14 +2040,28 @@ var useChartTooltip = (enabled) => {
1992
2040
  }, []);
1993
2041
  return { tooltip, show, hide, move, containerRef };
1994
2042
  };
1995
- var LineChart = ({ data, labels, onHover, onMove, onLeave }) => {
1996
- const entries = Object.entries(data);
1997
- const allValues = entries.flatMap(([, v]) => v);
1998
- const maxVal = Math.max(...allValues) * 1.2 || 1;
2043
+ var LineChart = import_react5.default.memo(({ data, labels, onHover, onMove, onLeave }) => {
2044
+ const entries = import_react5.default.useMemo(() => Object.entries(data), [data]);
2045
+ const maxVal = import_react5.default.useMemo(() => {
2046
+ const allValues = entries.flatMap(([, v]) => v);
2047
+ return Math.max(...allValues) * 1.2 || 1;
2048
+ }, [entries]);
1999
2049
  const count = labels.length;
2050
+ const chartW = 600 - PADDING.left - PADDING.right;
2051
+ const chartH = 300 - PADDING.top - PADDING.bottom;
2052
+ const seriesPoints = import_react5.default.useMemo(
2053
+ () => entries.map(
2054
+ ([, values]) => values.map((v, i) => ({
2055
+ x: PADDING.left + i / (count - 1 || 1) * chartW,
2056
+ y: PADDING.top + (1 - v / maxVal) * chartH,
2057
+ v
2058
+ }))
2059
+ ),
2060
+ [entries, count, chartW, chartH, maxVal]
2061
+ );
2000
2062
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("svg", { viewBox: "0 0 600 300", className: "chart-svg", children: [
2001
2063
  [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
2002
- const y = PADDING.top + (1 - ratio) * (300 - PADDING.top - PADDING.bottom);
2064
+ const y = PADDING.top + (1 - ratio) * chartH;
2003
2065
  const val = Math.round(maxVal * ratio);
2004
2066
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { children: [
2005
2067
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("line", { x1: PADDING.left, y1: y, x2: 600 - PADDING.right, y2: y, className: "chart-grid" }),
@@ -2007,17 +2069,13 @@ var LineChart = ({ data, labels, onHover, onMove, onLeave }) => {
2007
2069
  ] }, ratio);
2008
2070
  }),
2009
2071
  labels.map((label, i) => {
2010
- const x = PADDING.left + i / (count - 1 || 1) * (600 - PADDING.left - PADDING.right);
2072
+ const x = PADDING.left + i / (count - 1 || 1) * chartW;
2011
2073
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("text", { x, y: 300 - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i);
2012
2074
  }),
2013
- entries.map(([key, values], di) => {
2075
+ entries.map(([key], di) => {
2014
2076
  const palette = getPalette(LINE_BAR_PALETTES, di);
2015
2077
  const color = palette[4];
2016
- const points = values.map((v, i) => {
2017
- const x = PADDING.left + i / (count - 1 || 1) * (600 - PADDING.left - PADDING.right);
2018
- const y = PADDING.top + (1 - v / maxVal) * (300 - PADDING.top - PADDING.bottom);
2019
- return { x, y, v };
2020
- });
2078
+ const points = seriesPoints[di];
2021
2079
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { children: [
2022
2080
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2023
2081
  "polyline",
@@ -2045,17 +2103,31 @@ var LineChart = ({ data, labels, onHover, onMove, onLeave }) => {
2045
2103
  ] }, di);
2046
2104
  })
2047
2105
  ] });
2048
- };
2049
- var BarChart = ({ data, labels, onHover, onMove, onLeave }) => {
2050
- const entries = Object.entries(data);
2051
- const allValues = entries.flatMap(([, v]) => v);
2052
- const maxVal = Math.max(...allValues) * 1.2 || 1;
2106
+ });
2107
+ LineChart.displayName = "LineChart";
2108
+ var BarChart = import_react5.default.memo(({ data, labels, onHover, onMove, onLeave }) => {
2109
+ const entries = import_react5.default.useMemo(() => Object.entries(data), [data]);
2110
+ const maxVal = import_react5.default.useMemo(() => {
2111
+ const allValues = entries.flatMap(([, v]) => v);
2112
+ return Math.max(...allValues) * 1.2 || 1;
2113
+ }, [entries]);
2053
2114
  const count = labels.length;
2054
2115
  const groupCount = entries.length;
2055
2116
  const chartW = 600 - PADDING.left - PADDING.right;
2056
2117
  const chartH = 300 - PADDING.top - PADDING.bottom;
2057
2118
  const groupW = chartW / count;
2058
2119
  const barW = Math.min(32, groupW * 0.7 / groupCount);
2120
+ const bars = import_react5.default.useMemo(
2121
+ () => entries.map(
2122
+ ([, values], di) => values.map((v, i) => {
2123
+ const h = v / maxVal * chartH;
2124
+ const x = PADDING.left + groupW * i + (groupW - barW * groupCount) / 2 + barW * di;
2125
+ const y = PADDING.top + chartH - h;
2126
+ return { x, y, w: barW, h, v };
2127
+ })
2128
+ ),
2129
+ [entries, maxVal, chartH, groupW, barW, groupCount]
2130
+ );
2059
2131
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("svg", { viewBox: "0 0 600 300", className: "chart-svg", children: [
2060
2132
  [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
2061
2133
  const y = PADDING.top + (1 - ratio) * chartH;
@@ -2066,85 +2138,84 @@ var BarChart = ({ data, labels, onHover, onMove, onLeave }) => {
2066
2138
  ] }, ratio);
2067
2139
  }),
2068
2140
  labels.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("text", { x: PADDING.left + groupW * i + groupW / 2, y: 300 - 8, className: "chart-axis-label", textAnchor: "middle", children: label }, i)),
2069
- entries.map(([key, values], di) => {
2141
+ entries.map(([key], di) => {
2070
2142
  const palette = getPalette(LINE_BAR_PALETTES, di);
2071
2143
  const color = palette[4];
2072
- return values.map((v, i) => {
2073
- const h = v / maxVal * chartH;
2074
- const x = PADDING.left + groupW * i + (groupW - barW * groupCount) / 2 + barW * di;
2075
- const y = PADDING.top + chartH - h;
2076
- return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2077
- "rect",
2078
- {
2079
- x,
2080
- y,
2081
- width: barW,
2082
- height: h,
2083
- rx: "2",
2084
- fill: color,
2085
- className: "chart-bar",
2086
- onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${v}`),
2087
- onMouseMove: onMove,
2088
- onMouseLeave: onLeave
2089
- },
2090
- `${di}-${i}`
2091
- );
2092
- });
2144
+ return bars[di].map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2145
+ "rect",
2146
+ {
2147
+ x: b.x,
2148
+ y: b.y,
2149
+ width: b.w,
2150
+ height: b.h,
2151
+ rx: "2",
2152
+ fill: color,
2153
+ className: "chart-bar",
2154
+ onMouseEnter: (e) => onHover(e, `${key}: ${labels[i]} \u2014 ${b.v}`),
2155
+ onMouseMove: onMove,
2156
+ onMouseLeave: onLeave
2157
+ },
2158
+ `${di}-${i}`
2159
+ ));
2093
2160
  })
2094
2161
  ] });
2095
- };
2096
- var PieDonutChart = ({ data, labels, isDoughnut, onHover, onMove, onLeave }) => {
2097
- const entries = Object.entries(data);
2098
- const values = entries.flatMap(([, v]) => v);
2099
- const total = values.reduce((a, b) => a + b, 0) || 1;
2100
- const cx = 150;
2101
- const cy = 150;
2102
- const r2 = 120;
2103
- const innerR = isDoughnut ? 60 : 0;
2104
- const palette = getPalette(PIE_PALETTES, 0);
2105
- let startAngle = -Math.PI / 2;
2106
- const slices = values.map((v, i) => {
2107
- const angle = v / total * Math.PI * 2;
2108
- const endAngle = startAngle + angle;
2109
- const largeArc = angle > Math.PI ? 1 : 0;
2110
- const x1 = cx + r2 * Math.cos(startAngle);
2111
- const y1 = cy + r2 * Math.sin(startAngle);
2112
- const x2 = cx + r2 * Math.cos(endAngle);
2113
- const y2 = cy + r2 * Math.sin(endAngle);
2114
- let d;
2115
- if (innerR > 0) {
2116
- const ix1 = cx + innerR * Math.cos(startAngle);
2117
- const iy1 = cy + innerR * Math.sin(startAngle);
2118
- const ix2 = cx + innerR * Math.cos(endAngle);
2119
- const iy2 = cy + innerR * Math.sin(endAngle);
2120
- d = `M ${ix1} ${iy1} L ${x1} ${y1} A ${r2} ${r2} 0 ${largeArc} 1 ${x2} ${y2} L ${ix2} ${iy2} A ${innerR} ${innerR} 0 ${largeArc} 0 ${ix1} ${iy1} Z`;
2121
- } else {
2122
- d = `M ${cx} ${cy} L ${x1} ${y1} A ${r2} ${r2} 0 ${largeArc} 1 ${x2} ${y2} Z`;
2123
- }
2124
- const midAngle = startAngle + angle / 2;
2125
- const labelR = innerR > 0 ? (r2 + innerR) / 2 : r2 * 0.6;
2126
- const lx = cx + labelR * Math.cos(midAngle);
2127
- const ly = cy + labelR * Math.sin(midAngle);
2128
- const pct = Math.round(v / total * 100);
2129
- const label = labels[i] || `${i + 1}`;
2130
- startAngle = endAngle;
2131
- return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { children: [
2162
+ });
2163
+ BarChart.displayName = "BarChart";
2164
+ var PieDonutChart = import_react5.default.memo(
2165
+ ({ data, labels, isDoughnut, onHover, onMove, onLeave }) => {
2166
+ const values = import_react5.default.useMemo(() => Object.entries(data).flatMap(([, v]) => v), [data]);
2167
+ const total = import_react5.default.useMemo(() => values.reduce((a, b) => a + b, 0) || 1, [values]);
2168
+ const cx = 150;
2169
+ const cy = 150;
2170
+ const r2 = 120;
2171
+ const innerR = isDoughnut ? 60 : 0;
2172
+ const palette = getPalette(PIE_PALETTES, 0);
2173
+ const sliceData = import_react5.default.useMemo(() => {
2174
+ let angle0 = -Math.PI / 2;
2175
+ return values.map((v, i) => {
2176
+ const angle = v / total * Math.PI * 2;
2177
+ const endAngle = angle0 + angle;
2178
+ const largeArc = angle > Math.PI ? 1 : 0;
2179
+ const x1 = cx + r2 * Math.cos(angle0);
2180
+ const y1 = cy + r2 * Math.sin(angle0);
2181
+ const x2 = cx + r2 * Math.cos(endAngle);
2182
+ const y2 = cy + r2 * Math.sin(endAngle);
2183
+ let d;
2184
+ if (innerR > 0) {
2185
+ const ix1 = cx + innerR * Math.cos(angle0);
2186
+ const iy1 = cy + innerR * Math.sin(angle0);
2187
+ const ix2 = cx + innerR * Math.cos(endAngle);
2188
+ const iy2 = cy + innerR * Math.sin(endAngle);
2189
+ d = `M ${ix1} ${iy1} L ${x1} ${y1} A ${r2} ${r2} 0 ${largeArc} 1 ${x2} ${y2} L ${ix2} ${iy2} A ${innerR} ${innerR} 0 ${largeArc} 0 ${ix1} ${iy1} Z`;
2190
+ } else {
2191
+ d = `M ${cx} ${cy} L ${x1} ${y1} A ${r2} ${r2} 0 ${largeArc} 1 ${x2} ${y2} Z`;
2192
+ }
2193
+ const midAngle = angle0 + angle / 2;
2194
+ const labelR = innerR > 0 ? (r2 + innerR) / 2 : r2 * 0.6;
2195
+ const lx = cx + labelR * Math.cos(midAngle);
2196
+ const ly = cy + labelR * Math.sin(midAngle);
2197
+ const pct = Math.round(v / total * 100);
2198
+ angle0 = endAngle;
2199
+ return { d, lx, ly, v, pct, angle, label: labels[i] || `${i + 1}` };
2200
+ });
2201
+ }, [values, total, innerR, labels]);
2202
+ return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("svg", { viewBox: "0 0 300 300", className: "chart-svg chart-pie", children: sliceData.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { children: [
2132
2203
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
2133
2204
  "path",
2134
2205
  {
2135
- d,
2206
+ d: s.d,
2136
2207
  fill: palette[i % palette.length],
2137
2208
  className: "chart-slice",
2138
- onMouseEnter: (e) => onHover(e, `${label}: ${v} (${pct}%)`),
2209
+ onMouseEnter: (e) => onHover(e, `${s.label}: ${s.v} (${s.pct}%)`),
2139
2210
  onMouseMove: onMove,
2140
2211
  onMouseLeave: onLeave
2141
2212
  }
2142
2213
  ),
2143
- angle > 0.2 && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("text", { x: lx, y: ly, className: "chart-pie-label", textAnchor: "middle", dominantBaseline: "central", children: v })
2144
- ] }, i);
2145
- });
2146
- return /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("svg", { viewBox: "0 0 300 300", className: "chart-svg chart-pie", children: slices });
2147
- };
2214
+ s.angle > 0.2 && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("text", { x: s.lx, y: s.ly, className: "chart-pie-label", textAnchor: "middle", dominantBaseline: "central", children: s.v })
2215
+ ] }, i)) });
2216
+ }
2217
+ );
2218
+ PieDonutChart.displayName = "PieDonutChart";
2148
2219
  var Chart = (props) => {
2149
2220
  const { type, data, labels, tooltip: showTooltip = true } = props;
2150
2221
  const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
@@ -2440,7 +2511,7 @@ var useClickOutside_default = useClickOutside;
2440
2511
  // src/components/DatePicker/SingleDatePicker/index.tsx
2441
2512
  var import_react10 = __toESM(require("react"), 1);
2442
2513
  var import_jsx_runtime311 = require("react/jsx-runtime");
2443
- var DayCell = import_react10.default.memo(
2514
+ var DayCell2 = import_react10.default.memo(
2444
2515
  ({
2445
2516
  day,
2446
2517
  disabled,
@@ -2470,7 +2541,7 @@ var DayCell = import_react10.default.memo(
2470
2541
  ),
2471
2542
  (prev, next) => prev.selected === next.selected && prev.disabled === next.disabled && prev.highlighted === next.highlighted && prev.day === next.day
2472
2543
  );
2473
- DayCell.displayName = "DayCell";
2544
+ DayCell2.displayName = "DayCell";
2474
2545
  var SingleDatePicker = (props) => {
2475
2546
  const {
2476
2547
  value,
@@ -2593,7 +2664,7 @@ var SingleDatePicker = (props) => {
2593
2664
  `${day.date.getFullYear()}-${day.date.getMonth()}-${day.date.getDate()}`
2594
2665
  );
2595
2666
  return /* @__PURE__ */ (0, import_jsx_runtime311.jsx)(
2596
- DayCell,
2667
+ DayCell2,
2597
2668
  {
2598
2669
  day,
2599
2670
  disabled,
@@ -2708,6 +2779,35 @@ var Modal_default = Modal;
2708
2779
  // src/components/DatePicker/RangePicker/index.tsx
2709
2780
  var import_react13 = __toESM(require("react"), 1);
2710
2781
  var import_jsx_runtime314 = require("react/jsx-runtime");
2782
+ var RangeDayCell = import_react13.default.memo(
2783
+ ({
2784
+ day,
2785
+ disabled,
2786
+ isStart,
2787
+ isEnd,
2788
+ inRange,
2789
+ onClick
2790
+ }) => /* @__PURE__ */ (0, import_jsx_runtime314.jsx)(
2791
+ "button",
2792
+ {
2793
+ type: "button",
2794
+ className: clsx_default(
2795
+ "datepicker-day",
2796
+ !day.isCurrentMonth && "outside",
2797
+ disabled && "disabled",
2798
+ (isStart || isEnd) && "selected",
2799
+ inRange && !isStart && !isEnd && "in-range",
2800
+ day.isToday && "today",
2801
+ day.isSunday && "sunday",
2802
+ day.isSaturday && "saturday"
2803
+ ),
2804
+ disabled: disabled || !day.isCurrentMonth,
2805
+ onClick,
2806
+ children: day.day
2807
+ }
2808
+ )
2809
+ );
2810
+ RangeDayCell.displayName = "RangeDayCell";
2711
2811
  var RangePicker = (props) => {
2712
2812
  const {
2713
2813
  startDate,
@@ -2784,20 +2884,13 @@ var RangePicker = (props) => {
2784
2884
  const isEnd = isSameDay(day.date, endDate);
2785
2885
  const inRange = isInRange(day.date, startDate, endDate);
2786
2886
  return /* @__PURE__ */ (0, import_jsx_runtime314.jsx)(
2787
- "button",
2887
+ RangeDayCell,
2788
2888
  {
2789
- type: "button",
2790
- className: clsx_default(
2791
- "datepicker-day",
2792
- !day.isCurrentMonth && "outside",
2793
- disabled && "disabled",
2794
- (isStart || isEnd) && "selected",
2795
- inRange && !isStart && !isEnd && "in-range",
2796
- day.isToday && "today",
2797
- day.isSunday && "sunday",
2798
- day.isSaturday && "saturday"
2799
- ),
2800
- disabled: disabled || !day.isCurrentMonth,
2889
+ day,
2890
+ disabled,
2891
+ isStart,
2892
+ isEnd,
2893
+ inRange,
2801
2894
  onClick: () => {
2802
2895
  if (!disabled && day.isCurrentMonth) {
2803
2896
  if (type === "start") {
@@ -2808,8 +2901,7 @@ var RangePicker = (props) => {
2808
2901
  onChange?.({ startDate, endDate: newEnd });
2809
2902
  }
2810
2903
  }
2811
- },
2812
- children: day.day
2904
+ }
2813
2905
  },
2814
2906
  idx
2815
2907
  );
@@ -3867,10 +3959,7 @@ var Steps = (props) => {
3867
3959
  return /* @__PURE__ */ (0, import_jsx_runtime332.jsx)("div", { className: clsx_default("lib-xplat-steps", type), children: items.map((item, index) => {
3868
3960
  const status = index < current ? "completed" : index === current ? "active" : "pending";
3869
3961
  return /* @__PURE__ */ (0, import_jsx_runtime332.jsxs)("div", { className: clsx_default("step-item", status), children: [
3870
- /* @__PURE__ */ (0, import_jsx_runtime332.jsxs)("div", { className: "step-indicator", children: [
3871
- /* @__PURE__ */ (0, import_jsx_runtime332.jsx)("div", { className: "step-circle", children: status === "completed" ? /* @__PURE__ */ (0, import_jsx_runtime332.jsx)(CheckIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime332.jsx)("span", { children: index + 1 }) }),
3872
- index < items.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime332.jsx)("div", { className: "step-line" })
3873
- ] }),
3962
+ /* @__PURE__ */ (0, import_jsx_runtime332.jsx)("div", { className: "step-circle", children: status === "completed" ? /* @__PURE__ */ (0, import_jsx_runtime332.jsx)(CheckIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime332.jsx)("span", { children: index + 1 }) }),
3874
3963
  /* @__PURE__ */ (0, import_jsx_runtime332.jsxs)("div", { className: "step-content", children: [
3875
3964
  /* @__PURE__ */ (0, import_jsx_runtime332.jsx)("span", { className: "step-title", children: item.title }),
3876
3965
  item.description && /* @__PURE__ */ (0, import_jsx_runtime332.jsx)("span", { className: "step-description", children: item.description })
@@ -4081,6 +4170,21 @@ var Swiper = (props) => {
4081
4170
  }, [isDragging, dragOffset, innerIndex, useLoop, maxIndex, slideStep, moveToInner]);
4082
4171
  const slideWidthPercent = 100 / viewItemCount;
4083
4172
  const gapAdjust = spaceBetween * (viewItemCount - 1) / viewItemCount;
4173
+ const slideElements = import_react27.default.useMemo(
4174
+ () => extendedItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime333.jsx)(
4175
+ "div",
4176
+ {
4177
+ className: "lib-xplat-swiper__slide",
4178
+ style: {
4179
+ minWidth: `calc(${slideWidthPercent}% - ${gapAdjust}px)`,
4180
+ maxWidth: `calc(${slideWidthPercent}% - ${gapAdjust}px)`
4181
+ },
4182
+ children: item
4183
+ },
4184
+ idx
4185
+ )),
4186
+ [extendedItems, slideWidthPercent, gapAdjust]
4187
+ );
4084
4188
  const totalSteps = Math.ceil((maxIndex + 1) / slideBy);
4085
4189
  const currentStep = Math.min(
4086
4190
  Math.floor(realIndex / slideBy),
@@ -4106,18 +4210,7 @@ var Swiper = (props) => {
4106
4210
  gap: `${spaceBetween}px`
4107
4211
  },
4108
4212
  onTransitionEnd: handleTransitionEnd,
4109
- children: extendedItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime333.jsx)(
4110
- "div",
4111
- {
4112
- className: "lib-xplat-swiper__slide",
4113
- style: {
4114
- minWidth: `calc(${slideWidthPercent}% - ${gapAdjust}px)`,
4115
- maxWidth: `calc(${slideWidthPercent}% - ${gapAdjust}px)`
4116
- },
4117
- children: item
4118
- },
4119
- idx
4120
- ))
4213
+ children: slideElements
4121
4214
  }
4122
4215
  )
4123
4216
  }
@@ -4336,7 +4429,7 @@ var TableRowContext_default = TableRowContext;
4336
4429
 
4337
4430
  // src/components/Table/TableCell.tsx
4338
4431
  var import_jsx_runtime339 = require("react/jsx-runtime");
4339
- var TableCell = (props) => {
4432
+ var TableCell = import_react34.default.memo((props) => {
4340
4433
  const {
4341
4434
  children,
4342
4435
  align = "center",
@@ -4391,7 +4484,7 @@ var TableCell = (props) => {
4391
4484
  children
4392
4485
  }
4393
4486
  );
4394
- };
4487
+ });
4395
4488
  TableCell.displayName = "TableCell";
4396
4489
  var TableCell_default = TableCell;
4397
4490
 
@@ -4410,7 +4503,7 @@ var TableHead_default = TableHead;
4410
4503
  // src/components/Table/TableRow.tsx
4411
4504
  var import_react35 = __toESM(require("react"), 1);
4412
4505
  var import_jsx_runtime341 = require("react/jsx-runtime");
4413
- var TableRow = (props) => {
4506
+ var TableRow = import_react35.default.memo((props) => {
4414
4507
  const {
4415
4508
  children,
4416
4509
  type = "secondary",
@@ -4438,7 +4531,7 @@ var TableRow = (props) => {
4438
4531
  children
4439
4532
  }
4440
4533
  ) });
4441
- };
4534
+ });
4442
4535
  TableRow.displayName = "TableRow";
4443
4536
  var TableRow_default = TableRow;
4444
4537
 
@@ -4646,7 +4739,6 @@ var Video = import_react39.default.forwardRef((props, ref) => {
4646
4739
  const {
4647
4740
  src,
4648
4741
  poster,
4649
- controls = true,
4650
4742
  autoPlay,
4651
4743
  muted,
4652
4744
  loop,
@@ -4685,49 +4777,39 @@ var Video = import_react39.default.forwardRef((props, ref) => {
4685
4777
  videoRef.current.play();
4686
4778
  }
4687
4779
  };
4688
- const showCustomOverlay = !controls;
4689
- return /* @__PURE__ */ (0, import_jsx_runtime346.jsxs)(
4690
- "div",
4691
- {
4692
- className: clsx_default(
4693
- "lib-xplat-video",
4694
- showCustomOverlay && "custom-overlay"
4695
- ),
4696
- children: [
4697
- /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(
4698
- "video",
4699
- {
4700
- ref: setRefs,
4701
- src,
4702
- poster,
4703
- controls,
4704
- autoPlay,
4705
- muted,
4706
- loop,
4707
- playsInline: playsInline ?? true,
4708
- onPlay: handlePlay,
4709
- onPause: handlePause,
4710
- onLoadedData: handleLoadedData,
4711
- ...rest
4712
- }
4780
+ return /* @__PURE__ */ (0, import_jsx_runtime346.jsxs)("div", { className: "lib-xplat-video custom-overlay", children: [
4781
+ /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(
4782
+ "video",
4783
+ {
4784
+ ref: setRefs,
4785
+ src,
4786
+ poster,
4787
+ autoPlay,
4788
+ muted,
4789
+ loop,
4790
+ playsInline: playsInline ?? true,
4791
+ onPlay: handlePlay,
4792
+ onPause: handlePause,
4793
+ onLoadedData: handleLoadedData,
4794
+ onClick: togglePlay,
4795
+ ...rest
4796
+ }
4797
+ ),
4798
+ /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(
4799
+ "button",
4800
+ {
4801
+ type: "button",
4802
+ className: clsx_default(
4803
+ "play-overlay",
4804
+ isPlaying && "is-playing",
4805
+ !isLoaded && "is-loading"
4713
4806
  ),
4714
- showCustomOverlay && /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(
4715
- "button",
4716
- {
4717
- type: "button",
4718
- className: clsx_default(
4719
- "play-overlay",
4720
- isPlaying && "is-playing",
4721
- !isLoaded && "is-loading"
4722
- ),
4723
- onClick: togglePlay,
4724
- "aria-label": isPlaying ? "\uC77C\uC2DC\uC815\uC9C0" : "\uC7AC\uC0DD",
4725
- children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(PauseIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime346.jsx)("span", { className: "play-icon", children: /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(PlayCircleIcon_default, {}) })
4726
- }
4727
- )
4728
- ]
4729
- }
4730
- );
4807
+ onClick: togglePlay,
4808
+ "aria-label": isPlaying ? "\uC77C\uC2DC\uC815\uC9C0" : "\uC7AC\uC0DD",
4809
+ children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(PauseIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime346.jsx)("span", { className: "play-icon", children: /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(PlayCircleIcon_default, {}) })
4810
+ }
4811
+ )
4812
+ ] });
4731
4813
  });
4732
4814
  Video.displayName = "Video";
4733
4815
  var Video_default = Video;