@x-plat/design-system 0.8.3 → 0.10.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 (133) hide show
  1. package/dist/components/AutoResizeTextArea/index.cjs +140 -4
  2. package/dist/components/AutoResizeTextArea/index.css +38 -0
  3. package/dist/components/AutoResizeTextArea/index.d.cts +4 -0
  4. package/dist/components/AutoResizeTextArea/index.d.ts +4 -0
  5. package/dist/components/AutoResizeTextArea/index.js +140 -4
  6. package/dist/components/Badge/index.cjs +5 -1
  7. package/dist/components/Badge/index.css +1 -0
  8. package/dist/components/Badge/index.d.cts +1 -0
  9. package/dist/components/Badge/index.d.ts +1 -0
  10. package/dist/components/Badge/index.js +5 -1
  11. package/dist/components/Box/index.d.cts +3 -0
  12. package/dist/components/Box/index.d.ts +3 -0
  13. package/dist/components/Chart/index.cjs +7 -6
  14. package/dist/components/Chart/index.d.cts +12 -1
  15. package/dist/components/Chart/index.d.ts +12 -1
  16. package/dist/components/Chart/index.js +7 -6
  17. package/dist/components/ChatInput/index.cjs +150 -9
  18. package/dist/components/ChatInput/index.css +38 -0
  19. package/dist/components/ChatInput/index.d.cts +9 -0
  20. package/dist/components/ChatInput/index.d.ts +9 -0
  21. package/dist/components/ChatInput/index.js +151 -10
  22. package/dist/components/CheckBox/index.cjs +137 -6
  23. package/dist/components/CheckBox/index.css +40 -0
  24. package/dist/components/CheckBox/index.d.cts +13 -2
  25. package/dist/components/CheckBox/index.d.ts +13 -2
  26. package/dist/components/CheckBox/index.js +137 -6
  27. package/dist/components/Chip/index.d.cts +2 -0
  28. package/dist/components/Chip/index.d.ts +2 -0
  29. package/dist/components/DatePicker/index.cjs +76 -62
  30. package/dist/components/DatePicker/index.css +38 -31
  31. package/dist/components/DatePicker/index.js +42 -28
  32. package/dist/components/Drawer/index.d.cts +1 -0
  33. package/dist/components/Drawer/index.d.ts +1 -0
  34. package/dist/components/FieldMessage/index.cjs +183 -0
  35. package/dist/components/FieldMessage/index.css +37 -0
  36. package/dist/components/FieldMessage/index.d.cts +37 -0
  37. package/dist/components/FieldMessage/index.d.ts +37 -0
  38. package/dist/components/FieldMessage/index.js +154 -0
  39. package/dist/components/FileUpload/index.cjs +135 -8
  40. package/dist/components/FileUpload/index.css +38 -0
  41. package/dist/components/FileUpload/index.d.cts +9 -0
  42. package/dist/components/FileUpload/index.d.ts +9 -0
  43. package/dist/components/FileUpload/index.js +135 -8
  44. package/dist/components/ImageSelector/index.cjs +153 -11
  45. package/dist/components/ImageSelector/index.css +38 -0
  46. package/dist/components/ImageSelector/index.d.cts +6 -0
  47. package/dist/components/ImageSelector/index.d.ts +6 -0
  48. package/dist/components/ImageSelector/index.js +153 -11
  49. package/dist/components/Input/index.cjs +38 -25
  50. package/dist/components/Input/index.css +38 -31
  51. package/dist/components/Input/index.d.cts +7 -8
  52. package/dist/components/Input/index.d.ts +7 -8
  53. package/dist/components/Input/index.js +36 -23
  54. package/dist/components/NotificationBadge/index.cjs +5 -1
  55. package/dist/components/NotificationBadge/index.css +1 -0
  56. package/dist/components/NotificationBadge/index.d.cts +6 -2
  57. package/dist/components/NotificationBadge/index.d.ts +6 -2
  58. package/dist/components/NotificationBadge/index.js +5 -1
  59. package/dist/components/Pagination/index.cjs +6 -2
  60. package/dist/components/Pagination/index.css +1 -0
  61. package/dist/components/Pagination/index.d.cts +13 -2
  62. package/dist/components/Pagination/index.d.ts +13 -2
  63. package/dist/components/Pagination/index.js +6 -2
  64. package/dist/components/Progress/index.cjs +6 -2
  65. package/dist/components/Progress/index.css +1 -0
  66. package/dist/components/Progress/index.d.cts +11 -2
  67. package/dist/components/Progress/index.d.ts +11 -2
  68. package/dist/components/Progress/index.js +6 -2
  69. package/dist/components/Radio/index.cjs +158 -10
  70. package/dist/components/Radio/index.css +40 -0
  71. package/dist/components/Radio/index.d.cts +14 -2
  72. package/dist/components/Radio/index.d.ts +14 -2
  73. package/dist/components/Radio/index.js +158 -10
  74. package/dist/components/Select/index.cjs +139 -13
  75. package/dist/components/Select/index.css +38 -0
  76. package/dist/components/Select/index.d.cts +8 -1
  77. package/dist/components/Select/index.d.ts +8 -1
  78. package/dist/components/Select/index.js +139 -13
  79. package/dist/components/Skeleton/index.d.cts +3 -0
  80. package/dist/components/Skeleton/index.d.ts +3 -0
  81. package/dist/components/Spinner/index.cjs +6 -2
  82. package/dist/components/Spinner/index.css +1 -0
  83. package/dist/components/Spinner/index.d.cts +8 -2
  84. package/dist/components/Spinner/index.d.ts +8 -2
  85. package/dist/components/Spinner/index.js +6 -2
  86. package/dist/components/Steps/index.cjs +6 -2
  87. package/dist/components/Steps/index.css +11 -0
  88. package/dist/components/Steps/index.d.cts +9 -2
  89. package/dist/components/Steps/index.d.ts +9 -2
  90. package/dist/components/Steps/index.js +6 -2
  91. package/dist/components/Switch/index.cjs +146 -6
  92. package/dist/components/Switch/index.css +40 -0
  93. package/dist/components/Switch/index.d.cts +13 -2
  94. package/dist/components/Switch/index.d.ts +13 -2
  95. package/dist/components/Switch/index.js +146 -6
  96. package/dist/components/Tab/index.cjs +4 -3
  97. package/dist/components/Tab/index.d.cts +12 -1
  98. package/dist/components/Tab/index.d.ts +12 -1
  99. package/dist/components/Tab/index.js +4 -3
  100. package/dist/components/Tag/index.cjs +5 -3
  101. package/dist/components/Tag/index.d.cts +12 -2
  102. package/dist/components/Tag/index.d.ts +12 -2
  103. package/dist/components/Tag/index.js +5 -3
  104. package/dist/components/TextArea/index.cjs +138 -2
  105. package/dist/components/TextArea/index.css +38 -0
  106. package/dist/components/TextArea/index.d.cts +6 -0
  107. package/dist/components/TextArea/index.d.ts +6 -0
  108. package/dist/components/TextArea/index.js +138 -2
  109. package/dist/components/Tooltip/index.cjs +4 -2
  110. package/dist/components/Tooltip/index.d.cts +11 -1
  111. package/dist/components/Tooltip/index.d.ts +11 -1
  112. package/dist/components/Tooltip/index.js +4 -2
  113. package/dist/components/index.cjs +479 -408
  114. package/dist/components/index.css +59 -31
  115. package/dist/components/index.d.cts +3 -0
  116. package/dist/components/index.d.ts +3 -0
  117. package/dist/components/index.js +262 -194
  118. package/dist/index.cjs +484 -413
  119. package/dist/index.css +59 -31
  120. package/dist/index.d.cts +3 -0
  121. package/dist/index.d.ts +3 -0
  122. package/dist/index.js +264 -196
  123. package/dist/status-g_KP3qT6.d.cts +8 -0
  124. package/dist/status-g_KP3qT6.d.ts +8 -0
  125. package/dist/validation-Dqo1zqhT.d.cts +13 -0
  126. package/dist/validation-Dqo1zqhT.d.ts +13 -0
  127. package/guidelines/AGENT_PROMPT.md +15 -0
  128. package/guidelines/components/card.md +3 -3
  129. package/guidelines/components/feedback.md +1 -1
  130. package/guidelines/components/form.md +26 -0
  131. package/guidelines/components/navigation.md +16 -15
  132. package/guidelines/components/overlay.md +43 -4
  133. package/package.json +1 -1
@@ -38,7 +38,7 @@ __export(DatePicker_exports, {
38
38
  module.exports = __toCommonJS(DatePicker_exports);
39
39
 
40
40
  // src/components/DatePicker/InputDatePicker/index.tsx
41
- var import_react7 = __toESM(require("react"), 1);
41
+ var import_react6 = __toESM(require("react"), 1);
42
42
 
43
43
  // ../../node_modules/clsx/dist/clsx.mjs
44
44
  function r(e) {
@@ -180,22 +180,41 @@ var SuccessIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
180
180
  );
181
181
  var SuccessIcon_default = SuccessIcon;
182
182
 
183
- // src/components/Input/InputValidations.tsx
183
+ // src/components/FieldMessage/FieldMessage.tsx
184
184
  var import_jsx_runtime5 = require("react/jsx-runtime");
185
- var InputValidations = (props) => {
186
- const { message, status = "default" } = props;
187
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: clsx_default("lib-xplat-input-validation", status), children: [
188
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "icon", children: [
189
- status === "default" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InfoIcon_default, {}),
190
- status === "success" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SuccessIcon_default, {}),
191
- status === "warning" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InfoIcon_default, {}),
192
- status === "error" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ErrorIcon_default, {})
193
- ] }),
194
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "message", children: message })
185
+ var ICON = {
186
+ default: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InfoIcon_default, {}),
187
+ success: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SuccessIcon_default, {}),
188
+ warning: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InfoIcon_default, {}),
189
+ error: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ErrorIcon_default, {})
190
+ };
191
+ var FieldMessage = (props) => {
192
+ const { validations } = props;
193
+ if (!validations || validations.length === 0) return null;
194
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "lib-xplat-field-message-wrap", children: validations.map((v, idx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
195
+ "div",
196
+ {
197
+ className: clsx_default("lib-xplat-field-message", v.status),
198
+ children: [
199
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "icon", children: ICON[v.status] }),
200
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: v.message })
201
+ ]
202
+ },
203
+ `${v.message}_${idx}`
204
+ )) });
205
+ };
206
+ FieldMessage.displayName = "FieldMessage";
207
+ var FieldMessage_default = FieldMessage;
208
+ var Field = (props) => {
209
+ const { validations, children } = props;
210
+ if (!validations || validations.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children });
211
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "lib-xplat-field", children: [
212
+ children,
213
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FieldMessage, { validations })
195
214
  ] });
196
215
  };
197
- InputValidations.displayName = "InputValidations";
198
- var InputValidations_default = InputValidations;
216
+ Field.displayName = "Field";
217
+ var hasError = (validations) => !!validations?.some((v) => v.status === "error");
199
218
 
200
219
  // src/components/Input/reg.ts
201
220
  var numberAndCommaReg = /^[0-9,]+$/;
@@ -233,7 +252,6 @@ var handleTelBackspace = (prevValue, currValue) => {
233
252
 
234
253
  // src/components/Input/Input.tsx
235
254
  var import_jsx_runtime6 = require("react/jsx-runtime");
236
- var import_react2 = require("react");
237
255
  var formatValue = (type, value) => {
238
256
  if (value === null || value === void 0) return "";
239
257
  const strValue = Array.isArray(value) ? String(value[0] ?? "") : String(value);
@@ -322,27 +340,22 @@ var Input = import_react.default.forwardRef((props, ref) => {
322
340
  disabled,
323
341
  type: type === "number" ? "text" : type,
324
342
  value: localValue,
325
- onChange: handleChange
343
+ onChange: handleChange,
344
+ "aria-invalid": hasError(validations) || void 0
326
345
  }
327
346
  ),
328
347
  suffix && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "suffix", children: suffix })
329
348
  ]
330
349
  }
331
350
  ),
332
- validations && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "lib-xplat-input-validation-wrap", children: validations?.map((validation, idx) => /* @__PURE__ */ (0, import_react2.createElement)(
333
- InputValidations_default,
334
- {
335
- ...validation,
336
- key: `${validation.message}_${idx}`
337
- }
338
- )) })
351
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FieldMessage_default, { validations })
339
352
  ] });
340
353
  });
341
354
  Input.displayName = "Input";
342
355
  var Input_default = Input;
343
356
 
344
357
  // src/components/Input/PasswordInput/PasswordInput.tsx
345
- var import_react3 = __toESM(require("react"), 1);
358
+ var import_react2 = __toESM(require("react"), 1);
346
359
 
347
360
  // src/tokens/svg/form/CloseEyeIcon.tsx
348
361
  var import_jsx_runtime7 = require("react/jsx-runtime");
@@ -412,10 +425,10 @@ var OpenEyeIcon_default = OpenEyeIcon;
412
425
 
413
426
  // src/components/Input/PasswordInput/PasswordInput.tsx
414
427
  var import_jsx_runtime9 = require("react/jsx-runtime");
415
- var PasswordInput = import_react3.default.forwardRef(
428
+ var PasswordInput = import_react2.default.forwardRef(
416
429
  (props, ref) => {
417
430
  const { reg: _reg, ...inputProps } = props;
418
- const [isView, setIsView] = import_react3.default.useState(false);
431
+ const [isView, setIsView] = import_react2.default.useState(false);
419
432
  const handleChangeView = () => {
420
433
  setIsView((prev) => !prev);
421
434
  };
@@ -433,16 +446,16 @@ var PasswordInput = import_react3.default.forwardRef(
433
446
  PasswordInput.displayName = "PasswordInput";
434
447
 
435
448
  // src/components/Modal/Modal.tsx
436
- var import_react4 = __toESM(require("react"), 1);
449
+ var import_react3 = __toESM(require("react"), 1);
437
450
  var import_react_dom = require("react-dom");
438
451
  var import_jsx_runtime10 = require("react/jsx-runtime");
439
452
  var ANIMATION_DURATION_MS = 200;
440
453
  var Modal = (props) => {
441
454
  const { isOpen, onClose, children } = props;
442
- const [mounted, setMounted] = import_react4.default.useState(false);
443
- const [visible, setVisible] = import_react4.default.useState(false);
444
- const [settled, setSettled] = import_react4.default.useState(false);
445
- import_react4.default.useEffect(() => {
455
+ const [mounted, setMounted] = import_react3.default.useState(false);
456
+ const [visible, setVisible] = import_react3.default.useState(false);
457
+ const [settled, setSettled] = import_react3.default.useState(false);
458
+ import_react3.default.useEffect(() => {
446
459
  if (isOpen) {
447
460
  setMounted(true);
448
461
  const show = setTimeout(() => setVisible(true), 1);
@@ -1396,15 +1409,15 @@ var import_jsx_runtime298 = require("react/jsx-runtime");
1396
1409
  var import_jsx_runtime299 = require("react/jsx-runtime");
1397
1410
 
1398
1411
  // src/components/DatePicker/SingleDatePicker/index.tsx
1399
- var import_react6 = __toESM(require("react"), 1);
1412
+ var import_react5 = __toESM(require("react"), 1);
1400
1413
 
1401
1414
  // src/components/Calendar/useCalendar.ts
1402
- var import_react5 = __toESM(require("react"), 1);
1415
+ var import_react4 = __toESM(require("react"), 1);
1403
1416
  var useCalendar = (initialYear, initialMonth) => {
1404
1417
  const today = /* @__PURE__ */ new Date();
1405
- const [year, setYear] = import_react5.default.useState(initialYear ?? today.getFullYear());
1406
- const [month, setMonth] = import_react5.default.useState(initialMonth ?? today.getMonth());
1407
- const days = import_react5.default.useMemo(() => {
1418
+ const [year, setYear] = import_react4.default.useState(initialYear ?? today.getFullYear());
1419
+ const [month, setMonth] = import_react4.default.useState(initialMonth ?? today.getMonth());
1420
+ const days = import_react4.default.useMemo(() => {
1408
1421
  const firstDay = new Date(year, month, 1);
1409
1422
  const lastDay = new Date(year, month + 1, 0);
1410
1423
  const startDayOfWeek = firstDay.getDay();
@@ -1447,7 +1460,7 @@ var useCalendar = (initialYear, initialMonth) => {
1447
1460
  }
1448
1461
  return result;
1449
1462
  }, [year, month]);
1450
- const goToPrevMonth = import_react5.default.useCallback(() => {
1463
+ const goToPrevMonth = import_react4.default.useCallback(() => {
1451
1464
  setMonth((prev) => {
1452
1465
  if (prev === 0) {
1453
1466
  setYear((y) => y - 1);
@@ -1456,7 +1469,7 @@ var useCalendar = (initialYear, initialMonth) => {
1456
1469
  return prev - 1;
1457
1470
  });
1458
1471
  }, []);
1459
- const goToNextMonth = import_react5.default.useCallback(() => {
1472
+ const goToNextMonth = import_react4.default.useCallback(() => {
1460
1473
  setMonth((prev) => {
1461
1474
  if (prev === 11) {
1462
1475
  setYear((y) => y + 1);
@@ -1465,7 +1478,7 @@ var useCalendar = (initialYear, initialMonth) => {
1465
1478
  return prev + 1;
1466
1479
  });
1467
1480
  }, []);
1468
- const goToToday = import_react5.default.useCallback(() => {
1481
+ const goToToday = import_react4.default.useCallback(() => {
1469
1482
  setYear(today.getFullYear());
1470
1483
  setMonth(today.getMonth());
1471
1484
  }, []);
@@ -1500,7 +1513,7 @@ var MONTH_LABELS = {
1500
1513
 
1501
1514
  // src/components/DatePicker/SingleDatePicker/index.tsx
1502
1515
  var import_jsx_runtime300 = require("react/jsx-runtime");
1503
- var DayCell = import_react6.default.memo(
1516
+ var DayCell = import_react5.default.memo(
1504
1517
  ({
1505
1518
  day,
1506
1519
  disabled,
@@ -1552,26 +1565,26 @@ var SingleDatePicker = (props) => {
1552
1565
  initialYear,
1553
1566
  initialMonth
1554
1567
  );
1555
- const [pickerMode, setPickerMode] = import_react6.default.useState("days");
1556
- const [yearRangeStart, setYearRangeStart] = import_react6.default.useState(
1568
+ const [pickerMode, setPickerMode] = import_react5.default.useState("days");
1569
+ const [yearRangeStart, setYearRangeStart] = import_react5.default.useState(
1557
1570
  Math.floor((initialYear ?? (/* @__PURE__ */ new Date()).getFullYear()) / 12) * 12
1558
1571
  );
1559
- const minTime = import_react6.default.useMemo(
1572
+ const minTime = import_react5.default.useMemo(
1560
1573
  () => minDate ? new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()).getTime() : -Infinity,
1561
1574
  [minDate]
1562
1575
  );
1563
- const maxTime = import_react6.default.useMemo(
1576
+ const maxTime = import_react5.default.useMemo(
1564
1577
  () => maxDate ? new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate()).getTime() : Infinity,
1565
1578
  [maxDate]
1566
1579
  );
1567
- const highlightSet = import_react6.default.useMemo(() => {
1580
+ const highlightSet = import_react5.default.useMemo(() => {
1568
1581
  const set = /* @__PURE__ */ new Set();
1569
1582
  for (const h of highlightDates) {
1570
1583
  set.add(`${h.getFullYear()}-${h.getMonth()}-${h.getDate()}`);
1571
1584
  }
1572
1585
  return set;
1573
1586
  }, [highlightDates]);
1574
- const handleSelect = import_react6.default.useCallback(
1587
+ const handleSelect = import_react5.default.useCallback(
1575
1588
  (date) => {
1576
1589
  onChange?.(date);
1577
1590
  },
@@ -1700,8 +1713,8 @@ var formatDate = (date) => {
1700
1713
  };
1701
1714
  var InputDatePicker = (props) => {
1702
1715
  const { value, onChange, minDate, maxDate, disabled, locale = "ko", placeholder } = props;
1703
- const [isOpen, setIsOpen] = import_react7.default.useState(false);
1704
- const [tempDate, setTempDate] = import_react7.default.useState(value ?? /* @__PURE__ */ new Date());
1716
+ const [isOpen, setIsOpen] = import_react6.default.useState(false);
1717
+ const [tempDate, setTempDate] = import_react6.default.useState(value ?? /* @__PURE__ */ new Date());
1705
1718
  const handleOpen = () => {
1706
1719
  if (disabled) return;
1707
1720
  setTempDate(value ?? /* @__PURE__ */ new Date());
@@ -1750,18 +1763,18 @@ InputDatePicker.displayName = "InputDatePicker";
1750
1763
  var InputDatePicker_default = InputDatePicker;
1751
1764
 
1752
1765
  // src/components/DatePicker/PopupPicker/index.tsx
1753
- var import_react11 = __toESM(require("react"), 1);
1766
+ var import_react10 = __toESM(require("react"), 1);
1754
1767
 
1755
1768
  // src/components/DatePicker/RangePicker/index.tsx
1756
- var import_react10 = __toESM(require("react"), 1);
1769
+ var import_react9 = __toESM(require("react"), 1);
1757
1770
 
1758
1771
  // src/components/Tab/Tab.tsx
1759
- var import_react9 = __toESM(require("react"), 1);
1772
+ var import_react8 = __toESM(require("react"), 1);
1760
1773
 
1761
1774
  // src/components/Tab/TabItem.tsx
1762
- var import_react8 = __toESM(require("react"), 1);
1775
+ var import_react7 = __toESM(require("react"), 1);
1763
1776
  var import_jsx_runtime302 = require("react/jsx-runtime");
1764
- var TabItem = import_react8.default.forwardRef((props, ref) => {
1777
+ var TabItem = import_react7.default.forwardRef((props, ref) => {
1765
1778
  const { isActive, title, onClick } = props;
1766
1779
  return /* @__PURE__ */ (0, import_jsx_runtime302.jsx)(
1767
1780
  "div",
@@ -1779,22 +1792,23 @@ var TabItem_default = TabItem;
1779
1792
  // src/components/Tab/Tab.tsx
1780
1793
  var import_jsx_runtime303 = require("react/jsx-runtime");
1781
1794
  var Tab = (props) => {
1782
- const { activeIndex, onChange, tabs, type, size = "md" } = props;
1783
- const [underlineStyle, setUnderlineStyle] = import_react9.default.useState({
1795
+ const { activeIndex, onChange, tabs, variant, type, size = "md" } = props;
1796
+ const shape = variant ?? type ?? "default";
1797
+ const [underlineStyle, setUnderlineStyle] = import_react8.default.useState({
1784
1798
  left: 0,
1785
1799
  width: 0
1786
1800
  });
1787
- const itemRefs = import_react9.default.useRef([]);
1801
+ const itemRefs = import_react8.default.useRef([]);
1788
1802
  const handleChangeActiveTab = (tabItem, tabIdx) => {
1789
1803
  onChange(tabItem, tabIdx);
1790
1804
  };
1791
- import_react9.default.useEffect(() => {
1805
+ import_react8.default.useEffect(() => {
1792
1806
  const el = itemRefs.current[activeIndex];
1793
1807
  if (el) {
1794
1808
  setUnderlineStyle({ left: el.offsetLeft, width: el.offsetWidth });
1795
1809
  }
1796
1810
  }, [activeIndex, tabs.length]);
1797
- return /* @__PURE__ */ (0, import_jsx_runtime303.jsxs)("div", { className: clsx_default("lib-xplat-tab", `type-${type}`, size), children: [
1811
+ return /* @__PURE__ */ (0, import_jsx_runtime303.jsxs)("div", { className: clsx_default("lib-xplat-tab", `type-${shape}`, size), children: [
1798
1812
  tabs.map((tab, idx) => /* @__PURE__ */ (0, import_jsx_runtime303.jsx)(
1799
1813
  TabItem_default,
1800
1814
  {
@@ -1807,7 +1821,7 @@ var Tab = (props) => {
1807
1821
  },
1808
1822
  `${tab.value}_${idx}`
1809
1823
  )),
1810
- type === "toggle" && /* @__PURE__ */ (0, import_jsx_runtime303.jsx)(
1824
+ shape === "toggle" && /* @__PURE__ */ (0, import_jsx_runtime303.jsx)(
1811
1825
  "div",
1812
1826
  {
1813
1827
  className: "tab-toggle-underline",
@@ -1833,7 +1847,7 @@ var RangePicker = (props) => {
1833
1847
  maxDate,
1834
1848
  locale = "ko"
1835
1849
  } = props;
1836
- const [activeTab, setActiveTab] = import_react10.default.useState("start");
1850
+ const [activeTab, setActiveTab] = import_react9.default.useState("start");
1837
1851
  const handleStartChange = (date) => {
1838
1852
  if (!date) return;
1839
1853
  const newStart = date > endDate ? endDate : date;
@@ -1918,7 +1932,7 @@ var RangePicker_default = RangePicker;
1918
1932
  var import_jsx_runtime305 = require("react/jsx-runtime");
1919
1933
  var PopupPicker = (props) => {
1920
1934
  const { component, type, locale } = props;
1921
- const [isOpen, setIsOpen] = import_react11.default.useState(false);
1935
+ const [isOpen, setIsOpen] = import_react10.default.useState(false);
1922
1936
  const handleClick = () => setIsOpen(true);
1923
1937
  const handleClose = () => setIsOpen(false);
1924
1938
  const handleSingleChange = (date) => {
@@ -1927,7 +1941,7 @@ var PopupPicker = (props) => {
1927
1941
  handleClose();
1928
1942
  };
1929
1943
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("div", { className: "lib-xplat-popup-datepicker", children: [
1930
- import_react11.default.cloneElement(component, { onClick: handleClick }),
1944
+ import_react10.default.cloneElement(component, { onClick: handleClick }),
1931
1945
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(Modal_default, { isOpen, onClose: handleClose, children: /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("div", { className: clsx_default("lib-xplat-popup-datepicker-card", type === "range" && "range-mode"), children: [
1932
1946
  /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("div", { className: "popup-datepicker-content", children: [
1933
1947
  type === "single" && /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(
@@ -105,6 +105,44 @@
105
105
  outline-offset: 2px;
106
106
  }
107
107
 
108
+ /* src/components/FieldMessage/fieldMessage.scss */
109
+ .lib-xplat-field {
110
+ display: flex;
111
+ flex-direction: column;
112
+ gap: var(--spacing-space-2);
113
+ }
114
+ .lib-xplat-field-message-wrap {
115
+ display: flex;
116
+ gap: var(--spacing-space-2);
117
+ margin-left: var(--spacing-space-1);
118
+ }
119
+ .lib-xplat-field-message-wrap > .lib-xplat-field-message {
120
+ display: flex;
121
+ gap: var(--spacing-space-1);
122
+ font-family: var(--semantic-typo-caption-2-r-font);
123
+ font-size: var(--semantic-typo-caption-2-r-size);
124
+ line-height: var(--semantic-typo-caption-2-r-lh);
125
+ font-weight: var(--semantic-typo-caption-2-r-weight);
126
+ letter-spacing: var(--semantic-typo-caption-2-r-ls);
127
+ align-items: center;
128
+ user-select: none;
129
+ }
130
+ .lib-xplat-field-message-wrap > .lib-xplat-field-message.default {
131
+ color: var(--semantic-icon-secondary);
132
+ }
133
+ .lib-xplat-field-message-wrap > .lib-xplat-field-message.success {
134
+ color: var(--semantic-text-success);
135
+ }
136
+ .lib-xplat-field-message-wrap > .lib-xplat-field-message.warning {
137
+ color: var(--semantic-text-warning);
138
+ }
139
+ .lib-xplat-field-message-wrap > .lib-xplat-field-message.error {
140
+ color: var(--semantic-text-error);
141
+ }
142
+ .lib-xplat-field-message-wrap > .lib-xplat-field-message > .icon {
143
+ font-size: var(--semantic-typo-label-2-m-size);
144
+ }
145
+
108
146
  /* src/components/Input/input.scss */
109
147
  .lib-xplat-input-wrap {
110
148
  display: flex;
@@ -187,37 +225,6 @@
187
225
  .lib-xplat-input-wrap .lib-xplat-input > .suffix > .wrapper.pointer {
188
226
  cursor: pointer;
189
227
  }
190
- .lib-xplat-input-wrap .lib-xplat-input-validation-wrap {
191
- display: flex;
192
- gap: var(--spacing-space-2);
193
- margin-left: var(--spacing-space-1);
194
- }
195
- .lib-xplat-input-wrap .lib-xplat-input-validation-wrap > .lib-xplat-input-validation {
196
- display: flex;
197
- gap: var(--spacing-space-1);
198
- font-family: var(--semantic-typo-caption-2-r-font);
199
- font-size: var(--semantic-typo-caption-2-r-size);
200
- line-height: var(--semantic-typo-caption-2-r-lh);
201
- font-weight: var(--semantic-typo-caption-2-r-weight);
202
- letter-spacing: var(--semantic-typo-caption-2-r-ls);
203
- align-items: center;
204
- user-select: none;
205
- }
206
- .lib-xplat-input-wrap .lib-xplat-input-validation-wrap > .lib-xplat-input-validation.default {
207
- color: var(--semantic-icon-secondary);
208
- }
209
- .lib-xplat-input-wrap .lib-xplat-input-validation-wrap > .lib-xplat-input-validation.success {
210
- color: var(--semantic-text-success);
211
- }
212
- .lib-xplat-input-wrap .lib-xplat-input-validation-wrap > .lib-xplat-input-validation.warning {
213
- color: var(--semantic-text-warning);
214
- }
215
- .lib-xplat-input-wrap .lib-xplat-input-validation-wrap > .lib-xplat-input-validation.error {
216
- color: var(--semantic-text-error);
217
- }
218
- .lib-xplat-input-wrap .lib-xplat-input-validation-wrap > .lib-xplat-input-validation > .icon {
219
- font-size: var(--semantic-typo-label-2-m-size);
220
- }
221
228
 
222
229
  /* src/components/Modal/modal.scss */
223
230
  .lib-xplat-modal {
@@ -141,22 +141,41 @@ var SuccessIcon = () => /* @__PURE__ */ jsx4(
141
141
  );
142
142
  var SuccessIcon_default = SuccessIcon;
143
143
 
144
- // src/components/Input/InputValidations.tsx
145
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
146
- var InputValidations = (props) => {
147
- const { message, status = "default" } = props;
148
- return /* @__PURE__ */ jsxs3("div", { className: clsx_default("lib-xplat-input-validation", status), children: [
149
- /* @__PURE__ */ jsxs3("div", { className: "icon", children: [
150
- status === "default" && /* @__PURE__ */ jsx5(InfoIcon_default, {}),
151
- status === "success" && /* @__PURE__ */ jsx5(SuccessIcon_default, {}),
152
- status === "warning" && /* @__PURE__ */ jsx5(InfoIcon_default, {}),
153
- status === "error" && /* @__PURE__ */ jsx5(ErrorIcon_default, {})
154
- ] }),
155
- /* @__PURE__ */ jsx5("div", { className: "message", children: message })
144
+ // src/components/FieldMessage/FieldMessage.tsx
145
+ import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
146
+ var ICON = {
147
+ default: /* @__PURE__ */ jsx5(InfoIcon_default, {}),
148
+ success: /* @__PURE__ */ jsx5(SuccessIcon_default, {}),
149
+ warning: /* @__PURE__ */ jsx5(InfoIcon_default, {}),
150
+ error: /* @__PURE__ */ jsx5(ErrorIcon_default, {})
151
+ };
152
+ var FieldMessage = (props) => {
153
+ const { validations } = props;
154
+ if (!validations || validations.length === 0) return null;
155
+ return /* @__PURE__ */ jsx5("div", { className: "lib-xplat-field-message-wrap", children: validations.map((v, idx) => /* @__PURE__ */ jsxs3(
156
+ "div",
157
+ {
158
+ className: clsx_default("lib-xplat-field-message", v.status),
159
+ children: [
160
+ /* @__PURE__ */ jsx5("div", { className: "icon", children: ICON[v.status] }),
161
+ /* @__PURE__ */ jsx5("span", { children: v.message })
162
+ ]
163
+ },
164
+ `${v.message}_${idx}`
165
+ )) });
166
+ };
167
+ FieldMessage.displayName = "FieldMessage";
168
+ var FieldMessage_default = FieldMessage;
169
+ var Field = (props) => {
170
+ const { validations, children } = props;
171
+ if (!validations || validations.length === 0) return /* @__PURE__ */ jsx5(Fragment, { children });
172
+ return /* @__PURE__ */ jsxs3("div", { className: "lib-xplat-field", children: [
173
+ children,
174
+ /* @__PURE__ */ jsx5(FieldMessage, { validations })
156
175
  ] });
157
176
  };
158
- InputValidations.displayName = "InputValidations";
159
- var InputValidations_default = InputValidations;
177
+ Field.displayName = "Field";
178
+ var hasError = (validations) => !!validations?.some((v) => v.status === "error");
160
179
 
161
180
  // src/components/Input/reg.ts
162
181
  var numberAndCommaReg = /^[0-9,]+$/;
@@ -194,7 +213,6 @@ var handleTelBackspace = (prevValue, currValue) => {
194
213
 
195
214
  // src/components/Input/Input.tsx
196
215
  import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
197
- import { createElement } from "react";
198
216
  var formatValue = (type, value) => {
199
217
  if (value === null || value === void 0) return "";
200
218
  const strValue = Array.isArray(value) ? String(value[0] ?? "") : String(value);
@@ -283,20 +301,15 @@ var Input = React.forwardRef((props, ref) => {
283
301
  disabled,
284
302
  type: type === "number" ? "text" : type,
285
303
  value: localValue,
286
- onChange: handleChange
304
+ onChange: handleChange,
305
+ "aria-invalid": hasError(validations) || void 0
287
306
  }
288
307
  ),
289
308
  suffix && /* @__PURE__ */ jsx6("div", { className: "suffix", children: suffix })
290
309
  ]
291
310
  }
292
311
  ),
293
- validations && /* @__PURE__ */ jsx6("div", { className: "lib-xplat-input-validation-wrap", children: validations?.map((validation, idx) => /* @__PURE__ */ createElement(
294
- InputValidations_default,
295
- {
296
- ...validation,
297
- key: `${validation.message}_${idx}`
298
- }
299
- )) })
312
+ /* @__PURE__ */ jsx6(FieldMessage_default, { validations })
300
313
  ] });
301
314
  });
302
315
  Input.displayName = "Input";
@@ -1460,7 +1473,7 @@ var MONTH_LABELS = {
1460
1473
  };
1461
1474
 
1462
1475
  // src/components/DatePicker/SingleDatePicker/index.tsx
1463
- import { Fragment, jsx as jsx300, jsxs as jsxs191 } from "react/jsx-runtime";
1476
+ import { Fragment as Fragment2, jsx as jsx300, jsxs as jsxs191 } from "react/jsx-runtime";
1464
1477
  var DayCell = React5.memo(
1465
1478
  ({
1466
1479
  day,
@@ -1603,7 +1616,7 @@ var SingleDatePicker = (props) => {
1603
1616
  },
1604
1617
  i
1605
1618
  )) }),
1606
- pickerMode === "days" && /* @__PURE__ */ jsxs191(Fragment, { children: [
1619
+ pickerMode === "days" && /* @__PURE__ */ jsxs191(Fragment2, { children: [
1607
1620
  /* @__PURE__ */ jsx300("div", { className: "datepicker-weekdays", children: weekdays.map((label, i) => /* @__PURE__ */ jsx300(
1608
1621
  "div",
1609
1622
  {
@@ -1740,7 +1753,8 @@ var TabItem_default = TabItem;
1740
1753
  // src/components/Tab/Tab.tsx
1741
1754
  import { jsx as jsx303, jsxs as jsxs193 } from "react/jsx-runtime";
1742
1755
  var Tab = (props) => {
1743
- const { activeIndex, onChange, tabs, type, size = "md" } = props;
1756
+ const { activeIndex, onChange, tabs, variant, type, size = "md" } = props;
1757
+ const shape = variant ?? type ?? "default";
1744
1758
  const [underlineStyle, setUnderlineStyle] = React8.useState({
1745
1759
  left: 0,
1746
1760
  width: 0
@@ -1755,7 +1769,7 @@ var Tab = (props) => {
1755
1769
  setUnderlineStyle({ left: el.offsetLeft, width: el.offsetWidth });
1756
1770
  }
1757
1771
  }, [activeIndex, tabs.length]);
1758
- return /* @__PURE__ */ jsxs193("div", { className: clsx_default("lib-xplat-tab", `type-${type}`, size), children: [
1772
+ return /* @__PURE__ */ jsxs193("div", { className: clsx_default("lib-xplat-tab", `type-${shape}`, size), children: [
1759
1773
  tabs.map((tab, idx) => /* @__PURE__ */ jsx303(
1760
1774
  TabItem_default,
1761
1775
  {
@@ -1768,7 +1782,7 @@ var Tab = (props) => {
1768
1782
  },
1769
1783
  `${tab.value}_${idx}`
1770
1784
  )),
1771
- type === "toggle" && /* @__PURE__ */ jsx303(
1785
+ shape === "toggle" && /* @__PURE__ */ jsx303(
1772
1786
  "div",
1773
1787
  {
1774
1788
  className: "tab-toggle-underline",
@@ -6,6 +6,7 @@ interface DrawerProps {
6
6
  isOpen: boolean;
7
7
  onClose: () => void;
8
8
  placement?: DrawerPlacement;
9
+ /** 패널 너비 */
9
10
  size?: DrawerSize;
10
11
  title?: React.ReactNode;
11
12
  children?: React.ReactNode;
@@ -6,6 +6,7 @@ interface DrawerProps {
6
6
  isOpen: boolean;
7
7
  onClose: () => void;
8
8
  placement?: DrawerPlacement;
9
+ /** 패널 너비 */
9
10
  size?: DrawerSize;
10
11
  title?: React.ReactNode;
11
12
  children?: React.ReactNode;