@x-plat/design-system 0.11.0 → 0.13.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 (63) hide show
  1. package/dist/components/AutoResizeTextArea/index.cjs +2 -2
  2. package/dist/components/AutoResizeTextArea/index.js +2 -2
  3. package/dist/components/ChatInput/index.cjs +2 -2
  4. package/dist/components/ChatInput/index.js +2 -2
  5. package/dist/components/CheckBox/index.cjs +2 -2
  6. package/dist/components/CheckBox/index.js +2 -2
  7. package/dist/components/DatePicker/index.cjs +109 -75
  8. package/dist/components/DatePicker/index.d.cts +19 -0
  9. package/dist/components/DatePicker/index.d.ts +19 -0
  10. package/dist/components/DatePicker/index.js +109 -75
  11. package/dist/components/Dropdown/index.cjs +22 -9
  12. package/dist/components/Dropdown/index.css +3 -0
  13. package/dist/components/Dropdown/index.js +22 -9
  14. package/dist/components/Editor/index.cjs +602 -30
  15. package/dist/components/Editor/index.css +103 -0
  16. package/dist/components/Editor/index.d.cts +1 -1
  17. package/dist/components/Editor/index.d.ts +1 -1
  18. package/dist/components/Editor/index.js +602 -30
  19. package/dist/components/FieldMessage/index.cjs +2 -2
  20. package/dist/components/FieldMessage/index.d.cts +8 -0
  21. package/dist/components/FieldMessage/index.d.ts +8 -0
  22. package/dist/components/FieldMessage/index.js +2 -2
  23. package/dist/components/FileUpload/index.cjs +10 -6
  24. package/dist/components/FileUpload/index.d.cts +15 -2
  25. package/dist/components/FileUpload/index.d.ts +15 -2
  26. package/dist/components/FileUpload/index.js +10 -6
  27. package/dist/components/ImageSelector/index.cjs +7 -6
  28. package/dist/components/ImageSelector/index.d.cts +15 -2
  29. package/dist/components/ImageSelector/index.d.ts +15 -2
  30. package/dist/components/ImageSelector/index.js +7 -6
  31. package/dist/components/Input/index.cjs +2 -2
  32. package/dist/components/Input/index.d.cts +4 -0
  33. package/dist/components/Input/index.d.ts +4 -0
  34. package/dist/components/Input/index.js +2 -2
  35. package/dist/components/PopOver/index.cjs +21 -7
  36. package/dist/components/PopOver/index.css +3 -0
  37. package/dist/components/PopOver/index.js +21 -7
  38. package/dist/components/Radio/index.cjs +2 -2
  39. package/dist/components/Radio/index.js +2 -2
  40. package/dist/components/Select/index.cjs +23 -10
  41. package/dist/components/Select/index.css +3 -0
  42. package/dist/components/Select/index.d.cts +1 -2
  43. package/dist/components/Select/index.d.ts +1 -2
  44. package/dist/components/Select/index.js +23 -10
  45. package/dist/components/Switch/index.cjs +2 -2
  46. package/dist/components/Switch/index.js +2 -2
  47. package/dist/components/TextArea/index.cjs +2 -2
  48. package/dist/components/TextArea/index.js +2 -2
  49. package/dist/components/TimePicker/index.cjs +23 -10
  50. package/dist/components/TimePicker/index.css +3 -0
  51. package/dist/components/TimePicker/index.js +23 -10
  52. package/dist/components/index.cjs +751 -124
  53. package/dist/components/index.css +113 -0
  54. package/dist/components/index.js +751 -124
  55. package/dist/index.cjs +751 -124
  56. package/dist/index.css +113 -0
  57. package/dist/index.js +751 -124
  58. package/guidelines/Guidelines.md +12 -0
  59. package/guidelines/MIGRATION.md +270 -0
  60. package/guidelines/components/datepicker.md +26 -0
  61. package/guidelines/components/editor.md +58 -3
  62. package/guidelines/components/file-media.md +21 -4
  63. package/package.json +1 -1
@@ -167,11 +167,11 @@ var FieldMessage = (props) => {
167
167
  FieldMessage.displayName = "FieldMessage";
168
168
  var FieldMessage_default = FieldMessage;
169
169
  var Field = (props) => {
170
- const { label, required = false, htmlFor, validations, children } = props;
170
+ const { label, required = false, htmlFor, labelId, validations, children } = props;
171
171
  const hasMessages = !!validations && validations.length > 0;
172
172
  if (!label && !hasMessages) return /* @__PURE__ */ jsx5(Fragment, { children });
173
173
  return /* @__PURE__ */ jsxs3("div", { className: "lib-xplat-field", children: [
174
- label && /* @__PURE__ */ jsxs3("label", { className: "lib-xplat-field-label", htmlFor, children: [
174
+ label && /* @__PURE__ */ jsxs3("label", { className: "lib-xplat-field-label", id: labelId, htmlFor, children: [
175
175
  label,
176
176
  required && /* @__PURE__ */ jsx5("span", { className: "required", "aria-hidden": "true", children: "*" })
177
177
  ] }),
@@ -1609,8 +1609,12 @@ var SingleDatePicker = (props) => {
1609
1609
  highlightDates = [],
1610
1610
  locale = "ko",
1611
1611
  rangeStart,
1612
- rangeEnd
1612
+ rangeEnd,
1613
+ label,
1614
+ required,
1615
+ validations
1613
1616
  } = props;
1617
+ const labelId = React6.useId();
1614
1618
  const initialYear = value?.getFullYear();
1615
1619
  const initialMonth = value?.getMonth();
1616
1620
  const { year, month, days, goToPrevMonth, goToNextMonth, setYear, setMonth } = useCalendar(
@@ -1673,10 +1677,12 @@ var SingleDatePicker = (props) => {
1673
1677
  const monthLabels = MONTH_LABELS[locale];
1674
1678
  const titleText = pickerMode === "days" ? locale === "ko" ? `${year}\uB144 ${monthLabels[month]}` : `${monthLabels[month]} ${year}` : pickerMode === "months" ? `${year}` : `${yearRangeStart} - ${yearRangeStart + 11}`;
1675
1679
  const hasRange = rangeStart != null && rangeEnd != null;
1676
- return /* @__PURE__ */ jsxs191(
1680
+ const calendar = /* @__PURE__ */ jsxs191(
1677
1681
  "div",
1678
1682
  {
1679
1683
  className: clsx_default("lib-xplat-datepicker", "single"),
1684
+ role: "group",
1685
+ "aria-labelledby": label ? labelId : void 0,
1680
1686
  children: [
1681
1687
  /* @__PURE__ */ jsxs191("div", { className: "datepicker-header", children: [
1682
1688
  /* @__PURE__ */ jsx300("button", { className: "datepicker-nav", onClick: handlePrev, type: "button", children: /* @__PURE__ */ jsx300(ChevronLeftIcon_default, {}) }),
@@ -1697,18 +1703,18 @@ var SingleDatePicker = (props) => {
1697
1703
  y
1698
1704
  );
1699
1705
  }) }),
1700
- pickerMode === "months" && /* @__PURE__ */ jsx300("div", { className: "datepicker-picker-grid", children: monthLabels.map((label, i) => /* @__PURE__ */ jsx300(
1706
+ pickerMode === "months" && /* @__PURE__ */ jsx300("div", { className: "datepicker-picker-grid", children: monthLabels.map((label2, i) => /* @__PURE__ */ jsx300(
1701
1707
  "button",
1702
1708
  {
1703
1709
  type: "button",
1704
1710
  className: clsx_default("datepicker-picker-cell", i === month && "active"),
1705
1711
  onClick: () => handleMonthSelect(i),
1706
- children: label
1712
+ children: label2
1707
1713
  },
1708
1714
  i
1709
1715
  )) }),
1710
1716
  pickerMode === "days" && /* @__PURE__ */ jsxs191(Fragment2, { children: [
1711
- /* @__PURE__ */ jsx300("div", { className: "datepicker-weekdays", children: weekdays.map((label, i) => /* @__PURE__ */ jsx300(
1717
+ /* @__PURE__ */ jsx300("div", { className: "datepicker-weekdays", children: weekdays.map((label2, i) => /* @__PURE__ */ jsx300(
1712
1718
  "div",
1713
1719
  {
1714
1720
  className: clsx_default(
@@ -1716,9 +1722,9 @@ var SingleDatePicker = (props) => {
1716
1722
  i === 0 && "sunday",
1717
1723
  i === 6 && "saturday"
1718
1724
  ),
1719
- children: label
1725
+ children: label2
1720
1726
  },
1721
- label
1727
+ label2
1722
1728
  )) }),
1723
1729
  /* @__PURE__ */ jsx300("div", { className: "datepicker-grid", children: days.map((day, idx) => {
1724
1730
  const t = day.date.getTime();
@@ -1750,6 +1756,7 @@ var SingleDatePicker = (props) => {
1750
1756
  ]
1751
1757
  }
1752
1758
  );
1759
+ return /* @__PURE__ */ jsx300(Field, { label, required, labelId, validations, children: calendar });
1753
1760
  };
1754
1761
  SingleDatePicker.displayName = "SingleDatePicker";
1755
1762
  var SingleDatePicker_default = SingleDatePicker;
@@ -1764,7 +1771,18 @@ var formatDate = (date) => {
1764
1771
  return `${y}/${m}/${d}`;
1765
1772
  };
1766
1773
  var InputDatePicker = (props) => {
1767
- const { value, onChange, minDate, maxDate, disabled, locale = "ko", placeholder } = props;
1774
+ const {
1775
+ value,
1776
+ onChange,
1777
+ minDate,
1778
+ maxDate,
1779
+ disabled,
1780
+ locale = "ko",
1781
+ placeholder,
1782
+ label,
1783
+ required,
1784
+ validations
1785
+ } = props;
1768
1786
  const [isOpen, setIsOpen] = React7.useState(false);
1769
1787
  const [tempDate, setTempDate] = React7.useState(value ?? /* @__PURE__ */ new Date());
1770
1788
  const handleOpen = () => {
@@ -1790,6 +1808,9 @@ var InputDatePicker = (props) => {
1790
1808
  placeholder,
1791
1809
  suffix: /* @__PURE__ */ jsx301(CalenderIcon_default, {}),
1792
1810
  disabled,
1811
+ label,
1812
+ required,
1813
+ validations,
1793
1814
  readOnly: true
1794
1815
  }
1795
1816
  ) }),
@@ -1921,8 +1942,12 @@ var RangePicker = (props) => {
1921
1942
  onChange,
1922
1943
  minDate,
1923
1944
  maxDate,
1924
- locale = "ko"
1945
+ locale = "ko",
1946
+ label,
1947
+ required,
1948
+ validations
1925
1949
  } = props;
1950
+ const labelId = React10.useId();
1926
1951
  const [activeTab, setActiveTab] = React10.useState("start");
1927
1952
  const handleStartChange = (date) => {
1928
1953
  if (!date) return;
@@ -1936,70 +1961,79 @@ var RangePicker = (props) => {
1936
1961
  };
1937
1962
  const startMaxDate = maxDate && endDate < maxDate ? endDate : endDate;
1938
1963
  const endMinDate = minDate && startDate > minDate ? startDate : startDate;
1939
- return /* @__PURE__ */ jsxs194("div", { className: clsx_default("lib-xplat-datepicker", "range"), children: [
1940
- /* @__PURE__ */ jsx304("div", { className: "datepicker-range-tabs", children: /* @__PURE__ */ jsx304(
1941
- Tab_default,
1942
- {
1943
- activeIndex: activeTab === "start" ? 0 : 1,
1944
- tabs: [
1945
- { value: "start", title: locale === "ko" ? "\uC2DC\uC791\uC77C" : "Start" },
1946
- { value: "end", title: locale === "ko" ? "\uC885\uB8CC\uC77C" : "End" }
1947
- ],
1948
- onChange: (tab) => setActiveTab(tab.value),
1949
- type: "toggle",
1950
- size: "sm"
1951
- }
1952
- ) }),
1953
- /* @__PURE__ */ jsxs194("div", { className: "datepicker-range-panels", children: [
1954
- /* @__PURE__ */ jsx304(
1955
- SingleDatePicker_default,
1956
- {
1957
- value: startDate,
1958
- onChange: handleStartChange,
1959
- minDate,
1960
- maxDate: startMaxDate,
1961
- rangeStart: startDate,
1962
- rangeEnd: endDate,
1963
- locale
1964
- }
1965
- ),
1966
- /* @__PURE__ */ jsx304(
1967
- SingleDatePicker_default,
1968
- {
1969
- value: endDate,
1970
- onChange: handleEndChange,
1971
- minDate: endMinDate,
1972
- maxDate,
1973
- rangeStart: startDate,
1974
- rangeEnd: endDate,
1975
- locale
1976
- }
1977
- )
1978
- ] }),
1979
- /* @__PURE__ */ jsx304("div", { className: "datepicker-range-mobile", children: activeTab === "start" ? /* @__PURE__ */ jsx304(
1980
- SingleDatePicker_default,
1981
- {
1982
- value: startDate,
1983
- onChange: handleStartChange,
1984
- minDate,
1985
- maxDate: startMaxDate,
1986
- rangeStart: startDate,
1987
- rangeEnd: endDate,
1988
- locale
1989
- }
1990
- ) : /* @__PURE__ */ jsx304(
1991
- SingleDatePicker_default,
1992
- {
1993
- value: endDate,
1994
- onChange: handleEndChange,
1995
- minDate: endMinDate,
1996
- maxDate,
1997
- rangeStart: startDate,
1998
- rangeEnd: endDate,
1999
- locale
2000
- }
2001
- ) })
2002
- ] });
1964
+ const calendar = /* @__PURE__ */ jsxs194(
1965
+ "div",
1966
+ {
1967
+ className: clsx_default("lib-xplat-datepicker", "range"),
1968
+ role: "group",
1969
+ "aria-labelledby": label ? labelId : void 0,
1970
+ children: [
1971
+ /* @__PURE__ */ jsx304("div", { className: "datepicker-range-tabs", children: /* @__PURE__ */ jsx304(
1972
+ Tab_default,
1973
+ {
1974
+ activeIndex: activeTab === "start" ? 0 : 1,
1975
+ tabs: [
1976
+ { value: "start", title: locale === "ko" ? "\uC2DC\uC791\uC77C" : "Start" },
1977
+ { value: "end", title: locale === "ko" ? "\uC885\uB8CC\uC77C" : "End" }
1978
+ ],
1979
+ onChange: (tab) => setActiveTab(tab.value),
1980
+ type: "toggle",
1981
+ size: "sm"
1982
+ }
1983
+ ) }),
1984
+ /* @__PURE__ */ jsxs194("div", { className: "datepicker-range-panels", children: [
1985
+ /* @__PURE__ */ jsx304(
1986
+ SingleDatePicker_default,
1987
+ {
1988
+ value: startDate,
1989
+ onChange: handleStartChange,
1990
+ minDate,
1991
+ maxDate: startMaxDate,
1992
+ rangeStart: startDate,
1993
+ rangeEnd: endDate,
1994
+ locale
1995
+ }
1996
+ ),
1997
+ /* @__PURE__ */ jsx304(
1998
+ SingleDatePicker_default,
1999
+ {
2000
+ value: endDate,
2001
+ onChange: handleEndChange,
2002
+ minDate: endMinDate,
2003
+ maxDate,
2004
+ rangeStart: startDate,
2005
+ rangeEnd: endDate,
2006
+ locale
2007
+ }
2008
+ )
2009
+ ] }),
2010
+ /* @__PURE__ */ jsx304("div", { className: "datepicker-range-mobile", children: activeTab === "start" ? /* @__PURE__ */ jsx304(
2011
+ SingleDatePicker_default,
2012
+ {
2013
+ value: startDate,
2014
+ onChange: handleStartChange,
2015
+ minDate,
2016
+ maxDate: startMaxDate,
2017
+ rangeStart: startDate,
2018
+ rangeEnd: endDate,
2019
+ locale
2020
+ }
2021
+ ) : /* @__PURE__ */ jsx304(
2022
+ SingleDatePicker_default,
2023
+ {
2024
+ value: endDate,
2025
+ onChange: handleEndChange,
2026
+ minDate: endMinDate,
2027
+ maxDate,
2028
+ rangeStart: startDate,
2029
+ rangeEnd: endDate,
2030
+ locale
2031
+ }
2032
+ ) })
2033
+ ]
2034
+ }
2035
+ );
2036
+ return /* @__PURE__ */ jsx304(Field, { label, required, labelId, validations, children: calendar });
2003
2037
  };
2004
2038
  RangePicker.displayName = "RangePicker";
2005
2039
  var RangePicker_default = RangePicker;
@@ -51,8 +51,10 @@ var import_react = __toESM(require("react"), 1);
51
51
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
52
52
  const [position, setPosition] = import_react.default.useState({
53
53
  position: {},
54
- direction: "bottom"
54
+ direction: "bottom",
55
+ repositioning: false
55
56
  });
57
+ const placedRef = import_react.default.useRef(false);
56
58
  const calculatePosition = import_react.default.useCallback(() => {
57
59
  if (!triggerRef.current || !popRef.current) return;
58
60
  const triggerRect = triggerRef.current.getBoundingClientRect();
@@ -77,11 +79,16 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
77
79
  if (left < 8) left = 8;
78
80
  setPosition({
79
81
  position: { top, left },
80
- direction
82
+ direction,
83
+ repositioning: placedRef.current
81
84
  });
85
+ placedRef.current = true;
82
86
  }, [triggerRef, popRef]);
83
87
  import_react.default.useLayoutEffect(() => {
84
- if (!enabled) return;
88
+ if (!enabled) {
89
+ placedRef.current = false;
90
+ return;
91
+ }
85
92
  calculatePosition();
86
93
  const raf = requestAnimationFrame(calculatePosition);
87
94
  return () => cancelAnimationFrame(raf);
@@ -96,11 +103,17 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
96
103
  }, [calculatePosition, enabled, popRef]);
97
104
  import_react.default.useEffect(() => {
98
105
  if (!enabled) return;
99
- window.addEventListener("resize", calculatePosition);
100
- window.addEventListener("scroll", calculatePosition, true);
106
+ let raf = 0;
107
+ const onScrollOrResize = () => {
108
+ cancelAnimationFrame(raf);
109
+ raf = requestAnimationFrame(calculatePosition);
110
+ };
111
+ window.addEventListener("resize", onScrollOrResize, { passive: true });
112
+ window.addEventListener("scroll", onScrollOrResize, { passive: true, capture: true });
101
113
  return () => {
102
- window.removeEventListener("resize", calculatePosition);
103
- window.removeEventListener("scroll", calculatePosition, true);
114
+ cancelAnimationFrame(raf);
115
+ window.removeEventListener("resize", onScrollOrResize);
116
+ window.removeEventListener("scroll", onScrollOrResize, true);
104
117
  };
105
118
  }, [calculatePosition, enabled]);
106
119
  return position;
@@ -181,7 +194,7 @@ var Dropdown = (props) => {
181
194
  const [visible, setVisible] = import_react4.default.useState(false);
182
195
  const triggerRef = import_react4.default.useRef(null);
183
196
  const menuRef = import_react4.default.useRef(null);
184
- const { position, direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
197
+ const { position, direction, repositioning } = useAutoPosition_default(triggerRef, menuRef, mounted);
185
198
  useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
186
199
  useEscapeKey(isOpen, () => {
187
200
  setIsOpen(false);
@@ -216,7 +229,7 @@ var Dropdown = (props) => {
216
229
  "div",
217
230
  {
218
231
  ref: menuRef,
219
- className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }),
232
+ className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }, repositioning && "repositioning"),
220
233
  style: { top: position.top, left: position.left },
221
234
  role: "menu",
222
235
  children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -57,3 +57,6 @@
57
57
  color: var(--semantic-text-disabled);
58
58
  cursor: not-allowed;
59
59
  }
60
+ .lib-xplat-dropdown-menu.repositioning {
61
+ transition: none;
62
+ }
@@ -15,8 +15,10 @@ import React from "react";
15
15
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
16
16
  const [position, setPosition] = React.useState({
17
17
  position: {},
18
- direction: "bottom"
18
+ direction: "bottom",
19
+ repositioning: false
19
20
  });
21
+ const placedRef = React.useRef(false);
20
22
  const calculatePosition = React.useCallback(() => {
21
23
  if (!triggerRef.current || !popRef.current) return;
22
24
  const triggerRect = triggerRef.current.getBoundingClientRect();
@@ -41,11 +43,16 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
41
43
  if (left < 8) left = 8;
42
44
  setPosition({
43
45
  position: { top, left },
44
- direction
46
+ direction,
47
+ repositioning: placedRef.current
45
48
  });
49
+ placedRef.current = true;
46
50
  }, [triggerRef, popRef]);
47
51
  React.useLayoutEffect(() => {
48
- if (!enabled) return;
52
+ if (!enabled) {
53
+ placedRef.current = false;
54
+ return;
55
+ }
49
56
  calculatePosition();
50
57
  const raf = requestAnimationFrame(calculatePosition);
51
58
  return () => cancelAnimationFrame(raf);
@@ -60,11 +67,17 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
60
67
  }, [calculatePosition, enabled, popRef]);
61
68
  React.useEffect(() => {
62
69
  if (!enabled) return;
63
- window.addEventListener("resize", calculatePosition);
64
- window.addEventListener("scroll", calculatePosition, true);
70
+ let raf = 0;
71
+ const onScrollOrResize = () => {
72
+ cancelAnimationFrame(raf);
73
+ raf = requestAnimationFrame(calculatePosition);
74
+ };
75
+ window.addEventListener("resize", onScrollOrResize, { passive: true });
76
+ window.addEventListener("scroll", onScrollOrResize, { passive: true, capture: true });
65
77
  return () => {
66
- window.removeEventListener("resize", calculatePosition);
67
- window.removeEventListener("scroll", calculatePosition, true);
78
+ cancelAnimationFrame(raf);
79
+ window.removeEventListener("resize", onScrollOrResize);
80
+ window.removeEventListener("scroll", onScrollOrResize, true);
68
81
  };
69
82
  }, [calculatePosition, enabled]);
70
83
  return position;
@@ -145,7 +158,7 @@ var Dropdown = (props) => {
145
158
  const [visible, setVisible] = React4.useState(false);
146
159
  const triggerRef = React4.useRef(null);
147
160
  const menuRef = React4.useRef(null);
148
- const { position, direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
161
+ const { position, direction, repositioning } = useAutoPosition_default(triggerRef, menuRef, mounted);
149
162
  useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
150
163
  useEscapeKey(isOpen, () => {
151
164
  setIsOpen(false);
@@ -180,7 +193,7 @@ var Dropdown = (props) => {
180
193
  "div",
181
194
  {
182
195
  ref: menuRef,
183
- className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }),
196
+ className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }, repositioning && "repositioning"),
184
197
  style: { top: position.top, left: position.left },
185
198
  role: "menu",
186
199
  children: items.map((item) => /* @__PURE__ */ jsx(