@x-plat/design-system 0.7.2 → 0.8.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 (41) hide show
  1. package/dist/components/AutoResizeTextArea/index.css +2 -0
  2. package/dist/components/Button/index.css +2 -1
  3. package/dist/components/Button/index.d.cts +6 -0
  4. package/dist/components/Button/index.d.ts +6 -0
  5. package/dist/components/Chart/index.cjs +8 -1
  6. package/dist/components/Chart/index.js +8 -1
  7. package/dist/components/ChatInput/index.css +4 -0
  8. package/dist/components/DatePicker/index.css +4 -1
  9. package/dist/components/Input/index.css +2 -0
  10. package/dist/components/Link/index.cjs +64 -0
  11. package/dist/components/Link/index.css +25 -0
  12. package/dist/components/Link/index.d.cts +27 -0
  13. package/dist/components/Link/index.d.ts +27 -0
  14. package/dist/components/Link/index.js +37 -0
  15. package/dist/components/LinkButton/index.cjs +64 -0
  16. package/dist/components/LinkButton/index.css +106 -0
  17. package/dist/components/LinkButton/index.d.cts +28 -0
  18. package/dist/components/LinkButton/index.d.ts +28 -0
  19. package/dist/components/LinkButton/index.js +37 -0
  20. package/dist/components/TextArea/index.css +2 -0
  21. package/dist/components/Tooltip/index.cjs +77 -32
  22. package/dist/components/Tooltip/index.d.cts +10 -2
  23. package/dist/components/Tooltip/index.d.ts +10 -2
  24. package/dist/components/Tooltip/index.js +77 -32
  25. package/dist/components/index.cjs +247 -153
  26. package/dist/components/index.css +36 -1
  27. package/dist/components/index.d.cts +2 -0
  28. package/dist/components/index.d.ts +2 -0
  29. package/dist/components/index.js +222 -130
  30. package/dist/index.cjs +266 -172
  31. package/dist/index.css +36 -1
  32. package/dist/index.d.cts +2 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +239 -147
  35. package/guidelines/AGENT_PROMPT.md +2 -2
  36. package/guidelines/Guidelines.md +2 -1
  37. package/guidelines/components/button.md +54 -0
  38. package/guidelines/components/card.md +15 -19
  39. package/guidelines/components/link.md +35 -0
  40. package/guidelines/components/overlay.md +30 -1
  41. package/package.json +1 -1
@@ -56,6 +56,8 @@ __export(components_exports, {
56
56
  ImageSelector: () => ImageSelector_default,
57
57
  Input: () => Input_default,
58
58
  InputDatePicker: () => InputDatePicker_default,
59
+ Link: () => Link_default,
60
+ LinkButton: () => LinkButton_default,
59
61
  Modal: () => Modal_default,
60
62
  NotificationBadge: () => NotificationBadge_default,
61
63
  Pagination: () => Pagination_default,
@@ -2301,9 +2303,16 @@ var useChartTooltip = (enabled) => {
2301
2303
  }, []);
2302
2304
  return { tooltip, show, hide, move, containerRef };
2303
2305
  };
2306
+ var formatTick = (value, maxVal) => {
2307
+ const step = maxVal / 4;
2308
+ if (!Number.isFinite(step) || step <= 0) return "0";
2309
+ const decimals = step >= 1 ? 0 : Math.min(4, Math.ceil(-Math.log10(step)));
2310
+ const fixed = value.toFixed(decimals);
2311
+ return decimals === 0 ? Number(fixed).toLocaleString("en-US") : fixed;
2312
+ };
2304
2313
  var GridLines = import_react6.default.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ (0, import_jsx_runtime305.jsx)(import_jsx_runtime305.Fragment, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
2305
2314
  const y = PADDING.top + (1 - ratio) * chartH;
2306
- const val = Math.round(maxVal * ratio);
2315
+ const val = formatTick(maxVal * ratio, maxVal);
2307
2316
  return /* @__PURE__ */ (0, import_jsx_runtime305.jsxs)("g", { children: [
2308
2317
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("line", { x1: PADDING.left, y1: y, x2: width - PADDING.right, y2: y, className: "chart-grid" }),
2309
2318
  /* @__PURE__ */ (0, import_jsx_runtime305.jsx)("text", { x: PADDING.left - 8, y: y + 4, className: "chart-axis-label", textAnchor: "end", children: val })
@@ -4901,8 +4910,46 @@ var ImageSelector = (props) => {
4901
4910
  ImageSelector.displayName = "ImageSelector";
4902
4911
  var ImageSelector_default = ImageSelector;
4903
4912
 
4904
- // src/components/NotificationBadge/NotificationBadge.tsx
4913
+ // src/components/Link/Link.tsx
4905
4914
  var import_jsx_runtime329 = require("react/jsx-runtime");
4915
+ var Link = (props) => {
4916
+ const { children, href, underline = "always", target, rel, ...rest } = props;
4917
+ return /* @__PURE__ */ (0, import_jsx_runtime329.jsx)(
4918
+ "a",
4919
+ {
4920
+ className: clsx_default("lib-xplat-link", `underline-${underline}`),
4921
+ href,
4922
+ target,
4923
+ rel: target === "_blank" ? rel ?? "noopener noreferrer" : rel,
4924
+ ...rest,
4925
+ children
4926
+ }
4927
+ );
4928
+ };
4929
+ Link.displayName = "Link";
4930
+ var Link_default = Link;
4931
+
4932
+ // src/components/LinkButton/LinkButton.tsx
4933
+ var import_jsx_runtime330 = require("react/jsx-runtime");
4934
+ var LinkButton = (props) => {
4935
+ const { children, href, type = "primary", size = "md", target, rel, ...rest } = props;
4936
+ return /* @__PURE__ */ (0, import_jsx_runtime330.jsx)(
4937
+ "a",
4938
+ {
4939
+ className: clsx_default("lib-xplat-button", type, size),
4940
+ href,
4941
+ target,
4942
+ rel: target === "_blank" ? rel ?? "noopener noreferrer" : rel,
4943
+ ...rest,
4944
+ children
4945
+ }
4946
+ );
4947
+ };
4948
+ LinkButton.displayName = "LinkButton";
4949
+ var LinkButton_default = LinkButton;
4950
+
4951
+ // src/components/NotificationBadge/NotificationBadge.tsx
4952
+ var import_jsx_runtime331 = require("react/jsx-runtime");
4906
4953
  var NotificationBadge = (props) => {
4907
4954
  const {
4908
4955
  children,
@@ -4914,16 +4961,16 @@ var NotificationBadge = (props) => {
4914
4961
  } = props;
4915
4962
  const showBadge = dot || count !== void 0 && count > 0;
4916
4963
  const displayCount = count !== void 0 && count > maxCount ? `${maxCount}+` : count;
4917
- return /* @__PURE__ */ (0, import_jsx_runtime329.jsxs)("div", { className: clsx_default("lib-xplat-notification-badge", size), children: [
4964
+ return /* @__PURE__ */ (0, import_jsx_runtime331.jsxs)("div", { className: clsx_default("lib-xplat-notification-badge", size), children: [
4918
4965
  children,
4919
- showBadge && /* @__PURE__ */ (0, import_jsx_runtime329.jsx)("span", { className: clsx_default("badge-indicator", type, { dot }), children: !dot && displayCount })
4966
+ showBadge && /* @__PURE__ */ (0, import_jsx_runtime331.jsx)("span", { className: clsx_default("badge-indicator", type, { dot }), children: !dot && displayCount })
4920
4967
  ] });
4921
4968
  };
4922
4969
  NotificationBadge.displayName = "NotificationBadge";
4923
4970
  var NotificationBadge_default = NotificationBadge;
4924
4971
 
4925
4972
  // src/components/Pagination/Pagination.tsx
4926
- var import_jsx_runtime330 = require("react/jsx-runtime");
4973
+ var import_jsx_runtime332 = require("react/jsx-runtime");
4927
4974
  var getPageRange = (current, totalPages, siblingCount) => {
4928
4975
  const totalNumbers = siblingCount * 2 + 5;
4929
4976
  if (totalPages <= totalNumbers) {
@@ -4966,19 +5013,19 @@ var Pagination = (props) => {
4966
5013
  onChange?.(page);
4967
5014
  }
4968
5015
  };
4969
- return /* @__PURE__ */ (0, import_jsx_runtime330.jsxs)("nav", { className: clsx_default("lib-xplat-pagination", size, type), "aria-label": "\uD398\uC774\uC9C0 \uB124\uBE44\uAC8C\uC774\uC158", children: [
4970
- /* @__PURE__ */ (0, import_jsx_runtime330.jsx)(
5016
+ return /* @__PURE__ */ (0, import_jsx_runtime332.jsxs)("nav", { className: clsx_default("lib-xplat-pagination", size, type), "aria-label": "\uD398\uC774\uC9C0 \uB124\uBE44\uAC8C\uC774\uC158", children: [
5017
+ /* @__PURE__ */ (0, import_jsx_runtime332.jsx)(
4971
5018
  "button",
4972
5019
  {
4973
5020
  className: "page-btn prev",
4974
5021
  disabled: current <= 1,
4975
5022
  onClick: () => handleClick(current - 1),
4976
5023
  "aria-label": "\uC774\uC804 \uD398\uC774\uC9C0",
4977
- children: /* @__PURE__ */ (0, import_jsx_runtime330.jsx)(ChevronLeftIcon_default, {})
5024
+ children: /* @__PURE__ */ (0, import_jsx_runtime332.jsx)(ChevronLeftIcon_default, {})
4978
5025
  }
4979
5026
  ),
4980
5027
  pages.map(
4981
- (page, i) => page === "..." ? /* @__PURE__ */ (0, import_jsx_runtime330.jsx)("span", { className: "dots", children: "..." }, `dots-${i}`) : /* @__PURE__ */ (0, import_jsx_runtime330.jsx)(
5028
+ (page, i) => page === "..." ? /* @__PURE__ */ (0, import_jsx_runtime332.jsx)("span", { className: "dots", children: "..." }, `dots-${i}`) : /* @__PURE__ */ (0, import_jsx_runtime332.jsx)(
4982
5029
  "button",
4983
5030
  {
4984
5031
  className: clsx_default("page-btn", { active: page === current }),
@@ -4989,14 +5036,14 @@ var Pagination = (props) => {
4989
5036
  page
4990
5037
  )
4991
5038
  ),
4992
- /* @__PURE__ */ (0, import_jsx_runtime330.jsx)(
5039
+ /* @__PURE__ */ (0, import_jsx_runtime332.jsx)(
4993
5040
  "button",
4994
5041
  {
4995
5042
  className: "page-btn next",
4996
5043
  disabled: current >= totalPages,
4997
5044
  onClick: () => handleClick(current + 1),
4998
5045
  "aria-label": "\uB2E4\uC74C \uD398\uC774\uC9C0",
4999
- children: /* @__PURE__ */ (0, import_jsx_runtime330.jsx)(ChevronRightIcon_default, {})
5046
+ children: /* @__PURE__ */ (0, import_jsx_runtime332.jsx)(ChevronRightIcon_default, {})
5000
5047
  }
5001
5048
  )
5002
5049
  ] });
@@ -5006,7 +5053,7 @@ var Pagination_default = Pagination;
5006
5053
 
5007
5054
  // src/components/PopOver/PopOver.tsx
5008
5055
  var import_react28 = __toESM(require("react"), 1);
5009
- var import_jsx_runtime331 = require("react/jsx-runtime");
5056
+ var import_jsx_runtime333 = require("react/jsx-runtime");
5010
5057
  var PopOver = (props) => {
5011
5058
  const { children, isOpen, onClose, PopOverEl } = props;
5012
5059
  const popRef = import_react28.default.useRef(null);
@@ -5028,7 +5075,7 @@ var PopOver = (props) => {
5028
5075
  }, 200);
5029
5076
  }
5030
5077
  }, [isOpen]);
5031
- return /* @__PURE__ */ (0, import_jsx_runtime331.jsxs)(
5078
+ return /* @__PURE__ */ (0, import_jsx_runtime333.jsxs)(
5032
5079
  "div",
5033
5080
  {
5034
5081
  className: "lib-xplat-pop-over",
@@ -5038,7 +5085,7 @@ var PopOver = (props) => {
5038
5085
  },
5039
5086
  children: [
5040
5087
  children,
5041
- localOpen && /* @__PURE__ */ (0, import_jsx_runtime331.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime331.jsx)(
5088
+ localOpen && /* @__PURE__ */ (0, import_jsx_runtime333.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime333.jsx)(
5042
5089
  "div",
5043
5090
  {
5044
5091
  className: clsx_default(
@@ -5061,7 +5108,7 @@ PopOver.displayName = "PopOver";
5061
5108
  var PopOver_default = PopOver;
5062
5109
 
5063
5110
  // src/components/Progress/Progress.tsx
5064
- var import_jsx_runtime332 = require("react/jsx-runtime");
5111
+ var import_jsx_runtime334 = require("react/jsx-runtime");
5065
5112
  var Progress = (props) => {
5066
5113
  const {
5067
5114
  value,
@@ -5071,8 +5118,8 @@ var Progress = (props) => {
5071
5118
  showLabel = false
5072
5119
  } = props;
5073
5120
  const percentage = Math.min(100, Math.max(0, value / max * 100));
5074
- return /* @__PURE__ */ (0, import_jsx_runtime332.jsxs)("div", { className: clsx_default("lib-xplat-progress", size, type), children: [
5075
- /* @__PURE__ */ (0, import_jsx_runtime332.jsx)(
5121
+ return /* @__PURE__ */ (0, import_jsx_runtime334.jsxs)("div", { className: clsx_default("lib-xplat-progress", size, type), children: [
5122
+ /* @__PURE__ */ (0, import_jsx_runtime334.jsx)(
5076
5123
  "div",
5077
5124
  {
5078
5125
  className: "track",
@@ -5080,7 +5127,7 @@ var Progress = (props) => {
5080
5127
  "aria-valuenow": value,
5081
5128
  "aria-valuemin": 0,
5082
5129
  "aria-valuemax": max,
5083
- children: /* @__PURE__ */ (0, import_jsx_runtime332.jsx)(
5130
+ children: /* @__PURE__ */ (0, import_jsx_runtime334.jsx)(
5084
5131
  "div",
5085
5132
  {
5086
5133
  className: "bar",
@@ -5089,7 +5136,7 @@ var Progress = (props) => {
5089
5136
  )
5090
5137
  }
5091
5138
  ),
5092
- showLabel && /* @__PURE__ */ (0, import_jsx_runtime332.jsxs)("span", { className: "label", children: [
5139
+ showLabel && /* @__PURE__ */ (0, import_jsx_runtime334.jsxs)("span", { className: "label", children: [
5093
5140
  Math.round(percentage),
5094
5141
  "%"
5095
5142
  ] })
@@ -5109,7 +5156,7 @@ var useRadioGroupContext = () => {
5109
5156
  var RadioGroupContext_default = RadioGroupContext;
5110
5157
 
5111
5158
  // src/components/Radio/Radio.tsx
5112
- var import_jsx_runtime333 = require("react/jsx-runtime");
5159
+ var import_jsx_runtime335 = require("react/jsx-runtime");
5113
5160
  var Radio = (props) => {
5114
5161
  const {
5115
5162
  label,
@@ -5128,7 +5175,7 @@ var Radio = (props) => {
5128
5175
  value,
5129
5176
  onChange: rest.onChange
5130
5177
  };
5131
- return /* @__PURE__ */ (0, import_jsx_runtime333.jsxs)(
5178
+ return /* @__PURE__ */ (0, import_jsx_runtime335.jsxs)(
5132
5179
  "label",
5133
5180
  {
5134
5181
  className: clsx_default(
@@ -5139,18 +5186,18 @@ var Radio = (props) => {
5139
5186
  className
5140
5187
  ),
5141
5188
  children: [
5142
- /* @__PURE__ */ (0, import_jsx_runtime333.jsx)("input", { ...rest, ...inputProps, checked: localChecked, type: "radio" }),
5143
- /* @__PURE__ */ (0, import_jsx_runtime333.jsx)(
5189
+ /* @__PURE__ */ (0, import_jsx_runtime335.jsx)("input", { ...rest, ...inputProps, checked: localChecked, type: "radio" }),
5190
+ /* @__PURE__ */ (0, import_jsx_runtime335.jsx)(
5144
5191
  "div",
5145
5192
  {
5146
5193
  className: clsx_default(
5147
5194
  "circle",
5148
5195
  localChecked ? "checked" : void 0
5149
5196
  ),
5150
- children: localChecked && /* @__PURE__ */ (0, import_jsx_runtime333.jsx)("div", { className: "inner-circle" })
5197
+ children: localChecked && /* @__PURE__ */ (0, import_jsx_runtime335.jsx)("div", { className: "inner-circle" })
5151
5198
  }
5152
5199
  ),
5153
- label && /* @__PURE__ */ (0, import_jsx_runtime333.jsx)("span", { children: label })
5200
+ label && /* @__PURE__ */ (0, import_jsx_runtime335.jsx)("span", { children: label })
5154
5201
  ]
5155
5202
  }
5156
5203
  );
@@ -5159,10 +5206,10 @@ Radio.displayName = "Radio";
5159
5206
  var Radio_default = Radio;
5160
5207
 
5161
5208
  // src/components/Radio/RadioGroup.tsx
5162
- var import_jsx_runtime334 = require("react/jsx-runtime");
5209
+ var import_jsx_runtime336 = require("react/jsx-runtime");
5163
5210
  var RadioGroup = (props) => {
5164
5211
  const { children, ...rest } = props;
5165
- return /* @__PURE__ */ (0, import_jsx_runtime334.jsx)(import_jsx_runtime334.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime334.jsx)(RadioGroupContext_default.Provider, { value: rest, children }) });
5212
+ return /* @__PURE__ */ (0, import_jsx_runtime336.jsx)(import_jsx_runtime336.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime336.jsx)(RadioGroupContext_default.Provider, { value: rest, children }) });
5166
5213
  };
5167
5214
  RadioGroup.displayName = "RadioGroup";
5168
5215
  var RadioGroup_default = RadioGroup;
@@ -5177,7 +5224,7 @@ var context_default = SelectContext;
5177
5224
 
5178
5225
  // src/components/Select/SelectItem.tsx
5179
5226
  var import_react31 = __toESM(require("react"), 1);
5180
- var import_jsx_runtime335 = require("react/jsx-runtime");
5227
+ var import_jsx_runtime337 = require("react/jsx-runtime");
5181
5228
  var SelectItem = (props) => {
5182
5229
  const { children, value, onClick, disabled = false } = props;
5183
5230
  const ctx = import_react31.default.useContext(context_default);
@@ -5190,7 +5237,7 @@ var SelectItem = (props) => {
5190
5237
  onClick?.();
5191
5238
  };
5192
5239
  const isSelected = value !== void 0 ? ctx?.selectedValue === value : ctx?.selectedLabel === children;
5193
- return /* @__PURE__ */ (0, import_jsx_runtime335.jsx)(
5240
+ return /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(
5194
5241
  "div",
5195
5242
  {
5196
5243
  className: clsx_default("select-item", disabled && "disabled", isSelected && "is-selected"),
@@ -5211,7 +5258,7 @@ SelectItem.displayName = "Select.Item";
5211
5258
  var SelectItem_default = SelectItem;
5212
5259
 
5213
5260
  // src/components/Select/Select.tsx
5214
- var import_jsx_runtime336 = require("react/jsx-runtime");
5261
+ var import_jsx_runtime338 = require("react/jsx-runtime");
5215
5262
  var ANIMATION_DURATION_MS3 = 200;
5216
5263
  var SelectRoot = (props) => {
5217
5264
  const {
@@ -5291,7 +5338,7 @@ var SelectRoot = (props) => {
5291
5338
  if (disabled) return;
5292
5339
  toggle();
5293
5340
  };
5294
- return /* @__PURE__ */ (0, import_jsx_runtime336.jsx)(context_default.Provider, { value: ctxValue, children: /* @__PURE__ */ (0, import_jsx_runtime336.jsxs)(
5341
+ return /* @__PURE__ */ (0, import_jsx_runtime338.jsx)(context_default.Provider, { value: ctxValue, children: /* @__PURE__ */ (0, import_jsx_runtime338.jsxs)(
5295
5342
  "div",
5296
5343
  {
5297
5344
  className: clsx_default(
@@ -5302,7 +5349,7 @@ var SelectRoot = (props) => {
5302
5349
  mounted && "is-open"
5303
5350
  ),
5304
5351
  children: [
5305
- /* @__PURE__ */ (0, import_jsx_runtime336.jsxs)(
5352
+ /* @__PURE__ */ (0, import_jsx_runtime338.jsxs)(
5306
5353
  "div",
5307
5354
  {
5308
5355
  ref: triggerRef,
@@ -5326,7 +5373,7 @@ var SelectRoot = (props) => {
5326
5373
  }
5327
5374
  },
5328
5375
  children: [
5329
- /* @__PURE__ */ (0, import_jsx_runtime336.jsx)(
5376
+ /* @__PURE__ */ (0, import_jsx_runtime338.jsx)(
5330
5377
  "span",
5331
5378
  {
5332
5379
  className: clsx_default(
@@ -5336,25 +5383,25 @@ var SelectRoot = (props) => {
5336
5383
  children: selectedLabel ?? placeholder
5337
5384
  }
5338
5385
  ),
5339
- /* @__PURE__ */ (0, import_jsx_runtime336.jsx)(
5386
+ /* @__PURE__ */ (0, import_jsx_runtime338.jsx)(
5340
5387
  "span",
5341
5388
  {
5342
5389
  className: clsx_default("select-trigger-icon", isOpen && "open"),
5343
5390
  "aria-hidden": true,
5344
- children: /* @__PURE__ */ (0, import_jsx_runtime336.jsx)(ChevronDownIcon_default, {})
5391
+ children: /* @__PURE__ */ (0, import_jsx_runtime338.jsx)(ChevronDownIcon_default, {})
5345
5392
  }
5346
5393
  )
5347
5394
  ]
5348
5395
  }
5349
5396
  ),
5350
- mounted && /* @__PURE__ */ (0, import_jsx_runtime336.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime336.jsx)(
5397
+ mounted && /* @__PURE__ */ (0, import_jsx_runtime338.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime338.jsx)(
5351
5398
  "div",
5352
5399
  {
5353
5400
  className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass),
5354
5401
  ref: contentRef,
5355
5402
  style: { ...position.position, width: triggerRef.current?.offsetWidth },
5356
5403
  role: "listbox",
5357
- children: /* @__PURE__ */ (0, import_jsx_runtime336.jsx)(context_default.Provider, { value: ctxValue, children: itemChildren })
5404
+ children: /* @__PURE__ */ (0, import_jsx_runtime338.jsx)(context_default.Provider, { value: ctxValue, children: itemChildren })
5358
5405
  }
5359
5406
  ) })
5360
5407
  ]
@@ -5368,7 +5415,7 @@ var Select = Object.assign(SelectRoot, {
5368
5415
  var Select_default = Select;
5369
5416
 
5370
5417
  // src/components/Skeleton/Skeleton.tsx
5371
- var import_jsx_runtime337 = require("react/jsx-runtime");
5418
+ var import_jsx_runtime339 = require("react/jsx-runtime");
5372
5419
  var SIZE_MAP = {
5373
5420
  xs: "var(--spacing-space-1)",
5374
5421
  sm: "var(--spacing-space-2)",
@@ -5384,7 +5431,7 @@ var Skeleton = (props) => {
5384
5431
  ...width != null && { width: SIZE_MAP[width] },
5385
5432
  ...height != null && { height: SIZE_MAP[height] }
5386
5433
  };
5387
- return /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(
5434
+ return /* @__PURE__ */ (0, import_jsx_runtime339.jsx)(
5388
5435
  "div",
5389
5436
  {
5390
5437
  className: clsx_default("lib-xplat-skeleton", variant),
@@ -5397,20 +5444,20 @@ Skeleton.displayName = "Skeleton";
5397
5444
  var Skeleton_default = Skeleton;
5398
5445
 
5399
5446
  // src/components/Spinner/Spinner.tsx
5400
- var import_jsx_runtime338 = require("react/jsx-runtime");
5447
+ var import_jsx_runtime340 = require("react/jsx-runtime");
5401
5448
  var Spinner = (props) => {
5402
5449
  const {
5403
5450
  size = "md",
5404
5451
  type = "brand"
5405
5452
  } = props;
5406
- return /* @__PURE__ */ (0, import_jsx_runtime338.jsx)(
5453
+ return /* @__PURE__ */ (0, import_jsx_runtime340.jsx)(
5407
5454
  "div",
5408
5455
  {
5409
5456
  className: clsx_default("lib-xplat-spinner", size, type),
5410
5457
  role: "status",
5411
5458
  "aria-label": "\uB85C\uB529 \uC911",
5412
- children: /* @__PURE__ */ (0, import_jsx_runtime338.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
5413
- /* @__PURE__ */ (0, import_jsx_runtime338.jsx)(
5459
+ children: /* @__PURE__ */ (0, import_jsx_runtime340.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
5460
+ /* @__PURE__ */ (0, import_jsx_runtime340.jsx)(
5414
5461
  "circle",
5415
5462
  {
5416
5463
  className: "track",
@@ -5420,7 +5467,7 @@ var Spinner = (props) => {
5420
5467
  strokeWidth: "3"
5421
5468
  }
5422
5469
  ),
5423
- /* @__PURE__ */ (0, import_jsx_runtime338.jsx)(
5470
+ /* @__PURE__ */ (0, import_jsx_runtime340.jsx)(
5424
5471
  "circle",
5425
5472
  {
5426
5473
  className: "indicator",
@@ -5439,20 +5486,20 @@ Spinner.displayName = "Spinner";
5439
5486
  var Spinner_default = Spinner;
5440
5487
 
5441
5488
  // src/components/Steps/Steps.tsx
5442
- var import_jsx_runtime339 = require("react/jsx-runtime");
5489
+ var import_jsx_runtime341 = require("react/jsx-runtime");
5443
5490
  var Steps = (props) => {
5444
5491
  const {
5445
5492
  items,
5446
5493
  current,
5447
5494
  type = "brand"
5448
5495
  } = props;
5449
- return /* @__PURE__ */ (0, import_jsx_runtime339.jsx)("div", { className: clsx_default("lib-xplat-steps", type), children: items.map((item, index) => {
5496
+ return /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("div", { className: clsx_default("lib-xplat-steps", type), children: items.map((item, index) => {
5450
5497
  const status = index < current ? "completed" : index === current ? "active" : "pending";
5451
- return /* @__PURE__ */ (0, import_jsx_runtime339.jsxs)("div", { className: clsx_default("step-item", status), children: [
5452
- /* @__PURE__ */ (0, import_jsx_runtime339.jsx)("div", { className: "step-circle", children: status === "completed" ? /* @__PURE__ */ (0, import_jsx_runtime339.jsx)(CheckIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime339.jsx)("span", { children: index + 1 }) }),
5453
- /* @__PURE__ */ (0, import_jsx_runtime339.jsxs)("div", { className: "step-content", children: [
5454
- /* @__PURE__ */ (0, import_jsx_runtime339.jsx)("span", { className: "step-title", children: item.title }),
5455
- item.description && /* @__PURE__ */ (0, import_jsx_runtime339.jsx)("span", { className: "step-description", children: item.description })
5498
+ return /* @__PURE__ */ (0, import_jsx_runtime341.jsxs)("div", { className: clsx_default("step-item", status), children: [
5499
+ /* @__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 }) }),
5500
+ /* @__PURE__ */ (0, import_jsx_runtime341.jsxs)("div", { className: "step-content", children: [
5501
+ /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("span", { className: "step-title", children: item.title }),
5502
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("span", { className: "step-description", children: item.description })
5456
5503
  ] })
5457
5504
  ] }, index);
5458
5505
  }) });
@@ -5462,7 +5509,7 @@ var Steps_default = Steps;
5462
5509
 
5463
5510
  // src/components/Swiper/Swiper.tsx
5464
5511
  var import_react33 = __toESM(require("react"), 1);
5465
- var import_jsx_runtime340 = require("react/jsx-runtime");
5512
+ var import_jsx_runtime342 = require("react/jsx-runtime");
5466
5513
  var Swiper = (props) => {
5467
5514
  const {
5468
5515
  auto = false,
@@ -5691,7 +5738,7 @@ var Swiper = (props) => {
5691
5738
  const slideWidthPercent = 100 / viewItemCount;
5692
5739
  const gapAdjust = spaceBetween * (viewItemCount - 1) / viewItemCount;
5693
5740
  const slideElements = import_react33.default.useMemo(
5694
- () => extendedItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime340.jsx)(
5741
+ () => extendedItems.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(
5695
5742
  "div",
5696
5743
  {
5697
5744
  className: "lib-xplat-swiper__slide",
@@ -5710,15 +5757,15 @@ var Swiper = (props) => {
5710
5757
  Math.floor(realIndex / slideBy),
5711
5758
  totalSteps - 1
5712
5759
  );
5713
- return /* @__PURE__ */ (0, import_jsx_runtime340.jsxs)("div", { className: "lib-xplat-swiper", ref: containerRef, children: [
5714
- /* @__PURE__ */ (0, import_jsx_runtime340.jsx)(
5760
+ return /* @__PURE__ */ (0, import_jsx_runtime342.jsxs)("div", { className: "lib-xplat-swiper", ref: containerRef, children: [
5761
+ /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(
5715
5762
  "div",
5716
5763
  {
5717
5764
  className: "lib-xplat-swiper__viewport",
5718
5765
  onMouseDown: handleDragStart,
5719
5766
  onTouchStart: handleDragStart,
5720
5767
  onDragStart: (e) => e.preventDefault(),
5721
- children: /* @__PURE__ */ (0, import_jsx_runtime340.jsx)(
5768
+ children: /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(
5722
5769
  "div",
5723
5770
  {
5724
5771
  className: clsx_default(
@@ -5736,7 +5783,7 @@ var Swiper = (props) => {
5736
5783
  )
5737
5784
  }
5738
5785
  ),
5739
- showProgress && canSlide && /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("div", { className: "lib-xplat-swiper__progress", children: /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("div", { className: "lib-xplat-swiper__progress-track", children: /* @__PURE__ */ (0, import_jsx_runtime340.jsx)(
5786
+ 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)(
5740
5787
  "span",
5741
5788
  {
5742
5789
  className: "lib-xplat-swiper__progress-fill",
@@ -5746,7 +5793,7 @@ var Swiper = (props) => {
5746
5793
  }
5747
5794
  }
5748
5795
  ) }) }),
5749
- canSlide && /* @__PURE__ */ (0, import_jsx_runtime340.jsx)("div", { className: "lib-xplat-swiper__dots", children: Array.from({ length: totalSteps }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime340.jsx)(
5796
+ 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)(
5750
5797
  "button",
5751
5798
  {
5752
5799
  className: clsx_default(
@@ -5765,7 +5812,7 @@ var Swiper_default = Swiper;
5765
5812
 
5766
5813
  // src/components/Switch/Switch.tsx
5767
5814
  var import_react34 = __toESM(require("react"), 1);
5768
- var import_jsx_runtime341 = require("react/jsx-runtime");
5815
+ var import_jsx_runtime343 = require("react/jsx-runtime");
5769
5816
  var KNOB_TRANSITION_MS = 250;
5770
5817
  var Switch = (props) => {
5771
5818
  const {
@@ -5792,7 +5839,7 @@ var Switch = (props) => {
5792
5839
  timeoutRef.current = null;
5793
5840
  }, KNOB_TRANSITION_MS);
5794
5841
  };
5795
- return /* @__PURE__ */ (0, import_jsx_runtime341.jsx)(
5842
+ return /* @__PURE__ */ (0, import_jsx_runtime343.jsx)(
5796
5843
  "div",
5797
5844
  {
5798
5845
  className: clsx_default(
@@ -5805,7 +5852,7 @@ var Switch = (props) => {
5805
5852
  ),
5806
5853
  onClick: handleClick,
5807
5854
  "aria-disabled": disabled || isAnimating,
5808
- children: /* @__PURE__ */ (0, import_jsx_runtime341.jsx)("div", { className: clsx_default("knob", value ? "checked" : void 0) })
5855
+ children: /* @__PURE__ */ (0, import_jsx_runtime343.jsx)("div", { className: clsx_default("knob", value ? "checked" : void 0) })
5809
5856
  }
5810
5857
  );
5811
5858
  };
@@ -5823,7 +5870,7 @@ var useTableContext = () => {
5823
5870
  var TableContext_default = TableContext;
5824
5871
 
5825
5872
  // src/components/Table/Table.tsx
5826
- var import_jsx_runtime342 = require("react/jsx-runtime");
5873
+ var import_jsx_runtime344 = require("react/jsx-runtime");
5827
5874
  var Table = (props) => {
5828
5875
  const {
5829
5876
  children,
@@ -5833,7 +5880,7 @@ var Table = (props) => {
5833
5880
  headerSticky = false,
5834
5881
  stickyShadow = true
5835
5882
  } = props;
5836
- return /* @__PURE__ */ (0, import_jsx_runtime342.jsx)("div", { className: `lib-xplat-table-wrapper ${size}`, children: /* @__PURE__ */ (0, import_jsx_runtime342.jsx)(
5883
+ return /* @__PURE__ */ (0, import_jsx_runtime344.jsx)("div", { className: `lib-xplat-table-wrapper ${size}`, children: /* @__PURE__ */ (0, import_jsx_runtime344.jsx)(
5837
5884
  TableContext_default.Provider,
5838
5885
  {
5839
5886
  value: {
@@ -5842,7 +5889,7 @@ var Table = (props) => {
5842
5889
  headerSticky,
5843
5890
  stickyShadow
5844
5891
  },
5845
- children: /* @__PURE__ */ (0, import_jsx_runtime342.jsx)("table", { className: "lib-xplat-table", children })
5892
+ children: /* @__PURE__ */ (0, import_jsx_runtime344.jsx)("table", { className: "lib-xplat-table", children })
5846
5893
  }
5847
5894
  ) });
5848
5895
  };
@@ -5850,10 +5897,10 @@ Table.displayName = "Table";
5850
5897
  var Table_default = Table;
5851
5898
 
5852
5899
  // src/components/Table/TableBody.tsx
5853
- var import_jsx_runtime343 = require("react/jsx-runtime");
5900
+ var import_jsx_runtime345 = require("react/jsx-runtime");
5854
5901
  var TableBody = (props) => {
5855
5902
  const { children } = props;
5856
- return /* @__PURE__ */ (0, import_jsx_runtime343.jsx)("tbody", { children });
5903
+ return /* @__PURE__ */ (0, import_jsx_runtime345.jsx)("tbody", { children });
5857
5904
  };
5858
5905
  TableBody.displayName = "TableBody";
5859
5906
  var TableBody_default = TableBody;
@@ -5883,7 +5930,7 @@ var useTableRowContext = () => {
5883
5930
  var TableRowContext_default = TableRowContext;
5884
5931
 
5885
5932
  // src/components/Table/TableCell.tsx
5886
- var import_jsx_runtime344 = require("react/jsx-runtime");
5933
+ var import_jsx_runtime346 = require("react/jsx-runtime");
5887
5934
  var TableCell = import_react38.default.memo((props) => {
5888
5935
  const {
5889
5936
  children,
@@ -5928,7 +5975,7 @@ var TableCell = import_react38.default.memo((props) => {
5928
5975
  const CellTag = isHeaderCell ? "th" : "td";
5929
5976
  const isLastSticky = isSticky && stickyCells[stickyCells.length - 1] === cellRef;
5930
5977
  const enableHover = headContext && headContext.cellHover;
5931
- return /* @__PURE__ */ (0, import_jsx_runtime344.jsx)(
5978
+ return /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(
5932
5979
  CellTag,
5933
5980
  {
5934
5981
  ref: cellRef,
@@ -5955,20 +6002,20 @@ TableCell.displayName = "TableCell";
5955
6002
  var TableCell_default = TableCell;
5956
6003
 
5957
6004
  // src/components/Table/TableHead.tsx
5958
- var import_jsx_runtime345 = require("react/jsx-runtime");
6005
+ var import_jsx_runtime347 = require("react/jsx-runtime");
5959
6006
  var TableHead = ({
5960
6007
  children,
5961
6008
  cellHover = false
5962
6009
  }) => {
5963
6010
  const { headerSticky } = useTableContext();
5964
- return /* @__PURE__ */ (0, import_jsx_runtime345.jsx)(TableHeadContext_default.Provider, { value: { cellHover }, children: /* @__PURE__ */ (0, import_jsx_runtime345.jsx)("thead", { className: clsx_default(headerSticky ? "table-sticky" : null), children }) });
6011
+ 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 }) });
5965
6012
  };
5966
6013
  TableHead.displayName = "TableHead";
5967
6014
  var TableHead_default = TableHead;
5968
6015
 
5969
6016
  // src/components/Table/TableRow.tsx
5970
6017
  var import_react39 = __toESM(require("react"), 1);
5971
- var import_jsx_runtime346 = require("react/jsx-runtime");
6018
+ var import_jsx_runtime348 = require("react/jsx-runtime");
5972
6019
  var TableRow = import_react39.default.memo((props) => {
5973
6020
  const {
5974
6021
  children,
@@ -5985,7 +6032,7 @@ var TableRow = import_react39.default.memo((props) => {
5985
6032
  return [...prev, ref];
5986
6033
  });
5987
6034
  };
5988
- return /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(TableRowContext_default.Provider, { value: { stickyCells, registerStickyCell }, children: /* @__PURE__ */ (0, import_jsx_runtime346.jsx)(
6035
+ return /* @__PURE__ */ (0, import_jsx_runtime348.jsx)(TableRowContext_default.Provider, { value: { stickyCells, registerStickyCell }, children: /* @__PURE__ */ (0, import_jsx_runtime348.jsx)(
5989
6036
  "tr",
5990
6037
  {
5991
6038
  className: clsx_default(
@@ -6009,7 +6056,7 @@ TableRow.displayName = "TableRow";
6009
6056
  var TableRow_default = TableRow;
6010
6057
 
6011
6058
  // src/components/Tag/Tag.tsx
6012
- var import_jsx_runtime347 = require("react/jsx-runtime");
6059
+ var import_jsx_runtime349 = require("react/jsx-runtime");
6013
6060
  var Tag = (props) => {
6014
6061
  const {
6015
6062
  children,
@@ -6019,7 +6066,7 @@ var Tag = (props) => {
6019
6066
  disabled = false,
6020
6067
  colorIndex
6021
6068
  } = props;
6022
- return /* @__PURE__ */ (0, import_jsx_runtime347.jsxs)(
6069
+ return /* @__PURE__ */ (0, import_jsx_runtime349.jsxs)(
6023
6070
  "span",
6024
6071
  {
6025
6072
  className: clsx_default(
@@ -6030,8 +6077,8 @@ var Tag = (props) => {
6030
6077
  disabled && "disabled"
6031
6078
  ),
6032
6079
  children: [
6033
- /* @__PURE__ */ (0, import_jsx_runtime347.jsx)("span", { className: "tag-label", children }),
6034
- onClose && /* @__PURE__ */ (0, import_jsx_runtime347.jsx)("button", { className: "tag-close", onClick: onClose, "aria-label": "\uC0AD\uC81C", disabled, children: /* @__PURE__ */ (0, import_jsx_runtime347.jsx)(XIcon_default, {}) })
6080
+ /* @__PURE__ */ (0, import_jsx_runtime349.jsx)("span", { className: "tag-label", children }),
6081
+ 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, {}) })
6035
6082
  ]
6036
6083
  }
6037
6084
  );
@@ -6041,7 +6088,7 @@ var Tag_default = Tag;
6041
6088
 
6042
6089
  // src/components/TextArea/TextArea.tsx
6043
6090
  var import_react40 = __toESM(require("react"), 1);
6044
- var import_jsx_runtime348 = require("react/jsx-runtime");
6091
+ var import_jsx_runtime350 = require("react/jsx-runtime");
6045
6092
  var TextArea = import_react40.default.forwardRef(
6046
6093
  (props, ref) => {
6047
6094
  const {
@@ -6052,7 +6099,7 @@ var TextArea = import_react40.default.forwardRef(
6052
6099
  disabled,
6053
6100
  ...textareaProps
6054
6101
  } = props;
6055
- return /* @__PURE__ */ (0, import_jsx_runtime348.jsx)("div", { className: clsx_default("lib-xplat-textarea-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime348.jsx)(
6102
+ return /* @__PURE__ */ (0, import_jsx_runtime350.jsx)("div", { className: clsx_default("lib-xplat-textarea-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime350.jsx)(
6056
6103
  "textarea",
6057
6104
  {
6058
6105
  ...textareaProps,
@@ -6071,7 +6118,7 @@ var TextArea_default = TextArea;
6071
6118
  // src/components/Toast/Toast.tsx
6072
6119
  var import_react41 = __toESM(require("react"), 1);
6073
6120
  var import_react_dom4 = require("react-dom");
6074
- var import_jsx_runtime349 = require("react/jsx-runtime");
6121
+ var import_jsx_runtime351 = require("react/jsx-runtime");
6075
6122
  var ToastContext = import_react41.default.createContext(null);
6076
6123
  var useToast = () => {
6077
6124
  const ctx = import_react41.default.useContext(ToastContext);
@@ -6087,7 +6134,7 @@ var ToastItemComponent = ({ item, isExiting, onClose }) => {
6087
6134
  setHeight(ref.current.offsetHeight);
6088
6135
  }
6089
6136
  }, [isExiting]);
6090
- return /* @__PURE__ */ (0, import_jsx_runtime349.jsx)(
6137
+ return /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6091
6138
  "div",
6092
6139
  {
6093
6140
  className: clsx_default("lib-xplat-toast-wrapper", { exit: isExiting }),
@@ -6095,15 +6142,15 @@ var ToastItemComponent = ({ item, isExiting, onClose }) => {
6095
6142
  maxHeight: isExiting ? 0 : height ?? "none",
6096
6143
  marginBottom: isExiting ? 0 : void 0
6097
6144
  },
6098
- children: /* @__PURE__ */ (0, import_jsx_runtime349.jsxs)(
6145
+ children: /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)(
6099
6146
  "div",
6100
6147
  {
6101
6148
  ref,
6102
6149
  className: clsx_default("lib-xplat-toast", item.type, { exit: isExiting }),
6103
6150
  role: "alert",
6104
6151
  children: [
6105
- /* @__PURE__ */ (0, import_jsx_runtime349.jsx)("span", { className: "message", children: item.message }),
6106
- /* @__PURE__ */ (0, import_jsx_runtime349.jsx)("button", { className: "close-btn", onClick: onClose, "aria-label": "\uB2EB\uAE30", children: "\xD7" })
6152
+ /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("span", { className: "message", children: item.message }),
6153
+ /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("button", { className: "close-btn", onClick: onClose, "aria-label": "\uB2EB\uAE30", children: "\xD7" })
6107
6154
  ]
6108
6155
  }
6109
6156
  )
@@ -6141,10 +6188,10 @@ var ToastProvider = ({
6141
6188
  },
6142
6189
  [remove]
6143
6190
  );
6144
- return /* @__PURE__ */ (0, import_jsx_runtime349.jsxs)(ToastContext.Provider, { value: { toast }, children: [
6191
+ return /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)(ToastContext.Provider, { value: { toast }, children: [
6145
6192
  children,
6146
6193
  mounted && (0, import_react_dom4.createPortal)(
6147
- /* @__PURE__ */ (0, import_jsx_runtime349.jsx)("div", { className: clsx_default("lib-xplat-toast-container", position), children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime349.jsx)(
6194
+ /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("div", { className: clsx_default("lib-xplat-toast-container", position), children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6148
6195
  ToastItemComponent,
6149
6196
  {
6150
6197
  item: t,
@@ -6161,15 +6208,17 @@ ToastProvider.displayName = "ToastProvider";
6161
6208
 
6162
6209
  // src/components/Tooltip/Tooltip.tsx
6163
6210
  var import_react42 = __toESM(require("react"), 1);
6164
- var import_jsx_runtime350 = require("react/jsx-runtime");
6211
+ var import_jsx_runtime352 = require("react/jsx-runtime");
6165
6212
  var OFFSET = 12;
6213
+ var GAP = 8;
6166
6214
  var SHOW_DELAY = 300;
6167
6215
  var Tooltip = (props) => {
6168
6216
  const {
6169
- type = "dark",
6217
+ children,
6170
6218
  title,
6171
6219
  description,
6172
- children,
6220
+ type = "dark",
6221
+ follow = false,
6173
6222
  disabled = false
6174
6223
  } = props;
6175
6224
  const triggerRef = import_react42.default.useRef(null);
@@ -6177,51 +6226,93 @@ var Tooltip = (props) => {
6177
6226
  const [visible, setVisible] = import_react42.default.useState(false);
6178
6227
  const [pos, setPos] = import_react42.default.useState({ left: 0, top: 0 });
6179
6228
  const delayTimer = import_react42.default.useRef(0);
6180
- const calculatePos = import_react42.default.useCallback((clientX, clientY) => {
6229
+ const rafRef = import_react42.default.useRef(0);
6230
+ const cursor = import_react42.default.useRef(null);
6231
+ const clamp = import_react42.default.useCallback((left, top, w, h) => {
6232
+ const vw = window.innerWidth;
6233
+ const vh = window.innerHeight;
6234
+ return {
6235
+ left: Math.min(Math.max(GAP, left), Math.max(GAP, vw - w - GAP)),
6236
+ top: Math.min(Math.max(GAP, top), Math.max(GAP, vh - h - GAP))
6237
+ };
6238
+ }, []);
6239
+ const placeAtCursor = import_react42.default.useCallback((x, y) => {
6181
6240
  const el = tooltipRef.current;
6182
6241
  if (!el) return;
6183
6242
  const w = el.offsetWidth;
6184
6243
  const h = el.offsetHeight;
6185
- const vw = window.innerWidth;
6186
- let left = clientX + OFFSET;
6187
- let top = clientY - h - OFFSET;
6188
- if (left + w > vw - 8) left = clientX - w - OFFSET;
6189
- if (top < 8) top = clientY + OFFSET;
6190
- if (left < 8) left = 8;
6191
- setPos({ left, top });
6192
- }, []);
6193
- const handleMouseEnter = import_react42.default.useCallback(() => {
6244
+ let left = x + OFFSET;
6245
+ let top = y - h - OFFSET;
6246
+ if (left + w > window.innerWidth - GAP) left = x - w - OFFSET;
6247
+ if (top < GAP) top = y + OFFSET;
6248
+ setPos(clamp(left, top, w, h));
6249
+ }, [clamp]);
6250
+ const placeAtTrigger = import_react42.default.useCallback(() => {
6251
+ const el = tooltipRef.current;
6252
+ const trigger = triggerRef.current;
6253
+ if (!el || !trigger) return;
6254
+ const w = el.offsetWidth;
6255
+ const h = el.offsetHeight;
6256
+ const rect = trigger.getBoundingClientRect();
6257
+ let top = rect.top - h - GAP;
6258
+ if (top < GAP) top = rect.bottom + GAP;
6259
+ const left = rect.left + rect.width / 2 - w / 2;
6260
+ setPos(clamp(left, top, w, h));
6261
+ }, [clamp]);
6262
+ const reposition = import_react42.default.useCallback(() => {
6263
+ if (follow && cursor.current) {
6264
+ placeAtCursor(cursor.current.x, cursor.current.y);
6265
+ } else {
6266
+ placeAtTrigger();
6267
+ }
6268
+ }, [follow, placeAtCursor, placeAtTrigger]);
6269
+ const handleMouseEnter = import_react42.default.useCallback((e) => {
6194
6270
  if (disabled) return;
6195
- delayTimer.current = window.setTimeout(() => {
6196
- setVisible(true);
6197
- }, SHOW_DELAY);
6271
+ cursor.current = { x: e.clientX, y: e.clientY };
6272
+ delayTimer.current = window.setTimeout(() => setVisible(true), SHOW_DELAY);
6198
6273
  }, [disabled]);
6199
6274
  const handleMouseMove = import_react42.default.useCallback((e) => {
6200
- if (!visible) return;
6201
- calculatePos(e.clientX, e.clientY);
6202
- }, [visible, calculatePos]);
6203
- const handleMouseLeave = import_react42.default.useCallback(() => {
6204
- window.clearTimeout(delayTimer.current);
6205
- setVisible(false);
6206
- }, []);
6207
- const handleClick = import_react42.default.useCallback(() => {
6275
+ cursor.current = { x: e.clientX, y: e.clientY };
6276
+ if (!visible || !follow) return;
6277
+ cancelAnimationFrame(rafRef.current);
6278
+ rafRef.current = requestAnimationFrame(() => {
6279
+ if (cursor.current) placeAtCursor(cursor.current.x, cursor.current.y);
6280
+ });
6281
+ }, [visible, follow, placeAtCursor]);
6282
+ const close = import_react42.default.useCallback(() => {
6208
6283
  window.clearTimeout(delayTimer.current);
6284
+ cancelAnimationFrame(rafRef.current);
6209
6285
  setVisible(false);
6210
6286
  }, []);
6287
+ const handleMouseLeave = import_react42.default.useCallback(() => {
6288
+ cursor.current = null;
6289
+ close();
6290
+ }, [close]);
6211
6291
  const handleFocus = import_react42.default.useCallback(() => {
6212
6292
  if (disabled) return;
6293
+ cursor.current = null;
6213
6294
  setVisible(true);
6214
6295
  }, [disabled]);
6215
- const handleBlur = import_react42.default.useCallback(() => {
6216
- setVisible(false);
6217
- }, []);
6218
6296
  import_react42.default.useLayoutEffect(() => {
6219
- if (!visible || !triggerRef.current) return;
6220
- const rect = triggerRef.current.getBoundingClientRect();
6221
- calculatePos(rect.right, rect.top);
6222
- }, [visible, calculatePos]);
6223
- if (!title && !description) return /* @__PURE__ */ (0, import_jsx_runtime350.jsx)(import_jsx_runtime350.Fragment, { children });
6224
- return /* @__PURE__ */ (0, import_jsx_runtime350.jsxs)(
6297
+ if (!visible) return;
6298
+ reposition();
6299
+ }, [visible, reposition]);
6300
+ import_react42.default.useEffect(() => {
6301
+ if (!visible || follow) return;
6302
+ const onChange = () => placeAtTrigger();
6303
+ window.addEventListener("scroll", onChange, true);
6304
+ window.addEventListener("resize", onChange);
6305
+ return () => {
6306
+ window.removeEventListener("scroll", onChange, true);
6307
+ window.removeEventListener("resize", onChange);
6308
+ };
6309
+ }, [visible, follow, placeAtTrigger]);
6310
+ import_react42.default.useEffect(() => () => {
6311
+ window.clearTimeout(delayTimer.current);
6312
+ cancelAnimationFrame(rafRef.current);
6313
+ }, []);
6314
+ if (!title && !description) return /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(import_jsx_runtime352.Fragment, { children });
6315
+ return /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)(
6225
6316
  "div",
6226
6317
  {
6227
6318
  ref: triggerRef,
@@ -6229,20 +6320,21 @@ var Tooltip = (props) => {
6229
6320
  onMouseEnter: handleMouseEnter,
6230
6321
  onMouseMove: handleMouseMove,
6231
6322
  onMouseLeave: handleMouseLeave,
6232
- onClick: handleClick,
6323
+ onClick: close,
6233
6324
  onFocus: handleFocus,
6234
- onBlur: handleBlur,
6325
+ onBlur: close,
6235
6326
  children: [
6236
6327
  children,
6237
- visible && /* @__PURE__ */ (0, import_jsx_runtime350.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime350.jsxs)(
6328
+ visible && /* @__PURE__ */ (0, import_jsx_runtime352.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime352.jsxs)(
6238
6329
  "div",
6239
6330
  {
6240
6331
  ref: tooltipRef,
6332
+ role: "tooltip",
6241
6333
  className: clsx_default("lib-xplat-tooltip", type),
6242
6334
  style: { position: "fixed", left: pos.left, top: pos.top },
6243
6335
  children: [
6244
- title && /* @__PURE__ */ (0, import_jsx_runtime350.jsx)("div", { className: "tooltip-title", children: title }),
6245
- description && /* @__PURE__ */ (0, import_jsx_runtime350.jsx)("div", { className: "tooltip-desc", children: description })
6336
+ title && /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("div", { className: "tooltip-title", children: title }),
6337
+ description && /* @__PURE__ */ (0, import_jsx_runtime352.jsx)("div", { className: "tooltip-desc", children: description })
6246
6338
  ]
6247
6339
  }
6248
6340
  ) })
@@ -6255,10 +6347,10 @@ var Tooltip_default = Tooltip;
6255
6347
 
6256
6348
  // src/components/Video/Video.tsx
6257
6349
  var import_react43 = __toESM(require("react"), 1);
6258
- var import_jsx_runtime351 = require("react/jsx-runtime");
6259
- var PipIcon = () => /* @__PURE__ */ (0, import_jsx_runtime351.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: [
6260
- /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2" }),
6261
- /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("rect", { x: "12", y: "11", width: "7", height: "6", rx: "1", fill: "currentColor" })
6350
+ var import_jsx_runtime353 = require("react/jsx-runtime");
6351
+ var PipIcon = () => /* @__PURE__ */ (0, import_jsx_runtime353.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: [
6352
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsx)("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2" }),
6353
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsx)("rect", { x: "12", y: "11", width: "7", height: "6", rx: "1", fill: "currentColor" })
6262
6354
  ] });
6263
6355
  var formatTime = (sec) => {
6264
6356
  if (!Number.isFinite(sec) || sec < 0) return "0:00";
@@ -6433,13 +6525,13 @@ var Video = import_react43.default.forwardRef((props, ref) => {
6433
6525
  const volumePct = (isMuted ? 0 : volume) * 100;
6434
6526
  const VolumeGlyph = isMuted || volume === 0 ? VolumeXIcon_default : volume < 0.5 ? VolumeIcon_default : Volume2Icon_default;
6435
6527
  const pipSupported = typeof document !== "undefined" && "pictureInPictureEnabled" in document && document.pictureInPictureEnabled;
6436
- return /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)(
6528
+ return /* @__PURE__ */ (0, import_jsx_runtime353.jsxs)(
6437
6529
  "div",
6438
6530
  {
6439
6531
  ref: containerRef,
6440
6532
  className: clsx_default("lib-xplat-video", showControls && "has-controls"),
6441
6533
  children: [
6442
- /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6534
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(
6443
6535
  "video",
6444
6536
  {
6445
6537
  ref: setRefs,
@@ -6460,7 +6552,7 @@ var Video = import_react43.default.forwardRef((props, ref) => {
6460
6552
  children
6461
6553
  }
6462
6554
  ),
6463
- showCenterPlay && /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6555
+ showCenterPlay && /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(
6464
6556
  "button",
6465
6557
  {
6466
6558
  type: "button",
@@ -6472,11 +6564,11 @@ var Video = import_react43.default.forwardRef((props, ref) => {
6472
6564
  onClick: togglePlay,
6473
6565
  "aria-label": isPlaying ? "\uC77C\uC2DC\uC815\uC9C0" : "\uC7AC\uC0DD",
6474
6566
  tabIndex: -1,
6475
- children: /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("span", { className: "center-play-icon", children: /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(PlayCircleIcon_default, {}) })
6567
+ children: /* @__PURE__ */ (0, import_jsx_runtime353.jsx)("span", { className: "center-play-icon", children: /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(PlayCircleIcon_default, {}) })
6476
6568
  }
6477
6569
  ),
6478
- showControls && /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)("div", { className: "controls", onClick: (e) => e.stopPropagation(), children: [
6479
- /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6570
+ showControls && /* @__PURE__ */ (0, import_jsx_runtime353.jsxs)("div", { className: "controls", onClick: (e) => e.stopPropagation(), children: [
6571
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(
6480
6572
  "input",
6481
6573
  {
6482
6574
  type: "range",
@@ -6493,29 +6585,29 @@ var Video = import_react43.default.forwardRef((props, ref) => {
6493
6585
  }
6494
6586
  }
6495
6587
  ),
6496
- /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)("div", { className: "controls-row", children: [
6497
- /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6588
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsxs)("div", { className: "controls-row", children: [
6589
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(
6498
6590
  "button",
6499
6591
  {
6500
6592
  type: "button",
6501
6593
  className: "control-btn",
6502
6594
  onClick: togglePlay,
6503
6595
  "aria-label": isPlaying ? "\uC77C\uC2DC\uC815\uC9C0" : "\uC7AC\uC0DD",
6504
- children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(PauseIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(PlayIcon_default, {})
6596
+ children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(PauseIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(PlayIcon_default, {})
6505
6597
  }
6506
6598
  ),
6507
- /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)("div", { className: "volume-group", children: [
6508
- /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6599
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsxs)("div", { className: "volume-group", children: [
6600
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(
6509
6601
  "button",
6510
6602
  {
6511
6603
  type: "button",
6512
6604
  className: "control-btn",
6513
6605
  onClick: toggleMute,
6514
6606
  "aria-label": isMuted ? "\uC74C\uC18C\uAC70 \uD574\uC81C" : "\uC74C\uC18C\uAC70",
6515
- children: /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(VolumeGlyph, {})
6607
+ children: /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(VolumeGlyph, {})
6516
6608
  }
6517
6609
  ),
6518
- /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6610
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(
6519
6611
  "input",
6520
6612
  {
6521
6613
  type: "range",
@@ -6530,14 +6622,14 @@ var Video = import_react43.default.forwardRef((props, ref) => {
6530
6622
  }
6531
6623
  )
6532
6624
  ] }),
6533
- /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)("span", { className: "time", children: [
6625
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsxs)("span", { className: "time", children: [
6534
6626
  formatTime(currentTime),
6535
6627
  " / ",
6536
6628
  formatTime(duration)
6537
6629
  ] }),
6538
- /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("div", { className: "controls-spacer" }),
6539
- playbackRates && playbackRates.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)("div", { className: clsx_default("rate-group", rateMenuOpen && "is-open"), children: [
6540
- /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)(
6630
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsx)("div", { className: "controls-spacer" }),
6631
+ playbackRates && playbackRates.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime353.jsxs)("div", { className: clsx_default("rate-group", rateMenuOpen && "is-open"), children: [
6632
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsxs)(
6541
6633
  "button",
6542
6634
  {
6543
6635
  type: "button",
@@ -6551,7 +6643,7 @@ var Video = import_react43.default.forwardRef((props, ref) => {
6551
6643
  ]
6552
6644
  }
6553
6645
  ),
6554
- rateMenuOpen && /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("ul", { className: "rate-menu", role: "menu", children: playbackRates.map((r2) => /* @__PURE__ */ (0, import_jsx_runtime351.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime351.jsxs)(
6646
+ rateMenuOpen && /* @__PURE__ */ (0, import_jsx_runtime353.jsx)("ul", { className: "rate-menu", role: "menu", children: playbackRates.map((r2) => /* @__PURE__ */ (0, import_jsx_runtime353.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime353.jsxs)(
6555
6647
  "button",
6556
6648
  {
6557
6649
  type: "button",
@@ -6565,7 +6657,7 @@ var Video = import_react43.default.forwardRef((props, ref) => {
6565
6657
  }
6566
6658
  ) }, r2)) })
6567
6659
  ] }),
6568
- showCaptions && /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6660
+ showCaptions && /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(
6569
6661
  "button",
6570
6662
  {
6571
6663
  type: "button",
@@ -6573,37 +6665,37 @@ var Video = import_react43.default.forwardRef((props, ref) => {
6573
6665
  onClick: toggleCaptions,
6574
6666
  "aria-label": captionsOn ? "\uC790\uB9C9 \uB044\uAE30" : "\uC790\uB9C9 \uCF1C\uAE30",
6575
6667
  "aria-pressed": captionsOn,
6576
- children: /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(TypeIcon_default, {})
6668
+ children: /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(TypeIcon_default, {})
6577
6669
  }
6578
6670
  ),
6579
- showPip && pipSupported && /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6671
+ showPip && pipSupported && /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(
6580
6672
  "button",
6581
6673
  {
6582
6674
  type: "button",
6583
6675
  className: clsx_default("control-btn", isPip && "is-active"),
6584
6676
  onClick: togglePip,
6585
6677
  "aria-label": isPip ? "PIP \uC885\uB8CC" : "PIP",
6586
- children: /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(PipIcon, {})
6678
+ children: /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(PipIcon, {})
6587
6679
  }
6588
6680
  ),
6589
- showDownload && /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6681
+ showDownload && /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(
6590
6682
  "a",
6591
6683
  {
6592
6684
  className: "control-btn",
6593
6685
  href: src,
6594
6686
  download: downloadFileName ?? true,
6595
6687
  "aria-label": "\uB2E4\uC6B4\uB85C\uB4DC",
6596
- children: /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(DownloadIcon_default, {})
6688
+ children: /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(DownloadIcon_default, {})
6597
6689
  }
6598
6690
  ),
6599
- /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(
6691
+ /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(
6600
6692
  "button",
6601
6693
  {
6602
6694
  type: "button",
6603
6695
  className: "control-btn",
6604
6696
  onClick: toggleFullscreen,
6605
6697
  "aria-label": isFullscreen ? "\uC804\uCCB4\uD654\uBA74 \uC885\uB8CC" : "\uC804\uCCB4\uD654\uBA74",
6606
- children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(MinimizeIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime351.jsx)(MaximizeIcon_default, {})
6698
+ children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(MinimizeIcon_default, {}) : /* @__PURE__ */ (0, import_jsx_runtime353.jsx)(MaximizeIcon_default, {})
6607
6699
  }
6608
6700
  )
6609
6701
  ] })
@@ -6642,6 +6734,8 @@ var Video_default = Video;
6642
6734
  ImageSelector,
6643
6735
  Input,
6644
6736
  InputDatePicker,
6737
+ Link,
6738
+ LinkButton,
6645
6739
  Modal,
6646
6740
  NotificationBadge,
6647
6741
  Pagination,