sellmate-design-system-react 9.0.0-beta.60 → 9.0.0-beta.62

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 (43) hide show
  1. package/AGENTS.md +33 -10
  2. package/dist/components/SBadge/README.md +1 -0
  3. package/dist/components/SBadge/SBadge.d.ts +1 -1
  4. package/dist/components/SBarChart/README.md +15 -0
  5. package/dist/components/SBarChart/SBarChart.d.ts +15 -1
  6. package/dist/components/SBarChart/index.d.ts +1 -1
  7. package/dist/components/SCalendarBoard/README.md +2 -1
  8. package/dist/components/SCalendarBoard/calendarBoard.config.d.ts +2 -2
  9. package/dist/components/SCalendarBoard/types.d.ts +1 -1
  10. package/dist/components/SCallout/README.md +1 -0
  11. package/dist/components/SCallout/SCallout.d.ts +6 -1
  12. package/dist/components/SChip/README.md +25 -0
  13. package/dist/components/SChip/SChip.d.ts +8 -0
  14. package/dist/components/SChip/index.d.ts +1 -1
  15. package/dist/components/SDonutChart/README.md +91 -0
  16. package/dist/components/SDonutChart/SDonutChart.d.ts +70 -0
  17. package/dist/components/SDonutChart/index.d.ts +1 -0
  18. package/dist/components/SGhostButton/README.md +2 -0
  19. package/dist/components/SLineChart/README.md +15 -0
  20. package/dist/components/SLineChart/SLineChart.d.ts +15 -1
  21. package/dist/components/SLineChart/index.d.ts +1 -1
  22. package/dist/components/SLineChart/lineChart.config.d.ts +11 -7
  23. package/dist/components/SMeatballButton/README.md +67 -0
  24. package/dist/components/SMeatballButton/SMeatballButton.d.ts +36 -0
  25. package/dist/components/SMeatballButton/index.d.ts +1 -0
  26. package/dist/components/SPieChart/README.md +91 -0
  27. package/dist/components/SPieChart/SPieChart.d.ts +69 -0
  28. package/dist/components/SPieChart/index.d.ts +1 -0
  29. package/dist/index.cjs +702 -230
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.js +698 -230
  33. package/dist/index.js.map +1 -1
  34. package/dist/lib/chart/cartesian.d.ts +2 -2
  35. package/dist/lib/chart/radial.d.ts +89 -0
  36. package/dist/lib/chart/tooltip.d.ts +18 -1
  37. package/dist/lib/dropdown-menu.d.ts +19 -0
  38. package/dist/llms-full.txt +361 -22
  39. package/dist/llms.txt +53 -23
  40. package/dist/styles.css +85 -0
  41. package/dist/theme.css +62 -0
  42. package/eslint/scale.gen.mjs +2 -2
  43. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -10,7 +10,7 @@ var reactDom = require('react-dom');
10
10
  var RCheckbox = require('@radix-ui/react-checkbox');
11
11
  var client = require('react-dom/client');
12
12
  var RTooltip = require('@radix-ui/react-tooltip');
13
- var RDropdown3 = require('@radix-ui/react-dropdown-menu');
13
+ var RDropdown5 = require('@radix-ui/react-dropdown-menu');
14
14
  var RSwitch = require('@radix-ui/react-switch');
15
15
  var RDialog = require('@radix-ui/react-dialog');
16
16
  var Ariakit = require('@ariakit/react');
@@ -36,7 +36,7 @@ function _interopNamespace(e) {
36
36
  var RPopover12__namespace = /*#__PURE__*/_interopNamespace(RPopover12);
37
37
  var RCheckbox__namespace = /*#__PURE__*/_interopNamespace(RCheckbox);
38
38
  var RTooltip__namespace = /*#__PURE__*/_interopNamespace(RTooltip);
39
- var RDropdown3__namespace = /*#__PURE__*/_interopNamespace(RDropdown3);
39
+ var RDropdown5__namespace = /*#__PURE__*/_interopNamespace(RDropdown5);
40
40
  var RSwitch__namespace = /*#__PURE__*/_interopNamespace(RSwitch);
41
41
  var RDialog__namespace = /*#__PURE__*/_interopNamespace(RDialog);
42
42
  var Ariakit__namespace = /*#__PURE__*/_interopNamespace(Ariakit);
@@ -3949,6 +3949,7 @@ var BADGE_COLORS = [
3949
3949
  "blue",
3950
3950
  "darkblue",
3951
3951
  "indigo",
3952
+ "purple",
3952
3953
  "grey"
3953
3954
  ];
3954
3955
  var SBadge = /* @__PURE__ */ react.forwardRef(function SBadge2({ color = "blue", className, ...rest }, ref) {
@@ -4275,7 +4276,7 @@ var TAG_SIZE_CONFIG = {
4275
4276
  radius: 6,
4276
4277
  iconSize: 16,
4277
4278
  fontSize: 12,
4278
- fontWeight: 700,
4279
+ fontWeight: 600,
4279
4280
  lineHeight: 20
4280
4281
  },
4281
4282
  md: {
@@ -8034,8 +8035,8 @@ function renderItems(message, depth = 1) {
8034
8035
  });
8035
8036
  return out;
8036
8037
  }
8037
- var SCallout = /* @__PURE__ */ react.forwardRef(function SCallout2({ type = "default", message = [], children, className, style }, ref) {
8038
- const isDanger = type === "danger";
8038
+ var SCallout = /* @__PURE__ */ react.forwardRef(function SCallout2({ type = "default", showTitle = true, message = [], children, className, style }, ref) {
8039
+ const hasDangerTitle = type === "danger" && showTitle;
8039
8040
  const surface = SURFACE[type];
8040
8041
  const vars = {
8041
8042
  "--co-bg": surface.bg,
@@ -8054,7 +8055,7 @@ var SCallout = /* @__PURE__ */ react.forwardRef(function SCallout2({ type = "def
8054
8055
  ),
8055
8056
  style: { ...vars, ...style },
8056
8057
  children: [
8057
- isDanger && /* @__PURE__ */ jsxRuntime.jsxs(
8058
+ hasDangerTitle && /* @__PURE__ */ jsxRuntime.jsxs(
8058
8059
  "div",
8059
8060
  {
8060
8061
  className: "flex shrink-0 flex-col items-center justify-center gap-[var(--cmp-callout-danger-title-gap)] px-[var(--cmp-callout-danger-title-paddingX)] py-[8px] text-[16px] font-bold leading-[26px]",
@@ -8381,6 +8382,58 @@ function clampToAvailableWidth(value, availableWidth) {
8381
8382
  const css = typeof value === "number" ? `${value}px` : value;
8382
8383
  return `min(${css}, ${availableWidth})`;
8383
8384
  }
8385
+ var VIEWPORT_PADDING = 12;
8386
+ var itemClass = cn(
8387
+ "flex min-h-[28px] cursor-pointer select-none items-center gap-[8px] rounded-[2px] px-[12px] py-[4px] text-[12px] leading-[20px] outline-none",
8388
+ "text-[color:var(--sys-color-fg-secondary)]",
8389
+ "data-[disabled]:cursor-not-allowed data-[disabled]:text-[color:var(--cmp-button-text-disabled)]",
8390
+ "data-[highlighted]:bg-[var(--sys-color-bg-accent)] data-[highlighted]:text-[color:var(--sys-color-fg-inverse)]"
8391
+ );
8392
+ function DropdownMenuContent({
8393
+ items,
8394
+ onItemClick,
8395
+ align = "start",
8396
+ className,
8397
+ ...contentProps
8398
+ }) {
8399
+ const portalContainer = usePortalContainer();
8400
+ return /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
8401
+ RDropdown5__namespace.Content,
8402
+ {
8403
+ sideOffset: 4,
8404
+ align,
8405
+ collisionPadding: VIEWPORT_PADDING,
8406
+ className: cn(
8407
+ "z-50 overflow-hidden rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] shadow-normal-sm",
8408
+ // 창보다 넓은 메뉴는 창 폭에 맞춰 줄인다. 호출부가 하한(min-width)을 줄 때도 같은
8409
+ // 상한으로 감싸야 한다 — min-width 가 max-width 를 이기기 때문이다.
8410
+ "max-w-[var(--radix-dropdown-menu-content-available-width)]",
8411
+ FLOATING_SLIDE_ANIM,
8412
+ className
8413
+ ),
8414
+ ...contentProps,
8415
+ children: items.map((it) => /* @__PURE__ */ jsxRuntime.jsxs(
8416
+ RDropdown5__namespace.Item,
8417
+ {
8418
+ disabled: it.disabled,
8419
+ onSelect: () => onItemClick?.(it.value),
8420
+ className: itemClass,
8421
+ children: [
8422
+ it.icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: it.icon, size: 12 }),
8423
+ /* @__PURE__ */ jsxRuntime.jsx(
8424
+ "span",
8425
+ {
8426
+ className: "min-w-0 break-words",
8427
+ dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(it.label) }
8428
+ }
8429
+ )
8430
+ ]
8431
+ },
8432
+ it.value
8433
+ ))
8434
+ }
8435
+ ) });
8436
+ }
8384
8437
  var SIZE2 = {
8385
8438
  xs: { height: 24, paddingX: 8, gap: 6, arrow: 12, fontSize: 12, minWidth: 64, splitMinWidth: 72 },
8386
8439
  sm: {
@@ -8417,13 +8470,6 @@ function splitDivider(color, outline) {
8417
8470
  };
8418
8471
  return (outline ? outlined : solid)[color];
8419
8472
  }
8420
- var VIEWPORT_PADDING = 12;
8421
- var itemClass = cn(
8422
- "flex min-h-[28px] cursor-pointer select-none items-center gap-[8px] rounded-[2px] px-[12px] py-[4px] text-[12px] leading-[20px] outline-none",
8423
- "text-[color:var(--sys-color-fg-secondary)]",
8424
- "data-[disabled]:cursor-not-allowed data-[disabled]:text-[color:var(--cmp-button-text-disabled)]",
8425
- "data-[highlighted]:bg-[var(--sys-color-bg-accent)] data-[highlighted]:text-[color:var(--sys-color-fg-inverse)]"
8426
- );
8427
8473
  var SDropdownButtonImpl = /* @__PURE__ */ react.forwardRef(
8428
8474
  function SDropdownButton({
8429
8475
  color = "primary",
@@ -8439,7 +8485,6 @@ var SDropdownButtonImpl = /* @__PURE__ */ react.forwardRef(
8439
8485
  className,
8440
8486
  style
8441
8487
  }, ref) {
8442
- const portalContainer = usePortalContainer();
8443
8488
  const insideModal = useInsideModal();
8444
8489
  const [open, setOpen] = react.useState(false);
8445
8490
  const splitWrapRef = react.useRef(null);
@@ -8493,45 +8538,20 @@ var SDropdownButtonImpl = /* @__PURE__ */ react.forwardRef(
8493
8538
  "border-[color:var(--dd-border)] bg-[var(--dd-bg)] text-[color:var(--dd-text)]",
8494
8539
  disabled ? "cursor-not-allowed" : "cursor-pointer hover:bg-[var(--dd-bg-hover)]"
8495
8540
  );
8496
- const menu = /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
8497
- RDropdown3__namespace.Content,
8541
+ const menu = /* @__PURE__ */ jsxRuntime.jsx(
8542
+ DropdownMenuContent,
8498
8543
  {
8499
- sideOffset: 4,
8500
- align: "start",
8544
+ items,
8545
+ onItemClick,
8501
8546
  alignOffset: split ? splitAlignOffset : 0,
8502
- collisionPadding: VIEWPORT_PADDING,
8503
8547
  className: cn(
8504
- "z-50 overflow-hidden rounded-[var(--cmp-listBox-radius)] bg-[var(--cmp-listBox-bg)] shadow-normal-sm",
8505
- // 창보다 넓은 메뉴는 창 폭에 맞춰 줄인다. 트리거 너비를 따르는 하한도 같은 상한으로
8506
- // 감싸야 한다 — min-width 가 max-width 를 이기기 때문이다.
8507
- "max-w-[var(--radix-dropdown-menu-content-available-width)]",
8508
- !split && "min-w-[min(var(--radix-dropdown-menu-trigger-width),var(--radix-dropdown-menu-content-available-width))]",
8509
- FLOATING_SLIDE_ANIM
8548
+ !split && "min-w-[min(var(--radix-dropdown-menu-trigger-width),var(--radix-dropdown-menu-content-available-width))]"
8510
8549
  ),
8511
- style: split ? { minWidth: clampToAvailableWidth(splitWidth, DROPDOWN_AVAILABLE_WIDTH) } : void 0,
8512
- children: items.map((it) => /* @__PURE__ */ jsxRuntime.jsxs(
8513
- RDropdown3__namespace.Item,
8514
- {
8515
- disabled: it.disabled,
8516
- onSelect: () => onItemClick?.(it.value),
8517
- className: itemClass,
8518
- children: [
8519
- it.icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: it.icon, size: 12 }),
8520
- /* @__PURE__ */ jsxRuntime.jsx(
8521
- "span",
8522
- {
8523
- className: "min-w-0 break-words",
8524
- dangerouslySetInnerHTML: { __html: sanitizeInlineHtml(it.label) }
8525
- }
8526
- )
8527
- ]
8528
- },
8529
- it.value
8530
- ))
8550
+ style: split ? { minWidth: clampToAvailableWidth(splitWidth, DROPDOWN_AVAILABLE_WIDTH) } : void 0
8531
8551
  }
8532
- ) });
8552
+ );
8533
8553
  return /* @__PURE__ */ jsxRuntime.jsxs(
8534
- RDropdown3__namespace.Root,
8554
+ RDropdown5__namespace.Root,
8535
8555
  {
8536
8556
  modal: !insideModal,
8537
8557
  open,
@@ -8563,7 +8583,7 @@ var SDropdownButtonImpl = /* @__PURE__ */ react.forwardRef(
8563
8583
  children: label
8564
8584
  }
8565
8585
  ),
8566
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
8586
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
8567
8587
  "button",
8568
8588
  {
8569
8589
  ref: splitToggleRef,
@@ -8582,7 +8602,7 @@ var SDropdownButtonImpl = /* @__PURE__ */ react.forwardRef(
8582
8602
  ) })
8583
8603
  ]
8584
8604
  }
8585
- ) : /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
8605
+ ) : /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
8586
8606
  "button",
8587
8607
  {
8588
8608
  type: "button",
@@ -8610,6 +8630,87 @@ var SDropdownButtonImpl = /* @__PURE__ */ react.forwardRef(
8610
8630
  }
8611
8631
  );
8612
8632
  var SDropdownButton2 = /* @__PURE__ */ withDisplayName(SDropdownButtonImpl, "SDropdownButton");
8633
+ var DEFAULT_LABEL = "\uAE30\uB2A5 \uB354 \uBCF4\uAE30";
8634
+ var SMeatballButtonImpl = /* @__PURE__ */ react.forwardRef(
8635
+ function SMeatballButton({
8636
+ size = "sm",
8637
+ intent = "default",
8638
+ items = [],
8639
+ // 기본값을 리터럴로 둬야 README(docs:gen)에 실제 문구가 찍힌다
8640
+ tooltipText = "\uAE30\uB2A5 \uB354 \uBCF4\uAE30",
8641
+ ariaLabel,
8642
+ disabled = false,
8643
+ onItemClick,
8644
+ onOpenChange,
8645
+ className,
8646
+ style
8647
+ }, ref) {
8648
+ const insideModal = useInsideModal();
8649
+ const [open, setOpen] = react.useState(false);
8650
+ const buttonRef = react.useRef(null);
8651
+ const pointerRef = react.useRef(false);
8652
+ const setMenuOpen = (o) => {
8653
+ setOpen(o);
8654
+ onOpenChange?.(o);
8655
+ };
8656
+ react.useImperativeHandle(
8657
+ ref,
8658
+ () => ({
8659
+ open: () => setOpen(true),
8660
+ close: () => setOpen(false)
8661
+ }),
8662
+ []
8663
+ );
8664
+ const label = ariaLabel?.trim() || tooltipText.trim() || DEFAULT_LABEL;
8665
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8666
+ RDropdown5__namespace.Root,
8667
+ {
8668
+ modal: !insideModal,
8669
+ open,
8670
+ onOpenChange: setMenuOpen,
8671
+ children: [
8672
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Trigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxRuntime.jsx(
8673
+ "span",
8674
+ {
8675
+ className: cn("inline-flex", className),
8676
+ style,
8677
+ onPointerDownCapture: () => pointerRef.current = true,
8678
+ onKeyDownCapture: () => pointerRef.current = false,
8679
+ children: /* @__PURE__ */ jsxRuntime.jsx(
8680
+ SGhostButton,
8681
+ {
8682
+ ref: buttonRef,
8683
+ icon: "etc",
8684
+ size,
8685
+ intent,
8686
+ tooltipText: open ? "" : tooltipText,
8687
+ ariaLabel: label,
8688
+ ariaExpanded: open,
8689
+ disabled
8690
+ }
8691
+ )
8692
+ }
8693
+ ) }),
8694
+ /* @__PURE__ */ jsxRuntime.jsx(
8695
+ DropdownMenuContent,
8696
+ {
8697
+ items,
8698
+ onItemClick,
8699
+ onPointerDown: () => pointerRef.current = true,
8700
+ onPointerDownOutside: () => pointerRef.current = true,
8701
+ onKeyDown: () => pointerRef.current = false,
8702
+ onCloseAutoFocus: (e) => {
8703
+ e.preventDefault();
8704
+ if (!pointerRef.current) buttonRef.current?.focus();
8705
+ }
8706
+ }
8707
+ )
8708
+ ]
8709
+ }
8710
+ );
8711
+ }
8712
+ );
8713
+ var SMeatballButton2 = /* @__PURE__ */ withDisplayName(SMeatballButtonImpl, "SMeatballButton");
8613
8714
  function SSwitch({
8614
8715
  value = false,
8615
8716
  leftLabel,
@@ -9585,7 +9686,7 @@ var SPopup = /* @__PURE__ */ react.forwardRef(function SPopup2({
9585
9686
  }
9586
9687
  );
9587
9688
  });
9588
- var DEFAULT_LABEL = { tip: "\uD65C\uC6A9 TIP", notion: "\uC0AC\uC6A9\uBC95 \uC548\uB0B4" };
9689
+ var DEFAULT_LABEL2 = { tip: "\uD65C\uC6A9 TIP", notion: "\uC0AC\uC6A9\uBC95 \uC548\uB0B4" };
9589
9690
  var ICON = { tip: "helpOutline", notion: "notion" };
9590
9691
  var VIEWPORT_GUTTER = 24;
9591
9692
  var CLOSE_INSET = 12;
@@ -9607,7 +9708,7 @@ function SGuide({
9607
9708
  const portalContainer = usePortalContainer();
9608
9709
  const isNotion = type === "notion";
9609
9710
  const isAutoWidth = popupWidth === "auto";
9610
- const defaultLabel = DEFAULT_LABEL[type];
9711
+ const defaultLabel = DEFAULT_LABEL2[type];
9611
9712
  const iconName = ICON[type];
9612
9713
  const messages = flattenMessages(message);
9613
9714
  const active = open;
@@ -13619,6 +13720,7 @@ var CALENDAR_BOARD_EVENT_COLORS = [
13619
13720
  "yellow",
13620
13721
  "orange",
13621
13722
  "red",
13723
+ "purple",
13622
13724
  "white"
13623
13725
  ];
13624
13726
  var BG = (name) => `var(--cmp-calendarBoard-eventButton-bg-${name})`;
@@ -13631,6 +13733,7 @@ var CALENDAR_BOARD_EVENT_PRESETS = {
13631
13733
  yellow: { bg: BG("yellow"), dot: "yellow" },
13632
13734
  orange: { bg: BG("orange"), dot: "orange" },
13633
13735
  red: { bg: BG("red"), dot: "red" },
13736
+ purple: { bg: BG("purple"), dot: "purple" },
13634
13737
  white: { bg: BG("white"), dot: "grey" }
13635
13738
  };
13636
13739
  var CALENDAR_BOARD_MAX_VISIBLE_EVENTS = 4;
@@ -15561,7 +15664,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
15561
15664
  react.useEffect(() => {
15562
15665
  setColumnWidths(visibleCols.map(colWidthFromDef));
15563
15666
  }, [colSignature]);
15564
- const selectedKeys = react.useMemo(() => new Set(selected.map((r2) => r2[rowKey])), [selected, rowKey]);
15667
+ const selectedKeys = react.useMemo(() => new Set(selected.map((r3) => r3[rowKey])), [selected, rowKey]);
15565
15668
  const rangeAnchorRef = react.useRef(null);
15566
15669
  const shiftPressedRef = react.useRef(false);
15567
15670
  const isRowSelected = react.useCallback(
@@ -15581,7 +15684,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
15581
15684
  const targets = rws.filter(canSelectRow);
15582
15685
  const total = targets.length;
15583
15686
  if (total === 0) return false;
15584
- const cnt = targets.filter((r2) => selectedKeys.has(r2[rowKey])).length;
15687
+ const cnt = targets.filter((r3) => selectedKeys.has(r3[rowKey])).length;
15585
15688
  if (cnt === 0) return false;
15586
15689
  if (cnt === total) return true;
15587
15690
  return null;
@@ -15785,16 +15888,16 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
15785
15888
  updateRowSelect: (row) => {
15786
15889
  if (!canSelectRow(row)) return;
15787
15890
  if (selectedKeys.has(row[rowKey]))
15788
- onSelectedChange?.(selected.filter((r2) => r2[rowKey] !== row[rowKey]));
15891
+ onSelectedChange?.(selected.filter((r3) => r3[rowKey] !== row[rowKey]));
15789
15892
  else onSelectedChange?.([...selected, row]);
15790
15893
  },
15791
15894
  toggleSelectAll: (checked, rws) => {
15792
15895
  if (checked) {
15793
- const add = rws.filter((r2) => canSelectRow(r2) && !selectedKeys.has(r2[rowKey]));
15896
+ const add = rws.filter((r3) => canSelectRow(r3) && !selectedKeys.has(r3[rowKey]));
15794
15897
  onSelectedChange?.([...selected, ...add]);
15795
15898
  } else {
15796
- const keys = new Set(rws.map((r2) => r2[rowKey]));
15797
- onSelectedChange?.(selected.filter((r2) => !keys.has(r2[rowKey])));
15899
+ const keys = new Set(rws.map((r3) => r3[rowKey]));
15900
+ onSelectedChange?.(selected.filter((r3) => !keys.has(r3[rowKey])));
15798
15901
  }
15799
15902
  }
15800
15903
  }),
@@ -15888,10 +15991,10 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
15888
15991
  const toggleAll = () => {
15889
15992
  rangeAnchorRef.current = null;
15890
15993
  if (headerCheck === true) {
15891
- const targetKeys = new Set(selectAllRows.map((r2) => r2[rowKey]));
15892
- onSelectedChange?.(selected.filter((r2) => !targetKeys.has(r2[rowKey])));
15994
+ const targetKeys = new Set(selectAllRows.map((r3) => r3[rowKey]));
15995
+ onSelectedChange?.(selected.filter((r3) => !targetKeys.has(r3[rowKey])));
15893
15996
  } else {
15894
- const add = selectAllRows.filter((r2) => canSelectRow(r2) && !selectedKeys.has(r2[rowKey]));
15997
+ const add = selectAllRows.filter((r3) => canSelectRow(r3) && !selectedKeys.has(r3[rowKey]));
15895
15998
  onSelectedChange?.([...selected, ...add]);
15896
15999
  }
15897
16000
  };
@@ -15904,17 +16007,17 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
15904
16007
  const shouldSelect = selectedKeys.has(anchor.key);
15905
16008
  const range = rows.slice(from, to + 1).filter(canSelectRow);
15906
16009
  if (shouldSelect) {
15907
- const add = range.filter((r2) => !selectedKeys.has(r2[rowKey]));
16010
+ const add = range.filter((r3) => !selectedKeys.has(r3[rowKey]));
15908
16011
  onSelectedChange?.([...selected, ...add]);
15909
16012
  } else {
15910
- const keys = new Set(range.map((r2) => r2[rowKey]));
15911
- onSelectedChange?.(selected.filter((r2) => !keys.has(r2[rowKey])));
16013
+ const keys = new Set(range.map((r3) => r3[rowKey]));
16014
+ onSelectedChange?.(selected.filter((r3) => !keys.has(r3[rowKey])));
15912
16015
  }
15913
16016
  return;
15914
16017
  }
15915
16018
  rangeAnchorRef.current = { index, key: row[rowKey] };
15916
16019
  if (selectedKeys.has(row[rowKey]))
15917
- onSelectedChange?.(selected.filter((r2) => r2[rowKey] !== row[rowKey]));
16020
+ onSelectedChange?.(selected.filter((r3) => r3[rowKey] !== row[rowKey]));
15918
16021
  else onSelectedChange?.([...selected, row]);
15919
16022
  };
15920
16023
  const isViewSelected = (row) => row != null && (dragPreviewKeys ?? selectedKeys).has(row[rowKey]);
@@ -15922,14 +16025,14 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
15922
16025
  const [a, b] = from <= to ? [from, to] : [to, from];
15923
16026
  return rows.slice(a, b + 1).filter(canSelectRow);
15924
16027
  };
15925
- const dragPreviewOf = (base, anchor, to) => /* @__PURE__ */ new Set([...base, ...dragRangeRows(anchor, to).map((r2) => r2[rowKey])]);
16028
+ const dragPreviewOf = (base, anchor, to) => /* @__PURE__ */ new Set([...base, ...dragRangeRows(anchor, to).map((r3) => r3[rowKey])]);
15926
16029
  const startDragSelect = (index, event) => {
15927
16030
  if (event.button !== 0) return;
15928
16031
  const target = event.target;
15929
16032
  if (target?.closest?.(ROW_INTERACTIVE_SELECTOR)) return;
15930
16033
  event.preventDefault();
15931
16034
  const baseRows = event.ctrlKey || event.metaKey ? selected : [];
15932
- const baseKeys = new Set(baseRows.map((r2) => r2[rowKey]));
16035
+ const baseKeys = new Set(baseRows.map((r3) => r3[rowKey]));
15933
16036
  dragRef.current = { anchor: index, last: index, baseKeys, baseRows };
15934
16037
  setDragPreviewKeys(dragPreviewOf(baseKeys, index, index));
15935
16038
  };
@@ -15946,7 +16049,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
15946
16049
  if (!d) return;
15947
16050
  dragRef.current = null;
15948
16051
  setDragPreviewKeys(null);
15949
- const add = dragRangeRows(d.anchor, d.last).filter((r2) => !d.baseKeys.has(r2[rowKey]));
16052
+ const add = dragRangeRows(d.anchor, d.last).filter((r3) => !d.baseKeys.has(r3[rowKey]));
15950
16053
  onSelectedChange?.([...d.baseRows, ...add]);
15951
16054
  };
15952
16055
  react.useEffect(() => {
@@ -16503,7 +16606,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
16503
16606
  ),
16504
16607
  contextMenuOn && typeof document !== "undefined" && reactDom.createPortal(
16505
16608
  /* @__PURE__ */ jsxRuntime.jsxs(
16506
- RDropdown3__namespace.Root,
16609
+ RDropdown5__namespace.Root,
16507
16610
  {
16508
16611
  modal: false,
16509
16612
  open: contextMenuOpen,
@@ -16511,7 +16614,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
16511
16614
  if (!open) setContextMenu((m) => m == null ? null : { ...m, open: false });
16512
16615
  },
16513
16616
  children: [
16514
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
16617
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
16515
16618
  "span",
16516
16619
  {
16517
16620
  "aria-hidden": true,
@@ -16520,7 +16623,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
16520
16623
  }
16521
16624
  ) }),
16522
16625
  /* @__PURE__ */ jsxRuntime.jsx(
16523
- RDropdown3__namespace.Content,
16626
+ RDropdown5__namespace.Content,
16524
16627
  {
16525
16628
  align: "start",
16526
16629
  side: "bottom",
@@ -16534,7 +16637,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
16534
16637
  FLOATING_SLIDE_ANIM
16535
16638
  ),
16536
16639
  children: contextMenuItems?.map((item4) => /* @__PURE__ */ jsxRuntime.jsxs(
16537
- RDropdown3__namespace.Item,
16640
+ RDropdown5__namespace.Item,
16538
16641
  {
16539
16642
  disabled: item4.disabled,
16540
16643
  onSelect: () => onContextMenuItemClick?.(item4.value, contextMenu?.rows ?? []),
@@ -18419,10 +18522,10 @@ function SDateRangePicker({
18419
18522
  lineHeight: 20,
18420
18523
  radius: 4
18421
18524
  };
18422
- const select = (r2) => {
18525
+ const select = (r3) => {
18423
18526
  setPendingStart(null);
18424
- onValueChange?.(r2);
18425
- if (rules && rules.length > 0) setRuleError(runRules(r2, rules));
18527
+ onValueChange?.(r3);
18528
+ if (rules && rules.length > 0) setRuleError(runRules(r3, rules));
18426
18529
  if (!showTimePicker) setOpen(false);
18427
18530
  };
18428
18531
  const clear = () => {
@@ -18558,7 +18661,19 @@ function SDateRangePicker({
18558
18661
  }
18559
18662
  );
18560
18663
  }
18664
+ var CHIP_COLORS = [
18665
+ "red",
18666
+ "orange",
18667
+ "yellow",
18668
+ "green",
18669
+ "blue",
18670
+ "darkblue",
18671
+ "indigo",
18672
+ "purple",
18673
+ "grey"
18674
+ ];
18561
18675
  var SChipImpl = /* @__PURE__ */ react.forwardRef(function SChip({
18676
+ color,
18562
18677
  name,
18563
18678
  value = "",
18564
18679
  error: errorProp = false,
@@ -18633,9 +18748,10 @@ var SChipImpl = /* @__PURE__ */ react.forwardRef(function SChip({
18633
18748
  cancel();
18634
18749
  }
18635
18750
  };
18636
- const bg = disabled ? "var(--cmp-chip-bg-disabled)" : error ? "var(--cmp-chip-bg-error)" : editing ? "var(--cmp-chip-bg-focus)" : "var(--cmp-chip-bg-default)";
18637
- const content = disabled ? "var(--cmp-chip-content-disabled)" : error ? "var(--cmp-chip-content-error)" : editing ? "var(--cmp-chip-content-focus)" : "var(--cmp-chip-content-default)";
18638
- const borderColor = editing && !error ? "var(--cmp-chip-border-focus)" : "transparent";
18751
+ const colored = color != null && !disabled && !error && !editing;
18752
+ const bg = disabled ? "var(--cmp-chip-bg-disabled)" : error ? "var(--cmp-chip-bg-error)" : editing ? "var(--cmp-chip-bg-focus)" : colored ? `var(--cmp-chip-chip-${color}-bg)` : "var(--cmp-chip-bg-default)";
18753
+ const content = disabled ? "var(--cmp-chip-content-disabled)" : error ? "var(--cmp-chip-content-error)" : editing ? "var(--cmp-chip-content-focus)" : colored ? `var(--cmp-chip-chip-${color}-content)` : "var(--cmp-chip-content-default)";
18754
+ const borderColor = editing && !error ? "var(--cmp-chip-border-focus)" : colored ? `var(--cmp-chip-chip-${color}-border)` : "transparent";
18639
18755
  return (
18640
18756
  // 외곽 span 은 비상호작용 컨테이너다. 편집 진입 트리거는 값 텍스트의 실제 <button>
18641
18757
  // 이 담당하고, remove 는 형제 <button> 으로 둔다 — role="button" 안에 버튼을 넣던
@@ -18991,8 +19107,8 @@ function SKeyValueTable({
18991
19107
  const isLabelCol = [];
18992
19108
  const labelColWidth = [];
18993
19109
  let maxCols = 0;
18994
- fields.forEach((row, r2) => {
18995
- const occupied = grid[r2];
19110
+ fields.forEach((row, r3) => {
19111
+ const occupied = grid[r3];
18996
19112
  let col = 0;
18997
19113
  const skipOccupied = () => {
18998
19114
  let sawThSupply = false;
@@ -19009,7 +19125,7 @@ function SKeyValueTable({
19009
19125
  const tdColSpan = f.tdColSpan && f.tdColSpan > 1 ? f.tdColSpan : 1;
19010
19126
  const thSuppliedAbove = skipOccupied();
19011
19127
  const showTh = !f.hideTh && !thSuppliedAbove;
19012
- showThAt[r2][i] = showTh;
19128
+ showThAt[r3][i] = showTh;
19013
19129
  if (showTh) {
19014
19130
  isLabelCol[col] = true;
19015
19131
  if (thColSpan === 1 && f.thWidth != null && labelColWidth[col] == null)
@@ -19017,7 +19133,7 @@ function SKeyValueTable({
19017
19133
  for (let dr = 1; dr < thRowSpan; dr++) {
19018
19134
  const kind = dr >= tdRowSpan ? "th-supply" : "blocked";
19019
19135
  for (let dc = 0; dc < thColSpan; dc++) {
19020
- const target = grid[r2 + dr];
19136
+ const target = grid[r3 + dr];
19021
19137
  if (target) target[col + dc] = kind;
19022
19138
  }
19023
19139
  }
@@ -19026,7 +19142,7 @@ function SKeyValueTable({
19026
19142
  skipOccupied();
19027
19143
  for (let dr = 1; dr < tdRowSpan; dr++) {
19028
19144
  for (let dc = 0; dc < tdColSpan; dc++) {
19029
- const target = grid[r2 + dr];
19145
+ const target = grid[r3 + dr];
19030
19146
  if (target) target[col + dc] = "blocked";
19031
19147
  }
19032
19148
  }
@@ -19051,10 +19167,10 @@ function SKeyValueTable({
19051
19167
  { length: maxCols },
19052
19168
  (_, i) => isLabelCol[i] ? /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: cssLen2(labelColWidth[i]) ?? "120px" } }, `col-${i}`) : /* @__PURE__ */ jsxRuntime.jsx("col", {}, `col-${i}`)
19053
19169
  ) }),
19054
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: fields.map((row, r2) => {
19055
- const cellBorder = r2 === 0 ? "" : "border-t border-solid border-[color:var(--cmp-table-border-color)]";
19170
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: fields.map((row, r3) => {
19171
+ const cellBorder = r3 === 0 ? "" : "border-t border-solid border-[color:var(--cmp-table-border-color)]";
19056
19172
  return /* @__PURE__ */ jsxRuntime.jsx("tr", { children: row.map((f, c) => {
19057
- const showTh = showThAt[r2][c];
19173
+ const showTh = showThAt[r3][c];
19058
19174
  const isReadOnlyCell = f.render == null && (f.type == null || f.type === "text");
19059
19175
  return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
19060
19176
  showTh && /* @__PURE__ */ jsxRuntime.jsx(
@@ -19090,7 +19206,7 @@ function SKeyValueTable({
19090
19206
  )
19091
19207
  ] })
19092
19208
  },
19093
- `th-${r2}-${c}`
19209
+ `th-${r3}-${c}`
19094
19210
  ),
19095
19211
  /* @__PURE__ */ jsxRuntime.jsx(
19096
19212
  "td",
@@ -19107,10 +19223,10 @@ function SKeyValueTable({
19107
19223
  style: { height: cellHeight, paddingTop: cellPadY, paddingBottom: cellPadY },
19108
19224
  children: renderField(f)
19109
19225
  },
19110
- `td-${r2}-${c}`
19226
+ `td-${r3}-${c}`
19111
19227
  )
19112
- ] }, `${r2}-${c}`);
19113
- }) }, r2);
19228
+ ] }, `${r3}-${c}`);
19229
+ }) }, r3);
19114
19230
  }) })
19115
19231
  ]
19116
19232
  }
@@ -19416,6 +19532,7 @@ function ChartTooltip({
19416
19532
  anchor,
19417
19533
  bounds,
19418
19534
  gapX = DEFAULT_GAP_X,
19535
+ footer,
19419
19536
  className
19420
19537
  }) {
19421
19538
  const { ref, size } = useElementSize();
@@ -19466,7 +19583,8 @@ function ChartTooltip({
19466
19583
  ]
19467
19584
  },
19468
19585
  `${item4.label}-${index}`
19469
- ))
19586
+ )),
19587
+ footer != null && footer !== false && /* @__PURE__ */ jsxRuntime.jsx("div", { children: footer })
19470
19588
  ]
19471
19589
  }
19472
19590
  );
@@ -19521,23 +19639,23 @@ function barOpacity(hoveredCategory, categoryIndex) {
19521
19639
  return hoveredCategory === categoryIndex ? BAR_OPACITY_HOVER : BAR_OPACITY_DIMMED;
19522
19640
  }
19523
19641
  function barPath(x, y, width, height, direction, negative) {
19524
- const r2 = Math.max(0, Math.min(BAR_RADIUS, width / 2, height / 2));
19525
- if (r2 === 0) return `M${x} ${y}h${width}v${height}h${-width}Z`;
19642
+ const r3 = Math.max(0, Math.min(BAR_RADIUS, width / 2, height / 2));
19643
+ if (r3 === 0) return `M${x} ${y}h${width}v${height}h${-width}Z`;
19526
19644
  if (direction === "vertical") {
19527
19645
  return negative ? (
19528
19646
  // 아래로 자란다 — 아래쪽 두 모서리가 둥글다
19529
- `M${x} ${y}h${width}v${height - r2}a${r2} ${r2} 0 0 1 ${-r2} ${r2}h${-(width - 2 * r2)}a${r2} ${r2} 0 0 1 ${-r2} ${-r2}Z`
19647
+ `M${x} ${y}h${width}v${height - r3}a${r3} ${r3} 0 0 1 ${-r3} ${r3}h${-(width - 2 * r3)}a${r3} ${r3} 0 0 1 ${-r3} ${-r3}Z`
19530
19648
  ) : (
19531
19649
  // 위로 자란다 — 위쪽 두 모서리가 둥글다
19532
- `M${x} ${y + height}v${-(height - r2)}a${r2} ${r2} 0 0 1 ${r2} ${-r2}h${width - 2 * r2}a${r2} ${r2} 0 0 1 ${r2} ${r2}v${height - r2}Z`
19650
+ `M${x} ${y + height}v${-(height - r3)}a${r3} ${r3} 0 0 1 ${r3} ${-r3}h${width - 2 * r3}a${r3} ${r3} 0 0 1 ${r3} ${r3}v${height - r3}Z`
19533
19651
  );
19534
19652
  }
19535
19653
  return negative ? (
19536
19654
  // 왼쪽으로 자란다
19537
- `M${x + width} ${y}h${-(width - r2)}a${r2} ${r2} 0 0 0 ${-r2} ${r2}v${height - 2 * r2}a${r2} ${r2} 0 0 0 ${r2} ${r2}h${width - r2}Z`
19655
+ `M${x + width} ${y}h${-(width - r3)}a${r3} ${r3} 0 0 0 ${-r3} ${r3}v${height - 2 * r3}a${r3} ${r3} 0 0 0 ${r3} ${r3}h${width - r3}Z`
19538
19656
  ) : (
19539
19657
  // 오른쪽으로 자란다
19540
- `M${x} ${y}h${width - r2}a${r2} ${r2} 0 0 1 ${r2} ${r2}v${height - 2 * r2}a${r2} ${r2} 0 0 1 ${-r2} ${r2}h${-(width - r2)}Z`
19658
+ `M${x} ${y}h${width - r3}a${r3} ${r3} 0 0 1 ${r3} ${r3}v${height - 2 * r3}a${r3} ${r3} 0 0 1 ${-r3} ${r3}h${-(width - r3)}Z`
19541
19659
  );
19542
19660
  }
19543
19661
  var SBarChart = /* @__PURE__ */ react.forwardRef(function SBarChart2({
@@ -19557,6 +19675,7 @@ var SBarChart = /* @__PURE__ */ react.forwardRef(function SBarChart2({
19557
19675
  formatValue = defaultFormat,
19558
19676
  height,
19559
19677
  onBarClick,
19678
+ tooltipFooter,
19560
19679
  className,
19561
19680
  style
19562
19681
  }, ref) {
@@ -19985,7 +20104,16 @@ var SBarChart = /* @__PURE__ */ react.forwardRef(function SBarChart2({
19985
20104
  items: tooltipItems,
19986
20105
  anchor: tooltipAnchor,
19987
20106
  bounds: size,
19988
- gapX: tooltipGapX
20107
+ gapX: tooltipGapX,
20108
+ footer: tooltipFooter?.({
20109
+ categoryIndex: hoveredCategory,
20110
+ name: categories[hoveredCategory] ?? "",
20111
+ points: series.flatMap((s, seriesIndex) => {
20112
+ const value = s.data[hoveredCategory];
20113
+ if (value == null || !Number.isFinite(value)) return [];
20114
+ return [{ seriesIndex, categoryIndex: hoveredCategory, value }];
20115
+ })
20116
+ })
19989
20117
  }
19990
20118
  )
19991
20119
  ]
@@ -20047,7 +20175,8 @@ var POINT_HOVER_BG = "var(--cmp-chart-bg)";
20047
20175
  var POINT_HOVER_EXTENT = POINT_HOVER_RADIUS + POINT_HOVER_BORDER_WIDTH / 2;
20048
20176
  var BAND_MIN = 40;
20049
20177
  var VALUE_LABEL_GAP2 = 6;
20050
- var AREA_OPACITY = "var(--opacity-040)";
20178
+ var AREA_OPACITY_TOP = "30%";
20179
+ var AREA_OPACITY_BOTTOM = "var(--opacity-005)";
20051
20180
  var LINE_DATA_LABEL_COLOR = "var(--cmp-chart-bar-dataLabel-color-default)";
20052
20181
  var LINE_DATA_LABEL_TYPO = "typo-body-sm-medium";
20053
20182
  var LINE_DATA_LABEL_TYPO_HOVER = "typo-body-md-bold";
@@ -20143,6 +20272,7 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20143
20272
  formatValue = defaultFormat2,
20144
20273
  height,
20145
20274
  onPointClick,
20275
+ tooltipFooter,
20146
20276
  className,
20147
20277
  style
20148
20278
  }, ref) {
@@ -20150,6 +20280,7 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20150
20280
  const { ref: plotRef, size } = useElementSize();
20151
20281
  const { ref: axisTextRef, size: axisText } = useElementSize();
20152
20282
  const { ref: axisSampleRef, size: axisSample } = useElementSize();
20283
+ const gradientId = react.useId();
20153
20284
  const [hoveredCategory, setHoveredCategory] = react.useState(null);
20154
20285
  const colorAt = react.useCallback(
20155
20286
  (seriesIndex) => paletteColor(palette, seriesIndex, customColors),
@@ -20177,26 +20308,41 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20177
20308
  ),
20178
20309
  [rows, tickCount, max]
20179
20310
  );
20180
- const band = categories.length > 0 ? Math.max(0, size.width - AXIS_EDGE_PADDING * 2) / categories.length : 0;
20181
- const minPlotWidth = categories.length * BAND_MIN + AXIS_EDGE_PADDING * 2;
20311
+ const count = categories.length;
20312
+ const step = count > 1 ? size.width / (count - 1) : 0;
20313
+ const xAt = react.useCallback(
20314
+ (index) => count > 1 ? index * step : size.width / 2,
20315
+ [count, step, size.width]
20316
+ );
20317
+ const cellOf = react.useCallback(
20318
+ (index) => count > 1 ? {
20319
+ left: Math.max(0, xAt(index) - step / 2),
20320
+ right: Math.min(size.width, xAt(index) + step / 2)
20321
+ } : { left: 0, right: size.width },
20322
+ [count, step, xAt, size.width]
20323
+ );
20324
+ const edgeOf = react.useCallback(
20325
+ (index) => count > 1 && index === 0 ? "start" : count > 1 && index === count - 1 ? "end" : null,
20326
+ [count]
20327
+ );
20328
+ const minPlotWidth = categories.length * BAND_MIN;
20182
20329
  const totalHeight = height ?? 320;
20183
20330
  const plotHeight = typeof totalHeight === "number" ? Math.max(0, totalHeight - axisText.height) : `calc(${totalHeight} - ${axisText.height}px)`;
20184
20331
  const plotted = react.useMemo(() => {
20185
20332
  if (size.width <= 0 || size.height <= 0) return [];
20186
- const xOf = (index) => AXIS_EDGE_PADDING + (index + 0.5) * band;
20187
20333
  const yOf = (value) => size.height - ratioOf(value, scale) * size.height;
20188
20334
  return rows.map(
20189
20335
  (row) => row.map(
20190
- (point, categoryIndex) => point == null ? null : { x: xOf(categoryIndex), y: yOf(point.value), baseY: yOf(point.base), own: point.own }
20336
+ (point, categoryIndex) => point == null ? null : { x: xAt(categoryIndex), y: yOf(point.value), baseY: yOf(point.base), own: point.own }
20191
20337
  )
20192
20338
  );
20193
- }, [rows, size.width, size.height, band, scale]);
20339
+ }, [rows, size.width, size.height, xAt, scale]);
20194
20340
  const legend = showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { items: series.map((s, i) => ({ name: s.name, color: colorAt(i) })) }) : null;
20195
20341
  const handleMove = (event) => {
20196
- if (!showTooltip || band <= 0 || series.length === 0) return;
20342
+ if (!showTooltip || count === 0 || size.width <= 0 || series.length === 0) return;
20197
20343
  const rect = event.currentTarget.getBoundingClientRect();
20198
- const along = event.clientX - rect.left - AXIS_EDGE_PADDING;
20199
- const category = Math.floor(along / band);
20344
+ const along = event.clientX - rect.left;
20345
+ const category = count > 1 ? Math.round(along / step) : 0;
20200
20346
  setHoveredCategory(category >= 0 && category < categories.length ? category : null);
20201
20347
  };
20202
20348
  const tooltipItems = hoveredCategory == null ? [] : rows.flatMap((row, seriesIndex) => {
@@ -20222,10 +20368,9 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20222
20368
  const { ref: valueLabelRef, metrics: valueLabel } = useSvgTextMetrics();
20223
20369
  const tooltipAnchor = react.useMemo(() => {
20224
20370
  if (hoveredCategory == null || anchorTop == null) return null;
20225
- const left = AXIS_EDGE_PADDING + hoveredCategory * band;
20226
20371
  const top = showValueLabel ? anchorTop - POINT_RADIUS - VALUE_LABEL_GAP2 + valueLabel.top : anchorTop - POINT_HOVER_EXTENT;
20227
- return { left, right: left + band, top };
20228
- }, [hoveredCategory, anchorTop, band, showValueLabel, valueLabel.top]);
20372
+ return { ...cellOf(hoveredCategory), top };
20373
+ }, [hoveredCategory, anchorTop, cellOf, showValueLabel, valueLabel.top]);
20229
20374
  const categoryLabels = /* @__PURE__ */ jsxRuntime.jsxs(
20230
20375
  "div",
20231
20376
  {
@@ -20236,8 +20381,11 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20236
20381
  categories.map((label, index) => /* @__PURE__ */ jsxRuntime.jsx(
20237
20382
  "span",
20238
20383
  {
20239
- className: "absolute top-0 -translate-x-1/2 whitespace-nowrap",
20240
- style: { left: AXIS_EDGE_PADDING + (index + 0.5) * band },
20384
+ className: cn(
20385
+ "absolute top-0 whitespace-nowrap",
20386
+ edgeOf(index) === "start" ? "translate-x-0" : edgeOf(index) === "end" ? "-translate-x-full" : "-translate-x-1/2"
20387
+ ),
20388
+ style: { left: xAt(index) },
20241
20389
  children: label
20242
20390
  },
20243
20391
  `${label}-${index}`
@@ -20261,13 +20409,43 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20261
20409
  {
20262
20410
  "aria-hidden": true,
20263
20411
  d,
20264
- style: { fill: colorAt(seriesIndex), fillOpacity: AREA_OPACITY }
20412
+ style: { fill: `url(#${gradientId}-area-${seriesIndex})` }
20265
20413
  },
20266
20414
  `area-${seriesIndex}-${runIndex}`
20267
20415
  );
20268
20416
  })
20269
20417
  );
20270
- }, [area, plotted, smooth, colorAt]);
20418
+ }, [area, plotted, smooth, gradientId]);
20419
+ const areaGradients = react.useMemo(() => {
20420
+ if (!area) return null;
20421
+ return /* @__PURE__ */ jsxRuntime.jsx("defs", { children: plotted.map((_, seriesIndex) => /* @__PURE__ */ jsxRuntime.jsxs(
20422
+ "linearGradient",
20423
+ {
20424
+ id: `${gradientId}-area-${seriesIndex}`,
20425
+ x1: "0",
20426
+ y1: "0",
20427
+ x2: "0",
20428
+ y2: "1",
20429
+ children: [
20430
+ /* @__PURE__ */ jsxRuntime.jsx(
20431
+ "stop",
20432
+ {
20433
+ offset: "0",
20434
+ style: { stopColor: colorAt(seriesIndex), stopOpacity: AREA_OPACITY_TOP }
20435
+ }
20436
+ ),
20437
+ /* @__PURE__ */ jsxRuntime.jsx(
20438
+ "stop",
20439
+ {
20440
+ offset: "1",
20441
+ style: { stopColor: colorAt(seriesIndex), stopOpacity: AREA_OPACITY_BOTTOM }
20442
+ }
20443
+ )
20444
+ ]
20445
+ },
20446
+ `area-gradient-${seriesIndex}`
20447
+ )) });
20448
+ }, [area, plotted, colorAt, gradientId]);
20271
20449
  const lines = react.useMemo(
20272
20450
  () => plotted.flatMap(
20273
20451
  (row, seriesIndex) => runsOf(row).map((run, runIndex) => {
@@ -20347,7 +20525,7 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20347
20525
  y: point.y - POINT_RADIUS - VALUE_LABEL_GAP2,
20348
20526
  className: hoveredCategory === categoryIndex ? LINE_DATA_LABEL_TYPO_HOVER : LINE_DATA_LABEL_TYPO,
20349
20527
  style: { fill: LINE_DATA_LABEL_COLOR },
20350
- textAnchor: "middle",
20528
+ textAnchor: edgeOf(categoryIndex) === "start" ? "start" : edgeOf(categoryIndex) === "end" ? "end" : "middle",
20351
20529
  dominantBaseline: "auto",
20352
20530
  children: formatValue(point.own)
20353
20531
  },
@@ -20355,7 +20533,7 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20355
20533
  )
20356
20534
  )
20357
20535
  ) : [],
20358
- [showValueLabel, plotted, hoveredCategory, formatValue]
20536
+ [showValueLabel, plotted, hoveredCategory, formatValue, edgeOf]
20359
20537
  );
20360
20538
  const inset = { paddingTop: axisSample.height / 2, paddingBottom: axisSample.height / 2 };
20361
20539
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -20385,95 +20563,385 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20385
20563
  sampleRef: axisSampleRef
20386
20564
  }
20387
20565
  ) }),
20388
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 overflow-x-auto", children: [
20389
- /* @__PURE__ */ jsxRuntime.jsx(
20390
- "div",
20391
- {
20392
- className: "relative min-w-0",
20393
- style: { height: plotHeight, minWidth: minPlotWidth || void 0, ...inset },
20394
- children: /* @__PURE__ */ jsxRuntime.jsxs(
20566
+ /* @__PURE__ */ jsxRuntime.jsxs(
20567
+ "div",
20568
+ {
20569
+ className: "min-w-0 overflow-x-auto",
20570
+ style: { marginInline: -POINT_HOVER_EXTENT, paddingInline: POINT_HOVER_EXTENT },
20571
+ children: [
20572
+ /* @__PURE__ */ jsxRuntime.jsx(
20395
20573
  "div",
20396
20574
  {
20397
- ref: plotRef,
20398
- className: "relative h-full w-full",
20399
- onMouseMove: handleMove,
20400
- onMouseLeave: () => setHoveredCategory(null),
20401
- children: [
20402
- size.width > 0 && size.height > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
20403
- "svg",
20404
- {
20405
- width: size.width,
20406
- height: size.height,
20407
- role: "img",
20408
- "aria-label": `${categories.length}\uAC1C \uD56D\uBAA9, ${series.length}\uAC1C \uACC4\uC5F4 ${stacked ? "\uB204\uC801 " : ""}\uAEBE\uC740\uC120 \uADF8\uB798\uD504`,
20409
- children: [
20410
- /* @__PURE__ */ jsxRuntime.jsx(
20411
- "text",
20412
- {
20413
- ref: valueLabelRef,
20414
- "aria-hidden": true,
20415
- x: 0,
20416
- y: 0,
20417
- className: LINE_DATA_LABEL_TYPO_HOVER,
20418
- dominantBaseline: "auto",
20419
- style: { visibility: "hidden" },
20420
- children: "0"
20421
- }
20422
- ),
20423
- /* @__PURE__ */ jsxRuntime.jsx(
20424
- ChartGrid,
20425
- {
20426
- scale,
20427
- direction: "vertical",
20428
- width: size.width,
20429
- height: size.height
20430
- }
20431
- ),
20432
- hoveredCategory != null && /* @__PURE__ */ jsxRuntime.jsx(
20433
- "rect",
20434
- {
20435
- "aria-hidden": true,
20436
- x: AXIS_EDGE_PADDING + hoveredCategory * band,
20437
- y: 0,
20438
- width: band,
20439
- height: size.height,
20440
- style: {
20441
- fill: "var(--cmp-chart-barContainer-hover-bg)",
20442
- fillOpacity: "var(--cmp-chart-barContainer-hover-opacity)"
20443
- }
20444
- }
20445
- ),
20446
- areas,
20447
- lines,
20448
- pointHalos,
20449
- pointDots,
20450
- valueLabels
20451
- ]
20452
- }
20453
- ),
20454
- showTooltip && hoveredCategory != null && tooltipAnchor != null && tooltipItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
20455
- ChartTooltip,
20456
- {
20457
- title: categories[hoveredCategory] ?? "",
20458
- items: tooltipItems,
20459
- anchor: tooltipAnchor,
20460
- bounds: size,
20461
- gapX: { after: -4, before: -4 }
20462
- }
20463
- )
20464
- ]
20575
+ className: "relative min-w-0",
20576
+ style: { height: plotHeight, minWidth: minPlotWidth || void 0, ...inset },
20577
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
20578
+ "div",
20579
+ {
20580
+ ref: plotRef,
20581
+ className: "relative h-full w-full",
20582
+ onMouseMove: handleMove,
20583
+ onMouseLeave: () => setHoveredCategory(null),
20584
+ children: [
20585
+ size.width > 0 && size.height > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
20586
+ "svg",
20587
+ {
20588
+ width: size.width,
20589
+ height: size.height,
20590
+ overflow: "visible",
20591
+ role: "img",
20592
+ "aria-label": `${categories.length}\uAC1C \uD56D\uBAA9, ${series.length}\uAC1C \uACC4\uC5F4 ${stacked ? "\uB204\uC801 " : ""}\uAEBE\uC740\uC120 \uADF8\uB798\uD504`,
20593
+ children: [
20594
+ /* @__PURE__ */ jsxRuntime.jsx(
20595
+ "text",
20596
+ {
20597
+ ref: valueLabelRef,
20598
+ "aria-hidden": true,
20599
+ x: 0,
20600
+ y: 0,
20601
+ className: LINE_DATA_LABEL_TYPO_HOVER,
20602
+ dominantBaseline: "auto",
20603
+ style: { visibility: "hidden" },
20604
+ children: "0"
20605
+ }
20606
+ ),
20607
+ /* @__PURE__ */ jsxRuntime.jsx(
20608
+ ChartGrid,
20609
+ {
20610
+ scale,
20611
+ direction: "vertical",
20612
+ width: size.width,
20613
+ height: size.height
20614
+ }
20615
+ ),
20616
+ hoveredCategory != null && /* @__PURE__ */ jsxRuntime.jsx(
20617
+ "rect",
20618
+ {
20619
+ "aria-hidden": true,
20620
+ x: cellOf(hoveredCategory).left,
20621
+ y: 0,
20622
+ width: cellOf(hoveredCategory).right - cellOf(hoveredCategory).left,
20623
+ height: size.height,
20624
+ style: {
20625
+ fill: "var(--cmp-chart-barContainer-hover-bg)",
20626
+ fillOpacity: "var(--cmp-chart-barContainer-hover-opacity)"
20627
+ }
20628
+ }
20629
+ ),
20630
+ areaGradients,
20631
+ areas,
20632
+ lines,
20633
+ pointHalos,
20634
+ pointDots,
20635
+ valueLabels
20636
+ ]
20637
+ }
20638
+ ),
20639
+ showTooltip && hoveredCategory != null && tooltipAnchor != null && tooltipItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
20640
+ ChartTooltip,
20641
+ {
20642
+ title: categories[hoveredCategory] ?? "",
20643
+ items: tooltipItems,
20644
+ anchor: tooltipAnchor,
20645
+ bounds: size,
20646
+ gapX: { after: -4, before: -4 },
20647
+ footer: tooltipFooter?.({
20648
+ categoryIndex: hoveredCategory,
20649
+ name: categories[hoveredCategory] ?? "",
20650
+ points: rows.flatMap((row, seriesIndex) => {
20651
+ const point = row[hoveredCategory];
20652
+ if (point == null) return [];
20653
+ return [{ seriesIndex, categoryIndex: hoveredCategory, value: point.own }];
20654
+ })
20655
+ })
20656
+ }
20657
+ )
20658
+ ]
20659
+ }
20660
+ )
20465
20661
  }
20466
- )
20467
- }
20468
- ),
20469
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: axisTextRef, children: categoryLabels })
20470
- ] })
20662
+ ),
20663
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: axisTextRef, children: categoryLabels })
20664
+ ]
20665
+ }
20666
+ )
20471
20667
  ]
20472
20668
  }
20473
20669
  )
20474
20670
  }
20475
20671
  );
20476
20672
  });
20673
+ var DONUT_INNER_RATIO = 0.4;
20674
+ var LABEL_MIN_RATIO = 0.05;
20675
+ var PIE_LABEL_RADIUS_RATIO = 0.65;
20676
+ var HOVER_GROW = 4;
20677
+ var HOVER_CORNER = 2;
20678
+ var OPACITY_DEFAULT = "var(--cmp-chart-bar-opacity-default)";
20679
+ var OPACITY_DIMMED = "var(--cmp-chart-bar-opacity-dimmed)";
20680
+ var OPACITY_HOVER = 1;
20681
+ var defaultFormat3 = (value) => value.toLocaleString();
20682
+ function formatRatio(ratio) {
20683
+ if (ratio > 0 && ratio < 0.01) return "<1%";
20684
+ return `${Math.round(ratio * 100)}%`;
20685
+ }
20686
+ var r2 = (value) => Math.round(value * 100) / 100;
20687
+ function polar(center, radius, angle) {
20688
+ return { x: center + radius * Math.sin(angle), y: center - radius * Math.cos(angle) };
20689
+ }
20690
+ var arc = (radius, large, sweep, p) => `A${r2(radius)} ${r2(radius)} 0 ${large} ${sweep} ${r2(p.x)} ${r2(p.y)}`;
20691
+ function fitCorner(corner, outer, inner, span) {
20692
+ if (corner <= 0 || outer <= 0) return 0;
20693
+ let fitted = Math.min(corner, (outer - inner) / 2);
20694
+ if (span < Math.PI) {
20695
+ const half = Math.sin(span / 2);
20696
+ fitted = Math.min(fitted, outer * half / (1 + half));
20697
+ if (inner > 0) fitted = Math.min(fitted, inner * half / (1 - half));
20698
+ }
20699
+ return fitted >= 0.5 ? fitted : 0;
20700
+ }
20701
+ function slicePath(center, outer, inner, start, end, corner = 0) {
20702
+ if (end - start >= Math.PI * 2 - 1e-6) {
20703
+ const ring = (radius) => `M${r2(center - radius)} ${r2(center)}A${r2(radius)} ${r2(radius)} 0 1 1 ${r2(center + radius)} ${r2(center)}A${r2(radius)} ${r2(radius)} 0 1 1 ${r2(center - radius)} ${r2(center)}Z`;
20704
+ return inner > 0 ? ring(outer) + ring(inner) : ring(outer);
20705
+ }
20706
+ const span = end - start;
20707
+ const round = fitCorner(corner, outer, inner, span);
20708
+ const outerLine = Math.sqrt(Math.max(outer * outer - 2 * outer * round, 0));
20709
+ const outerPhi = round > 0 ? Math.asin(round / (outer - round)) : 0;
20710
+ const outerLarge = span - 2 * outerPhi > Math.PI ? 1 : 0;
20711
+ const o0 = polar(center, outerLine, start);
20712
+ let d = `M${r2(o0.x)} ${r2(o0.y)}`;
20713
+ if (round > 0) d += arc(round, 0, 1, polar(center, outer, start + outerPhi));
20714
+ d += arc(outer, outerLarge, 1, polar(center, outer, end - outerPhi));
20715
+ if (round > 0) d += arc(round, 0, 1, polar(center, outerLine, end));
20716
+ if (inner <= 0) return `${d}L${r2(center)} ${r2(center)}Z`;
20717
+ const innerLine = Math.sqrt(inner * inner + 2 * inner * round);
20718
+ const innerPhi = round > 0 ? Math.asin(round / (inner + round)) : 0;
20719
+ const innerLarge = span - 2 * innerPhi > Math.PI ? 1 : 0;
20720
+ const i0 = polar(center, innerLine, end);
20721
+ d += `L${r2(i0.x)} ${r2(i0.y)}`;
20722
+ if (round > 0) d += arc(round, 0, 1, polar(center, inner, end - innerPhi));
20723
+ d += arc(inner, innerLarge, 0, polar(center, inner, start + innerPhi));
20724
+ if (round > 0) d += arc(round, 0, 1, polar(center, innerLine, start));
20725
+ return `${d}Z`;
20726
+ }
20727
+ var RadialChart = /* @__PURE__ */ react.forwardRef(function RadialChart2({
20728
+ data,
20729
+ palette = "multi",
20730
+ colors,
20731
+ showValueLabel = false,
20732
+ showLegend = true,
20733
+ legendPosition = "top",
20734
+ showTooltip = true,
20735
+ formatValue = defaultFormat3,
20736
+ onSliceClick,
20737
+ tooltipFooter,
20738
+ className,
20739
+ style,
20740
+ innerRatio,
20741
+ kind
20742
+ }, ref) {
20743
+ const { ref: plotRef, size } = useElementSize();
20744
+ const [hovered, setHovered] = react.useState(null);
20745
+ const arcs = react.useMemo(() => {
20746
+ const effective = palette === "custom" && !colors?.length ? "multi" : palette;
20747
+ const valid = data.map((slice2, index) => ({ ...slice2, index })).filter((slice2) => Number.isFinite(slice2.value) && slice2.value > 0);
20748
+ const sum = valid.reduce((acc, slice2) => acc + slice2.value, 0);
20749
+ let angle = 0;
20750
+ const list = valid.map((slice2) => {
20751
+ const ratio = slice2.value / sum;
20752
+ const start = angle;
20753
+ angle += ratio * Math.PI * 2;
20754
+ return {
20755
+ index: slice2.index,
20756
+ name: slice2.name,
20757
+ value: slice2.value,
20758
+ ratio,
20759
+ start,
20760
+ end: angle,
20761
+ color: paletteColor(effective, slice2.index, colors)
20762
+ };
20763
+ });
20764
+ return list;
20765
+ }, [data, palette, colors]);
20766
+ const diameter = size.width;
20767
+ const center = diameter / 2;
20768
+ const outer = Math.max(center - HOVER_GROW, 0);
20769
+ const inner = outer * innerRatio;
20770
+ const hoveredArc = arcs.find((arc2) => arc2.index === hovered) ?? null;
20771
+ const legend = showLegend ? /* @__PURE__ */ jsxRuntime.jsx(
20772
+ ChartLegend,
20773
+ {
20774
+ items: arcs.map((arc2) => ({ name: arc2.name, color: arc2.color })),
20775
+ activeIndex: hoveredArc ? arcs.indexOf(hoveredArc) : null
20776
+ }
20777
+ ) : null;
20778
+ const tooltipAnchor = react.useMemo(() => {
20779
+ if (!hoveredArc || diameter <= 0) return null;
20780
+ const mid = (hoveredArc.start + hoveredArc.end) / 2;
20781
+ const point = polar(center, (outer + inner) / 2, mid);
20782
+ return { left: point.x, right: point.x, top: point.y };
20783
+ }, [hoveredArc, diameter, center, outer, inner]);
20784
+ const labelRadius = inner > 0 ? (outer + inner) / 2 : outer * PIE_LABEL_RADIUS_RATIO;
20785
+ const slice = (target) => {
20786
+ const picked = hovered === target.index;
20787
+ return slicePath(
20788
+ center,
20789
+ picked ? outer + HOVER_GROW : outer,
20790
+ picked ? Math.max(inner - HOVER_GROW, 0) : inner,
20791
+ target.start,
20792
+ target.end,
20793
+ picked ? HOVER_CORNER : 0
20794
+ );
20795
+ };
20796
+ return /* @__PURE__ */ jsxRuntime.jsx(
20797
+ ChartFrame,
20798
+ {
20799
+ ref,
20800
+ legend,
20801
+ legendPosition,
20802
+ className,
20803
+ style,
20804
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: plotRef, className: "relative aspect-square w-full", children: [
20805
+ diameter > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
20806
+ "svg",
20807
+ {
20808
+ width: diameter,
20809
+ height: diameter,
20810
+ role: "img",
20811
+ "aria-label": `${arcs.length}\uAC1C \uD56D\uBAA9 ${kind}`,
20812
+ onMouseLeave: () => setHovered(null),
20813
+ children: [
20814
+ arcs.length === 0 ? (
20815
+ // 그릴 값이 없어도 자리는 남긴다 — 차트가 사라지면 화면이 무너진 것처럼 보인다.
20816
+ /* @__PURE__ */ jsxRuntime.jsx(
20817
+ "path",
20818
+ {
20819
+ "aria-hidden": true,
20820
+ d: slicePath(center, outer, inner, 0, Math.PI * 2),
20821
+ fillRule: "evenodd",
20822
+ style: { fill: "var(--cmp-chart-grid-line-color)" }
20823
+ }
20824
+ )
20825
+ ) : arcs.map((arc2) => {
20826
+ const opacity = hovered == null ? OPACITY_DEFAULT : hovered === arc2.index ? OPACITY_HOVER : OPACITY_DIMMED;
20827
+ return /* @__PURE__ */ jsxRuntime.jsx(
20828
+ "path",
20829
+ {
20830
+ d: slice(arc2),
20831
+ fillRule: "evenodd",
20832
+ className: "transition-opacity duration-200 ease-out motion-reduce:transition-none",
20833
+ style: {
20834
+ fill: arc2.color,
20835
+ opacity,
20836
+ cursor: onSliceClick ? "pointer" : void 0
20837
+ },
20838
+ onMouseEnter: () => setHovered(arc2.index),
20839
+ onClick: onSliceClick ? () => onSliceClick({
20840
+ index: arc2.index,
20841
+ name: arc2.name,
20842
+ value: arc2.value,
20843
+ ratio: arc2.ratio
20844
+ }) : void 0,
20845
+ children: /* @__PURE__ */ jsxRuntime.jsx("title", { children: `${arc2.name} ${formatValue(arc2.value)} (${formatRatio(arc2.ratio)})` })
20846
+ },
20847
+ `slice-${arc2.index}`
20848
+ );
20849
+ }),
20850
+ showValueLabel && arcs.map((arc2) => {
20851
+ if (arc2.ratio < LABEL_MIN_RATIO) return null;
20852
+ const point = polar(center, labelRadius, (arc2.start + arc2.end) / 2);
20853
+ return /* @__PURE__ */ jsxRuntime.jsx(
20854
+ "text",
20855
+ {
20856
+ "aria-hidden": true,
20857
+ x: point.x,
20858
+ y: point.y,
20859
+ textAnchor: "middle",
20860
+ dominantBaseline: "central",
20861
+ className: "pointer-events-none typo-body-sm-bold transition-opacity duration-200 ease-out motion-reduce:transition-none",
20862
+ style: {
20863
+ fill: "var(--sys-color-fg-inverse)",
20864
+ opacity: hovered != null && hovered !== arc2.index ? OPACITY_DIMMED : void 0
20865
+ },
20866
+ children: formatRatio(arc2.ratio)
20867
+ },
20868
+ `label-${arc2.index}`
20869
+ );
20870
+ })
20871
+ ]
20872
+ }
20873
+ ),
20874
+ showTooltip && hoveredArc && tooltipAnchor && /* @__PURE__ */ jsxRuntime.jsx(
20875
+ ChartTooltip,
20876
+ {
20877
+ title: hoveredArc.name,
20878
+ items: [
20879
+ {
20880
+ color: hoveredArc.color,
20881
+ label: formatValue(hoveredArc.value),
20882
+ value: formatRatio(hoveredArc.ratio)
20883
+ }
20884
+ ],
20885
+ anchor: tooltipAnchor,
20886
+ bounds: size,
20887
+ footer: tooltipFooter?.({
20888
+ index: hoveredArc.index,
20889
+ name: hoveredArc.name,
20890
+ value: hoveredArc.value,
20891
+ ratio: hoveredArc.ratio
20892
+ })
20893
+ }
20894
+ )
20895
+ ] })
20896
+ }
20897
+ );
20898
+ });
20899
+ var SPieChart = /* @__PURE__ */ react.forwardRef(function SPieChart2({
20900
+ palette = "multi",
20901
+ showValueLabel = false,
20902
+ showLegend = true,
20903
+ legendPosition = "top",
20904
+ showTooltip = true,
20905
+ ...props
20906
+ }, ref) {
20907
+ return /* @__PURE__ */ jsxRuntime.jsx(
20908
+ RadialChart,
20909
+ {
20910
+ ref,
20911
+ ...props,
20912
+ palette,
20913
+ showValueLabel,
20914
+ showLegend,
20915
+ legendPosition,
20916
+ showTooltip,
20917
+ innerRatio: 0,
20918
+ kind: "\uD30C\uC774 \uADF8\uB798\uD504"
20919
+ }
20920
+ );
20921
+ });
20922
+ var SDonutChart = /* @__PURE__ */ react.forwardRef(function SDonutChart2({
20923
+ palette = "multi",
20924
+ showValueLabel = false,
20925
+ showLegend = true,
20926
+ legendPosition = "top",
20927
+ showTooltip = true,
20928
+ ...props
20929
+ }, ref) {
20930
+ return /* @__PURE__ */ jsxRuntime.jsx(
20931
+ RadialChart,
20932
+ {
20933
+ ref,
20934
+ ...props,
20935
+ palette,
20936
+ showValueLabel,
20937
+ showLegend,
20938
+ legendPosition,
20939
+ showTooltip,
20940
+ innerRatio: DONUT_INNER_RATIO,
20941
+ kind: "\uB3C4\uB11B \uADF8\uB798\uD504"
20942
+ }
20943
+ );
20944
+ });
20477
20945
  var BUTTON_STYLE = {
20478
20946
  default: { color: "secondary" },
20479
20947
  danger: { color: "danger", outline: true },
@@ -21756,7 +22224,7 @@ var PaletteItem = ({
21756
22224
  className,
21757
22225
  onSelect,
21758
22226
  children
21759
- }) => asMenu ? /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Item, { title: label, "aria-label": label, className, onSelect, children }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", title: label, "aria-label": label, className, onClick: onSelect, children });
22227
+ }) => asMenu ? /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Item, { title: label, "aria-label": label, className, onSelect, children }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", title: label, "aria-label": label, className, onClick: onSelect, children });
21760
22228
  var ColorPalette = ({
21761
22229
  colors,
21762
22230
  columns,
@@ -21842,14 +22310,14 @@ var TableSizePicker = ({
21842
22310
  onPick(size.rows, size.cols);
21843
22311
  }
21844
22312
  },
21845
- children: Array.from({ length: TABLE_PICKER_ROWS }, (_, r2) => /* @__PURE__ */ jsxRuntime.jsx("div", { role: "row", className: "flex", style: { gap: TABLE_PICKER_GAP }, children: Array.from({ length: TABLE_PICKER_COLS }, (_2, c) => {
21846
- const on = r2 < size.rows && c < size.cols;
22313
+ children: Array.from({ length: TABLE_PICKER_ROWS }, (_, r3) => /* @__PURE__ */ jsxRuntime.jsx("div", { role: "row", className: "flex", style: { gap: TABLE_PICKER_GAP }, children: Array.from({ length: TABLE_PICKER_COLS }, (_2, c) => {
22314
+ const on = r3 < size.rows && c < size.cols;
21847
22315
  return /* @__PURE__ */ jsxRuntime.jsx(
21848
22316
  "button",
21849
22317
  {
21850
22318
  type: "button",
21851
22319
  role: "gridcell",
21852
- "aria-label": `${r2 + 1}\uD589 ${c + 1}\uC5F4`,
22320
+ "aria-label": `${r3 + 1}\uD589 ${c + 1}\uC5F4`,
21853
22321
  "aria-selected": on,
21854
22322
  tabIndex: -1,
21855
22323
  className: "box-border cursor-pointer rounded-[3px] border border-solid p-0 outline-none",
@@ -21859,13 +22327,13 @@ var TableSizePicker = ({
21859
22327
  borderColor: on ? "var(--sys-color-bg-accent)" : "var(--sys-color-border-default)",
21860
22328
  background: on ? "var(--color-bg-accentFaint)" : "transparent"
21861
22329
  },
21862
- onMouseEnter: () => setSize({ rows: r2 + 1, cols: c + 1 }),
21863
- onFocus: () => setSize({ rows: r2 + 1, cols: c + 1 }),
21864
- onClick: () => onPick(r2 + 1, c + 1)
22330
+ onMouseEnter: () => setSize({ rows: r3 + 1, cols: c + 1 }),
22331
+ onFocus: () => setSize({ rows: r3 + 1, cols: c + 1 }),
22332
+ onClick: () => onPick(r3 + 1, c + 1)
21865
22333
  },
21866
22334
  c
21867
22335
  );
21868
- }) }, r2))
22336
+ }) }, r3))
21869
22337
  }
21870
22338
  ),
21871
22339
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -21888,7 +22356,7 @@ var TableMenuItem = ({
21888
22356
  disabled,
21889
22357
  onSelect
21890
22358
  }) => /* @__PURE__ */ jsxRuntime.jsx(
21891
- RDropdown3__namespace.Item,
22359
+ RDropdown5__namespace.Item,
21892
22360
  {
21893
22361
  className: cn(menuItemClass, menuItemDisabledClass),
21894
22362
  disabled,
@@ -22055,8 +22523,8 @@ function EditorToolbarBar({
22055
22523
  const node = (item4) => {
22056
22524
  switch (item4) {
22057
22525
  case "heading":
22058
- return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown3__namespace.Root, { modal: !insideModal, children: [
22059
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsxs(
22526
+ return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown5__namespace.Root, { modal: !insideModal, children: [
22527
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsxs(
22060
22528
  ToolbarButton,
22061
22529
  {
22062
22530
  label: "\uC81C\uBAA9 \uB2E8\uACC4",
@@ -22069,9 +22537,9 @@ function EditorToolbarBar({
22069
22537
  ]
22070
22538
  }
22071
22539
  ) }),
22072
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(RDropdown3__namespace.Content, { sideOffset: 4, align: "start", className: menuClass, children: [
22540
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(RDropdown5__namespace.Content, { sideOffset: 4, align: "start", className: menuClass, children: [
22073
22541
  /* @__PURE__ */ jsxRuntime.jsx(
22074
- RDropdown3__namespace.Item,
22542
+ RDropdown5__namespace.Item,
22075
22543
  {
22076
22544
  className: menuItemClass,
22077
22545
  onSelect: () => chain()?.setParagraph().run(),
@@ -22079,7 +22547,7 @@ function EditorToolbarBar({
22079
22547
  }
22080
22548
  ),
22081
22549
  SEDITOR_HEADING_LEVELS.map((level) => /* @__PURE__ */ jsxRuntime.jsx(
22082
- RDropdown3__namespace.Item,
22550
+ RDropdown5__namespace.Item,
22083
22551
  {
22084
22552
  className: menuItemClass,
22085
22553
  onSelect: () => chain()?.setHeading({ level }).run(),
@@ -22090,13 +22558,13 @@ function EditorToolbarBar({
22090
22558
  ] }) })
22091
22559
  ] }, item4);
22092
22560
  case "fontSize":
22093
- return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown3__namespace.Root, { modal: !insideModal, children: [
22094
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsxs(ToolbarButton, { label: "\uAE00\uC790 \uD06C\uAE30", disabled: off, className: "px-[6px]", children: [
22561
+ return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown5__namespace.Root, { modal: !insideModal, children: [
22562
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsxs(ToolbarButton, { label: "\uAE00\uC790 \uD06C\uAE30", disabled: off, className: "px-[6px]", children: [
22095
22563
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[12px] leading-[20px]", children: activeFontSize ?? FONT_SIZE_DEFAULT_LABEL }),
22096
22564
  /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "caretDown", size: 12 })
22097
22565
  ] }) }),
22098
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
22099
- RDropdown3__namespace.Content,
22566
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
22567
+ RDropdown5__namespace.Content,
22100
22568
  {
22101
22569
  sideOffset: 4,
22102
22570
  align: "start",
@@ -22104,7 +22572,7 @@ function EditorToolbarBar({
22104
22572
  style: { maxHeight: FONT_SIZE_MENU_MAX_HEIGHT },
22105
22573
  children: [
22106
22574
  /* @__PURE__ */ jsxRuntime.jsx(
22107
- RDropdown3__namespace.Item,
22575
+ RDropdown5__namespace.Item,
22108
22576
  {
22109
22577
  className: cn(menuItemClass, activeFontSize === null && menuItemSelectedClass),
22110
22578
  title: `${FONT_SIZE_DEFAULT_LABEL} (\uBCF8\uBB38 ${SEDITOR_DEFAULT_FONT_SIZE}px)`,
@@ -22113,7 +22581,7 @@ function EditorToolbarBar({
22113
22581
  }
22114
22582
  ),
22115
22583
  SEDITOR_FONT_SIZES.map((size) => /* @__PURE__ */ jsxRuntime.jsx(
22116
- RDropdown3__namespace.Item,
22584
+ RDropdown5__namespace.Item,
22117
22585
  {
22118
22586
  ref: activeFontSize === size ? (el) => {
22119
22587
  el?.scrollIntoView({ block: "nearest" });
@@ -22205,9 +22673,9 @@ function EditorToolbarBar({
22205
22673
  },
22206
22674
  item4
22207
22675
  );
22208
- return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown3__namespace.Root, { modal: !insideModal, children: [
22209
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { label: "\uAE00\uC790\uC0C9", disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(ColorIndicator, { color: off ? "currentColor" : activeColor, children: /* @__PURE__ */ jsxRuntime.jsx(IconTextColor, { size: ICON_SIZE }) }) }) }),
22210
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Content, { sideOffset: 4, align: "start", className: menuClass, children: /* @__PURE__ */ jsxRuntime.jsx(
22676
+ return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown5__namespace.Root, { modal: !insideModal, children: [
22677
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { label: "\uAE00\uC790\uC0C9", disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(ColorIndicator, { color: off ? "currentColor" : activeColor, children: /* @__PURE__ */ jsxRuntime.jsx(IconTextColor, { size: ICON_SIZE }) }) }) }),
22678
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Content, { sideOffset: 4, align: "start", className: menuClass, children: /* @__PURE__ */ jsxRuntime.jsx(
22211
22679
  ColorPalette,
22212
22680
  {
22213
22681
  asMenu: true,
@@ -22313,14 +22781,14 @@ function EditorToolbarBar({
22313
22781
  case "list": {
22314
22782
  const ListIcon = state2.orderedList ? IconOrderedList : state2.taskList ? IconTaskList : IconBulletList;
22315
22783
  const listActive = state2.bulletList || state2.orderedList || state2.taskList;
22316
- return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown3__namespace.Root, { modal: !insideModal, children: [
22317
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsxs(ToolbarButton, { label: "\uBAA9\uB85D", active: listActive, disabled: off, className: "px-[4px]", children: [
22784
+ return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown5__namespace.Root, { modal: !insideModal, children: [
22785
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsxs(ToolbarButton, { label: "\uBAA9\uB85D", active: listActive, disabled: off, className: "px-[4px]", children: [
22318
22786
  /* @__PURE__ */ jsxRuntime.jsx(ListIcon, { size: ICON_SIZE }),
22319
22787
  /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "caretDown", size: CARET_SIZE })
22320
22788
  ] }) }),
22321
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(RDropdown3__namespace.Content, { sideOffset: 4, align: "start", className: menuClass, children: [
22789
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(RDropdown5__namespace.Content, { sideOffset: 4, align: "start", className: menuClass, children: [
22322
22790
  /* @__PURE__ */ jsxRuntime.jsxs(
22323
- RDropdown3__namespace.Item,
22791
+ RDropdown5__namespace.Item,
22324
22792
  {
22325
22793
  className: menuItemClass,
22326
22794
  onSelect: () => chain()?.toggleBulletList().run(),
@@ -22331,7 +22799,7 @@ function EditorToolbarBar({
22331
22799
  }
22332
22800
  ),
22333
22801
  /* @__PURE__ */ jsxRuntime.jsxs(
22334
- RDropdown3__namespace.Item,
22802
+ RDropdown5__namespace.Item,
22335
22803
  {
22336
22804
  className: menuItemClass,
22337
22805
  onSelect: () => chain()?.toggleOrderedList().run(),
@@ -22342,7 +22810,7 @@ function EditorToolbarBar({
22342
22810
  }
22343
22811
  ),
22344
22812
  /* @__PURE__ */ jsxRuntime.jsxs(
22345
- RDropdown3__namespace.Item,
22813
+ RDropdown5__namespace.Item,
22346
22814
  {
22347
22815
  className: menuItemClass,
22348
22816
  onSelect: () => chain()?.toggleTaskList().run(),
@@ -22446,17 +22914,17 @@ function EditorToolbarBar({
22446
22914
  );
22447
22915
  case "table":
22448
22916
  return /* @__PURE__ */ jsxRuntime.jsxs(
22449
- RDropdown3__namespace.Root,
22917
+ RDropdown5__namespace.Root,
22450
22918
  {
22451
22919
  open: tableOpen,
22452
22920
  onOpenChange: setTableOpen,
22453
22921
  modal: !insideModal,
22454
22922
  children: [
22455
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsxs(ToolbarButton, { label: "\uD45C", active: state2.inTable, disabled: off, className: "px-[6px]", children: [
22923
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsxs(ToolbarButton, { label: "\uD45C", active: state2.inTable, disabled: off, className: "px-[6px]", children: [
22456
22924
  /* @__PURE__ */ jsxRuntime.jsx(IconTable, { size: ICON_SIZE }),
22457
22925
  /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "caretDown", size: CARET_SIZE })
22458
22926
  ] }) }),
22459
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(RDropdown3__namespace.Content, { sideOffset: 4, align: "start", className: menuClass, children: [
22927
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(RDropdown5__namespace.Content, { sideOffset: 4, align: "start", className: menuClass, children: [
22460
22928
  !state2.inTable && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
22461
22929
  /* @__PURE__ */ jsxRuntime.jsx(
22462
22930
  TableSizePicker,
@@ -22468,7 +22936,7 @@ function EditorToolbarBar({
22468
22936
  }
22469
22937
  }
22470
22938
  ),
22471
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Separator, { className: menuSeparatorClass })
22939
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Separator, { className: menuSeparatorClass })
22472
22940
  ] }),
22473
22941
  /* @__PURE__ */ jsxRuntime.jsx(
22474
22942
  TableMenuItem,
@@ -22502,7 +22970,7 @@ function EditorToolbarBar({
22502
22970
  onSelect: () => chain()?.addColumnAfter().run()
22503
22971
  }
22504
22972
  ),
22505
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Separator, { className: menuSeparatorClass }),
22973
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Separator, { className: menuSeparatorClass }),
22506
22974
  /* @__PURE__ */ jsxRuntime.jsx(
22507
22975
  TableMenuItem,
22508
22976
  {
@@ -22535,7 +23003,7 @@ function EditorToolbarBar({
22535
23003
  onSelect: () => chain()?.toggleHeaderColumn().run()
22536
23004
  }
22537
23005
  ),
22538
- /* @__PURE__ */ jsxRuntime.jsx(RDropdown3__namespace.Separator, { className: menuSeparatorClass }),
23006
+ /* @__PURE__ */ jsxRuntime.jsx(RDropdown5__namespace.Separator, { className: menuSeparatorClass }),
22539
23007
  /* @__PURE__ */ jsxRuntime.jsx(
22540
23008
  TableMenuItem,
22541
23009
  {
@@ -26509,6 +26977,7 @@ exports.CHAT_FILE_CONFIG = CHAT_FILE_CONFIG;
26509
26977
  exports.CHAT_MESSAGE_DIRECTIONS = CHAT_MESSAGE_DIRECTIONS;
26510
26978
  exports.CHAT_MESSAGE_READ_STATUSES = CHAT_MESSAGE_READ_STATUSES;
26511
26979
  exports.CHAT_MESSAGE_VARIANTS = CHAT_MESSAGE_VARIANTS;
26980
+ exports.CHIP_COLORS = CHIP_COLORS;
26512
26981
  exports.COLOR_KEYS = COLOR_KEYS;
26513
26982
  exports.FIELD_WIDTH_GRADES = FIELD_WIDTH_GRADES;
26514
26983
  exports.GNB_COLORS = GNB_COLORS;
@@ -26568,6 +27037,7 @@ exports.SDatePickerMonthListbox = SDatePickerMonthListbox;
26568
27037
  exports.SDatePickerYearListbox = SDatePickerYearListbox;
26569
27038
  exports.SDateRangePicker = SDateRangePicker;
26570
27039
  exports.SDivider = SDivider;
27040
+ exports.SDonutChart = SDonutChart;
26571
27041
  exports.SDraggableGroup = SDraggableGroup;
26572
27042
  exports.SDraggableItem = SDraggableItem2;
26573
27043
  exports.SDraggableList = SDraggableList;
@@ -26605,12 +27075,14 @@ exports.SLoadingModal = SLoadingModal;
26605
27075
  exports.SLoadingViewport = SLoadingViewport;
26606
27076
  exports.SLoginCard = SLoginCard2;
26607
27077
  exports.SLogo = SLogo;
27078
+ exports.SMeatballButton = SMeatballButton2;
26608
27079
  exports.SModal = SModal;
26609
27080
  exports.SModalOutlet = SModalOutlet;
26610
27081
  exports.SNumberInput = SNumberInput;
26611
27082
  exports.SPage = SPage;
26612
27083
  exports.SPageHeader = SPageHeader;
26613
27084
  exports.SPagination = SPagination;
27085
+ exports.SPieChart = SPieChart;
26614
27086
  exports.SPopover = SPopover;
26615
27087
  exports.SPopup = SPopup;
26616
27088
  exports.SPortal = SPortal;