@x-plat/design-system 0.9.0 → 0.11.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 (156) hide show
  1. package/dist/components/AutoResizeTextArea/index.cjs +14 -5
  2. package/dist/components/AutoResizeTextArea/index.css +15 -0
  3. package/dist/components/AutoResizeTextArea/index.d.cts +5 -0
  4. package/dist/components/AutoResizeTextArea/index.d.ts +5 -0
  5. package/dist/components/AutoResizeTextArea/index.js +14 -5
  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 +20 -7
  18. package/dist/components/ChatInput/index.css +15 -0
  19. package/dist/components/ChatInput/index.d.cts +10 -0
  20. package/dist/components/ChatInput/index.d.ts +10 -0
  21. package/dist/components/ChatInput/index.js +20 -7
  22. package/dist/components/CheckBox/index.cjs +14 -5
  23. package/dist/components/CheckBox/index.css +17 -0
  24. package/dist/components/CheckBox/index.d.cts +10 -2
  25. package/dist/components/CheckBox/index.d.ts +10 -2
  26. package/dist/components/CheckBox/index.js +14 -5
  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 +181 -65
  30. package/dist/components/DatePicker/index.css +19 -0
  31. package/dist/components/DatePicker/index.js +181 -65
  32. package/dist/components/Drawer/index.cjs +83 -4
  33. package/dist/components/Drawer/index.d.cts +1 -0
  34. package/dist/components/Drawer/index.d.ts +1 -0
  35. package/dist/components/Drawer/index.js +83 -4
  36. package/dist/components/Dropdown/index.cjs +35 -7
  37. package/dist/components/Dropdown/index.js +35 -7
  38. package/dist/components/Editor/index.cjs +178 -21
  39. package/dist/components/Editor/index.js +178 -21
  40. package/dist/components/FieldMessage/index.cjs +8 -3
  41. package/dist/components/FieldMessage/index.css +15 -0
  42. package/dist/components/FieldMessage/index.d.cts +11 -4
  43. package/dist/components/FieldMessage/index.d.ts +11 -4
  44. package/dist/components/FieldMessage/index.js +8 -3
  45. package/dist/components/FileUpload/index.cjs +8 -3
  46. package/dist/components/FileUpload/index.css +15 -0
  47. package/dist/components/FileUpload/index.d.cts +6 -0
  48. package/dist/components/FileUpload/index.d.ts +6 -0
  49. package/dist/components/FileUpload/index.js +8 -3
  50. package/dist/components/ImageSelector/index.cjs +8 -3
  51. package/dist/components/ImageSelector/index.css +15 -0
  52. package/dist/components/ImageSelector/index.d.cts +3 -0
  53. package/dist/components/ImageSelector/index.d.ts +3 -0
  54. package/dist/components/ImageSelector/index.js +8 -3
  55. package/dist/components/Input/index.cjs +15 -5
  56. package/dist/components/Input/index.css +15 -0
  57. package/dist/components/Input/index.d.cts +8 -0
  58. package/dist/components/Input/index.d.ts +8 -0
  59. package/dist/components/Input/index.js +15 -5
  60. package/dist/components/Modal/index.cjs +84 -5
  61. package/dist/components/Modal/index.js +84 -5
  62. package/dist/components/NotificationBadge/index.cjs +5 -1
  63. package/dist/components/NotificationBadge/index.css +1 -0
  64. package/dist/components/NotificationBadge/index.d.cts +6 -2
  65. package/dist/components/NotificationBadge/index.d.ts +6 -2
  66. package/dist/components/NotificationBadge/index.js +5 -1
  67. package/dist/components/Pagination/index.cjs +6 -2
  68. package/dist/components/Pagination/index.css +1 -0
  69. package/dist/components/Pagination/index.d.cts +13 -2
  70. package/dist/components/Pagination/index.d.ts +13 -2
  71. package/dist/components/Pagination/index.js +6 -2
  72. package/dist/components/PopOver/index.cjs +34 -6
  73. package/dist/components/PopOver/index.js +34 -6
  74. package/dist/components/Progress/index.cjs +6 -2
  75. package/dist/components/Progress/index.css +1 -0
  76. package/dist/components/Progress/index.d.cts +11 -2
  77. package/dist/components/Progress/index.d.ts +11 -2
  78. package/dist/components/Progress/index.js +6 -2
  79. package/dist/components/Radio/index.cjs +14 -5
  80. package/dist/components/Radio/index.css +17 -0
  81. package/dist/components/Radio/index.d.cts +11 -2
  82. package/dist/components/Radio/index.d.ts +11 -2
  83. package/dist/components/Radio/index.js +14 -5
  84. package/dist/components/Select/index.cjs +99 -31
  85. package/dist/components/Select/index.css +54 -0
  86. package/dist/components/Select/index.d.cts +16 -1
  87. package/dist/components/Select/index.d.ts +16 -1
  88. package/dist/components/Select/index.js +99 -31
  89. package/dist/components/Skeleton/index.d.cts +3 -0
  90. package/dist/components/Skeleton/index.d.ts +3 -0
  91. package/dist/components/Spinner/index.cjs +6 -2
  92. package/dist/components/Spinner/index.css +1 -0
  93. package/dist/components/Spinner/index.d.cts +8 -2
  94. package/dist/components/Spinner/index.d.ts +8 -2
  95. package/dist/components/Spinner/index.js +6 -2
  96. package/dist/components/Stat/index.cjs +84 -0
  97. package/dist/components/Stat/index.css +96 -0
  98. package/dist/components/Stat/index.d.cts +37 -0
  99. package/dist/components/Stat/index.d.ts +37 -0
  100. package/dist/components/Stat/index.js +57 -0
  101. package/dist/components/Steps/index.cjs +6 -2
  102. package/dist/components/Steps/index.css +11 -0
  103. package/dist/components/Steps/index.d.cts +9 -2
  104. package/dist/components/Steps/index.d.ts +9 -2
  105. package/dist/components/Steps/index.js +6 -2
  106. package/dist/components/Switch/index.cjs +20 -7
  107. package/dist/components/Switch/index.css +17 -0
  108. package/dist/components/Switch/index.d.cts +15 -2
  109. package/dist/components/Switch/index.d.ts +15 -2
  110. package/dist/components/Switch/index.js +20 -7
  111. package/dist/components/Tab/index.cjs +51 -26
  112. package/dist/components/Tab/index.css +4 -0
  113. package/dist/components/Tab/index.d.cts +12 -1
  114. package/dist/components/Tab/index.d.ts +12 -1
  115. package/dist/components/Tab/index.js +51 -26
  116. package/dist/components/Tag/index.cjs +5 -3
  117. package/dist/components/Tag/index.d.cts +12 -2
  118. package/dist/components/Tag/index.d.ts +12 -2
  119. package/dist/components/Tag/index.js +5 -3
  120. package/dist/components/TextArea/index.cjs +14 -4
  121. package/dist/components/TextArea/index.css +15 -0
  122. package/dist/components/TextArea/index.d.cts +7 -0
  123. package/dist/components/TextArea/index.d.ts +7 -0
  124. package/dist/components/TextArea/index.js +14 -4
  125. package/dist/components/TimePicker/index.cjs +448 -0
  126. package/dist/components/TimePicker/index.css +172 -0
  127. package/dist/components/TimePicker/index.d.cts +42 -0
  128. package/dist/components/TimePicker/index.d.ts +42 -0
  129. package/dist/components/TimePicker/index.js +411 -0
  130. package/dist/components/Tooltip/index.cjs +4 -2
  131. package/dist/components/Tooltip/index.d.cts +11 -1
  132. package/dist/components/Tooltip/index.d.ts +11 -1
  133. package/dist/components/Tooltip/index.js +4 -2
  134. package/dist/components/index.cjs +916 -385
  135. package/dist/components/index.css +296 -0
  136. package/dist/components/index.d.cts +3 -0
  137. package/dist/components/index.d.ts +3 -0
  138. package/dist/components/index.js +914 -385
  139. package/dist/index.cjs +940 -409
  140. package/dist/index.css +296 -0
  141. package/dist/index.d.cts +3 -0
  142. package/dist/index.d.ts +3 -0
  143. package/dist/index.js +938 -409
  144. package/dist/status-njWqQWFV.d.cts +20 -0
  145. package/dist/status-njWqQWFV.d.ts +20 -0
  146. package/guidelines/AGENT_PROMPT.md +18 -3
  147. package/guidelines/Guidelines.md +3 -0
  148. package/guidelines/components/card.md +3 -3
  149. package/guidelines/components/editor.md +86 -0
  150. package/guidelines/components/feedback.md +1 -1
  151. package/guidelines/components/form.md +19 -0
  152. package/guidelines/components/navigation.md +16 -15
  153. package/guidelines/components/overlay.md +43 -4
  154. package/guidelines/components/stat.md +31 -0
  155. package/guidelines/components/time-picker.md +49 -0
  156. package/package.json +1 -1
@@ -75,6 +75,7 @@ __export(components_exports, {
75
75
  SingleDatePicker: () => SingleDatePicker_default,
76
76
  Skeleton: () => Skeleton_default,
77
77
  Spinner: () => Spinner_default,
78
+ Stat: () => Stat_default,
78
79
  Steps: () => Steps_default,
79
80
  Swiper: () => Swiper_default,
80
81
  Switch: () => Switch_default,
@@ -86,6 +87,7 @@ __export(components_exports, {
86
87
  TableRow: () => TableRow_default,
87
88
  Tag: () => Tag_default,
88
89
  TextArea: () => TextArea_default,
90
+ TimePicker: () => TimePicker_default,
89
91
  ToastProvider: () => ToastProvider,
90
92
  Tooltip: () => Tooltip_default,
91
93
  Video: () => Video_default,
@@ -1631,11 +1633,16 @@ var FieldMessage = (props) => {
1631
1633
  FieldMessage.displayName = "FieldMessage";
1632
1634
  var FieldMessage_default = FieldMessage;
1633
1635
  var Field = (props) => {
1634
- const { validations, children } = props;
1635
- if (!validations || validations.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime297.jsx)(import_jsx_runtime297.Fragment, { children });
1636
+ const { label, required = false, htmlFor, validations, children } = props;
1637
+ const hasMessages = !!validations && validations.length > 0;
1638
+ if (!label && !hasMessages) return /* @__PURE__ */ (0, import_jsx_runtime297.jsx)(import_jsx_runtime297.Fragment, { children });
1636
1639
  return /* @__PURE__ */ (0, import_jsx_runtime297.jsxs)("div", { className: "lib-xplat-field", children: [
1640
+ label && /* @__PURE__ */ (0, import_jsx_runtime297.jsxs)("label", { className: "lib-xplat-field-label", htmlFor, children: [
1641
+ label,
1642
+ required && /* @__PURE__ */ (0, import_jsx_runtime297.jsx)("span", { className: "required", "aria-hidden": "true", children: "*" })
1643
+ ] }),
1637
1644
  children,
1638
- /* @__PURE__ */ (0, import_jsx_runtime297.jsx)(FieldMessage, { validations })
1645
+ hasMessages && /* @__PURE__ */ (0, import_jsx_runtime297.jsx)(FieldMessage, { validations })
1639
1646
  ] });
1640
1647
  };
1641
1648
  Field.displayName = "Field";
@@ -1646,7 +1653,9 @@ var import_jsx_runtime298 = require("react/jsx-runtime");
1646
1653
  var MAX_HEIGHT = 400;
1647
1654
  var AutoResizeTextArea = import_react2.default.forwardRef(
1648
1655
  (props, ref) => {
1649
- const { value, className, onChange, disabled, bare = false, validations, ...textareaProps } = props;
1656
+ const { value, className, onChange, disabled, bare = false, validations, label, required, ...textareaProps } = props;
1657
+ const autoId = import_react2.default.useId();
1658
+ const fieldId = props.id ?? autoId;
1650
1659
  const localRef = import_react2.default.useRef(null);
1651
1660
  const setRefs = (el) => {
1652
1661
  localRef.current = el;
@@ -1680,6 +1689,7 @@ var AutoResizeTextArea = import_react2.default.forwardRef(
1680
1689
  "aria-invalid": hasError(validations) || void 0,
1681
1690
  ...textareaProps,
1682
1691
  ref: setRefs,
1692
+ id: fieldId,
1683
1693
  className,
1684
1694
  disabled,
1685
1695
  value,
@@ -1693,12 +1703,13 @@ var AutoResizeTextArea = import_react2.default.forwardRef(
1693
1703
  "aria-invalid": hasError(validations) || void 0,
1694
1704
  ...textareaProps,
1695
1705
  ref: setRefs,
1706
+ id: fieldId,
1696
1707
  disabled,
1697
1708
  value,
1698
1709
  onChange: handleChange
1699
1710
  }
1700
1711
  ) }) });
1701
- return /* @__PURE__ */ (0, import_jsx_runtime298.jsx)(Field, { validations, children: control });
1712
+ return /* @__PURE__ */ (0, import_jsx_runtime298.jsx)(Field, { validations, label, required, htmlFor: fieldId, children: control });
1702
1713
  }
1703
1714
  );
1704
1715
  AutoResizeTextArea.displayName = "AutoResizeTextArea";
@@ -2857,7 +2868,8 @@ var ChartLegend = ({ data, labels, type }) => {
2857
2868
  }) });
2858
2869
  };
2859
2870
  var Chart = import_react6.default.memo((props) => {
2860
- const { type, data, labels, tooltip: showTooltip = true, tooltipType = "light" } = props;
2871
+ const { variant, type, data, labels, tooltip: showTooltip = true, tooltipType = "light" } = props;
2872
+ const shape = variant ?? type ?? "line";
2861
2873
  const { tooltip, show, hide, move, containerRef } = useChartTooltip(showTooltip);
2862
2874
  const { width, height } = useChartSize(containerRef);
2863
2875
  const stableData = import_react6.default.useMemo(() => data, [JSON.stringify(data)]);
@@ -2866,11 +2878,11 @@ var Chart = import_react6.default.memo((props) => {
2866
2878
  const animate = useChartAnimation(containerRef, dataKey);
2867
2879
  const ready = width > 0 && height > 0;
2868
2880
  return /* @__PURE__ */ (0, import_jsx_runtime306.jsxs)("div", { className: "lib-xplat-chart", ref: containerRef, children: [
2869
- ready && type === "line" && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2870
- ready && type === "curve" && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2871
- ready && type === "bar" && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2872
- ready && type === "pie" && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2873
- ready && type === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
2881
+ ready && shape === "line" && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(LineChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2882
+ ready && shape === "curve" && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(CurveChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2883
+ ready && shape === "bar" && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(BarChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2884
+ ready && shape === "pie" && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, onHover: show, onMove: move, onLeave: hide }),
2885
+ ready && shape === "doughnut" && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(PieDonutChart, { data: stableData, labels: stableLabels, width, height, animate, isDoughnut: true, onHover: show, onMove: move, onLeave: hide }),
2874
2886
  ready && (type === "pie" || type === "doughnut") && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(ChartLegend, { data: stableData, labels: stableLabels, type }),
2875
2887
  tooltip.visible && tooltip.content && /* @__PURE__ */ (0, import_jsx_runtime306.jsx)(ChartTooltip, { x: tooltip.x, y: tooltip.y, containerWidth: width, containerHeight: height, tooltipType, children: tooltip.content })
2876
2888
  ] });
@@ -2915,8 +2927,11 @@ var ChatInput = import_react7.default.forwardRef(
2915
2927
  buttonType = "primary",
2916
2928
  onSubmit,
2917
2929
  onChange,
2918
- validations
2930
+ validations,
2931
+ label,
2932
+ required
2919
2933
  } = props;
2934
+ const fieldId = import_react7.default.useId();
2920
2935
  const isControlled = valueProp !== void 0;
2921
2936
  const [internalValue, setInternalValue] = import_react7.default.useState("");
2922
2937
  const value = isControlled ? valueProp : internalValue;
@@ -2941,6 +2956,7 @@ var ChatInput = import_react7.default.forwardRef(
2941
2956
  /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(
2942
2957
  AutoResizeTextArea_default,
2943
2958
  {
2959
+ id: fieldId,
2944
2960
  ref,
2945
2961
  bare: true,
2946
2962
  className: "chat-input-textarea",
@@ -2965,7 +2981,7 @@ var ChatInput = import_react7.default.forwardRef(
2965
2981
  }
2966
2982
  )
2967
2983
  ] });
2968
- return /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(Field, { validations, children: control });
2984
+ return /* @__PURE__ */ (0, import_jsx_runtime308.jsx)(Field, { validations, label, required, htmlFor: fieldId, children: control });
2969
2985
  }
2970
2986
  );
2971
2987
  ChatInput.displayName = "ChatInput";
@@ -2977,6 +2993,9 @@ var import_tokens_core = require("@x-plat/tokens-core");
2977
2993
  // src/tokens/index.ts
2978
2994
  var import_tokens_core2 = require("@x-plat/tokens-core");
2979
2995
 
2996
+ // src/tokens/interface/status.ts
2997
+ var normalizeStatus = (value) => value === "brand" ? "primary" : value;
2998
+
2980
2999
  // src/components/CheckBox/CheckBox.tsx
2981
3000
  var import_jsx_runtime309 = require("react/jsx-runtime");
2982
3001
  var CheckBox = (props) => {
@@ -2987,10 +3006,11 @@ var CheckBox = (props) => {
2987
3006
  onChange,
2988
3007
  disabled,
2989
3008
  size = "md",
2990
- type = "brand",
3009
+ type = "primary",
2991
3010
  validations,
2992
3011
  ...rest
2993
3012
  } = props;
3013
+ const statusType = normalizeStatus(type);
2994
3014
  const handleChange = (e) => {
2995
3015
  if (onChange) onChange(e);
2996
3016
  };
@@ -2998,7 +3018,7 @@ var CheckBox = (props) => {
2998
3018
  const checkedClasses = `checked`;
2999
3019
  const disabledClasses = "disabled";
3000
3020
  const boxClasses = disabled ? disabledClasses : checked ? checkedClasses : uncheckedClasses;
3001
- const control = /* @__PURE__ */ (0, import_jsx_runtime309.jsxs)("label", { className: clsx_default("lib-xplat-checkbox", size, type, className), children: [
3021
+ const control = /* @__PURE__ */ (0, import_jsx_runtime309.jsxs)("label", { className: clsx_default("lib-xplat-checkbox", size, statusType, className), children: [
3002
3022
  /* @__PURE__ */ (0, import_jsx_runtime309.jsx)(
3003
3023
  "input",
3004
3024
  {
@@ -3032,7 +3052,7 @@ Chip.displayName = "Chip";
3032
3052
  var Chip_default = Chip;
3033
3053
 
3034
3054
  // src/components/DatePicker/InputDatePicker/index.tsx
3035
- var import_react12 = __toESM(require("react"), 1);
3055
+ var import_react13 = __toESM(require("react"), 1);
3036
3056
 
3037
3057
  // src/components/Input/Input.tsx
3038
3058
  var import_react8 = __toESM(require("react"), 1);
@@ -3130,8 +3150,12 @@ var Input = import_react8.default.forwardRef((props, ref) => {
3130
3150
  suffix,
3131
3151
  disabled,
3132
3152
  validations,
3153
+ label,
3154
+ required,
3133
3155
  ...inputProps
3134
3156
  } = props;
3157
+ const autoId = import_react8.default.useId();
3158
+ const fieldId = inputProps.id ?? autoId;
3135
3159
  const localValue = formatValue(type, value);
3136
3160
  const handleChange = (e) => {
3137
3161
  let val = e.target.value;
@@ -3147,7 +3171,7 @@ var Input = import_react8.default.forwardRef((props, ref) => {
3147
3171
  onChange(event);
3148
3172
  }
3149
3173
  };
3150
- return /* @__PURE__ */ (0, import_jsx_runtime311.jsxs)("div", { className: clsx_default("lib-xplat-input-wrap", className), children: [
3174
+ return /* @__PURE__ */ (0, import_jsx_runtime311.jsx)(Field, { label, required, htmlFor: fieldId, children: /* @__PURE__ */ (0, import_jsx_runtime311.jsxs)("div", { className: clsx_default("lib-xplat-input-wrap", className), children: [
3151
3175
  /* @__PURE__ */ (0, import_jsx_runtime311.jsxs)(
3152
3176
  "div",
3153
3177
  {
@@ -3158,6 +3182,7 @@ var Input = import_react8.default.forwardRef((props, ref) => {
3158
3182
  {
3159
3183
  ...inputProps,
3160
3184
  ref,
3185
+ id: fieldId,
3161
3186
  disabled,
3162
3187
  type: type === "number" ? "text" : type,
3163
3188
  value: localValue,
@@ -3170,7 +3195,7 @@ var Input = import_react8.default.forwardRef((props, ref) => {
3170
3195
  }
3171
3196
  ),
3172
3197
  /* @__PURE__ */ (0, import_jsx_runtime311.jsx)(FieldMessage_default, { validations })
3173
- ] });
3198
+ ] }) });
3174
3199
  });
3175
3200
  Input.displayName = "Input";
3176
3201
  var Input_default = Input;
@@ -3200,16 +3225,96 @@ PasswordInput.displayName = "PasswordInput";
3200
3225
  var PasswordInput_default = PasswordInput;
3201
3226
 
3202
3227
  // src/components/Modal/Modal.tsx
3203
- var import_react10 = __toESM(require("react"), 1);
3228
+ var import_react11 = __toESM(require("react"), 1);
3204
3229
  var import_react_dom = require("react-dom");
3230
+
3231
+ // src/tokens/hooks/useOverlayKeyboard.ts
3232
+ var import_react10 = __toESM(require("react"), 1);
3233
+ var FOCUSABLE = [
3234
+ "a[href]",
3235
+ "button:not([disabled])",
3236
+ "input:not([disabled]):not([type='hidden'])",
3237
+ "select:not([disabled])",
3238
+ "textarea:not([disabled])",
3239
+ "[tabindex]:not([tabindex='-1'])"
3240
+ ].join(",");
3241
+ var focusableIn = (el) => Array.from(el.querySelectorAll(FOCUSABLE)).filter(
3242
+ // 화면에 없는 것은 제외 (display:none 등)
3243
+ (n) => n.offsetWidth > 0 || n.offsetHeight > 0 || n === document.activeElement
3244
+ );
3245
+ var useEscapeKey = (enabled, onEscape) => {
3246
+ import_react10.default.useEffect(() => {
3247
+ if (!enabled) return;
3248
+ const onKey = (e) => {
3249
+ if (e.key !== "Escape") return;
3250
+ if (e.defaultPrevented) return;
3251
+ e.preventDefault();
3252
+ onEscape();
3253
+ };
3254
+ document.addEventListener("keydown", onKey);
3255
+ return () => document.removeEventListener("keydown", onKey);
3256
+ }, [enabled, onEscape]);
3257
+ };
3258
+ var useFocusTrap = (containerRef, enabled, options = {}) => {
3259
+ const { trap = false, initialFocus } = options;
3260
+ const restoreRef = import_react10.default.useRef(null);
3261
+ import_react10.default.useEffect(() => {
3262
+ if (!enabled) return;
3263
+ restoreRef.current = document.activeElement;
3264
+ const raf = requestAnimationFrame(() => {
3265
+ const el = containerRef.current;
3266
+ if (!el) return;
3267
+ const target = initialFocus?.current ?? focusableIn(el)[0] ?? el;
3268
+ if (!target.hasAttribute("tabindex") && !focusableIn(el).includes(target)) {
3269
+ target.setAttribute("tabindex", "-1");
3270
+ }
3271
+ target.focus({ preventScroll: true });
3272
+ });
3273
+ return () => {
3274
+ cancelAnimationFrame(raf);
3275
+ const prev = restoreRef.current;
3276
+ if (prev && document.contains(prev)) prev.focus({ preventScroll: true });
3277
+ };
3278
+ }, [enabled, containerRef, initialFocus]);
3279
+ import_react10.default.useEffect(() => {
3280
+ if (!enabled || !trap) return;
3281
+ const onKey = (e) => {
3282
+ if (e.key !== "Tab") return;
3283
+ const el = containerRef.current;
3284
+ if (!el) return;
3285
+ const items = focusableIn(el);
3286
+ if (items.length === 0) {
3287
+ e.preventDefault();
3288
+ return;
3289
+ }
3290
+ const first = items[0];
3291
+ const last = items[items.length - 1];
3292
+ const active = document.activeElement;
3293
+ if (e.shiftKey && (active === first || !el.contains(active))) {
3294
+ e.preventDefault();
3295
+ last.focus();
3296
+ } else if (!e.shiftKey && (active === last || !el.contains(active))) {
3297
+ e.preventDefault();
3298
+ first.focus();
3299
+ }
3300
+ };
3301
+ document.addEventListener("keydown", onKey);
3302
+ return () => document.removeEventListener("keydown", onKey);
3303
+ }, [enabled, trap, containerRef]);
3304
+ };
3305
+
3306
+ // src/components/Modal/Modal.tsx
3205
3307
  var import_jsx_runtime313 = require("react/jsx-runtime");
3206
3308
  var ANIMATION_DURATION_MS = 200;
3207
3309
  var Modal = (props) => {
3208
3310
  const { isOpen, onClose, children } = props;
3209
- const [mounted, setMounted] = import_react10.default.useState(false);
3210
- const [visible, setVisible] = import_react10.default.useState(false);
3211
- const [settled, setSettled] = import_react10.default.useState(false);
3212
- import_react10.default.useEffect(() => {
3311
+ const [mounted, setMounted] = import_react11.default.useState(false);
3312
+ const [visible, setVisible] = import_react11.default.useState(false);
3313
+ const [settled, setSettled] = import_react11.default.useState(false);
3314
+ const boxRef = import_react11.default.useRef(null);
3315
+ useEscapeKey(isOpen, onClose);
3316
+ useFocusTrap(boxRef, isOpen && mounted, { trap: true });
3317
+ import_react11.default.useEffect(() => {
3213
3318
  if (isOpen) {
3214
3319
  setMounted(true);
3215
3320
  const show = setTimeout(() => setVisible(true), 1);
@@ -3236,6 +3341,7 @@ var Modal = (props) => {
3236
3341
  children: /* @__PURE__ */ (0, import_jsx_runtime313.jsx)(
3237
3342
  "div",
3238
3343
  {
3344
+ ref: boxRef,
3239
3345
  className: clsx_default("lib-xplat-modal", "modal-box", stateClass, settled && "settled"),
3240
3346
  role: "dialog",
3241
3347
  "aria-modal": "true",
@@ -3252,9 +3358,9 @@ Modal.displayName = "Modal";
3252
3358
  var Modal_default = Modal;
3253
3359
 
3254
3360
  // src/components/DatePicker/SingleDatePicker/index.tsx
3255
- var import_react11 = __toESM(require("react"), 1);
3361
+ var import_react12 = __toESM(require("react"), 1);
3256
3362
  var import_jsx_runtime314 = require("react/jsx-runtime");
3257
- var DayCell2 = import_react11.default.memo(
3363
+ var DayCell2 = import_react12.default.memo(
3258
3364
  ({
3259
3365
  day,
3260
3366
  disabled,
@@ -3306,26 +3412,26 @@ var SingleDatePicker = (props) => {
3306
3412
  initialYear,
3307
3413
  initialMonth
3308
3414
  );
3309
- const [pickerMode, setPickerMode] = import_react11.default.useState("days");
3310
- const [yearRangeStart, setYearRangeStart] = import_react11.default.useState(
3415
+ const [pickerMode, setPickerMode] = import_react12.default.useState("days");
3416
+ const [yearRangeStart, setYearRangeStart] = import_react12.default.useState(
3311
3417
  Math.floor((initialYear ?? (/* @__PURE__ */ new Date()).getFullYear()) / 12) * 12
3312
3418
  );
3313
- const minTime = import_react11.default.useMemo(
3419
+ const minTime = import_react12.default.useMemo(
3314
3420
  () => minDate ? new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()).getTime() : -Infinity,
3315
3421
  [minDate]
3316
3422
  );
3317
- const maxTime = import_react11.default.useMemo(
3423
+ const maxTime = import_react12.default.useMemo(
3318
3424
  () => maxDate ? new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate()).getTime() : Infinity,
3319
3425
  [maxDate]
3320
3426
  );
3321
- const highlightSet = import_react11.default.useMemo(() => {
3427
+ const highlightSet = import_react12.default.useMemo(() => {
3322
3428
  const set = /* @__PURE__ */ new Set();
3323
3429
  for (const h of highlightDates) {
3324
3430
  set.add(`${h.getFullYear()}-${h.getMonth()}-${h.getDate()}`);
3325
3431
  }
3326
3432
  return set;
3327
3433
  }, [highlightDates]);
3328
- const handleSelect = import_react11.default.useCallback(
3434
+ const handleSelect = import_react12.default.useCallback(
3329
3435
  (date) => {
3330
3436
  onChange?.(date);
3331
3437
  },
@@ -3454,8 +3560,8 @@ var formatDate = (date) => {
3454
3560
  };
3455
3561
  var InputDatePicker = (props) => {
3456
3562
  const { value, onChange, minDate, maxDate, disabled, locale = "ko", placeholder } = props;
3457
- const [isOpen, setIsOpen] = import_react12.default.useState(false);
3458
- const [tempDate, setTempDate] = import_react12.default.useState(value ?? /* @__PURE__ */ new Date());
3563
+ const [isOpen, setIsOpen] = import_react13.default.useState(false);
3564
+ const [tempDate, setTempDate] = import_react13.default.useState(value ?? /* @__PURE__ */ new Date());
3459
3565
  const handleOpen = () => {
3460
3566
  if (disabled) return;
3461
3567
  setTempDate(value ?? /* @__PURE__ */ new Date());
@@ -3504,23 +3610,27 @@ InputDatePicker.displayName = "InputDatePicker";
3504
3610
  var InputDatePicker_default = InputDatePicker;
3505
3611
 
3506
3612
  // src/components/DatePicker/PopupPicker/index.tsx
3507
- var import_react16 = __toESM(require("react"), 1);
3613
+ var import_react17 = __toESM(require("react"), 1);
3508
3614
 
3509
3615
  // src/components/DatePicker/RangePicker/index.tsx
3510
- var import_react15 = __toESM(require("react"), 1);
3616
+ var import_react16 = __toESM(require("react"), 1);
3511
3617
 
3512
3618
  // src/components/Tab/Tab.tsx
3513
- var import_react14 = __toESM(require("react"), 1);
3619
+ var import_react15 = __toESM(require("react"), 1);
3514
3620
 
3515
3621
  // src/components/Tab/TabItem.tsx
3516
- var import_react13 = __toESM(require("react"), 1);
3622
+ var import_react14 = __toESM(require("react"), 1);
3517
3623
  var import_jsx_runtime316 = require("react/jsx-runtime");
3518
- var TabItem = import_react13.default.forwardRef((props, ref) => {
3624
+ var TabItem = import_react14.default.forwardRef((props, ref) => {
3519
3625
  const { isActive: isActive2, title, onClick } = props;
3520
3626
  return /* @__PURE__ */ (0, import_jsx_runtime316.jsx)(
3521
- "div",
3627
+ "button",
3522
3628
  {
3523
3629
  ref,
3630
+ type: "button",
3631
+ role: "tab",
3632
+ "aria-selected": isActive2,
3633
+ tabIndex: isActive2 ? 0 : -1,
3524
3634
  className: clsx_default("tab-item", isActive2 ? "active" : null),
3525
3635
  onClick,
3526
3636
  children: title
@@ -3533,45 +3643,66 @@ var TabItem_default = TabItem;
3533
3643
  // src/components/Tab/Tab.tsx
3534
3644
  var import_jsx_runtime317 = require("react/jsx-runtime");
3535
3645
  var Tab = (props) => {
3536
- const { activeIndex, onChange, tabs, type, size = "md" } = props;
3537
- const [underlineStyle, setUnderlineStyle] = import_react14.default.useState({
3646
+ const { activeIndex, onChange, tabs, variant, type, size = "md" } = props;
3647
+ const shape = variant ?? type ?? "default";
3648
+ const [underlineStyle, setUnderlineStyle] = import_react15.default.useState({
3538
3649
  left: 0,
3539
3650
  width: 0
3540
3651
  });
3541
- const itemRefs = import_react14.default.useRef([]);
3652
+ const itemRefs = import_react15.default.useRef([]);
3653
+ const handleKeyDown = (e) => {
3654
+ const last = tabs.length - 1;
3655
+ let next = null;
3656
+ if (e.key === "ArrowRight") next = activeIndex >= last ? 0 : activeIndex + 1;
3657
+ else if (e.key === "ArrowLeft") next = activeIndex <= 0 ? last : activeIndex - 1;
3658
+ else if (e.key === "Home") next = 0;
3659
+ else if (e.key === "End") next = last;
3660
+ if (next === null) return;
3661
+ e.preventDefault();
3662
+ onChange(tabs[next], next);
3663
+ itemRefs.current[next]?.focus();
3664
+ };
3542
3665
  const handleChangeActiveTab = (tabItem, tabIdx) => {
3543
3666
  onChange(tabItem, tabIdx);
3544
3667
  };
3545
- import_react14.default.useEffect(() => {
3668
+ import_react15.default.useEffect(() => {
3546
3669
  const el = itemRefs.current[activeIndex];
3547
3670
  if (el) {
3548
3671
  setUnderlineStyle({ left: el.offsetLeft, width: el.offsetWidth });
3549
3672
  }
3550
3673
  }, [activeIndex, tabs.length]);
3551
- return /* @__PURE__ */ (0, import_jsx_runtime317.jsxs)("div", { className: clsx_default("lib-xplat-tab", `type-${type}`, size), children: [
3552
- tabs.map((tab, idx) => /* @__PURE__ */ (0, import_jsx_runtime317.jsx)(
3553
- TabItem_default,
3554
- {
3555
- onClick: () => handleChangeActiveTab(tab, idx),
3556
- isActive: activeIndex === idx,
3557
- ref: (el) => {
3558
- itemRefs.current[idx] = el;
3559
- },
3560
- title: tab.title
3561
- },
3562
- `${tab.value}_${idx}`
3563
- )),
3564
- type === "toggle" && /* @__PURE__ */ (0, import_jsx_runtime317.jsx)(
3565
- "div",
3566
- {
3567
- className: "tab-toggle-underline",
3568
- style: {
3569
- left: underlineStyle.left,
3570
- width: underlineStyle.width
3571
- }
3572
- }
3573
- )
3574
- ] });
3674
+ return /* @__PURE__ */ (0, import_jsx_runtime317.jsxs)(
3675
+ "div",
3676
+ {
3677
+ className: clsx_default("lib-xplat-tab", `type-${shape}`, size),
3678
+ role: "tablist",
3679
+ onKeyDown: handleKeyDown,
3680
+ children: [
3681
+ tabs.map((tab, idx) => /* @__PURE__ */ (0, import_jsx_runtime317.jsx)(
3682
+ TabItem_default,
3683
+ {
3684
+ onClick: () => handleChangeActiveTab(tab, idx),
3685
+ isActive: activeIndex === idx,
3686
+ ref: (el) => {
3687
+ itemRefs.current[idx] = el;
3688
+ },
3689
+ title: tab.title
3690
+ },
3691
+ `${tab.value}_${idx}`
3692
+ )),
3693
+ shape === "toggle" && /* @__PURE__ */ (0, import_jsx_runtime317.jsx)(
3694
+ "div",
3695
+ {
3696
+ className: "tab-toggle-underline",
3697
+ style: {
3698
+ left: underlineStyle.left,
3699
+ width: underlineStyle.width
3700
+ }
3701
+ }
3702
+ )
3703
+ ]
3704
+ }
3705
+ );
3575
3706
  };
3576
3707
  Tab.displayName = "Tab";
3577
3708
  var Tab_default = Tab;
@@ -3587,7 +3718,7 @@ var RangePicker = (props) => {
3587
3718
  maxDate,
3588
3719
  locale = "ko"
3589
3720
  } = props;
3590
- const [activeTab, setActiveTab] = import_react15.default.useState("start");
3721
+ const [activeTab, setActiveTab] = import_react16.default.useState("start");
3591
3722
  const handleStartChange = (date) => {
3592
3723
  if (!date) return;
3593
3724
  const newStart = date > endDate ? endDate : date;
@@ -3672,7 +3803,7 @@ var RangePicker_default = RangePicker;
3672
3803
  var import_jsx_runtime319 = require("react/jsx-runtime");
3673
3804
  var PopupPicker = (props) => {
3674
3805
  const { component, type, locale } = props;
3675
- const [isOpen, setIsOpen] = import_react16.default.useState(false);
3806
+ const [isOpen, setIsOpen] = import_react17.default.useState(false);
3676
3807
  const handleClick = () => setIsOpen(true);
3677
3808
  const handleClose = () => setIsOpen(false);
3678
3809
  const handleSingleChange = (date) => {
@@ -3681,7 +3812,7 @@ var PopupPicker = (props) => {
3681
3812
  handleClose();
3682
3813
  };
3683
3814
  return /* @__PURE__ */ (0, import_jsx_runtime319.jsxs)("div", { className: "lib-xplat-popup-datepicker", children: [
3684
- import_react16.default.cloneElement(component, { onClick: handleClick }),
3815
+ import_react17.default.cloneElement(component, { onClick: handleClick }),
3685
3816
  /* @__PURE__ */ (0, import_jsx_runtime319.jsx)(Modal_default, { isOpen, onClose: handleClose, children: /* @__PURE__ */ (0, import_jsx_runtime319.jsxs)("div", { className: clsx_default("lib-xplat-popup-datepicker-card", type === "range" && "range-mode"), children: [
3686
3817
  /* @__PURE__ */ (0, import_jsx_runtime319.jsxs)("div", { className: "popup-datepicker-content", children: [
3687
3818
  type === "single" && /* @__PURE__ */ (0, import_jsx_runtime319.jsx)(
@@ -3740,15 +3871,18 @@ Divider.displayName = "Divider";
3740
3871
  var Divider_default = Divider;
3741
3872
 
3742
3873
  // src/components/Drawer/Drawer.tsx
3743
- var import_react17 = __toESM(require("react"), 1);
3874
+ var import_react18 = __toESM(require("react"), 1);
3744
3875
  var import_react_dom2 = require("react-dom");
3745
3876
  var import_jsx_runtime321 = require("react/jsx-runtime");
3746
3877
  var ANIMATION_DURATION_MS2 = 250;
3747
3878
  var Drawer = (props) => {
3748
3879
  const { isOpen, onClose, placement = "right", size = "md", title, children } = props;
3749
- const [mounted, setMounted] = import_react17.default.useState(false);
3750
- const [visible, setVisible] = import_react17.default.useState(false);
3751
- import_react17.default.useEffect(() => {
3880
+ const [mounted, setMounted] = import_react18.default.useState(false);
3881
+ const [visible, setVisible] = import_react18.default.useState(false);
3882
+ const panelRef = import_react18.default.useRef(null);
3883
+ useEscapeKey(isOpen, onClose);
3884
+ useFocusTrap(panelRef, isOpen && mounted, { trap: true });
3885
+ import_react18.default.useEffect(() => {
3752
3886
  if (isOpen) {
3753
3887
  setMounted(true);
3754
3888
  const t2 = setTimeout(() => setVisible(true), 1);
@@ -3770,6 +3904,7 @@ var Drawer = (props) => {
3770
3904
  children: /* @__PURE__ */ (0, import_jsx_runtime321.jsxs)(
3771
3905
  "div",
3772
3906
  {
3907
+ ref: panelRef,
3773
3908
  className: clsx_default("lib-xplat-drawer", placement, size, stateClass),
3774
3909
  role: "dialog",
3775
3910
  "aria-modal": "true",
@@ -3792,7 +3927,7 @@ Drawer.displayName = "Drawer";
3792
3927
  var Drawer_default = Drawer;
3793
3928
 
3794
3929
  // src/components/Dropdown/Dropdown.tsx
3795
- var import_react20 = __toESM(require("react"), 1);
3930
+ var import_react21 = __toESM(require("react"), 1);
3796
3931
 
3797
3932
  // src/tokens/hooks/Portal.tsx
3798
3933
  var import_react_dom3 = __toESM(require("react-dom"), 1);
@@ -3804,13 +3939,13 @@ Portal.displayName = "Portal";
3804
3939
  var Portal_default = Portal;
3805
3940
 
3806
3941
  // src/tokens/hooks/useAutoPosition.ts
3807
- var import_react18 = __toESM(require("react"), 1);
3942
+ var import_react19 = __toESM(require("react"), 1);
3808
3943
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3809
- const [position, setPosition] = import_react18.default.useState({
3944
+ const [position, setPosition] = import_react19.default.useState({
3810
3945
  position: {},
3811
3946
  direction: "bottom"
3812
3947
  });
3813
- const calculatePosition = import_react18.default.useCallback(() => {
3948
+ const calculatePosition = import_react19.default.useCallback(() => {
3814
3949
  if (!triggerRef.current || !popRef.current) return;
3815
3950
  const triggerRect = triggerRef.current.getBoundingClientRect();
3816
3951
  const popW = popRef.current.offsetWidth;
@@ -3837,13 +3972,13 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3837
3972
  direction
3838
3973
  });
3839
3974
  }, [triggerRef, popRef]);
3840
- import_react18.default.useLayoutEffect(() => {
3975
+ import_react19.default.useLayoutEffect(() => {
3841
3976
  if (!enabled) return;
3842
3977
  calculatePosition();
3843
3978
  const raf = requestAnimationFrame(calculatePosition);
3844
3979
  return () => cancelAnimationFrame(raf);
3845
3980
  }, [calculatePosition, enabled]);
3846
- import_react18.default.useEffect(() => {
3981
+ import_react19.default.useEffect(() => {
3847
3982
  if (!enabled || !popRef.current) return;
3848
3983
  const observer = new ResizeObserver(() => {
3849
3984
  calculatePosition();
@@ -3851,7 +3986,7 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3851
3986
  observer.observe(popRef.current);
3852
3987
  return () => observer.disconnect();
3853
3988
  }, [calculatePosition, enabled, popRef]);
3854
- import_react18.default.useEffect(() => {
3989
+ import_react19.default.useEffect(() => {
3855
3990
  if (!enabled) return;
3856
3991
  window.addEventListener("resize", calculatePosition);
3857
3992
  window.addEventListener("scroll", calculatePosition, true);
@@ -3865,9 +4000,9 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3865
4000
  var useAutoPosition_default = useAutoPosition;
3866
4001
 
3867
4002
  // src/tokens/hooks/useClickOutside.ts
3868
- var import_react19 = __toESM(require("react"), 1);
4003
+ var import_react20 = __toESM(require("react"), 1);
3869
4004
  var useClickOutside = (refs, handler, enabled = true) => {
3870
- import_react19.default.useEffect(() => {
4005
+ import_react20.default.useEffect(() => {
3871
4006
  if (!enabled) return;
3872
4007
  const refArray = Array.isArray(refs) ? refs : [refs];
3873
4008
  const listener = (event) => {
@@ -3893,14 +4028,18 @@ var useClickOutside_default = useClickOutside;
3893
4028
  var import_jsx_runtime322 = require("react/jsx-runtime");
3894
4029
  var Dropdown = (props) => {
3895
4030
  const { items, children } = props;
3896
- const [isOpen, setIsOpen] = import_react20.default.useState(false);
3897
- const [mounted, setMounted] = import_react20.default.useState(false);
3898
- const [visible, setVisible] = import_react20.default.useState(false);
3899
- const triggerRef = import_react20.default.useRef(null);
3900
- const menuRef = import_react20.default.useRef(null);
4031
+ const [isOpen, setIsOpen] = import_react21.default.useState(false);
4032
+ const [mounted, setMounted] = import_react21.default.useState(false);
4033
+ const [visible, setVisible] = import_react21.default.useState(false);
4034
+ const triggerRef = import_react21.default.useRef(null);
4035
+ const menuRef = import_react21.default.useRef(null);
3901
4036
  const { position, direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
3902
4037
  useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
3903
- import_react20.default.useEffect(() => {
4038
+ useEscapeKey(isOpen, () => {
4039
+ setIsOpen(false);
4040
+ triggerRef.current?.focus({ preventScroll: true });
4041
+ });
4042
+ import_react21.default.useEffect(() => {
3904
4043
  if (isOpen) {
3905
4044
  setMounted(true);
3906
4045
  const t2 = setTimeout(() => setVisible(true), 1);
@@ -3954,7 +4093,7 @@ Dropdown.displayName = "Dropdown";
3954
4093
  var Dropdown_default = Dropdown;
3955
4094
 
3956
4095
  // src/components/Editor/Editor.tsx
3957
- var import_react21 = __toESM(require("react"), 1);
4096
+ var import_react22 = __toESM(require("react"), 1);
3958
4097
  var import_jsx_runtime323 = require("react/jsx-runtime");
3959
4098
  var DEFAULT_TOOLBAR = [
3960
4099
  "bold",
@@ -4004,6 +4143,15 @@ var ALLOWED_ATTRS = {
4004
4143
  a: ["href", "target", "rel"],
4005
4144
  img: ["src", "alt"]
4006
4145
  };
4146
+ var DROP_WITH_CONTENT = /* @__PURE__ */ new Set([
4147
+ "script",
4148
+ "style",
4149
+ "noscript",
4150
+ "iframe",
4151
+ "object",
4152
+ "embed",
4153
+ "template"
4154
+ ]);
4007
4155
  var sanitizeHtml = (input) => {
4008
4156
  const doc = new DOMParser().parseFromString(`<div>${input}</div>`, "text/html");
4009
4157
  const root = doc.body.firstElementChild;
@@ -4012,6 +4160,10 @@ var sanitizeHtml = (input) => {
4012
4160
  const children = Array.from(node.children);
4013
4161
  for (const child of children) {
4014
4162
  const tag = child.tagName.toLowerCase();
4163
+ if (DROP_WITH_CONTENT.has(tag)) {
4164
+ node.removeChild(child);
4165
+ continue;
4166
+ }
4015
4167
  if (!ALLOWED_TAGS.has(tag)) {
4016
4168
  while (child.firstChild) node.insertBefore(child.firstChild, child);
4017
4169
  node.removeChild(child);
@@ -4062,26 +4214,30 @@ var Editor = (props) => {
4062
4214
  onImageUpload,
4063
4215
  minHeight = 200
4064
4216
  } = props;
4065
- const editorRef = import_react21.default.useRef(null);
4066
- const lastRangeRef = import_react21.default.useRef(null);
4067
- const composingRef = import_react21.default.useRef(false);
4068
- const [isFocused, setIsFocused] = import_react21.default.useState(false);
4069
- const [isEmpty, setIsEmpty] = import_react21.default.useState(!value);
4070
- const [activeFormats, setActiveFormats] = import_react21.default.useState(/* @__PURE__ */ new Set());
4071
- const [slashOpen, setSlashOpen] = import_react21.default.useState(false);
4072
- const [slashFilter, setSlashFilter] = import_react21.default.useState("");
4073
- const [slashIdx, setSlashIdx] = import_react21.default.useState(0);
4074
- const [slashPos, setSlashPos] = import_react21.default.useState({ top: 0, left: 0 });
4075
- const slashStartRangeRef = import_react21.default.useRef(null);
4076
- const [linkOpen, setLinkOpen] = import_react21.default.useState(false);
4077
- const [linkValue, setLinkValue] = import_react21.default.useState("");
4078
- const [linkPos, setLinkPos] = import_react21.default.useState({ top: 0, left: 0 });
4079
- import_react21.default.useEffect(() => {
4080
- if (!editorRef.current) return;
4081
- if (editorRef.current.innerHTML !== value) {
4082
- editorRef.current.innerHTML = sanitizeHtml(value || "");
4083
- updateEmpty();
4084
- }
4217
+ const editorRef = import_react22.default.useRef(null);
4218
+ const lastRangeRef = import_react22.default.useRef(null);
4219
+ const composingRef = import_react22.default.useRef(false);
4220
+ const [isFocused, setIsFocused] = import_react22.default.useState(false);
4221
+ const [isEmpty, setIsEmpty] = import_react22.default.useState(!value);
4222
+ const [activeFormats, setActiveFormats] = import_react22.default.useState(/* @__PURE__ */ new Set());
4223
+ const [slashOpen, setSlashOpen] = import_react22.default.useState(false);
4224
+ const [slashFilter, setSlashFilter] = import_react22.default.useState("");
4225
+ const [slashIdx, setSlashIdx] = import_react22.default.useState(0);
4226
+ const [slashPos, setSlashPos] = import_react22.default.useState({ top: 0, left: 0 });
4227
+ const slashStartRangeRef = import_react22.default.useRef(null);
4228
+ const [linkOpen, setLinkOpen] = import_react22.default.useState(false);
4229
+ const [linkValue, setLinkValue] = import_react22.default.useState("");
4230
+ const [linkPos, setLinkPos] = import_react22.default.useState({ top: 0, left: 0 });
4231
+ const lastEmittedRef = import_react22.default.useRef(null);
4232
+ import_react22.default.useEffect(() => {
4233
+ const el = editorRef.current;
4234
+ if (!el) return;
4235
+ if (value === lastEmittedRef.current) return;
4236
+ if (el.innerHTML === value) return;
4237
+ el.innerHTML = sanitizeHtml(value || "");
4238
+ if (!el.firstChild) el.innerHTML = "<p><br></p>";
4239
+ lastEmittedRef.current = null;
4240
+ updateEmpty();
4085
4241
  }, [value]);
4086
4242
  const updateEmpty = () => {
4087
4243
  const el = editorRef.current;
@@ -4097,10 +4253,19 @@ var Editor = (props) => {
4097
4253
  }
4098
4254
  };
4099
4255
  const restoreSelection = () => {
4100
- if (!lastRangeRef.current) return;
4256
+ const range = lastRangeRef.current;
4257
+ if (!range) return;
4258
+ if (!editorRef.current?.contains(range.startContainer)) {
4259
+ lastRangeRef.current = null;
4260
+ return;
4261
+ }
4101
4262
  const sel = window.getSelection();
4102
- sel?.removeAllRanges();
4103
- sel?.addRange(lastRangeRef.current);
4263
+ try {
4264
+ sel?.removeAllRanges();
4265
+ sel?.addRange(range);
4266
+ } catch {
4267
+ lastRangeRef.current = null;
4268
+ }
4104
4269
  };
4105
4270
  const updateActiveFormats = () => {
4106
4271
  if (!editorRef.current) return;
@@ -4129,6 +4294,96 @@ var Editor = (props) => {
4129
4294
  const setBlock = (tag) => {
4130
4295
  exec("formatBlock", tag);
4131
4296
  };
4297
+ const closestPre = () => {
4298
+ const sel = window.getSelection();
4299
+ const node = sel?.anchorNode;
4300
+ if (!node || !editorRef.current?.contains(node)) return null;
4301
+ const el = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
4302
+ return el?.closest("pre") ?? null;
4303
+ };
4304
+ const insertCodeBlock = () => {
4305
+ const el = editorRef.current;
4306
+ const sel = window.getSelection();
4307
+ if (!el || !sel || sel.rangeCount === 0) return;
4308
+ const existing = closestPre();
4309
+ if (existing) {
4310
+ const p = document.createElement("p");
4311
+ p.textContent = existing.textContent || "";
4312
+ if (!p.textContent) p.innerHTML = "<br>";
4313
+ existing.replaceWith(p);
4314
+ placeCaretAtEnd(p);
4315
+ handleInput();
4316
+ return;
4317
+ }
4318
+ const range = sel.getRangeAt(0);
4319
+ const frag = range.cloneContents();
4320
+ const holder = document.createElement("div");
4321
+ holder.appendChild(frag);
4322
+ const BLOCK = /^(p|div|h[1-6]|li|blockquote|pre|tr)$/i;
4323
+ const linesOf = (node) => {
4324
+ const out = [];
4325
+ let cur = "";
4326
+ for (const child of Array.from(node.childNodes)) {
4327
+ if (child.nodeType === Node.TEXT_NODE) {
4328
+ cur += child.textContent || "";
4329
+ } else if (child.nodeName === "BR") {
4330
+ out.push(cur);
4331
+ cur = "";
4332
+ } else if (BLOCK.test(child.nodeName)) {
4333
+ if (cur) {
4334
+ out.push(cur);
4335
+ cur = "";
4336
+ }
4337
+ const sub = linesOf(child);
4338
+ out.push(...sub.length > 0 ? sub : [""]);
4339
+ } else {
4340
+ cur += linesOf(child).join("\n");
4341
+ }
4342
+ }
4343
+ if (cur) out.push(cur);
4344
+ return out;
4345
+ };
4346
+ const text = linesOf(holder).join("\n").replace(/\n+$/, "");
4347
+ const pre = document.createElement("pre");
4348
+ const code = document.createElement("code");
4349
+ code.textContent = text || "";
4350
+ pre.appendChild(code);
4351
+ range.deleteContents();
4352
+ range.insertNode(pre);
4353
+ ensureParagraphAfter(pre);
4354
+ placeCaretAtEnd(code);
4355
+ handleInput();
4356
+ };
4357
+ const insertTextAtCaret = (text) => {
4358
+ const sel = window.getSelection();
4359
+ if (!sel || sel.rangeCount === 0) return;
4360
+ const range = sel.getRangeAt(0);
4361
+ range.deleteContents();
4362
+ const node = document.createTextNode(text);
4363
+ range.insertNode(node);
4364
+ range.setStartAfter(node);
4365
+ range.collapse(true);
4366
+ sel.removeAllRanges();
4367
+ sel.addRange(range);
4368
+ handleInput();
4369
+ };
4370
+ const ensureParagraphAfter = (node) => {
4371
+ const next = node.nextElementSibling;
4372
+ if (next && next.tagName === "P") return;
4373
+ const p = document.createElement("p");
4374
+ p.innerHTML = "<br>";
4375
+ node.after(p);
4376
+ };
4377
+ const placeCaretAtEnd = (node) => {
4378
+ const sel = window.getSelection();
4379
+ if (!sel) return;
4380
+ const r2 = document.createRange();
4381
+ r2.selectNodeContents(node);
4382
+ r2.collapse(false);
4383
+ sel.removeAllRanges();
4384
+ sel.addRange(r2);
4385
+ editorRef.current?.focus();
4386
+ };
4132
4387
  const insertDivider = () => {
4133
4388
  exec("insertHorizontalRule");
4134
4389
  const el = editorRef.current;
@@ -4175,7 +4430,9 @@ var Editor = (props) => {
4175
4430
  const range = sel.getRangeAt(0);
4176
4431
  slashStartRangeRef.current = range.cloneRange();
4177
4432
  const rect = range.getBoundingClientRect();
4178
- const editorRect = editorRef.current.getBoundingClientRect();
4433
+ const editorEl = editorRef.current;
4434
+ if (!editorEl) return;
4435
+ const editorRect = editorEl.getBoundingClientRect();
4179
4436
  setSlashPos({
4180
4437
  top: rect.bottom - editorRect.top + 4,
4181
4438
  left: rect.left - editorRect.left
@@ -4190,7 +4447,7 @@ var Editor = (props) => {
4190
4447
  setSlashIdx(0);
4191
4448
  slashStartRangeRef.current = null;
4192
4449
  };
4193
- const filteredSlashItems = import_react21.default.useMemo(() => {
4450
+ const filteredSlashItems = import_react22.default.useMemo(() => {
4194
4451
  if (!slashFilter) return SLASH_ITEMS;
4195
4452
  const f = slashFilter.toLowerCase();
4196
4453
  return SLASH_ITEMS.filter((it) => it.label.toLowerCase().includes(f) || it.key.includes(f));
@@ -4233,7 +4490,7 @@ var Editor = (props) => {
4233
4490
  setBlock("blockquote");
4234
4491
  break;
4235
4492
  case "code-block":
4236
- setBlock("pre");
4493
+ insertCodeBlock();
4237
4494
  break;
4238
4495
  case "divider":
4239
4496
  insertDivider();
@@ -4251,7 +4508,9 @@ var Editor = (props) => {
4251
4508
  if (!sel || sel.rangeCount === 0) return;
4252
4509
  const range = sel.getRangeAt(0);
4253
4510
  const rect = range.getBoundingClientRect();
4254
- const editorRect = editorRef.current.getBoundingClientRect();
4511
+ const editorEl2 = editorRef.current;
4512
+ if (!editorEl2) return;
4513
+ const editorRect = editorEl2.getBoundingClientRect();
4255
4514
  setLinkPos({
4256
4515
  top: rect.bottom - editorRect.top + 4,
4257
4516
  left: rect.left - editorRect.left
@@ -4284,13 +4543,13 @@ var Editor = (props) => {
4284
4543
  if (node.nodeType !== Node.TEXT_NODE) return false;
4285
4544
  const text = (node.textContent || "").slice(0, range.startOffset);
4286
4545
  const patterns = [
4287
- [/^###\s$/, () => setBlock("h3")],
4288
- [/^##\s$/, () => setBlock("h2")],
4289
- [/^#\s$/, () => setBlock("h1")],
4290
- [/^-\s$/, () => exec("insertUnorderedList")],
4291
- [/^\*\s$/, () => exec("insertUnorderedList")],
4292
- [/^1\.\s$/, () => exec("insertOrderedList")],
4293
- [/^>\s$/, () => setBlock("blockquote")]
4546
+ [/^###$/, () => setBlock("h3")],
4547
+ [/^##$/, () => setBlock("h2")],
4548
+ [/^#$/, () => setBlock("h1")],
4549
+ [/^-$/, () => exec("insertUnorderedList")],
4550
+ [/^\*$/, () => exec("insertUnorderedList")],
4551
+ [/^1\.$/, () => exec("insertOrderedList")],
4552
+ [/^>$/, () => setBlock("blockquote")]
4294
4553
  ];
4295
4554
  for (const [re, fn] of patterns) {
4296
4555
  if (re.test(text)) {
@@ -4310,7 +4569,9 @@ var Editor = (props) => {
4310
4569
  if (composingRef.current) return;
4311
4570
  const el = editorRef.current;
4312
4571
  if (!el) return;
4313
- onChange?.(el.innerHTML);
4572
+ const html = el.innerHTML;
4573
+ lastEmittedRef.current = html;
4574
+ onChange?.(html);
4314
4575
  updateEmpty();
4315
4576
  updateActiveFormats();
4316
4577
  if (slashOpen) {
@@ -4338,6 +4599,31 @@ var Editor = (props) => {
4338
4599
  };
4339
4600
  const handleKeyDown = (e) => {
4340
4601
  if (readOnly) return;
4602
+ if (composingRef.current || e.nativeEvent.isComposing || e.keyCode === 229) return;
4603
+ const pre = closestPre();
4604
+ if (pre && !slashOpen) {
4605
+ if (e.key === "Enter" && !e.shiftKey) {
4606
+ const text = pre.textContent || "";
4607
+ if (text.endsWith("\n\n")) {
4608
+ e.preventDefault();
4609
+ const code = pre.querySelector("code") ?? pre;
4610
+ code.textContent = text.replace(/\n\n$/, "");
4611
+ ensureParagraphAfter(pre);
4612
+ const next = pre.nextElementSibling;
4613
+ if (next) placeCaretAtEnd(next);
4614
+ handleInput();
4615
+ return;
4616
+ }
4617
+ e.preventDefault();
4618
+ insertTextAtCaret("\n");
4619
+ return;
4620
+ }
4621
+ if (e.key === "Tab") {
4622
+ e.preventDefault();
4623
+ insertTextAtCaret(" ");
4624
+ return;
4625
+ }
4626
+ }
4341
4627
  if (slashOpen) {
4342
4628
  if (e.key === "ArrowDown") {
4343
4629
  e.preventDefault();
@@ -4384,6 +4670,7 @@ var Editor = (props) => {
4384
4670
  return;
4385
4671
  }
4386
4672
  }
4673
+ if (pre) return;
4387
4674
  if (enableSlashCommand && e.key === "/") {
4388
4675
  setTimeout(openSlashMenu, 0);
4389
4676
  }
@@ -4396,8 +4683,12 @@ var Editor = (props) => {
4396
4683
  const handlePaste = (e) => {
4397
4684
  if (readOnly) return;
4398
4685
  e.preventDefault();
4399
- const html = e.clipboardData.getData("text/html");
4400
4686
  const text = e.clipboardData.getData("text/plain");
4687
+ if (closestPre()) {
4688
+ insertTextAtCaret(text);
4689
+ return;
4690
+ }
4691
+ const html = e.clipboardData.getData("text/html");
4401
4692
  const clean = html ? sanitizeHtml(html) : escapeHtml(text);
4402
4693
  document.execCommand("insertHTML", false, clean);
4403
4694
  handleInput();
@@ -4421,6 +4712,7 @@ var Editor = (props) => {
4421
4712
  updateActiveFormats();
4422
4713
  };
4423
4714
  const onToolbarAction = (item) => {
4715
+ if (closestPre() && item !== "code-block") return;
4424
4716
  switch (item) {
4425
4717
  case "bold":
4426
4718
  exec("bold");
@@ -4462,7 +4754,7 @@ var Editor = (props) => {
4462
4754
  setBlock("blockquote");
4463
4755
  break;
4464
4756
  case "code-block":
4465
- setBlock("pre");
4757
+ insertCodeBlock();
4466
4758
  break;
4467
4759
  case "link":
4468
4760
  openLinkEditor();
@@ -4492,6 +4784,10 @@ var Editor = (props) => {
4492
4784
  ref: editorRef,
4493
4785
  contentEditable: !readOnly,
4494
4786
  suppressContentEditableWarning: true,
4787
+ role: "textbox",
4788
+ "aria-multiline": "true",
4789
+ "aria-readonly": readOnly || void 0,
4790
+ "aria-label": placeholder,
4495
4791
  className: "lib-xplat-editor__editable",
4496
4792
  onInput: handleInput,
4497
4793
  onKeyDown: handleKeyDown,
@@ -4583,7 +4879,7 @@ var EditorToolbar = ({ items, active, onAction }) => {
4583
4879
  )) });
4584
4880
  };
4585
4881
  var SlashMenu = ({ position, items, activeIndex, onSelect, onClose }) => {
4586
- import_react21.default.useEffect(() => {
4882
+ import_react22.default.useEffect(() => {
4587
4883
  const handleClickOutside = (e) => {
4588
4884
  const target = e.target;
4589
4885
  const menu = document.querySelector(".lib-xplat-editor__slash-menu");
@@ -4617,8 +4913,8 @@ var SlashMenu = ({ position, items, activeIndex, onSelect, onClose }) => {
4617
4913
  );
4618
4914
  };
4619
4915
  var LinkPopover = ({ position, value, onChange, onConfirm, onClose }) => {
4620
- const inputRef = import_react21.default.useRef(null);
4621
- import_react21.default.useEffect(() => {
4916
+ const inputRef = import_react22.default.useRef(null);
4917
+ import_react22.default.useEffect(() => {
4622
4918
  inputRef.current?.focus();
4623
4919
  }, []);
4624
4920
  return /* @__PURE__ */ (0, import_jsx_runtime323.jsxs)(
@@ -4676,7 +4972,7 @@ EmptyState.displayName = "EmptyState";
4676
4972
  var EmptyState_default = EmptyState;
4677
4973
 
4678
4974
  // src/components/FileUpload/FileUpload.tsx
4679
- var import_react22 = __toESM(require("react"), 1);
4975
+ var import_react23 = __toESM(require("react"), 1);
4680
4976
  var import_jsx_runtime325 = require("react/jsx-runtime");
4681
4977
  var FileUpload = (props) => {
4682
4978
  const {
@@ -4688,8 +4984,8 @@ var FileUpload = (props) => {
4688
4984
  description,
4689
4985
  validations
4690
4986
  } = props;
4691
- const [isDragOver, setIsDragOver] = import_react22.default.useState(false);
4692
- const inputRef = import_react22.default.useRef(null);
4987
+ const [isDragOver, setIsDragOver] = import_react23.default.useState(false);
4988
+ const inputRef = import_react23.default.useRef(null);
4693
4989
  const handleFiles = (fileList) => {
4694
4990
  let files = Array.from(fileList);
4695
4991
  if (maxSize) {
@@ -4751,10 +5047,10 @@ FileUpload.displayName = "FileUpload";
4751
5047
  var FileUpload_default = FileUpload;
4752
5048
 
4753
5049
  // src/components/HtmlTypeWriter/HtmlTypeWriter.tsx
4754
- var import_react24 = __toESM(require("react"), 1);
5050
+ var import_react25 = __toESM(require("react"), 1);
4755
5051
 
4756
5052
  // src/components/HtmlTypeWriter/utils.ts
4757
- var import_react23 = __toESM(require("react"), 1);
5053
+ var import_react24 = __toESM(require("react"), 1);
4758
5054
  var voidTags = /* @__PURE__ */ new Set([
4759
5055
  "br",
4760
5056
  "img",
@@ -4822,15 +5118,15 @@ var convertNodeToReactWithRange = (node, typedLen, rangeMap) => {
4822
5118
  props[attr.name] = attr.value;
4823
5119
  });
4824
5120
  if (voidTags.has(tag)) {
4825
- return import_react23.default.createElement(tag, props);
5121
+ return import_react24.default.createElement(tag, props);
4826
5122
  }
4827
5123
  const children = Array.from(element.childNodes).map((child) => convertNodeToReactWithRange(child, typedLen, rangeMap)).filter((n) => n != null);
4828
- return import_react23.default.createElement(tag, props, ...children);
5124
+ return import_react24.default.createElement(tag, props, ...children);
4829
5125
  };
4830
5126
  var htmlToReactProgressive = (root, typedLen, rangeMap) => {
4831
5127
  const nodes = Array.from(root.childNodes).map((child, idx) => {
4832
5128
  const node = convertNodeToReactWithRange(child, typedLen, rangeMap);
4833
- return node == null ? null : import_react23.default.createElement(import_react23.default.Fragment, { key: idx }, node);
5129
+ return node == null ? null : import_react24.default.createElement(import_react24.default.Fragment, { key: idx }, node);
4834
5130
  }).filter(Boolean);
4835
5131
  return nodes.length === 0 ? null : nodes;
4836
5132
  };
@@ -4843,20 +5139,20 @@ var HtmlTypeWriter = ({
4843
5139
  onDone,
4844
5140
  onChange
4845
5141
  }) => {
4846
- const [typedLen, setTypedLen] = import_react24.default.useState(0);
4847
- const doneCalledRef = import_react24.default.useRef(false);
4848
- const { doc, rangeMap, totalLength } = import_react24.default.useMemo(() => {
5142
+ const [typedLen, setTypedLen] = import_react25.default.useState(0);
5143
+ const doneCalledRef = import_react25.default.useRef(false);
5144
+ const { doc, rangeMap, totalLength } = import_react25.default.useMemo(() => {
4849
5145
  if (typeof window === "undefined") return { doc: null, rangeMap: /* @__PURE__ */ new Map(), totalLength: 0 };
4850
5146
  const decoded = decodeHtmlEntities(html);
4851
5147
  const doc2 = new DOMParser().parseFromString(decoded, "text/html");
4852
5148
  const { rangeMap: rangeMap2, totalLength: totalLength2 } = buildRangeMap(doc2.body);
4853
5149
  return { doc: doc2, rangeMap: rangeMap2, totalLength: totalLength2 };
4854
5150
  }, [html]);
4855
- import_react24.default.useEffect(() => {
5151
+ import_react25.default.useEffect(() => {
4856
5152
  setTypedLen(0);
4857
5153
  doneCalledRef.current = false;
4858
5154
  }, [html]);
4859
- import_react24.default.useEffect(() => {
5155
+ import_react25.default.useEffect(() => {
4860
5156
  if (!totalLength) return;
4861
5157
  if (typedLen >= totalLength) return;
4862
5158
  const timer = window.setInterval(() => {
@@ -4864,18 +5160,18 @@ var HtmlTypeWriter = ({
4864
5160
  }, duration);
4865
5161
  return () => window.clearInterval(timer);
4866
5162
  }, [typedLen, totalLength, duration]);
4867
- import_react24.default.useEffect(() => {
5163
+ import_react25.default.useEffect(() => {
4868
5164
  if (typedLen > 0 && typedLen < totalLength) {
4869
5165
  onChange?.();
4870
5166
  }
4871
5167
  }, [typedLen, totalLength, onChange]);
4872
- import_react24.default.useEffect(() => {
5168
+ import_react25.default.useEffect(() => {
4873
5169
  if (typedLen === totalLength && totalLength > 0 && !doneCalledRef.current) {
4874
5170
  doneCalledRef.current = true;
4875
5171
  onDone?.();
4876
5172
  }
4877
5173
  }, [typedLen, totalLength, onDone]);
4878
- const parsed = import_react24.default.useMemo(
5174
+ const parsed = import_react25.default.useMemo(
4879
5175
  () => doc ? htmlToReactProgressive(doc.body, typedLen, rangeMap) : null,
4880
5176
  [doc, typedLen, rangeMap]
4881
5177
  );
@@ -4885,12 +5181,12 @@ HtmlTypeWriter.displayName = "HtmlTypeWriter";
4885
5181
  var HtmlTypeWriter_default = HtmlTypeWriter;
4886
5182
 
4887
5183
  // src/components/ImageSelector/ImageSelector.tsx
4888
- var import_react25 = __toESM(require("react"), 1);
5184
+ var import_react26 = __toESM(require("react"), 1);
4889
5185
  var import_jsx_runtime327 = require("react/jsx-runtime");
4890
5186
  var ImageSelector = (props) => {
4891
5187
  const { value, label, onChange, validations } = props;
4892
- const [previewUrl, setPreviewUrl] = import_react25.default.useState();
4893
- import_react25.default.useEffect(() => {
5188
+ const [previewUrl, setPreviewUrl] = import_react26.default.useState();
5189
+ import_react26.default.useEffect(() => {
4894
5190
  if (!value) {
4895
5191
  setPreviewUrl(void 0);
4896
5192
  return;
@@ -4899,7 +5195,7 @@ var ImageSelector = (props) => {
4899
5195
  setPreviewUrl(url);
4900
5196
  return () => URL.revokeObjectURL(url);
4901
5197
  }, [value]);
4902
- const inputRef = import_react25.default.useRef(null);
5198
+ const inputRef = import_react26.default.useRef(null);
4903
5199
  const handleFileChange = (e) => {
4904
5200
  const selectedFile = e.target.files?.[0];
4905
5201
  if (selectedFile) {
@@ -4987,11 +5283,12 @@ var NotificationBadge = (props) => {
4987
5283
  dot = false,
4988
5284
  size = "md"
4989
5285
  } = props;
5286
+ const statusType = normalizeStatus(type);
4990
5287
  const showBadge = dot || count !== void 0 && count > 0;
4991
5288
  const displayCount = count !== void 0 && count > maxCount ? `${maxCount}+` : count;
4992
5289
  return /* @__PURE__ */ (0, import_jsx_runtime330.jsxs)("div", { className: clsx_default("lib-xplat-notification-badge", size), children: [
4993
5290
  children,
4994
- showBadge && /* @__PURE__ */ (0, import_jsx_runtime330.jsx)("span", { className: clsx_default("badge-indicator", type, { dot }), children: !dot && displayCount })
5291
+ showBadge && /* @__PURE__ */ (0, import_jsx_runtime330.jsx)("span", { className: clsx_default("badge-indicator", statusType, { dot }), children: !dot && displayCount })
4995
5292
  ] });
4996
5293
  };
4997
5294
  NotificationBadge.displayName = "NotificationBadge";
@@ -5032,8 +5329,9 @@ var Pagination = (props) => {
5032
5329
  siblingCount = 1,
5033
5330
  onChange,
5034
5331
  size = "md",
5035
- type = "brand"
5332
+ type = "primary"
5036
5333
  } = props;
5334
+ const statusType = normalizeStatus(type);
5037
5335
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
5038
5336
  const pages = getPageRange(current, totalPages, siblingCount);
5039
5337
  const handleClick = (page) => {
@@ -5041,7 +5339,7 @@ var Pagination = (props) => {
5041
5339
  onChange?.(page);
5042
5340
  }
5043
5341
  };
5044
- return /* @__PURE__ */ (0, import_jsx_runtime331.jsxs)("nav", { className: clsx_default("lib-xplat-pagination", size, type), "aria-label": "\uD398\uC774\uC9C0 \uB124\uBE44\uAC8C\uC774\uC158", children: [
5342
+ return /* @__PURE__ */ (0, import_jsx_runtime331.jsxs)("nav", { className: clsx_default("lib-xplat-pagination", size, statusType), "aria-label": "\uD398\uC774\uC9C0 \uB124\uBE44\uAC8C\uC774\uC158", children: [
5045
5343
  /* @__PURE__ */ (0, import_jsx_runtime331.jsx)(
5046
5344
  "button",
5047
5345
  {
@@ -5080,17 +5378,21 @@ Pagination.displayName = "Pagination";
5080
5378
  var Pagination_default = Pagination;
5081
5379
 
5082
5380
  // src/components/PopOver/PopOver.tsx
5083
- var import_react26 = __toESM(require("react"), 1);
5381
+ var import_react27 = __toESM(require("react"), 1);
5084
5382
  var import_jsx_runtime332 = require("react/jsx-runtime");
5085
5383
  var PopOver = (props) => {
5086
5384
  const { children, isOpen, onClose, PopOverEl } = props;
5087
- const popRef = import_react26.default.useRef(null);
5088
- const triggerRef = import_react26.default.useRef(null);
5089
- const [localOpen, setLocalOpen] = import_react26.default.useState(false);
5090
- const [eventTrigger, setEventTrigger] = import_react26.default.useState(false);
5385
+ const popRef = import_react27.default.useRef(null);
5386
+ const triggerRef = import_react27.default.useRef(null);
5387
+ const [localOpen, setLocalOpen] = import_react27.default.useState(false);
5388
+ const [eventTrigger, setEventTrigger] = import_react27.default.useState(false);
5091
5389
  useClickOutside_default([popRef, triggerRef], onClose, isOpen);
5390
+ useEscapeKey(isOpen, () => {
5391
+ onClose();
5392
+ triggerRef.current?.focus({ preventScroll: true });
5393
+ });
5092
5394
  const position = useAutoPosition_default(triggerRef, popRef, localOpen);
5093
- import_react26.default.useEffect(() => {
5395
+ import_react27.default.useEffect(() => {
5094
5396
  if (isOpen) {
5095
5397
  setLocalOpen(isOpen);
5096
5398
  setTimeout(() => {
@@ -5142,11 +5444,12 @@ var Progress = (props) => {
5142
5444
  value,
5143
5445
  max = 100,
5144
5446
  size = "md",
5145
- type = "brand",
5447
+ type = "primary",
5146
5448
  showLabel = false
5147
5449
  } = props;
5450
+ const statusType = normalizeStatus(type);
5148
5451
  const percentage = Math.min(100, Math.max(0, value / max * 100));
5149
- return /* @__PURE__ */ (0, import_jsx_runtime333.jsxs)("div", { className: clsx_default("lib-xplat-progress", size, type), children: [
5452
+ return /* @__PURE__ */ (0, import_jsx_runtime333.jsxs)("div", { className: clsx_default("lib-xplat-progress", size, statusType), children: [
5150
5453
  /* @__PURE__ */ (0, import_jsx_runtime333.jsx)(
5151
5454
  "div",
5152
5455
  {
@@ -5174,12 +5477,12 @@ Progress.displayName = "Progress";
5174
5477
  var Progress_default = Progress;
5175
5478
 
5176
5479
  // src/components/Radio/RadioGroupContext.tsx
5177
- var import_react27 = __toESM(require("react"), 1);
5178
- var RadioGroupContext = import_react27.default.createContext(
5480
+ var import_react28 = __toESM(require("react"), 1);
5481
+ var RadioGroupContext = import_react28.default.createContext(
5179
5482
  null
5180
5483
  );
5181
5484
  var useRadioGroupContext = () => {
5182
- return import_react27.default.useContext(RadioGroupContext);
5485
+ return import_react28.default.useContext(RadioGroupContext);
5183
5486
  };
5184
5487
  var RadioGroupContext_default = RadioGroupContext;
5185
5488
 
@@ -5191,10 +5494,11 @@ var Radio = (props) => {
5191
5494
  className,
5192
5495
  value,
5193
5496
  size: sizeProp,
5194
- type = "brand",
5497
+ type = "primary",
5195
5498
  validations,
5196
5499
  ...rest
5197
5500
  } = props;
5501
+ const statusType = normalizeStatus(type);
5198
5502
  const context = useRadioGroupContext();
5199
5503
  const size = sizeProp ?? context?.size ?? "md";
5200
5504
  const isGroup = !!context;
@@ -5210,7 +5514,7 @@ var Radio = (props) => {
5210
5514
  className: clsx_default(
5211
5515
  "lib-xplat-radio",
5212
5516
  size,
5213
- type,
5517
+ statusType,
5214
5518
  localChecked ? "checked" : void 0,
5215
5519
  className
5216
5520
  ),
@@ -5254,19 +5558,19 @@ RadioGroup.displayName = "RadioGroup";
5254
5558
  var RadioGroup_default = RadioGroup;
5255
5559
 
5256
5560
  // src/components/Select/Select.tsx
5257
- var import_react30 = __toESM(require("react"), 1);
5561
+ var import_react31 = __toESM(require("react"), 1);
5258
5562
 
5259
5563
  // src/components/Select/context.ts
5260
- var import_react28 = __toESM(require("react"), 1);
5261
- var SelectContext = import_react28.default.createContext(null);
5564
+ var import_react29 = __toESM(require("react"), 1);
5565
+ var SelectContext = import_react29.default.createContext(null);
5262
5566
  var context_default = SelectContext;
5263
5567
 
5264
5568
  // src/components/Select/SelectItem.tsx
5265
- var import_react29 = __toESM(require("react"), 1);
5569
+ var import_react30 = __toESM(require("react"), 1);
5266
5570
  var import_jsx_runtime336 = require("react/jsx-runtime");
5267
5571
  var SelectItem = (props) => {
5268
5572
  const { children, value, onClick, disabled = false } = props;
5269
- const ctx = import_react29.default.useContext(context_default);
5573
+ const ctx = import_react30.default.useContext(context_default);
5270
5574
  const handleClick = (e) => {
5271
5575
  e.preventDefault();
5272
5576
  e.stopPropagation();
@@ -5306,32 +5610,37 @@ var SelectRoot = (props) => {
5306
5610
  onChange,
5307
5611
  children,
5308
5612
  disabled = false,
5613
+ searchable = false,
5614
+ searchPlaceholder = "\uAC80\uC0C9",
5309
5615
  error = false,
5310
5616
  validations,
5617
+ label,
5618
+ required,
5311
5619
  size = "md"
5312
5620
  } = props;
5313
- const itemChildren = import_react30.default.Children.toArray(children).filter(
5314
- (child) => import_react30.default.isValidElement(child) && child.type === SelectItem_default
5621
+ const fieldId = import_react31.default.useId();
5622
+ const itemChildren = import_react31.default.Children.toArray(children).filter(
5623
+ (child) => import_react31.default.isValidElement(child) && child.type === SelectItem_default
5315
5624
  );
5316
5625
  const isControlled = valueProp !== void 0;
5317
- const [isOpen, setOpen] = import_react30.default.useState(false);
5318
- const [uncontrolledLabel, setUncontrolledLabel] = import_react30.default.useState(null);
5319
- const [uncontrolledValue, setUncontrolledValue] = import_react30.default.useState(void 0);
5320
- const controlledLabel = import_react30.default.useMemo(() => {
5626
+ const [isOpen, setOpen] = import_react31.default.useState(false);
5627
+ const [uncontrolledLabel, setUncontrolledLabel] = import_react31.default.useState(null);
5628
+ const [uncontrolledValue, setUncontrolledValue] = import_react31.default.useState(void 0);
5629
+ const controlledLabel = import_react31.default.useMemo(() => {
5321
5630
  if (!isControlled) return null;
5322
5631
  const match = itemChildren.find((child) => child.props.value === valueProp);
5323
5632
  return match ? match.props.children : null;
5324
5633
  }, [isControlled, valueProp, itemChildren]);
5325
5634
  const selectedLabel = isControlled ? controlledLabel : uncontrolledLabel;
5326
5635
  const selectedValue = isControlled ? valueProp : uncontrolledValue;
5327
- const triggerRef = import_react30.default.useRef(null);
5328
- const contentRef = import_react30.default.useRef(null);
5329
- const [mounted, setMounted] = import_react30.default.useState(false);
5330
- const [visible, setVisible] = import_react30.default.useState(false);
5331
- import_react30.default.useEffect(() => {
5636
+ const triggerRef = import_react31.default.useRef(null);
5637
+ const contentRef = import_react31.default.useRef(null);
5638
+ const [mounted, setMounted] = import_react31.default.useState(false);
5639
+ const [visible, setVisible] = import_react31.default.useState(false);
5640
+ import_react31.default.useEffect(() => {
5332
5641
  if (disabled && isOpen) setOpen(false);
5333
5642
  }, [disabled, isOpen]);
5334
- import_react30.default.useEffect(() => {
5643
+ import_react31.default.useEffect(() => {
5335
5644
  if (isOpen) {
5336
5645
  setMounted(true);
5337
5646
  const t2 = setTimeout(() => setVisible(true), 1);
@@ -5341,22 +5650,42 @@ var SelectRoot = (props) => {
5341
5650
  const t = setTimeout(() => setMounted(false), ANIMATION_DURATION_MS3);
5342
5651
  return () => clearTimeout(t);
5343
5652
  }, [isOpen]);
5344
- const open = import_react30.default.useCallback(() => setOpen(true), []);
5345
- const close = import_react30.default.useCallback(() => setOpen(false), []);
5346
- const toggle = import_react30.default.useCallback(() => setOpen((prev) => !prev), []);
5653
+ const [query, setQuery] = import_react31.default.useState("");
5654
+ const textOf = (node) => {
5655
+ if (node === null || node === void 0 || typeof node === "boolean") return "";
5656
+ if (typeof node === "string" || typeof node === "number") return String(node);
5657
+ if (Array.isArray(node)) return node.map(textOf).join("");
5658
+ if (import_react31.default.isValidElement(node)) return textOf(node.props.children);
5659
+ return "";
5660
+ };
5661
+ const visibleItems = import_react31.default.useMemo(() => {
5662
+ if (!searchable || !query.trim()) return itemChildren;
5663
+ const q = query.trim().toLowerCase();
5664
+ return itemChildren.filter((c) => textOf(c.props.children).toLowerCase().includes(q));
5665
+ }, [searchable, query, itemChildren]);
5666
+ const open = import_react31.default.useCallback(() => setOpen(true), []);
5667
+ const close = import_react31.default.useCallback(() => {
5668
+ setOpen(false);
5669
+ setQuery("");
5670
+ }, []);
5671
+ const toggle = import_react31.default.useCallback(() => setOpen((prev) => !prev), []);
5347
5672
  useClickOutside_default([contentRef, triggerRef], close, isOpen);
5673
+ useEscapeKey(isOpen, () => {
5674
+ close();
5675
+ triggerRef.current?.focus({ preventScroll: true });
5676
+ });
5348
5677
  const position = useAutoPosition_default(triggerRef, contentRef, mounted);
5349
- const setSelected = import_react30.default.useCallback(
5350
- (label, itemValue) => {
5678
+ const setSelected = import_react31.default.useCallback(
5679
+ (label2, itemValue) => {
5351
5680
  if (!isControlled) {
5352
- setUncontrolledLabel(label);
5681
+ setUncontrolledLabel(label2);
5353
5682
  setUncontrolledValue(itemValue);
5354
5683
  }
5355
- onChange?.(itemValue, label);
5684
+ onChange?.(itemValue, label2);
5356
5685
  },
5357
5686
  [isControlled, onChange]
5358
5687
  );
5359
- const ctxValue = import_react30.default.useMemo(
5688
+ const ctxValue = import_react31.default.useMemo(
5360
5689
  () => ({
5361
5690
  isOpen,
5362
5691
  mounted,
@@ -5392,6 +5721,7 @@ var SelectRoot = (props) => {
5392
5721
  /* @__PURE__ */ (0, import_jsx_runtime337.jsxs)(
5393
5722
  "div",
5394
5723
  {
5724
+ id: fieldId,
5395
5725
  ref: triggerRef,
5396
5726
  className: clsx_default(
5397
5727
  "select-trigger",
@@ -5434,20 +5764,33 @@ var SelectRoot = (props) => {
5434
5764
  ]
5435
5765
  }
5436
5766
  ),
5437
- mounted && /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(
5767
+ mounted && /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime337.jsxs)(
5438
5768
  "div",
5439
5769
  {
5440
5770
  className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass),
5441
5771
  ref: contentRef,
5442
5772
  style: { ...position.position, width: triggerRef.current?.offsetWidth },
5443
5773
  role: "listbox",
5444
- children: /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(context_default.Provider, { value: ctxValue, children: itemChildren })
5774
+ children: [
5775
+ searchable && /* @__PURE__ */ (0, import_jsx_runtime337.jsx)("div", { className: "select-search", children: /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(
5776
+ "input",
5777
+ {
5778
+ type: "text",
5779
+ value: query,
5780
+ placeholder: searchPlaceholder,
5781
+ onChange: (e) => setQuery(e.target.value),
5782
+ autoFocus: true,
5783
+ "aria-label": searchPlaceholder
5784
+ }
5785
+ ) }),
5786
+ /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(context_default.Provider, { value: ctxValue, children: visibleItems.length > 0 ? visibleItems : /* @__PURE__ */ (0, import_jsx_runtime337.jsx)("div", { className: "select-empty", children: "\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4" }) })
5787
+ ]
5445
5788
  }
5446
5789
  ) })
5447
5790
  ]
5448
5791
  }
5449
5792
  ) });
5450
- return /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(Field, { validations, children: control });
5793
+ return /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(Field, { validations, label, required, htmlFor: fieldId, children: control });
5451
5794
  };
5452
5795
  SelectRoot.displayName = "Select";
5453
5796
  var Select = Object.assign(SelectRoot, {
@@ -5489,12 +5832,13 @@ var import_jsx_runtime339 = require("react/jsx-runtime");
5489
5832
  var Spinner = (props) => {
5490
5833
  const {
5491
5834
  size = "md",
5492
- type = "brand"
5835
+ type = "primary"
5493
5836
  } = props;
5837
+ const statusType = normalizeStatus(type);
5494
5838
  return /* @__PURE__ */ (0, import_jsx_runtime339.jsx)(
5495
5839
  "div",
5496
5840
  {
5497
- className: clsx_default("lib-xplat-spinner", size, type),
5841
+ className: clsx_default("lib-xplat-spinner", size, statusType),
5498
5842
  role: "status",
5499
5843
  "aria-label": "\uB85C\uB529 \uC911",
5500
5844
  children: /* @__PURE__ */ (0, import_jsx_runtime339.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
@@ -5526,21 +5870,58 @@ var Spinner = (props) => {
5526
5870
  Spinner.displayName = "Spinner";
5527
5871
  var Spinner_default = Spinner;
5528
5872
 
5529
- // src/components/Steps/Steps.tsx
5873
+ // src/components/Stat/Stat.tsx
5530
5874
  var import_jsx_runtime340 = require("react/jsx-runtime");
5875
+ var ARROW = {
5876
+ up: "\u25B2",
5877
+ down: "\u25BC",
5878
+ flat: "\u2014"
5879
+ };
5880
+ var Stat = (props) => {
5881
+ const {
5882
+ label,
5883
+ value,
5884
+ unit,
5885
+ description,
5886
+ trend,
5887
+ icon,
5888
+ size = "md",
5889
+ type = "primary"
5890
+ } = props;
5891
+ const statusType = normalizeStatus(type);
5892
+ return /* @__PURE__ */ (0, import_jsx_runtime340.jsxs)("div", { className: clsx_default("lib-xplat-stat", size, statusType), children: [
5893
+ /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("div", { className: "stat-label", children: label }),
5894
+ /* @__PURE__ */ (0, import_jsx_runtime340.jsxs)("div", { className: "stat-value-row", children: [
5895
+ icon && /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("span", { className: "stat-icon", children: icon }),
5896
+ /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("span", { className: "stat-value", children: value }),
5897
+ unit && /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("span", { className: "stat-unit", children: unit }),
5898
+ trend && /* @__PURE__ */ (0, import_jsx_runtime340.jsxs)("span", { className: clsx_default("stat-trend", trend.direction), children: [
5899
+ /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("span", { "aria-hidden": "true", children: ARROW[trend.direction] }),
5900
+ trend.value
5901
+ ] })
5902
+ ] }),
5903
+ description && /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("div", { className: "stat-description", children: description })
5904
+ ] });
5905
+ };
5906
+ Stat.displayName = "Stat";
5907
+ var Stat_default = Stat;
5908
+
5909
+ // src/components/Steps/Steps.tsx
5910
+ var import_jsx_runtime341 = require("react/jsx-runtime");
5531
5911
  var Steps = (props) => {
5532
5912
  const {
5533
5913
  items,
5534
5914
  current,
5535
- type = "brand"
5915
+ type = "primary"
5536
5916
  } = props;
5537
- return /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("div", { className: clsx_default("lib-xplat-steps", type), children: items.map((item, index) => {
5917
+ const statusType = normalizeStatus(type);
5918
+ return /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("div", { className: clsx_default("lib-xplat-steps", statusType), children: items.map((item, index) => {
5538
5919
  const status = index < current ? "completed" : index === current ? "active" : "pending";
5539
- return /* @__PURE__ */ (0, import_jsx_runtime340.jsxs)("div", { className: clsx_default("step-item", status), children: [
5540
- /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("div", { className: "step-circle", children: status === "completed" ? /* @__PURE__ */ (0, import_jsx_runtime340.jsx)(CheckIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("span", { children: index + 1 }) }),
5541
- /* @__PURE__ */ (0, import_jsx_runtime340.jsxs)("div", { className: "step-content", children: [
5542
- /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("span", { className: "step-title", children: item.title }),
5543
- item.description && /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("span", { className: "step-description", children: item.description })
5920
+ return /* @__PURE__ */ (0, import_jsx_runtime341.jsxs)("div", { className: clsx_default("step-item", status), children: [
5921
+ /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("div", { className: "step-circle", children: status === "completed" ? /* @__PURE__ */ (0, import_jsx_runtime341.jsx)(CheckIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("span", { children: index + 1 }) }),
5922
+ /* @__PURE__ */ (0, import_jsx_runtime341.jsxs)("div", { className: "step-content", children: [
5923
+ /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("span", { className: "step-title", children: item.title }),
5924
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("span", { className: "step-description", children: item.description })
5544
5925
  ] })
5545
5926
  ] }, index);
5546
5927
  }) });
@@ -5549,8 +5930,8 @@ Steps.displayName = "Steps";
5549
5930
  var Steps_default = Steps;
5550
5931
 
5551
5932
  // src/components/Swiper/Swiper.tsx
5552
- var import_react31 = __toESM(require("react"), 1);
5553
- var import_jsx_runtime341 = require("react/jsx-runtime");
5933
+ var import_react32 = __toESM(require("react"), 1);
5934
+ var import_jsx_runtime342 = require("react/jsx-runtime");
5554
5935
  var Swiper = (props) => {
5555
5936
  const {
5556
5937
  auto = false,
@@ -5574,26 +5955,26 @@ var Swiper = (props) => {
5574
5955
  const maxIndex = Math.max(0, totalSlides - viewItemCount);
5575
5956
  const useLoop = loop && canSlide;
5576
5957
  const cloneCount = useLoop ? totalSlides : 0;
5577
- const extendedItems = import_react31.default.useMemo(() => {
5958
+ const extendedItems = import_react32.default.useMemo(() => {
5578
5959
  if (!useLoop) return items;
5579
5960
  return [...items, ...items, ...items];
5580
5961
  }, [items, useLoop]);
5581
5962
  const initialIdx = Math.max(0, Math.min(indexProp ?? 0, maxIndex));
5582
- const [innerIndex, setInnerIndex] = import_react31.default.useState(
5963
+ const [innerIndex, setInnerIndex] = import_react32.default.useState(
5583
5964
  useLoop ? cloneCount + initialIdx : initialIdx
5584
5965
  );
5585
- const [isDragging, setIsDragging] = import_react31.default.useState(false);
5586
- const [dragOffset, setDragOffset] = import_react31.default.useState(0);
5587
- const [animated, setAnimated] = import_react31.default.useState(false);
5588
- const [containerWidth, setContainerWidth] = import_react31.default.useState(0);
5589
- const containerRef = import_react31.default.useRef(null);
5590
- const startXRef = import_react31.default.useRef(0);
5591
- const startTimeRef = import_react31.default.useRef(0);
5592
- const autoplayTimerRef = import_react31.default.useRef(null);
5593
- const resumeTimeoutRef = import_react31.default.useRef(null);
5594
- const [paused, setPaused] = import_react31.default.useState(false);
5595
- const initializedRef = import_react31.default.useRef(false);
5596
- import_react31.default.useEffect(() => {
5966
+ const [isDragging, setIsDragging] = import_react32.default.useState(false);
5967
+ const [dragOffset, setDragOffset] = import_react32.default.useState(0);
5968
+ const [animated, setAnimated] = import_react32.default.useState(false);
5969
+ const [containerWidth, setContainerWidth] = import_react32.default.useState(0);
5970
+ const containerRef = import_react32.default.useRef(null);
5971
+ const startXRef = import_react32.default.useRef(0);
5972
+ const startTimeRef = import_react32.default.useRef(0);
5973
+ const autoplayTimerRef = import_react32.default.useRef(null);
5974
+ const resumeTimeoutRef = import_react32.default.useRef(null);
5975
+ const [paused, setPaused] = import_react32.default.useState(false);
5976
+ const initializedRef = import_react32.default.useRef(false);
5977
+ import_react32.default.useEffect(() => {
5597
5978
  const el = containerRef.current;
5598
5979
  if (!el) return;
5599
5980
  const ro = new ResizeObserver((entries) => {
@@ -5616,7 +5997,7 @@ var Swiper = (props) => {
5616
5997
  return ((inner - cloneCount) % totalSlides + totalSlides) % totalSlides;
5617
5998
  };
5618
5999
  const realIndex = getRealIndex(innerIndex);
5619
- const moveToInner = import_react31.default.useCallback(
6000
+ const moveToInner = import_react32.default.useCallback(
5620
6001
  (idx, withAnim = true) => {
5621
6002
  if (!useLoop) {
5622
6003
  setAnimated(withAnim);
@@ -5644,7 +6025,7 @@ var Swiper = (props) => {
5644
6025
  },
5645
6026
  [useLoop, cloneCount, totalSlides]
5646
6027
  );
5647
- const handleTransitionEnd = import_react31.default.useCallback(() => {
6028
+ const handleTransitionEnd = import_react32.default.useCallback(() => {
5648
6029
  if (!useLoop) return;
5649
6030
  const real = getRealIndex(innerIndex);
5650
6031
  const canonical = cloneCount + real;
@@ -5654,7 +6035,7 @@ var Swiper = (props) => {
5654
6035
  }
5655
6036
  onChange?.(Math.min(real, maxIndex));
5656
6037
  }, [useLoop, innerIndex, cloneCount, totalSlides, maxIndex, onChange]);
5657
- const slideTo = import_react31.default.useCallback(
6038
+ const slideTo = import_react32.default.useCallback(
5658
6039
  (logicalIndex) => {
5659
6040
  if (!canSlide) return;
5660
6041
  const clamped = useLoop ? logicalIndex : Math.max(0, Math.min(logicalIndex, maxIndex));
@@ -5664,7 +6045,7 @@ var Swiper = (props) => {
5664
6045
  },
5665
6046
  [canSlide, useLoop, cloneCount, maxIndex, onChange, moveToInner]
5666
6047
  );
5667
- const slideNext = import_react31.default.useCallback(() => {
6048
+ const slideNext = import_react32.default.useCallback(() => {
5668
6049
  if (!canSlide) return;
5669
6050
  const nextInner = innerIndex + slideBy;
5670
6051
  if (useLoop) {
@@ -5673,7 +6054,7 @@ var Swiper = (props) => {
5673
6054
  moveToInner(Math.min(nextInner, maxIndex), true);
5674
6055
  }
5675
6056
  }, [canSlide, useLoop, innerIndex, slideBy, maxIndex, moveToInner]);
5676
- const slidePrev = import_react31.default.useCallback(() => {
6057
+ const slidePrev = import_react32.default.useCallback(() => {
5677
6058
  if (!canSlide) return;
5678
6059
  const prevInner = innerIndex - slideBy;
5679
6060
  if (useLoop) {
@@ -5682,7 +6063,7 @@ var Swiper = (props) => {
5682
6063
  moveToInner(Math.max(prevInner, 0), true);
5683
6064
  }
5684
6065
  }, [canSlide, useLoop, innerIndex, slideBy, moveToInner]);
5685
- import_react31.default.useEffect(() => {
6066
+ import_react32.default.useEffect(() => {
5686
6067
  if (indexProp === void 0) return;
5687
6068
  const clamped = Math.max(0, Math.min(indexProp, maxIndex));
5688
6069
  const target = useLoop ? cloneCount + clamped : clamped;
@@ -5690,12 +6071,12 @@ var Swiper = (props) => {
5690
6071
  moveToInner(target, true);
5691
6072
  }
5692
6073
  }, [indexProp]);
5693
- import_react31.default.useImperativeHandle(swiperRef, () => ({
6074
+ import_react32.default.useImperativeHandle(swiperRef, () => ({
5694
6075
  slidePrev,
5695
6076
  slideNext,
5696
6077
  slideTo
5697
6078
  }));
5698
- import_react31.default.useEffect(() => {
6079
+ import_react32.default.useEffect(() => {
5699
6080
  if (!auto || !canSlide || paused) return;
5700
6081
  autoplayTimerRef.current = setInterval(slideNext, autoplayDelay);
5701
6082
  return () => {
@@ -5721,7 +6102,7 @@ var Swiper = (props) => {
5721
6102
  resumeTimeoutRef.current = null;
5722
6103
  }, pauseOnInteraction);
5723
6104
  };
5724
- import_react31.default.useEffect(() => {
6105
+ import_react32.default.useEffect(() => {
5725
6106
  return () => {
5726
6107
  if (resumeTimeoutRef.current) clearTimeout(resumeTimeoutRef.current);
5727
6108
  };
@@ -5739,7 +6120,7 @@ var Swiper = (props) => {
5739
6120
  startXRef.current = getClientX(e);
5740
6121
  startTimeRef.current = Date.now();
5741
6122
  };
5742
- import_react31.default.useEffect(() => {
6123
+ import_react32.default.useEffect(() => {
5743
6124
  if (!isDragging) return;
5744
6125
  const handleMove = (e) => {
5745
6126
  setDragOffset(getClientX(e) - startXRef.current);
@@ -5778,8 +6159,8 @@ var Swiper = (props) => {
5778
6159
  }, [isDragging, dragOffset, innerIndex, useLoop, maxIndex, slideStep, moveToInner]);
5779
6160
  const slideWidthPercent = 100 / viewItemCount;
5780
6161
  const gapAdjust = spaceBetween * (viewItemCount - 1) / viewItemCount;
5781
- const slideElements = import_react31.default.useMemo(
5782
- () => extendedItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime341.jsx)(
6162
+ const slideElements = import_react32.default.useMemo(
6163
+ () => extendedItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(
5783
6164
  "div",
5784
6165
  {
5785
6166
  className: "lib-xplat-swiper__slide",
@@ -5798,15 +6179,15 @@ var Swiper = (props) => {
5798
6179
  Math.floor(realIndex / slideBy),
5799
6180
  totalSteps - 1
5800
6181
  );
5801
- return /* @__PURE__ */ (0, import_jsx_runtime341.jsxs)("div", { className: "lib-xplat-swiper", ref: containerRef, children: [
5802
- /* @__PURE__ */ (0, import_jsx_runtime341.jsx)(
6182
+ return /* @__PURE__ */ (0, import_jsx_runtime342.jsxs)("div", { className: "lib-xplat-swiper", ref: containerRef, children: [
6183
+ /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(
5803
6184
  "div",
5804
6185
  {
5805
6186
  className: "lib-xplat-swiper__viewport",
5806
6187
  onMouseDown: handleDragStart,
5807
6188
  onTouchStart: handleDragStart,
5808
6189
  onDragStart: (e) => e.preventDefault(),
5809
- children: /* @__PURE__ */ (0, import_jsx_runtime341.jsx)(
6190
+ children: /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(
5810
6191
  "div",
5811
6192
  {
5812
6193
  className: clsx_default(
@@ -5824,7 +6205,7 @@ var Swiper = (props) => {
5824
6205
  )
5825
6206
  }
5826
6207
  ),
5827
- showProgress && canSlide && /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("div", { className: "lib-xplat-swiper__progress", children: /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("div", { className: "lib-xplat-swiper__progress-track", children: /* @__PURE__ */ (0, import_jsx_runtime341.jsx)(
6208
+ showProgress && canSlide && /* @__PURE__ */ (0, import_jsx_runtime342.jsx)("div", { className: "lib-xplat-swiper__progress", children: /* @__PURE__ */ (0, import_jsx_runtime342.jsx)("div", { className: "lib-xplat-swiper__progress-track", children: /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(
5828
6209
  "span",
5829
6210
  {
5830
6211
  className: "lib-xplat-swiper__progress-fill",
@@ -5834,7 +6215,7 @@ var Swiper = (props) => {
5834
6215
  }
5835
6216
  }
5836
6217
  ) }) }),
5837
- canSlide && /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("div", { className: "lib-xplat-swiper__dots", children: Array.from({ length: totalSteps }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime341.jsx)(
6218
+ canSlide && /* @__PURE__ */ (0, import_jsx_runtime342.jsx)("div", { className: "lib-xplat-swiper__dots", children: Array.from({ length: totalSteps }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(
5838
6219
  "button",
5839
6220
  {
5840
6221
  className: clsx_default(
@@ -5852,21 +6233,25 @@ Swiper.displayName = "Swiper";
5852
6233
  var Swiper_default = Swiper;
5853
6234
 
5854
6235
  // src/components/Switch/Switch.tsx
5855
- var import_react32 = __toESM(require("react"), 1);
5856
- var import_jsx_runtime342 = require("react/jsx-runtime");
6236
+ var import_react33 = __toESM(require("react"), 1);
6237
+ var import_jsx_runtime343 = require("react/jsx-runtime");
5857
6238
  var KNOB_TRANSITION_MS = 250;
5858
6239
  var Switch = (props) => {
5859
6240
  const {
5860
6241
  value,
5861
6242
  size = "md",
5862
- type = "brand",
6243
+ type = "primary",
5863
6244
  disabled,
5864
6245
  onChange,
5865
- validations
6246
+ validations,
6247
+ label,
6248
+ required
5866
6249
  } = props;
5867
- const [isAnimating, setIsAnimating] = import_react32.default.useState(false);
5868
- const timeoutRef = import_react32.default.useRef(null);
5869
- import_react32.default.useEffect(() => {
6250
+ const fieldId = import_react33.default.useId();
6251
+ const statusType = normalizeStatus(type);
6252
+ const [isAnimating, setIsAnimating] = import_react33.default.useState(false);
6253
+ const timeoutRef = import_react33.default.useRef(null);
6254
+ import_react33.default.useEffect(() => {
5870
6255
  return () => {
5871
6256
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
5872
6257
  };
@@ -5881,13 +6266,14 @@ var Switch = (props) => {
5881
6266
  timeoutRef.current = null;
5882
6267
  }, KNOB_TRANSITION_MS);
5883
6268
  };
5884
- const control = /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(
6269
+ const control = /* @__PURE__ */ (0, import_jsx_runtime343.jsx)(
5885
6270
  "div",
5886
6271
  {
6272
+ id: fieldId,
5887
6273
  className: clsx_default(
5888
6274
  "lib-xplat-switch",
5889
6275
  size,
5890
- type,
6276
+ statusType,
5891
6277
  value ? "checked" : void 0,
5892
6278
  disabled && "disabled",
5893
6279
  isAnimating && "animating"
@@ -5895,26 +6281,26 @@ var Switch = (props) => {
5895
6281
  onClick: handleClick,
5896
6282
  "aria-invalid": hasError(validations) || void 0,
5897
6283
  "aria-disabled": disabled || isAnimating,
5898
- children: /* @__PURE__ */ (0, import_jsx_runtime342.jsx)("div", { className: clsx_default("knob", value ? "checked" : void 0) })
6284
+ children: /* @__PURE__ */ (0, import_jsx_runtime343.jsx)("div", { className: clsx_default("knob", value ? "checked" : void 0) })
5899
6285
  }
5900
6286
  );
5901
- return /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(Field, { validations, children: control });
6287
+ return /* @__PURE__ */ (0, import_jsx_runtime343.jsx)(Field, { validations, label, required, htmlFor: fieldId, children: control });
5902
6288
  };
5903
6289
  Switch.displayName = "Switch";
5904
6290
  var Switch_default = Switch;
5905
6291
 
5906
6292
  // src/components/Table/TableContext.tsx
5907
- var import_react33 = __toESM(require("react"), 1);
5908
- var TableContext = import_react33.default.createContext(null);
6293
+ var import_react34 = __toESM(require("react"), 1);
6294
+ var TableContext = import_react34.default.createContext(null);
5909
6295
  var useTableContext = () => {
5910
- const ctx = import_react33.default.useContext(TableContext);
6296
+ const ctx = import_react34.default.useContext(TableContext);
5911
6297
  if (!ctx) throw new Error("Table components must be used inside <Table>");
5912
6298
  return ctx;
5913
6299
  };
5914
6300
  var TableContext_default = TableContext;
5915
6301
 
5916
6302
  // src/components/Table/Table.tsx
5917
- var import_jsx_runtime343 = require("react/jsx-runtime");
6303
+ var import_jsx_runtime344 = require("react/jsx-runtime");
5918
6304
  var Table = (props) => {
5919
6305
  const {
5920
6306
  children,
@@ -5924,7 +6310,7 @@ var Table = (props) => {
5924
6310
  headerSticky = false,
5925
6311
  stickyShadow = true
5926
6312
  } = props;
5927
- return /* @__PURE__ */ (0, import_jsx_runtime343.jsx)("div", { className: `lib-xplat-table-wrapper ${size}`, children: /* @__PURE__ */ (0, import_jsx_runtime343.jsx)(
6313
+ return /* @__PURE__ */ (0, import_jsx_runtime344.jsx)("div", { className: `lib-xplat-table-wrapper ${size}`, children: /* @__PURE__ */ (0, import_jsx_runtime344.jsx)(
5928
6314
  TableContext_default.Provider,
5929
6315
  {
5930
6316
  value: {
@@ -5933,7 +6319,7 @@ var Table = (props) => {
5933
6319
  headerSticky,
5934
6320
  stickyShadow
5935
6321
  },
5936
- children: /* @__PURE__ */ (0, import_jsx_runtime343.jsx)("table", { className: "lib-xplat-table", children })
6322
+ children: /* @__PURE__ */ (0, import_jsx_runtime344.jsx)("table", { className: "lib-xplat-table", children })
5937
6323
  }
5938
6324
  ) });
5939
6325
  };
@@ -5941,41 +6327,41 @@ Table.displayName = "Table";
5941
6327
  var Table_default = Table;
5942
6328
 
5943
6329
  // src/components/Table/TableBody.tsx
5944
- var import_jsx_runtime344 = require("react/jsx-runtime");
6330
+ var import_jsx_runtime345 = require("react/jsx-runtime");
5945
6331
  var TableBody = (props) => {
5946
6332
  const { children } = props;
5947
- return /* @__PURE__ */ (0, import_jsx_runtime344.jsx)("tbody", { children });
6333
+ return /* @__PURE__ */ (0, import_jsx_runtime345.jsx)("tbody", { children });
5948
6334
  };
5949
6335
  TableBody.displayName = "TableBody";
5950
6336
  var TableBody_default = TableBody;
5951
6337
 
5952
6338
  // src/components/Table/TableCell.tsx
5953
- var import_react36 = __toESM(require("react"), 1);
6339
+ var import_react37 = __toESM(require("react"), 1);
5954
6340
 
5955
6341
  // src/components/Table/TableHeadContext.tsx
5956
- var import_react34 = __toESM(require("react"), 1);
5957
- var TableHeadContext = import_react34.default.createContext(
6342
+ var import_react35 = __toESM(require("react"), 1);
6343
+ var TableHeadContext = import_react35.default.createContext(
5958
6344
  null
5959
6345
  );
5960
6346
  var useTableHeadContext = () => {
5961
- const ctx = import_react34.default.useContext(TableHeadContext);
6347
+ const ctx = import_react35.default.useContext(TableHeadContext);
5962
6348
  return ctx;
5963
6349
  };
5964
6350
  var TableHeadContext_default = TableHeadContext;
5965
6351
 
5966
6352
  // src/components/Table/TableRowContext.tsx
5967
- var import_react35 = __toESM(require("react"), 1);
5968
- var TableRowContext = import_react35.default.createContext(null);
6353
+ var import_react36 = __toESM(require("react"), 1);
6354
+ var TableRowContext = import_react36.default.createContext(null);
5969
6355
  var useTableRowContext = () => {
5970
- const ctx = import_react35.default.useContext(TableRowContext);
6356
+ const ctx = import_react36.default.useContext(TableRowContext);
5971
6357
  if (!ctx) throw new Error("Table components must be used inside <Table>");
5972
6358
  return ctx;
5973
6359
  };
5974
6360
  var TableRowContext_default = TableRowContext;
5975
6361
 
5976
6362
  // src/components/Table/TableCell.tsx
5977
- var import_jsx_runtime345 = require("react/jsx-runtime");
5978
- var TableCell = import_react36.default.memo((props) => {
6363
+ var import_jsx_runtime346 = require("react/jsx-runtime");
6364
+ var TableCell = import_react37.default.memo((props) => {
5979
6365
  const {
5980
6366
  children,
5981
6367
  align = "center",
@@ -5989,9 +6375,9 @@ var TableCell = import_react36.default.memo((props) => {
5989
6375
  const { registerStickyCell, stickyCells } = useTableRowContext();
5990
6376
  const { stickyShadow } = useTableContext();
5991
6377
  const headContext = useTableHeadContext();
5992
- const [left, setLeft] = import_react36.default.useState(0);
5993
- const cellRef = import_react36.default.useRef(null);
5994
- const calculateLeft = import_react36.default.useCallback(() => {
6378
+ const [left, setLeft] = import_react37.default.useState(0);
6379
+ const cellRef = import_react37.default.useRef(null);
6380
+ const calculateLeft = import_react37.default.useCallback(() => {
5995
6381
  if (!cellRef.current) return 0;
5996
6382
  let totalLeft = 0;
5997
6383
  for (const ref of stickyCells) {
@@ -6000,7 +6386,7 @@ var TableCell = import_react36.default.memo((props) => {
6000
6386
  }
6001
6387
  return totalLeft;
6002
6388
  }, [stickyCells]);
6003
- import_react36.default.useEffect(() => {
6389
+ import_react37.default.useEffect(() => {
6004
6390
  if (!isSticky || !cellRef.current) return;
6005
6391
  registerStickyCell(cellRef);
6006
6392
  setLeft(calculateLeft());
@@ -6019,7 +6405,7 @@ var TableCell = import_react36.default.memo((props) => {
6019
6405
  const CellTag = isHeaderCell ? "th" : "td";
6020
6406
  const isLastSticky = isSticky && stickyCells[stickyCells.length - 1] === cellRef;
6021
6407
  const enableHover = headContext && headContext.cellHover;
6022
- return /* @__PURE__ */ (0, import_jsx_runtime345.jsx)(
6408
+ return /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(
6023
6409
  CellTag,
6024
6410
  {
6025
6411
  ref: cellRef,
@@ -6046,21 +6432,21 @@ TableCell.displayName = "TableCell";
6046
6432
  var TableCell_default = TableCell;
6047
6433
 
6048
6434
  // src/components/Table/TableHead.tsx
6049
- var import_jsx_runtime346 = require("react/jsx-runtime");
6435
+ var import_jsx_runtime347 = require("react/jsx-runtime");
6050
6436
  var TableHead = ({
6051
6437
  children,
6052
6438
  cellHover = false
6053
6439
  }) => {
6054
6440
  const { headerSticky } = useTableContext();
6055
- return /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(TableHeadContext_default.Provider, { value: { cellHover }, children: /* @__PURE__ */ (0, import_jsx_runtime346.jsx)("thead", { className: clsx_default(headerSticky ? "table-sticky" : null), children }) });
6441
+ return /* @__PURE__ */ (0, import_jsx_runtime347.jsx)(TableHeadContext_default.Provider, { value: { cellHover }, children: /* @__PURE__ */ (0, import_jsx_runtime347.jsx)("thead", { className: clsx_default(headerSticky ? "table-sticky" : null), children }) });
6056
6442
  };
6057
6443
  TableHead.displayName = "TableHead";
6058
6444
  var TableHead_default = TableHead;
6059
6445
 
6060
6446
  // src/components/Table/TableRow.tsx
6061
- var import_react37 = __toESM(require("react"), 1);
6062
- var import_jsx_runtime347 = require("react/jsx-runtime");
6063
- var TableRow = import_react37.default.memo((props) => {
6447
+ var import_react38 = __toESM(require("react"), 1);
6448
+ var import_jsx_runtime348 = require("react/jsx-runtime");
6449
+ var TableRow = import_react38.default.memo((props) => {
6064
6450
  const {
6065
6451
  children,
6066
6452
  type = "secondary",
@@ -6069,14 +6455,14 @@ var TableRow = import_react37.default.memo((props) => {
6069
6455
  onClick
6070
6456
  } = props;
6071
6457
  const { rowBorderUse } = useTableContext();
6072
- const [stickyCells, setStickyCells] = import_react37.default.useState([]);
6458
+ const [stickyCells, setStickyCells] = import_react38.default.useState([]);
6073
6459
  const registerStickyCell = (ref) => {
6074
6460
  setStickyCells((prev) => {
6075
6461
  if (prev.includes(ref)) return prev;
6076
6462
  return [...prev, ref];
6077
6463
  });
6078
6464
  };
6079
- return /* @__PURE__ */ (0, import_jsx_runtime347.jsx)(TableRowContext_default.Provider, { value: { stickyCells, registerStickyCell }, children: /* @__PURE__ */ (0, import_jsx_runtime347.jsx)(
6465
+ return /* @__PURE__ */ (0, import_jsx_runtime348.jsx)(TableRowContext_default.Provider, { value: { stickyCells, registerStickyCell }, children: /* @__PURE__ */ (0, import_jsx_runtime348.jsx)(
6080
6466
  "tr",
6081
6467
  {
6082
6468
  className: clsx_default(
@@ -6100,29 +6486,31 @@ TableRow.displayName = "TableRow";
6100
6486
  var TableRow_default = TableRow;
6101
6487
 
6102
6488
  // src/components/Tag/Tag.tsx
6103
- var import_jsx_runtime348 = require("react/jsx-runtime");
6489
+ var import_jsx_runtime349 = require("react/jsx-runtime");
6104
6490
  var Tag = (props) => {
6105
6491
  const {
6106
6492
  children,
6107
- type = "neutral",
6493
+ variant,
6494
+ type,
6108
6495
  onClose,
6109
6496
  size = "md",
6110
6497
  disabled = false,
6111
6498
  colorIndex
6112
6499
  } = props;
6113
- return /* @__PURE__ */ (0, import_jsx_runtime348.jsxs)(
6500
+ const shape = variant ?? type ?? "neutral";
6501
+ return /* @__PURE__ */ (0, import_jsx_runtime349.jsxs)(
6114
6502
  "span",
6115
6503
  {
6116
6504
  className: clsx_default(
6117
6505
  "lib-xplat-tag",
6118
- type,
6506
+ shape,
6119
6507
  size,
6120
- type === "categorical" && colorIndex !== void 0 && `cat-${colorIndex}`,
6508
+ shape === "categorical" && colorIndex !== void 0 && `cat-${colorIndex}`,
6121
6509
  disabled && "disabled"
6122
6510
  ),
6123
6511
  children: [
6124
- /* @__PURE__ */ (0, import_jsx_runtime348.jsx)("span", { className: "tag-label", children }),
6125
- onClose && /* @__PURE__ */ (0, import_jsx_runtime348.jsx)("button", { className: "tag-close", onClick: onClose, "aria-label": "\uC0AD\uC81C", disabled, children: /* @__PURE__ */ (0, import_jsx_runtime348.jsx)(XIcon_default, {}) })
6512
+ /* @__PURE__ */ (0, import_jsx_runtime349.jsx)("span", { className: "tag-label", children }),
6513
+ onClose && /* @__PURE__ */ (0, import_jsx_runtime349.jsx)("button", { className: "tag-close", onClick: onClose, "aria-label": "\uC0AD\uC81C", disabled, children: /* @__PURE__ */ (0, import_jsx_runtime349.jsx)(XIcon_default, {}) })
6126
6514
  ]
6127
6515
  }
6128
6516
  );
@@ -6131,24 +6519,29 @@ Tag.displayName = "Tag";
6131
6519
  var Tag_default = Tag;
6132
6520
 
6133
6521
  // src/components/TextArea/TextArea.tsx
6134
- var import_react38 = __toESM(require("react"), 1);
6135
- var import_jsx_runtime349 = require("react/jsx-runtime");
6136
- var TextArea = import_react38.default.forwardRef(
6522
+ var import_react39 = __toESM(require("react"), 1);
6523
+ var import_jsx_runtime350 = require("react/jsx-runtime");
6524
+ var TextArea = import_react39.default.forwardRef(
6137
6525
  (props, ref) => {
6138
6526
  const {
6139
6527
  className,
6140
6528
  size = "md",
6141
6529
  validations,
6530
+ label,
6531
+ required,
6142
6532
  resize = "vertical",
6143
6533
  rows = 3,
6144
6534
  disabled,
6145
6535
  ...textareaProps
6146
6536
  } = props;
6147
- const control = /* @__PURE__ */ (0, import_jsx_runtime349.jsx)("div", { className: clsx_default("lib-xplat-textarea-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime349.jsx)(
6537
+ const autoId = import_react39.default.useId();
6538
+ const fieldId = props.id ?? autoId;
6539
+ const control = /* @__PURE__ */ (0, import_jsx_runtime350.jsx)("div", { className: clsx_default("lib-xplat-textarea-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime350.jsx)(
6148
6540
  "textarea",
6149
6541
  {
6150
6542
  ...textareaProps,
6151
6543
  ref,
6544
+ id: fieldId,
6152
6545
  rows,
6153
6546
  disabled,
6154
6547
  "aria-invalid": hasError(validations) || void 0,
@@ -6156,32 +6549,166 @@ var TextArea = import_react38.default.forwardRef(
6156
6549
  style: { resize }
6157
6550
  }
6158
6551
  ) });
6159
- return /* @__PURE__ */ (0, import_jsx_runtime349.jsx)(Field, { validations, children: control });
6552
+ return /* @__PURE__ */ (0, import_jsx_runtime350.jsx)(Field, { validations, label, required, htmlFor: fieldId, children: control });
6160
6553
  }
6161
6554
  );
6162
6555
  TextArea.displayName = "TextArea";
6163
6556
  var TextArea_default = TextArea;
6164
6557
 
6558
+ // src/components/TimePicker/TimePicker.tsx
6559
+ var import_react40 = __toESM(require("react"), 1);
6560
+ var import_jsx_runtime351 = require("react/jsx-runtime");
6561
+ var ANIMATION_DURATION_MS4 = 200;
6562
+ var toMinutes = (hhmm) => {
6563
+ if (!hhmm) return null;
6564
+ const m = /^(\d{1,2}):(\d{2})$/.exec(hhmm.trim());
6565
+ if (!m) return null;
6566
+ const h = Number(m[1]);
6567
+ const min = Number(m[2]);
6568
+ if (h > 23 || min > 59) return null;
6569
+ return h * 60 + min;
6570
+ };
6571
+ var toHHmm = (minutes) => `${String(Math.floor(minutes / 60)).padStart(2, "0")}:${String(minutes % 60).padStart(2, "0")}`;
6572
+ var display = (hhmm, use12Hours) => {
6573
+ if (!use12Hours) return hhmm;
6574
+ const total = toMinutes(hhmm);
6575
+ if (total === null) return hhmm;
6576
+ const h24 = Math.floor(total / 60);
6577
+ const mm = String(total % 60).padStart(2, "0");
6578
+ const period = h24 < 12 ? "\uC624\uC804" : "\uC624\uD6C4";
6579
+ const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
6580
+ return `${period} ${h12}:${mm}`;
6581
+ };
6582
+ var TimePicker = (props) => {
6583
+ const {
6584
+ value,
6585
+ onChange,
6586
+ step = 30,
6587
+ min,
6588
+ max,
6589
+ use12Hours = false,
6590
+ placeholder = "\uC2DC\uAC01 \uC120\uD0DD",
6591
+ disabled = false,
6592
+ size = "md",
6593
+ label,
6594
+ required,
6595
+ validations
6596
+ } = props;
6597
+ const fieldId = import_react40.default.useId();
6598
+ const triggerRef = import_react40.default.useRef(null);
6599
+ const contentRef = import_react40.default.useRef(null);
6600
+ const [isOpen, setOpen] = import_react40.default.useState(false);
6601
+ const [mounted, setMounted] = import_react40.default.useState(false);
6602
+ const [visible, setVisible] = import_react40.default.useState(false);
6603
+ const options = import_react40.default.useMemo(() => {
6604
+ const safeStep = step > 0 && step <= 720 ? step : 30;
6605
+ const lo = toMinutes(min) ?? 0;
6606
+ const hi = toMinutes(max) ?? 24 * 60 - 1;
6607
+ const out = [];
6608
+ for (let t = lo; t <= hi; t += safeStep) out.push(toHHmm(t));
6609
+ return out;
6610
+ }, [step, min, max]);
6611
+ const close = import_react40.default.useCallback(() => setOpen(false), []);
6612
+ useClickOutside_default([triggerRef, contentRef], close, isOpen);
6613
+ useEscapeKey(isOpen, () => {
6614
+ close();
6615
+ triggerRef.current?.focus({ preventScroll: true });
6616
+ });
6617
+ const position = useAutoPosition_default(triggerRef, contentRef, mounted);
6618
+ import_react40.default.useEffect(() => {
6619
+ if (disabled && isOpen) setOpen(false);
6620
+ }, [disabled, isOpen]);
6621
+ import_react40.default.useEffect(() => {
6622
+ if (isOpen) {
6623
+ setMounted(true);
6624
+ const t2 = setTimeout(() => setVisible(true), 1);
6625
+ return () => clearTimeout(t2);
6626
+ }
6627
+ setVisible(false);
6628
+ const t = setTimeout(() => setMounted(false), ANIMATION_DURATION_MS4);
6629
+ return () => clearTimeout(t);
6630
+ }, [isOpen]);
6631
+ const pick = (hhmm) => {
6632
+ onChange?.(hhmm);
6633
+ close();
6634
+ triggerRef.current?.focus({ preventScroll: true });
6635
+ };
6636
+ const control = /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)("div", { className: clsx_default("lib-xplat-time-picker", size, disabled && "disabled"), children: [
6637
+ /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6638
+ "div",
6639
+ {
6640
+ id: fieldId,
6641
+ ref: triggerRef,
6642
+ className: clsx_default("time-picker-trigger", hasError(validations) && "error"),
6643
+ role: "combobox",
6644
+ "aria-expanded": isOpen,
6645
+ "aria-haspopup": "listbox",
6646
+ "aria-invalid": hasError(validations) || void 0,
6647
+ tabIndex: disabled ? void 0 : 0,
6648
+ onClick: () => !disabled && setOpen((p) => !p),
6649
+ onKeyDown: (e) => {
6650
+ if (disabled) return;
6651
+ if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
6652
+ e.preventDefault();
6653
+ setOpen(true);
6654
+ }
6655
+ },
6656
+ children: /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("span", { className: clsx_default("time-picker-value", !value && "placeholder"), children: value ? display(value, use12Hours) : placeholder })
6657
+ }
6658
+ ),
6659
+ mounted && /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6660
+ "div",
6661
+ {
6662
+ ref: contentRef,
6663
+ className: clsx_default("lib-xplat-time-picker-content", size, visible ? "enter" : "exit"),
6664
+ style: { ...position.position, width: triggerRef.current?.offsetWidth },
6665
+ role: "listbox",
6666
+ children: options.map((t) => /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6667
+ "div",
6668
+ {
6669
+ className: clsx_default("time-picker-item", t === value && "is-selected"),
6670
+ role: "option",
6671
+ "aria-selected": t === value,
6672
+ tabIndex: 0,
6673
+ onClick: () => pick(t),
6674
+ onKeyDown: (e) => {
6675
+ if (e.key === "Enter" || e.key === " ") {
6676
+ e.preventDefault();
6677
+ pick(t);
6678
+ }
6679
+ },
6680
+ children: display(t, use12Hours)
6681
+ },
6682
+ t
6683
+ ))
6684
+ }
6685
+ ) })
6686
+ ] });
6687
+ return /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(Field, { validations, label, required, htmlFor: fieldId, children: control });
6688
+ };
6689
+ TimePicker.displayName = "TimePicker";
6690
+ var TimePicker_default = TimePicker;
6691
+
6165
6692
  // src/components/Toast/Toast.tsx
6166
- var import_react39 = __toESM(require("react"), 1);
6693
+ var import_react41 = __toESM(require("react"), 1);
6167
6694
  var import_react_dom4 = require("react-dom");
6168
- var import_jsx_runtime350 = require("react/jsx-runtime");
6169
- var ToastContext = import_react39.default.createContext(null);
6695
+ var import_jsx_runtime352 = require("react/jsx-runtime");
6696
+ var ToastContext = import_react41.default.createContext(null);
6170
6697
  var useToast = () => {
6171
- const ctx = import_react39.default.useContext(ToastContext);
6698
+ const ctx = import_react41.default.useContext(ToastContext);
6172
6699
  if (!ctx) throw new Error("useToast must be used within ToastProvider");
6173
6700
  return ctx;
6174
6701
  };
6175
6702
  var EXIT_DURATION = 300;
6176
6703
  var ToastItemComponent = ({ item, isExiting, onClose }) => {
6177
- const ref = import_react39.default.useRef(null);
6178
- const [height, setHeight] = import_react39.default.useState(void 0);
6179
- import_react39.default.useEffect(() => {
6704
+ const ref = import_react41.default.useRef(null);
6705
+ const [height, setHeight] = import_react41.default.useState(void 0);
6706
+ import_react41.default.useEffect(() => {
6180
6707
  if (ref.current && !isExiting) {
6181
6708
  setHeight(ref.current.offsetHeight);
6182
6709
  }
6183
6710
  }, [isExiting]);
6184
- return /* @__PURE__ */ (0, import_jsx_runtime350.jsx)(
6711
+ return /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
6185
6712
  "div",
6186
6713
  {
6187
6714
  className: clsx_default("lib-xplat-toast-wrapper", { exit: isExiting }),
@@ -6189,15 +6716,15 @@ var ToastItemComponent = ({ item, isExiting, onClose }) => {
6189
6716
  maxHeight: isExiting ? 0 : height ?? "none",
6190
6717
  marginBottom: isExiting ? 0 : void 0
6191
6718
  },
6192
- children: /* @__PURE__ */ (0, import_jsx_runtime350.jsxs)(
6719
+ children: /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)(
6193
6720
  "div",
6194
6721
  {
6195
6722
  ref,
6196
6723
  className: clsx_default("lib-xplat-toast", item.type, { exit: isExiting }),
6197
6724
  role: "alert",
6198
6725
  children: [
6199
- /* @__PURE__ */ (0, import_jsx_runtime350.jsx)("span", { className: "message", children: item.message }),
6200
- /* @__PURE__ */ (0, import_jsx_runtime350.jsx)("button", { className: "close-btn", onClick: onClose, "aria-label": "\uB2EB\uAE30", children: "\xD7" })
6726
+ /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("span", { className: "message", children: item.message }),
6727
+ /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("button", { className: "close-btn", onClick: onClose, "aria-label": "\uB2EB\uAE30", children: "\xD7" })
6201
6728
  ]
6202
6729
  }
6203
6730
  )
@@ -6208,13 +6735,13 @@ var ToastProvider = ({
6208
6735
  children,
6209
6736
  position = "top-right"
6210
6737
  }) => {
6211
- const [toasts, setToasts] = import_react39.default.useState([]);
6212
- const [removing, setRemoving] = import_react39.default.useState(/* @__PURE__ */ new Set());
6213
- const [mounted, setMounted] = import_react39.default.useState(false);
6214
- import_react39.default.useEffect(() => {
6738
+ const [toasts, setToasts] = import_react41.default.useState([]);
6739
+ const [removing, setRemoving] = import_react41.default.useState(/* @__PURE__ */ new Set());
6740
+ const [mounted, setMounted] = import_react41.default.useState(false);
6741
+ import_react41.default.useEffect(() => {
6215
6742
  setMounted(true);
6216
6743
  }, []);
6217
- const remove = import_react39.default.useCallback((id) => {
6744
+ const remove = import_react41.default.useCallback((id) => {
6218
6745
  setRemoving((prev) => new Set(prev).add(id));
6219
6746
  setTimeout(() => {
6220
6747
  setToasts((prev) => prev.filter((t) => t.id !== id));
@@ -6225,7 +6752,7 @@ var ToastProvider = ({
6225
6752
  });
6226
6753
  }, EXIT_DURATION);
6227
6754
  }, []);
6228
- const toast = import_react39.default.useCallback(
6755
+ const toast = import_react41.default.useCallback(
6229
6756
  (type, message, duration = 3e3) => {
6230
6757
  const id = `${Date.now()}-${Math.random()}`;
6231
6758
  setToasts((prev) => [...prev, { id, type, message }]);
@@ -6235,10 +6762,10 @@ var ToastProvider = ({
6235
6762
  },
6236
6763
  [remove]
6237
6764
  );
6238
- return /* @__PURE__ */ (0, import_jsx_runtime350.jsxs)(ToastContext.Provider, { value: { toast }, children: [
6765
+ return /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)(ToastContext.Provider, { value: { toast }, children: [
6239
6766
  children,
6240
6767
  mounted && (0, import_react_dom4.createPortal)(
6241
- /* @__PURE__ */ (0, import_jsx_runtime350.jsx)("div", { className: clsx_default("lib-xplat-toast-container", position), children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime350.jsx)(
6768
+ /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("div", { className: clsx_default("lib-xplat-toast-container", position), children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
6242
6769
  ToastItemComponent,
6243
6770
  {
6244
6771
  item: t,
@@ -6254,8 +6781,8 @@ var ToastProvider = ({
6254
6781
  ToastProvider.displayName = "ToastProvider";
6255
6782
 
6256
6783
  // src/components/Tooltip/Tooltip.tsx
6257
- var import_react40 = __toESM(require("react"), 1);
6258
- var import_jsx_runtime351 = require("react/jsx-runtime");
6784
+ var import_react42 = __toESM(require("react"), 1);
6785
+ var import_jsx_runtime353 = require("react/jsx-runtime");
6259
6786
  var OFFSET = 12;
6260
6787
  var GAP = 8;
6261
6788
  var SHOW_DELAY = 300;
@@ -6264,18 +6791,20 @@ var Tooltip = (props) => {
6264
6791
  children,
6265
6792
  title,
6266
6793
  description,
6267
- type = "dark",
6794
+ variant,
6795
+ type,
6268
6796
  follow = false,
6269
6797
  disabled = false
6270
6798
  } = props;
6271
- const triggerRef = import_react40.default.useRef(null);
6272
- const tooltipRef = import_react40.default.useRef(null);
6273
- const [visible, setVisible] = import_react40.default.useState(false);
6274
- const [pos, setPos] = import_react40.default.useState({ left: 0, top: 0 });
6275
- const delayTimer = import_react40.default.useRef(0);
6276
- const rafRef = import_react40.default.useRef(0);
6277
- const cursor = import_react40.default.useRef(null);
6278
- const clamp = import_react40.default.useCallback((left, top, w, h) => {
6799
+ const shape = variant ?? type ?? "dark";
6800
+ const triggerRef = import_react42.default.useRef(null);
6801
+ const tooltipRef = import_react42.default.useRef(null);
6802
+ const [visible, setVisible] = import_react42.default.useState(false);
6803
+ const [pos, setPos] = import_react42.default.useState({ left: 0, top: 0 });
6804
+ const delayTimer = import_react42.default.useRef(0);
6805
+ const rafRef = import_react42.default.useRef(0);
6806
+ const cursor = import_react42.default.useRef(null);
6807
+ const clamp = import_react42.default.useCallback((left, top, w, h) => {
6279
6808
  const vw = window.innerWidth;
6280
6809
  const vh = window.innerHeight;
6281
6810
  return {
@@ -6283,7 +6812,7 @@ var Tooltip = (props) => {
6283
6812
  top: Math.min(Math.max(GAP, top), Math.max(GAP, vh - h - GAP))
6284
6813
  };
6285
6814
  }, []);
6286
- const placeAtCursor = import_react40.default.useCallback((x, y) => {
6815
+ const placeAtCursor = import_react42.default.useCallback((x, y) => {
6287
6816
  const el = tooltipRef.current;
6288
6817
  if (!el) return;
6289
6818
  const w = el.offsetWidth;
@@ -6294,7 +6823,7 @@ var Tooltip = (props) => {
6294
6823
  if (top < GAP) top = y + OFFSET;
6295
6824
  setPos(clamp(left, top, w, h));
6296
6825
  }, [clamp]);
6297
- const placeAtTrigger = import_react40.default.useCallback(() => {
6826
+ const placeAtTrigger = import_react42.default.useCallback(() => {
6298
6827
  const el = tooltipRef.current;
6299
6828
  const trigger = triggerRef.current;
6300
6829
  if (!el || !trigger) return;
@@ -6306,19 +6835,19 @@ var Tooltip = (props) => {
6306
6835
  const left = rect.left + rect.width / 2 - w / 2;
6307
6836
  setPos(clamp(left, top, w, h));
6308
6837
  }, [clamp]);
6309
- const reposition = import_react40.default.useCallback(() => {
6838
+ const reposition = import_react42.default.useCallback(() => {
6310
6839
  if (follow && cursor.current) {
6311
6840
  placeAtCursor(cursor.current.x, cursor.current.y);
6312
6841
  } else {
6313
6842
  placeAtTrigger();
6314
6843
  }
6315
6844
  }, [follow, placeAtCursor, placeAtTrigger]);
6316
- const handleMouseEnter = import_react40.default.useCallback((e) => {
6845
+ const handleMouseEnter = import_react42.default.useCallback((e) => {
6317
6846
  if (disabled) return;
6318
6847
  cursor.current = { x: e.clientX, y: e.clientY };
6319
6848
  delayTimer.current = window.setTimeout(() => setVisible(true), SHOW_DELAY);
6320
6849
  }, [disabled]);
6321
- const handleMouseMove = import_react40.default.useCallback((e) => {
6850
+ const handleMouseMove = import_react42.default.useCallback((e) => {
6322
6851
  cursor.current = { x: e.clientX, y: e.clientY };
6323
6852
  if (!visible || !follow) return;
6324
6853
  cancelAnimationFrame(rafRef.current);
@@ -6326,25 +6855,25 @@ var Tooltip = (props) => {
6326
6855
  if (cursor.current) placeAtCursor(cursor.current.x, cursor.current.y);
6327
6856
  });
6328
6857
  }, [visible, follow, placeAtCursor]);
6329
- const close = import_react40.default.useCallback(() => {
6858
+ const close = import_react42.default.useCallback(() => {
6330
6859
  window.clearTimeout(delayTimer.current);
6331
6860
  cancelAnimationFrame(rafRef.current);
6332
6861
  setVisible(false);
6333
6862
  }, []);
6334
- const handleMouseLeave = import_react40.default.useCallback(() => {
6863
+ const handleMouseLeave = import_react42.default.useCallback(() => {
6335
6864
  cursor.current = null;
6336
6865
  close();
6337
6866
  }, [close]);
6338
- const handleFocus = import_react40.default.useCallback(() => {
6867
+ const handleFocus = import_react42.default.useCallback(() => {
6339
6868
  if (disabled) return;
6340
6869
  cursor.current = null;
6341
6870
  setVisible(true);
6342
6871
  }, [disabled]);
6343
- import_react40.default.useLayoutEffect(() => {
6872
+ import_react42.default.useLayoutEffect(() => {
6344
6873
  if (!visible) return;
6345
6874
  reposition();
6346
6875
  }, [visible, reposition]);
6347
- import_react40.default.useEffect(() => {
6876
+ import_react42.default.useEffect(() => {
6348
6877
  if (!visible || follow) return;
6349
6878
  const onChange = () => placeAtTrigger();
6350
6879
  window.addEventListener("scroll", onChange, true);
@@ -6354,12 +6883,12 @@ var Tooltip = (props) => {
6354
6883
  window.removeEventListener("resize", onChange);
6355
6884
  };
6356
6885
  }, [visible, follow, placeAtTrigger]);
6357
- import_react40.default.useEffect(() => () => {
6886
+ import_react42.default.useEffect(() => () => {
6358
6887
  window.clearTimeout(delayTimer.current);
6359
6888
  cancelAnimationFrame(rafRef.current);
6360
6889
  }, []);
6361
- if (!title && !description) return /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(import_jsx_runtime351.Fragment, { children });
6362
- return /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)(
6890
+ if (!title && !description) return /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(import_jsx_runtime353.Fragment, { children });
6891
+ return /* @__PURE__ */ (0, import_jsx_runtime353.jsxs)(
6363
6892
  "div",
6364
6893
  {
6365
6894
  ref: triggerRef,
@@ -6372,16 +6901,16 @@ var Tooltip = (props) => {
6372
6901
  onBlur: close,
6373
6902
  children: [
6374
6903
  children,
6375
- visible && /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)(
6904
+ visible && /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime353.jsxs)(
6376
6905
  "div",
6377
6906
  {
6378
6907
  ref: tooltipRef,
6379
6908
  role: "tooltip",
6380
- className: clsx_default("lib-xplat-tooltip", type),
6909
+ className: clsx_default("lib-xplat-tooltip", shape),
6381
6910
  style: { position: "fixed", left: pos.left, top: pos.top },
6382
6911
  children: [
6383
- title && /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("div", { className: "tooltip-title", children: title }),
6384
- description && /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("div", { className: "tooltip-desc", children: description })
6912
+ title && /* @__PURE__ */ (0, import_jsx_runtime353.jsx)("div", { className: "tooltip-title", children: title }),
6913
+ description && /* @__PURE__ */ (0, import_jsx_runtime353.jsx)("div", { className: "tooltip-desc", children: description })
6385
6914
  ]
6386
6915
  }
6387
6916
  ) })
@@ -6393,11 +6922,11 @@ Tooltip.displayName = "Tooltip";
6393
6922
  var Tooltip_default = Tooltip;
6394
6923
 
6395
6924
  // src/components/Video/Video.tsx
6396
- var import_react41 = __toESM(require("react"), 1);
6397
- var import_jsx_runtime352 = require("react/jsx-runtime");
6398
- var PipIcon = () => /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)("svg", { viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
6399
- /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2" }),
6400
- /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("rect", { x: "12", y: "11", width: "7", height: "6", rx: "1", fill: "currentColor" })
6925
+ var import_react43 = __toESM(require("react"), 1);
6926
+ var import_jsx_runtime354 = require("react/jsx-runtime");
6927
+ var PipIcon = () => /* @__PURE__ */ (0, import_jsx_runtime354.jsxs)("svg", { viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
6928
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsx)("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2" }),
6929
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsx)("rect", { x: "12", y: "11", width: "7", height: "6", rx: "1", fill: "currentColor" })
6401
6930
  ] });
6402
6931
  var formatTime = (sec) => {
6403
6932
  if (!Number.isFinite(sec) || sec < 0) return "0:00";
@@ -6405,7 +6934,7 @@ var formatTime = (sec) => {
6405
6934
  const s = Math.floor(sec % 60);
6406
6935
  return `${m}:${s.toString().padStart(2, "0")}`;
6407
6936
  };
6408
- var Video = import_react41.default.forwardRef((props, ref) => {
6937
+ var Video = import_react43.default.forwardRef((props, ref) => {
6409
6938
  const {
6410
6939
  src,
6411
6940
  poster,
@@ -6429,21 +6958,21 @@ var Video = import_react41.default.forwardRef((props, ref) => {
6429
6958
  children,
6430
6959
  ...rest
6431
6960
  } = props;
6432
- const containerRef = import_react41.default.useRef(null);
6433
- const videoRef = import_react41.default.useRef(null);
6434
- const [isPlaying, setIsPlaying] = import_react41.default.useState(Boolean(autoPlay));
6435
- const [isLoaded, setIsLoaded] = import_react41.default.useState(false);
6436
- const [currentTime, setCurrentTime] = import_react41.default.useState(0);
6437
- const [duration, setDuration] = import_react41.default.useState(0);
6438
- const [buffered, setBuffered] = import_react41.default.useState(0);
6439
- const [volume, setVolume] = import_react41.default.useState(1);
6440
- const [isMuted, setIsMuted] = import_react41.default.useState(Boolean(muted));
6441
- const [isFullscreen, setIsFullscreen] = import_react41.default.useState(false);
6442
- const [playbackRate, setPlaybackRate] = import_react41.default.useState(1);
6443
- const [rateMenuOpen, setRateMenuOpen] = import_react41.default.useState(false);
6444
- const [captionsOn, setCaptionsOn] = import_react41.default.useState(false);
6445
- const [isPip, setIsPip] = import_react41.default.useState(false);
6446
- const setRefs = import_react41.default.useCallback(
6961
+ const containerRef = import_react43.default.useRef(null);
6962
+ const videoRef = import_react43.default.useRef(null);
6963
+ const [isPlaying, setIsPlaying] = import_react43.default.useState(Boolean(autoPlay));
6964
+ const [isLoaded, setIsLoaded] = import_react43.default.useState(false);
6965
+ const [currentTime, setCurrentTime] = import_react43.default.useState(0);
6966
+ const [duration, setDuration] = import_react43.default.useState(0);
6967
+ const [buffered, setBuffered] = import_react43.default.useState(0);
6968
+ const [volume, setVolume] = import_react43.default.useState(1);
6969
+ const [isMuted, setIsMuted] = import_react43.default.useState(Boolean(muted));
6970
+ const [isFullscreen, setIsFullscreen] = import_react43.default.useState(false);
6971
+ const [playbackRate, setPlaybackRate] = import_react43.default.useState(1);
6972
+ const [rateMenuOpen, setRateMenuOpen] = import_react43.default.useState(false);
6973
+ const [captionsOn, setCaptionsOn] = import_react43.default.useState(false);
6974
+ const [isPip, setIsPip] = import_react43.default.useState(false);
6975
+ const setRefs = import_react43.default.useCallback(
6447
6976
  (el) => {
6448
6977
  videoRef.current = el;
6449
6978
  if (typeof ref === "function") ref(el);
@@ -6451,14 +6980,14 @@ var Video = import_react41.default.forwardRef((props, ref) => {
6451
6980
  },
6452
6981
  [ref]
6453
6982
  );
6454
- import_react41.default.useEffect(() => {
6983
+ import_react43.default.useEffect(() => {
6455
6984
  const onFsChange = () => {
6456
6985
  setIsFullscreen(document.fullscreenElement === containerRef.current);
6457
6986
  };
6458
6987
  document.addEventListener("fullscreenchange", onFsChange);
6459
6988
  return () => document.removeEventListener("fullscreenchange", onFsChange);
6460
6989
  }, []);
6461
- import_react41.default.useEffect(() => {
6990
+ import_react43.default.useEffect(() => {
6462
6991
  const v = videoRef.current;
6463
6992
  if (!v) return;
6464
6993
  const onEnter = () => setIsPip(true);
@@ -6572,13 +7101,13 @@ var Video = import_react41.default.forwardRef((props, ref) => {
6572
7101
  const volumePct = (isMuted ? 0 : volume) * 100;
6573
7102
  const VolumeGlyph = isMuted || volume === 0 ? VolumeXIcon_default : volume < 0.5 ? VolumeIcon_default : Volume2Icon_default;
6574
7103
  const pipSupported = typeof document !== "undefined" && "pictureInPictureEnabled" in document && document.pictureInPictureEnabled;
6575
- return /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)(
7104
+ return /* @__PURE__ */ (0, import_jsx_runtime354.jsxs)(
6576
7105
  "div",
6577
7106
  {
6578
7107
  ref: containerRef,
6579
7108
  className: clsx_default("lib-xplat-video", showControls && "has-controls"),
6580
7109
  children: [
6581
- /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
7110
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(
6582
7111
  "video",
6583
7112
  {
6584
7113
  ref: setRefs,
@@ -6599,7 +7128,7 @@ var Video = import_react41.default.forwardRef((props, ref) => {
6599
7128
  children
6600
7129
  }
6601
7130
  ),
6602
- showCenterPlay && /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
7131
+ showCenterPlay && /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(
6603
7132
  "button",
6604
7133
  {
6605
7134
  type: "button",
@@ -6611,11 +7140,11 @@ var Video = import_react41.default.forwardRef((props, ref) => {
6611
7140
  onClick: togglePlay,
6612
7141
  "aria-label": isPlaying ? "\uC77C\uC2DC\uC815\uC9C0" : "\uC7AC\uC0DD",
6613
7142
  tabIndex: -1,
6614
- children: /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("span", { className: "center-play-icon", children: /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(PlayCircleIcon_default, {}) })
7143
+ children: /* @__PURE__ */ (0, import_jsx_runtime354.jsx)("span", { className: "center-play-icon", children: /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(PlayCircleIcon_default, {}) })
6615
7144
  }
6616
7145
  ),
6617
- showControls && /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)("div", { className: "controls", onClick: (e) => e.stopPropagation(), children: [
6618
- /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
7146
+ showControls && /* @__PURE__ */ (0, import_jsx_runtime354.jsxs)("div", { className: "controls", onClick: (e) => e.stopPropagation(), children: [
7147
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(
6619
7148
  "input",
6620
7149
  {
6621
7150
  type: "range",
@@ -6632,29 +7161,29 @@ var Video = import_react41.default.forwardRef((props, ref) => {
6632
7161
  }
6633
7162
  }
6634
7163
  ),
6635
- /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)("div", { className: "controls-row", children: [
6636
- /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
7164
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsxs)("div", { className: "controls-row", children: [
7165
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(
6637
7166
  "button",
6638
7167
  {
6639
7168
  type: "button",
6640
7169
  className: "control-btn",
6641
7170
  onClick: togglePlay,
6642
7171
  "aria-label": isPlaying ? "\uC77C\uC2DC\uC815\uC9C0" : "\uC7AC\uC0DD",
6643
- children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(PauseIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(PlayIcon_default, {})
7172
+ children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(PauseIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(PlayIcon_default, {})
6644
7173
  }
6645
7174
  ),
6646
- /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)("div", { className: "volume-group", children: [
6647
- /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
7175
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsxs)("div", { className: "volume-group", children: [
7176
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(
6648
7177
  "button",
6649
7178
  {
6650
7179
  type: "button",
6651
7180
  className: "control-btn",
6652
7181
  onClick: toggleMute,
6653
7182
  "aria-label": isMuted ? "\uC74C\uC18C\uAC70 \uD574\uC81C" : "\uC74C\uC18C\uAC70",
6654
- children: /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(VolumeGlyph, {})
7183
+ children: /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(VolumeGlyph, {})
6655
7184
  }
6656
7185
  ),
6657
- /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
7186
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(
6658
7187
  "input",
6659
7188
  {
6660
7189
  type: "range",
@@ -6669,14 +7198,14 @@ var Video = import_react41.default.forwardRef((props, ref) => {
6669
7198
  }
6670
7199
  )
6671
7200
  ] }),
6672
- /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)("span", { className: "time", children: [
7201
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsxs)("span", { className: "time", children: [
6673
7202
  formatTime(currentTime),
6674
7203
  " / ",
6675
7204
  formatTime(duration)
6676
7205
  ] }),
6677
- /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("div", { className: "controls-spacer" }),
6678
- playbackRates && playbackRates.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)("div", { className: clsx_default("rate-group", rateMenuOpen && "is-open"), children: [
6679
- /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)(
7206
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsx)("div", { className: "controls-spacer" }),
7207
+ playbackRates && playbackRates.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime354.jsxs)("div", { className: clsx_default("rate-group", rateMenuOpen && "is-open"), children: [
7208
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsxs)(
6680
7209
  "button",
6681
7210
  {
6682
7211
  type: "button",
@@ -6690,7 +7219,7 @@ var Video = import_react41.default.forwardRef((props, ref) => {
6690
7219
  ]
6691
7220
  }
6692
7221
  ),
6693
- rateMenuOpen && /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("ul", { className: "rate-menu", role: "menu", children: playbackRates.map((r2) => /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)(
7222
+ rateMenuOpen && /* @__PURE__ */ (0, import_jsx_runtime354.jsx)("ul", { className: "rate-menu", role: "menu", children: playbackRates.map((r2) => /* @__PURE__ */ (0, import_jsx_runtime354.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime354.jsxs)(
6694
7223
  "button",
6695
7224
  {
6696
7225
  type: "button",
@@ -6704,7 +7233,7 @@ var Video = import_react41.default.forwardRef((props, ref) => {
6704
7233
  }
6705
7234
  ) }, r2)) })
6706
7235
  ] }),
6707
- showCaptions && /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
7236
+ showCaptions && /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(
6708
7237
  "button",
6709
7238
  {
6710
7239
  type: "button",
@@ -6712,37 +7241,37 @@ var Video = import_react41.default.forwardRef((props, ref) => {
6712
7241
  onClick: toggleCaptions,
6713
7242
  "aria-label": captionsOn ? "\uC790\uB9C9 \uB044\uAE30" : "\uC790\uB9C9 \uCF1C\uAE30",
6714
7243
  "aria-pressed": captionsOn,
6715
- children: /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(TypeIcon_default, {})
7244
+ children: /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(TypeIcon_default, {})
6716
7245
  }
6717
7246
  ),
6718
- showPip && pipSupported && /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
7247
+ showPip && pipSupported && /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(
6719
7248
  "button",
6720
7249
  {
6721
7250
  type: "button",
6722
7251
  className: clsx_default("control-btn", isPip && "is-active"),
6723
7252
  onClick: togglePip,
6724
7253
  "aria-label": isPip ? "PIP \uC885\uB8CC" : "PIP",
6725
- children: /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(PipIcon, {})
7254
+ children: /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(PipIcon, {})
6726
7255
  }
6727
7256
  ),
6728
- showDownload && /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
7257
+ showDownload && /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(
6729
7258
  "a",
6730
7259
  {
6731
7260
  className: "control-btn",
6732
7261
  href: src,
6733
7262
  download: downloadFileName ?? true,
6734
7263
  "aria-label": "\uB2E4\uC6B4\uB85C\uB4DC",
6735
- children: /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(DownloadIcon_default, {})
7264
+ children: /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(DownloadIcon_default, {})
6736
7265
  }
6737
7266
  ),
6738
- /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(
7267
+ /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(
6739
7268
  "button",
6740
7269
  {
6741
7270
  type: "button",
6742
7271
  className: "control-btn",
6743
7272
  onClick: toggleFullscreen,
6744
7273
  "aria-label": isFullscreen ? "\uC804\uCCB4\uD654\uBA74 \uC885\uB8CC" : "\uC804\uCCB4\uD654\uBA74",
6745
- children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(MinimizeIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(MaximizeIcon_default, {})
7274
+ children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(MinimizeIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime354.jsx)(MaximizeIcon_default, {})
6746
7275
  }
6747
7276
  )
6748
7277
  ] })
@@ -6800,6 +7329,7 @@ var Video_default = Video;
6800
7329
  SingleDatePicker,
6801
7330
  Skeleton,
6802
7331
  Spinner,
7332
+ Stat,
6803
7333
  Steps,
6804
7334
  Swiper,
6805
7335
  Switch,
@@ -6811,6 +7341,7 @@ var Video_default = Video;
6811
7341
  TableRow,
6812
7342
  Tag,
6813
7343
  TextArea,
7344
+ TimePicker,
6814
7345
  ToastProvider,
6815
7346
  Tooltip,
6816
7347
  Video,