sellmate-design-system-react 9.0.0-beta.65 → 9.0.0-beta.67

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.
package/dist/index.cjs CHANGED
@@ -5,7 +5,7 @@ var clsx = require('clsx');
5
5
  var tailwindMerge = require('tailwind-merge');
6
6
  var react = require('react');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
- var RPopover12 = require('@radix-ui/react-popover');
8
+ var RPopover13 = require('@radix-ui/react-popover');
9
9
  var reactDom = require('react-dom');
10
10
  var RCheckbox = require('@radix-ui/react-checkbox');
11
11
  var client = require('react-dom/client');
@@ -33,7 +33,7 @@ function _interopNamespace(e) {
33
33
  return Object.freeze(n);
34
34
  }
35
35
 
36
- var RPopover12__namespace = /*#__PURE__*/_interopNamespace(RPopover12);
36
+ var RPopover13__namespace = /*#__PURE__*/_interopNamespace(RPopover13);
37
37
  var RCheckbox__namespace = /*#__PURE__*/_interopNamespace(RCheckbox);
38
38
  var RTooltip__namespace = /*#__PURE__*/_interopNamespace(RTooltip);
39
39
  var RDropdown5__namespace = /*#__PURE__*/_interopNamespace(RDropdown5);
@@ -3735,6 +3735,57 @@ var SIcon = /* @__PURE__ */ react.forwardRef(function SIcon2({ name, size = 24,
3735
3735
  }
3736
3736
  );
3737
3737
  });
3738
+
3739
+ // src/lib/display-name.ts
3740
+ function withDisplayName(component, name) {
3741
+ component.displayName = name;
3742
+ return component;
3743
+ }
3744
+
3745
+ // src/lib/floating-anim.ts
3746
+ var FLOATING_SLIDE_ANIM = [
3747
+ "data-[state=open]:data-[side=top]:animate-floating-in-top",
3748
+ "data-[state=delayed-open]:data-[side=top]:animate-floating-in-top",
3749
+ "data-[state=instant-open]:data-[side=top]:animate-floating-in-top",
3750
+ "data-[state=closed]:data-[side=top]:animate-floating-out-top",
3751
+ "data-[state=open]:data-[side=bottom]:animate-floating-in-bottom",
3752
+ "data-[state=delayed-open]:data-[side=bottom]:animate-floating-in-bottom",
3753
+ "data-[state=instant-open]:data-[side=bottom]:animate-floating-in-bottom",
3754
+ "data-[state=closed]:data-[side=bottom]:animate-floating-out-bottom",
3755
+ "data-[state=open]:data-[side=left]:animate-floating-in-left",
3756
+ "data-[state=delayed-open]:data-[side=left]:animate-floating-in-left",
3757
+ "data-[state=instant-open]:data-[side=left]:animate-floating-in-left",
3758
+ "data-[state=closed]:data-[side=left]:animate-floating-out-left",
3759
+ "data-[state=open]:data-[side=right]:animate-floating-in-right",
3760
+ "data-[state=delayed-open]:data-[side=right]:animate-floating-in-right",
3761
+ "data-[state=instant-open]:data-[side=right]:animate-floating-in-right",
3762
+ "data-[state=closed]:data-[side=right]:animate-floating-out-right"
3763
+ ].join(" ");
3764
+
3765
+ // src/lib/hover-preview.ts
3766
+ function hoverPreviewOrigin({
3767
+ anchor,
3768
+ size,
3769
+ viewportWidth,
3770
+ viewportHeight,
3771
+ padding = 8
3772
+ }) {
3773
+ const startX = anchor.left + anchor.width / 2;
3774
+ const startY = anchor.top + anchor.height / 2;
3775
+ const x = Math.max(padding, Math.min(startX, viewportWidth - size - padding));
3776
+ const y = Math.max(padding, Math.min(startY, viewportHeight - size - padding));
3777
+ return { x, y };
3778
+ }
3779
+ var PortalContainerContext = /* @__PURE__ */ react.createContext(null);
3780
+ var InsideModalContext = /* @__PURE__ */ react.createContext(false);
3781
+ var PortalContainerProvider = PortalContainerContext.Provider;
3782
+ var InsideModalProvider = InsideModalContext.Provider;
3783
+ function usePortalContainer() {
3784
+ return react.useContext(PortalContainerContext) ?? void 0;
3785
+ }
3786
+ function useInsideModal() {
3787
+ return react.useContext(InsideModalContext);
3788
+ }
3738
3789
  var VIEWBOX = 80;
3739
3790
  var RADIUS = 34;
3740
3791
  var STROKE = 12;
@@ -3852,7 +3903,10 @@ var SCircleProgress = /* @__PURE__ */ react.forwardRef(
3852
3903
  var IMAGE_FITS = ["cover", "contain", "fill", "none", "scale-down"];
3853
3904
  var EMPTY_ICON_SIZE = "60cqh";
3854
3905
  var SPINNER_SIZE = "45cqh";
3855
- var SImage = /* @__PURE__ */ react.forwardRef(function SImage2({
3906
+ var PREVIEW_HIDE_DELAY_MS = 100;
3907
+ var PREVIEW_MAX_SIZE = 200;
3908
+ var PREVIEW_VIEWPORT_PADDING = 8;
3909
+ var SImageImpl = /* @__PURE__ */ react.forwardRef(function SImageImpl2({
3856
3910
  src,
3857
3911
  alt = "",
3858
3912
  ratio = 1,
@@ -3864,6 +3918,9 @@ var SImage = /* @__PURE__ */ react.forwardRef(function SImage2({
3864
3918
  loadingSlot,
3865
3919
  errorSlot,
3866
3920
  imgProps,
3921
+ previewOnHover = false,
3922
+ previewSrc,
3923
+ previewSize = PREVIEW_MAX_SIZE,
3867
3924
  onLoad,
3868
3925
  onError,
3869
3926
  className,
@@ -3894,16 +3951,94 @@ var SImage = /* @__PURE__ */ react.forwardRef(function SImage2({
3894
3951
  const timer = setTimeout(() => setSpinnerVisible(true), loadingShowDelay);
3895
3952
  return () => clearTimeout(timer);
3896
3953
  }, [status, loadingShowDelay, src]);
3954
+ const portalContainer = usePortalContainer();
3955
+ const [previewOpen, setPreviewOpen] = react.useState(false);
3956
+ const previewHideTimer = react.useRef(void 0);
3957
+ const boxRef = react.useRef(null);
3958
+ const previewSource = previewSrc ?? src;
3959
+ const previewEnabled = previewOnHover && !!previewSource;
3960
+ const previewBoxSize = Math.min(previewSize, PREVIEW_MAX_SIZE);
3961
+ const previewBoxSizeRef = react.useRef(previewBoxSize);
3962
+ previewBoxSizeRef.current = previewBoxSize;
3963
+ const previewAnchorRef = react.useRef(null);
3964
+ if (previewAnchorRef.current == null) {
3965
+ previewAnchorRef.current = {
3966
+ getBoundingClientRect: () => {
3967
+ const anchor = boxRef.current?.getBoundingClientRect();
3968
+ if (!anchor) return new DOMRect(0, 0, 0, 0);
3969
+ const { x, y } = hoverPreviewOrigin({
3970
+ anchor,
3971
+ size: previewBoxSizeRef.current,
3972
+ viewportWidth: window.innerWidth,
3973
+ viewportHeight: window.innerHeight,
3974
+ padding: PREVIEW_VIEWPORT_PADDING
3975
+ });
3976
+ return new DOMRect(x, y, 0, 0);
3977
+ },
3978
+ // autoUpdate 가 스크롤 조상을 찾는 기준 — 없으면 표 안에서 스크롤할 때 위치가 굳는다
3979
+ get contextElement() {
3980
+ return boxRef.current ?? void 0;
3981
+ }
3982
+ };
3983
+ }
3984
+ const cancelPreviewHide = react.useCallback(() => {
3985
+ if (previewHideTimer.current) {
3986
+ clearTimeout(previewHideTimer.current);
3987
+ previewHideTimer.current = void 0;
3988
+ }
3989
+ }, []);
3990
+ const openPreview = () => {
3991
+ cancelPreviewHide();
3992
+ setPreviewOpen(true);
3993
+ };
3994
+ const startPreviewHide = () => {
3995
+ cancelPreviewHide();
3996
+ previewHideTimer.current = setTimeout(() => setPreviewOpen(false), PREVIEW_HIDE_DELAY_MS);
3997
+ };
3998
+ react.useEffect(() => {
3999
+ if (!previewEnabled) {
4000
+ cancelPreviewHide();
4001
+ setPreviewOpen(false);
4002
+ }
4003
+ }, [previewEnabled, cancelPreviewHide]);
4004
+ react.useEffect(() => cancelPreviewHide, [cancelPreviewHide]);
4005
+ const previewContentRef = react.useCallback((node) => {
4006
+ node?.parentElement?.style.setProperty("pointer-events", "none");
4007
+ }, []);
4008
+ const previewHandlers = previewEnabled ? {
4009
+ onMouseEnter: (event) => {
4010
+ rest.onMouseEnter?.(event);
4011
+ openPreview();
4012
+ },
4013
+ onMouseLeave: (event) => {
4014
+ rest.onMouseLeave?.(event);
4015
+ startPreviewHide();
4016
+ },
4017
+ // 소비자가 tabIndex 를 준 썸네일에서는 키보드로도 열린다
4018
+ onFocus: (event) => {
4019
+ rest.onFocus?.(event);
4020
+ openPreview();
4021
+ },
4022
+ onBlur: (event) => {
4023
+ rest.onBlur?.(event);
4024
+ startPreviewHide();
4025
+ }
4026
+ } : void 0;
3897
4027
  const isEmpty = !src;
3898
4028
  const showFallback = isEmpty || status === "error";
3899
4029
  const spinnerShown = !isEmpty && status === "loading" && showSpinner && spinnerVisible;
3900
- return /* @__PURE__ */ jsxRuntime.jsxs(
4030
+ const box3 = /* @__PURE__ */ jsxRuntime.jsxs(
3901
4031
  "div",
3902
4032
  {
3903
- ref,
4033
+ ref: (node) => {
4034
+ boxRef.current = node;
4035
+ if (typeof ref === "function") ref(node);
4036
+ else if (ref) ref.current = node;
4037
+ },
3904
4038
  className: cn("relative overflow-hidden bg-(--cmp-image-bg)", className),
3905
4039
  style: { containerType: "size", aspectRatio: ratio, ...style },
3906
4040
  ...rest,
4041
+ ...previewHandlers,
3907
4042
  children: [
3908
4043
  !isEmpty && /* @__PURE__ */ jsxRuntime.jsx(
3909
4044
  "img",
@@ -3939,7 +4074,47 @@ var SImage = /* @__PURE__ */ react.forwardRef(function SImage2({
3939
4074
  ]
3940
4075
  }
3941
4076
  );
4077
+ if (!previewEnabled) return box3;
4078
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open: previewOpen, onOpenChange: setPreviewOpen, children: [
4079
+ box3,
4080
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Anchor, { virtualRef: previewAnchorRef }),
4081
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
4082
+ RPopover13__namespace.Content,
4083
+ {
4084
+ ref: previewContentRef,
4085
+ side: "bottom",
4086
+ align: "start",
4087
+ sideOffset: 0,
4088
+ alignOffset: 0,
4089
+ avoidCollisions: false,
4090
+ role: "presentation",
4091
+ "aria-hidden": true,
4092
+ className: cn(
4093
+ "z-50 overflow-hidden rounded-[6px] shadow-normal-sm",
4094
+ // 읽기 전용이라 호버 브릿지를 두지 않는다. 그 대신 마우스를 통과시켜,
4095
+ // 목록 위로 뜬 미리보기가 아래 행의 클릭을 가로채지 않게 한다.
4096
+ // (래퍼 쪽은 previewContentRef 가 함께 끈다 — 둘 다 꺼야 깜빡이지 않는다)
4097
+ "pointer-events-none",
4098
+ FLOATING_SLIDE_ANIM
4099
+ ),
4100
+ onOpenAutoFocus: (event) => event.preventDefault(),
4101
+ onCloseAutoFocus: (event) => event.preventDefault(),
4102
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4103
+ SImage,
4104
+ {
4105
+ src: previewSource,
4106
+ alt: "",
4107
+ ratio: 1,
4108
+ fit: "contain",
4109
+ loading: "eager",
4110
+ style: { width: previewBoxSize }
4111
+ }
4112
+ )
4113
+ }
4114
+ ) })
4115
+ ] });
3942
4116
  });
4117
+ var SImage = /* @__PURE__ */ withDisplayName(SImageImpl, "SImage");
3943
4118
  var BADGE_COLORS = [
3944
4119
  "red",
3945
4120
  "orange",
@@ -4208,42 +4383,6 @@ var SCard = /* @__PURE__ */ react.forwardRef(function SCard2({ bordered = false,
4208
4383
  );
4209
4384
  });
4210
4385
 
4211
- // src/lib/display-name.ts
4212
- function withDisplayName(component, name) {
4213
- component.displayName = name;
4214
- return component;
4215
- }
4216
-
4217
- // src/lib/floating-anim.ts
4218
- var FLOATING_SLIDE_ANIM = [
4219
- "data-[state=open]:data-[side=top]:animate-floating-in-top",
4220
- "data-[state=delayed-open]:data-[side=top]:animate-floating-in-top",
4221
- "data-[state=instant-open]:data-[side=top]:animate-floating-in-top",
4222
- "data-[state=closed]:data-[side=top]:animate-floating-out-top",
4223
- "data-[state=open]:data-[side=bottom]:animate-floating-in-bottom",
4224
- "data-[state=delayed-open]:data-[side=bottom]:animate-floating-in-bottom",
4225
- "data-[state=instant-open]:data-[side=bottom]:animate-floating-in-bottom",
4226
- "data-[state=closed]:data-[side=bottom]:animate-floating-out-bottom",
4227
- "data-[state=open]:data-[side=left]:animate-floating-in-left",
4228
- "data-[state=delayed-open]:data-[side=left]:animate-floating-in-left",
4229
- "data-[state=instant-open]:data-[side=left]:animate-floating-in-left",
4230
- "data-[state=closed]:data-[side=left]:animate-floating-out-left",
4231
- "data-[state=open]:data-[side=right]:animate-floating-in-right",
4232
- "data-[state=delayed-open]:data-[side=right]:animate-floating-in-right",
4233
- "data-[state=instant-open]:data-[side=right]:animate-floating-in-right",
4234
- "data-[state=closed]:data-[side=right]:animate-floating-out-right"
4235
- ].join(" ");
4236
- var PortalContainerContext = /* @__PURE__ */ react.createContext(null);
4237
- var InsideModalContext = /* @__PURE__ */ react.createContext(false);
4238
- var PortalContainerProvider = PortalContainerContext.Provider;
4239
- var InsideModalProvider = InsideModalContext.Provider;
4240
- function usePortalContainer() {
4241
- return react.useContext(PortalContainerContext) ?? void 0;
4242
- }
4243
- function useInsideModal() {
4244
- return react.useContext(InsideModalContext);
4245
- }
4246
-
4247
4386
  // src/components/STag/tag.config.ts
4248
4387
  var TAG_SHAPES = ["square", "pill"];
4249
4388
  var TAG_SIZES = ["xs", "sm", "md"];
@@ -4431,8 +4570,8 @@ var SGhostButton = /* @__PURE__ */ react.forwardRef(function SGhostButton2({
4431
4570
  }
4432
4571
  );
4433
4572
  if (!hasTooltip) return btn2;
4434
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: setOpen, children: [
4435
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4573
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open, onOpenChange: setOpen, children: [
4574
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4436
4575
  "span",
4437
4576
  {
4438
4577
  className: cn("inline-flex", anchorClassName),
@@ -4444,8 +4583,8 @@ var SGhostButton = /* @__PURE__ */ react.forwardRef(function SGhostButton2({
4444
4583
  children: btn2
4445
4584
  }
4446
4585
  ) }),
4447
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
4448
- RPopover12__namespace.Content,
4586
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
4587
+ RPopover13__namespace.Content,
4449
4588
  {
4450
4589
  side: "top",
4451
4590
  sideOffset: 4,
@@ -4634,14 +4773,14 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
4634
4773
  ...style,
4635
4774
  ...contentPropsStyle
4636
4775
  };
4637
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: setOpenState, children: [
4776
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open, onOpenChange: setOpenState, children: [
4638
4777
  isNone ? (
4639
4778
  // 트리거 없음: children 을 래퍼 없이 그대로 앵커로 쓴다 (소비자 레이아웃 보존).
4640
4779
  // mouse/focus 핸들러가 없으므로 showClose 없이도 자동 닫힘이 발생하지 않는다.
4641
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { asChild: true, children: triggerNode })
4780
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Anchor, { asChild: true, children: triggerNode })
4642
4781
  ) : isHover ? (
4643
4782
  // hover: Anchor(위치 기준) + 직접 mouse 핸들러 — 클릭으로 토글되지 않도록 Trigger 미사용
4644
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4783
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4645
4784
  "span",
4646
4785
  {
4647
4786
  className: "inline-flex",
@@ -4652,9 +4791,9 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
4652
4791
  children: triggerNode
4653
4792
  }
4654
4793
  ) })
4655
- ) : /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: triggerNode }),
4656
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
4657
- RPopover12__namespace.Content,
4794
+ ) : /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: triggerNode }),
4795
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
4796
+ RPopover13__namespace.Content,
4658
4797
  {
4659
4798
  side: placement,
4660
4799
  sideOffset,
@@ -4688,7 +4827,7 @@ var STooltipImpl = /* @__PURE__ */ react.forwardRef(function STooltip({
4688
4827
  }
4689
4828
  )
4690
4829
  ] }),
4691
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
4830
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
4692
4831
  ]
4693
4832
  }
4694
4833
  ) })
@@ -8337,12 +8476,18 @@ var release = (id) => {
8337
8476
  entries = next;
8338
8477
  sync();
8339
8478
  };
8479
+ var updateEntry = (id, message) => {
8480
+ const index = entries.findIndex((e) => e.id === id);
8481
+ if (index === -1) return;
8482
+ entries = entries.map((e, i) => i === index ? { ...e, message } : e);
8483
+ sync();
8484
+ };
8340
8485
  var subscribe = (cb) => {
8341
8486
  listeners.add(cb);
8342
8487
  return () => listeners.delete(cb);
8343
8488
  };
8344
8489
  var getSnapshot = () => state;
8345
- function SLoadingViewport() {
8490
+ function LoadingViewport() {
8346
8491
  const s = react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
8347
8492
  return /* @__PURE__ */ jsxRuntime.jsx(SLoadingContainer, { open: s.open, message: s.message });
8348
8493
  }
@@ -8353,39 +8498,56 @@ function ensureMounted() {
8353
8498
  const host = document.createElement("div");
8354
8499
  host.setAttribute("data-sd-loading-root", "");
8355
8500
  document.body.appendChild(host);
8356
- client.createRoot(host).render(/* @__PURE__ */ jsxRuntime.jsx(SLoadingViewport, {}));
8501
+ client.createRoot(host).render(/* @__PURE__ */ jsxRuntime.jsx(LoadingViewport, {}));
8502
+ }
8503
+ function showEntry(options = {}) {
8504
+ ensureMounted();
8505
+ const id = ++seq;
8506
+ entries = [...entries, { id, message: options.message }];
8507
+ sync();
8508
+ let released = false;
8509
+ const handle = (() => {
8510
+ if (released) return;
8511
+ released = true;
8512
+ release(id);
8513
+ });
8514
+ handle.update = (next) => {
8515
+ if (released) return;
8516
+ updateEntry(id, next.message);
8517
+ };
8518
+ return handle;
8357
8519
  }
8358
8520
  var loading = {
8359
8521
  /**
8360
8522
  * 로딩 오버레이 표시. 겹쳐 부르면 그만큼 쌓이고 **마지막 하나가 걷힐 때** 닫힌다.
8361
- * 반환값은 이 호출 하나만 걷는 함수다(두 번 불러도 한 번만 걷힌다) — `hide()` 대신 이것을
8362
- * 쓰면 짝이 어긋나지 않는다.
8523
+ * 반환값은 이 호출 하나를 걷고 갱신하는 핸들이다(두 번 걷어도 한 번만 걷힌다).
8524
+ *
8525
+ * **걷는 것은 `finally` 에 둔다.** 빠뜨리면 그 즉시 화면이 갇히고, 정상 경로에서는 아무
8526
+ * 표시가 없다.
8363
8527
  *
8364
- * ⚠️ 메시지만 바꾸려면 `update()` 를 쓴다. `show()` 를 다시 부르면 하나 더 쌓여
8365
- * `hide()` 한 번으로는 닫히지 않는다.
8528
+ * ```ts
8529
+ * const done = loading.show({ message: '1/2 ...' });
8530
+ * try {
8531
+ * done.update({ message: '2/2 ...' }); // 이 호출의 메시지만 바뀐다
8532
+ * await api.submit(payload);
8533
+ * } finally {
8534
+ * done(); // 이 호출만 걷는다
8535
+ * }
8536
+ * ```
8537
+ *
8538
+ * ⚠️ **메시지를 바꾸려고 `show()` 를 다시 부르지 않는다.** 하나 더 쌓여 한 번 걷는 것으로는
8539
+ * 닫히지 않는다. 핸들의 `update()` 를 쓴다. (참조 카운트 이전에는 `show()` 를 다시 부르는
8540
+ * 것이 갱신이었다 — Quasar 도 같은 그룹에 다시 show 하면 갱신이다. 그 시절 관행대로 쓰인
8541
+ * 코드는 지금 오버레이를 하나 남긴다.)
8366
8542
  */
8367
8543
  show(options = {}) {
8368
- ensureMounted();
8369
- const id = ++seq;
8370
- entries = [...entries, { id, message: options.message }];
8371
- sync();
8372
- return () => release(id);
8373
- },
8374
- /** 표시 중인 메시지 갱신 — 쌓인 수는 그대로다 */
8375
- update(options) {
8376
- const top = entries[entries.length - 1];
8377
- if (!top) return;
8378
- entries = [...entries.slice(0, -1), { ...top, message: options.message }];
8379
- sync();
8380
- },
8381
- /** 가장 나중의 show 하나를 걷는다. 남은 것이 없을 때만 오버레이가 닫힌다 */
8382
- hide() {
8383
- const top = entries[entries.length - 1];
8384
- if (top) release(top.id);
8544
+ return showEntry(options);
8385
8545
  },
8386
8546
  /**
8387
- * 쌓인 것을 모두 걷고 즉시 닫는다. 화면 전환·에러 복구처럼 진행 중이던 작업의 짝을 더는
8388
- * 맞출 수 없을 때만 쓴다 — 평소에는 `hide()` 나 `show()` 가 준 함수로 하나씩 걷는다.
8547
+ * 쌓인 것을 모두 걷고 즉시 닫는다. **원본(Quasar)의 인자 없는 `hide()` 가 이것이다.**
8548
+ * 화면 전환·에러 복구처럼 진행 중이던 작업의 짝을 더는 맞출 수 없을 때만 쓴다 — 평소에는
8549
+ * `show()` 가 준 핸들로 걷는다.
8550
+ * 이걸로 걷힌 항목의 주인이 뒤늦게 자기 핸들을 불러도 아무 일도 일어나지 않는다.
8389
8551
  */
8390
8552
  hideAll() {
8391
8553
  if (entries.length === 0) return;
@@ -8907,7 +9069,7 @@ function SPortal({
8907
9069
  const portalContainer = usePortalContainer();
8908
9070
  const { minWidth: styleMinWidth, maxWidth: styleMaxWidth, ...restStyle } = style ?? {};
8909
9071
  return /* @__PURE__ */ jsxRuntime.jsxs(
8910
- RPopover12__namespace.Root,
9072
+ RPopover13__namespace.Root,
8911
9073
  {
8912
9074
  open,
8913
9075
  onOpenChange: (next) => {
@@ -8915,9 +9077,9 @@ function SPortal({
8915
9077
  if (!next) onClose?.();
8916
9078
  },
8917
9079
  children: [
8918
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { virtualRef: anchorRef }),
8919
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
8920
- RPopover12__namespace.Content,
9080
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Anchor, { virtualRef: anchorRef }),
9081
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
9082
+ RPopover13__namespace.Content,
8921
9083
  {
8922
9084
  side: placement,
8923
9085
  align,
@@ -9668,10 +9830,10 @@ function SPopover({
9668
9830
  const descColor = type === "default" ? "var(--cmp-popover-default-description)" : "var(--cmp-popover-light-description)";
9669
9831
  const leftLinkLabelClass = type === "default" ? "text-[color:var(--cmp-popover-default-subAction)]" : "text-[color:var(--cmp-popover-light-subAction)]";
9670
9832
  const triggerNode = trigger ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex cursor-pointer", "aria-label": ariaLabel, children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: icon, size: iconSize, color }) });
9671
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: actualOpen, onOpenChange: setOpen, children: [
9672
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: triggerNode }),
9673
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
9674
- RPopover12__namespace.Content,
9833
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open: actualOpen, onOpenChange: setOpen, children: [
9834
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: triggerNode }),
9835
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
9836
+ RPopover13__namespace.Content,
9675
9837
  {
9676
9838
  side: placement,
9677
9839
  sideOffset: 8,
@@ -9737,7 +9899,7 @@ function SPopover({
9737
9899
  ]
9738
9900
  }
9739
9901
  ),
9740
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
9902
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Arrow, { width: 16, height: 12, style: { fill: bg } })
9741
9903
  ]
9742
9904
  }
9743
9905
  ) })
@@ -9855,10 +10017,10 @@ function SGuide({
9855
10017
  );
9856
10018
  if (isNotion)
9857
10019
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className, style, children: trigger });
9858
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: setOpen, children: [
9859
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: trigger }),
9860
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
9861
- RPopover12__namespace.Content,
10020
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open, onOpenChange: setOpen, children: [
10021
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: trigger }),
10022
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(
10023
+ RPopover13__namespace.Content,
9862
10024
  {
9863
10025
  side: "bottom",
9864
10026
  align: "start",
@@ -12351,10 +12513,10 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
12351
12513
  ),
12352
12514
  header === "fix" && menuResizeHandle,
12353
12515
  launcherListBox,
12354
- /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: labelTip !== null, onOpenChange: (open) => !open && setLabelTip(null), children: [
12355
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { virtualRef: labelTipAnchorRef }),
12356
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
12357
- RPopover12__namespace.Content,
12516
+ /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open: labelTip !== null, onOpenChange: (open) => !open && setLabelTip(null), children: [
12517
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Anchor, { virtualRef: labelTipAnchorRef }),
12518
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
12519
+ RPopover13__namespace.Content,
12358
12520
  {
12359
12521
  side: "right",
12360
12522
  sideOffset: 4,
@@ -14449,7 +14611,7 @@ function SCalendarBoard({
14449
14611
  }
14450
14612
  ),
14451
14613
  /* @__PURE__ */ jsxRuntime.jsxs(
14452
- RPopover12__namespace.Root,
14614
+ RPopover13__namespace.Root,
14453
14615
  {
14454
14616
  open: openDate !== null,
14455
14617
  onOpenChange: (open) => {
@@ -14493,12 +14655,12 @@ function SCalendarBoard({
14493
14655
  },
14494
14656
  cell.date
14495
14657
  );
14496
- return cell.date === openDate ? /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { asChild: true, children: card }, cell.date) : card;
14658
+ return cell.date === openDate ? /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Anchor, { asChild: true, children: card }, cell.date) : card;
14497
14659
  })
14498
14660
  }
14499
14661
  ),
14500
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
14501
- RPopover12__namespace.Content,
14662
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
14663
+ RPopover13__namespace.Content,
14502
14664
  {
14503
14665
  onInteractOutside: (e) => {
14504
14666
  const target = e.detail.originalEvent.target;
@@ -17001,10 +17163,10 @@ function useTruncatedValueTooltip({
17001
17163
  valueRef: elRef,
17002
17164
  onMouseEnter: active ? onMouseEnter : cancelHide,
17003
17165
  onMouseLeave: active ? startHide : cancelHide,
17004
- tooltip: active ? /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: setOpen, children: [
17005
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Anchor, { virtualRef: elRef }),
17006
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
17007
- RPopover12__namespace.Content,
17166
+ tooltip: active ? /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open, onOpenChange: setOpen, children: [
17167
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Anchor, { virtualRef: elRef }),
17168
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
17169
+ RPopover13__namespace.Content,
17008
17170
  {
17009
17171
  side: "top",
17010
17172
  sideOffset: 4,
@@ -18258,8 +18420,8 @@ function SDatePicker({
18258
18420
  disabled,
18259
18421
  className,
18260
18422
  style,
18261
- children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
18262
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
18423
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
18424
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
18263
18425
  "div",
18264
18426
  {
18265
18427
  role: "button",
@@ -18318,8 +18480,8 @@ function SDatePicker({
18318
18480
  ]
18319
18481
  }
18320
18482
  ) }),
18321
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
18322
- RPopover12__namespace.Content,
18483
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
18484
+ RPopover13__namespace.Content,
18323
18485
  {
18324
18486
  side: "bottom",
18325
18487
  align: mode === "date" ? "start" : "center",
@@ -18795,7 +18957,7 @@ function SDateRangePicker({
18795
18957
  className,
18796
18958
  style,
18797
18959
  children: /* @__PURE__ */ jsxRuntime.jsxs(
18798
- RPopover12__namespace.Root,
18960
+ RPopover13__namespace.Root,
18799
18961
  {
18800
18962
  open,
18801
18963
  onOpenChange: (o) => {
@@ -18804,7 +18966,7 @@ function SDateRangePicker({
18804
18966
  if (!o) setPendingStart(null);
18805
18967
  },
18806
18968
  children: [
18807
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
18969
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
18808
18970
  "div",
18809
18971
  {
18810
18972
  role: "button",
@@ -18868,8 +19030,8 @@ function SDateRangePicker({
18868
19030
  ]
18869
19031
  }
18870
19032
  ) }),
18871
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
18872
- RPopover12__namespace.Content,
19033
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
19034
+ RPopover13__namespace.Content,
18873
19035
  {
18874
19036
  side: "bottom",
18875
19037
  align: "start",
@@ -19636,9 +19798,56 @@ var ChartFrame = /* @__PURE__ */ react.forwardRef(function ChartFrame2({ title,
19636
19798
  }
19637
19799
  );
19638
19800
  });
19801
+
19802
+ // src/lib/chart/hover-dim.ts
19803
+ var CHART_DIM_OPACITY_TRANSITION = "transition-opacity duration-200 ease-out motion-reduce:transition-none";
19804
+ var CHART_DIM_COLOR_TRANSITION = "transition-colors duration-200 ease-out motion-reduce:transition-none";
19639
19805
  var DOT_SIZE = 6;
19640
- function ChartLegend({ items, align = "center", activeIndex, className }) {
19806
+ function ChartLegend({
19807
+ items,
19808
+ align = "center",
19809
+ activeIndex,
19810
+ className,
19811
+ variant = "simple"
19812
+ }) {
19641
19813
  if (items.length === 0) return null;
19814
+ const dot = (color) => /* @__PURE__ */ jsxRuntime.jsx(
19815
+ "span",
19816
+ {
19817
+ "aria-hidden": true,
19818
+ className: "shrink-0 rounded-full",
19819
+ style: { width: DOT_SIZE, height: DOT_SIZE, background: color }
19820
+ }
19821
+ );
19822
+ if (variant === "default") {
19823
+ return /* @__PURE__ */ jsxRuntime.jsx(
19824
+ "ul",
19825
+ {
19826
+ className: cn(
19827
+ "flex list-none flex-col gap-(--cmp-chart-doughnut-legend-data-default-gap) p-0",
19828
+ className
19829
+ ),
19830
+ children: items.map((item4, index) => /* @__PURE__ */ jsxRuntime.jsxs(
19831
+ "li",
19832
+ {
19833
+ className: cn(
19834
+ "flex items-center gap-(--cmp-chart-legendItem-gap)",
19835
+ "py-(--cmp-chart-legendItem-paddingY)",
19836
+ "typo-body-sm-medium text-(--cmp-chart-legendItem-color)",
19837
+ CHART_DIM_OPACITY_TRANSITION,
19838
+ activeIndex != null && activeIndex !== index && "opacity-(--opacity-060)"
19839
+ ),
19840
+ children: [
19841
+ dot(item4.color),
19842
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item4.name }),
19843
+ item4.value != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto typo-body-sm-bold", style: { color: item4.valueColor }, children: item4.value })
19844
+ ]
19845
+ },
19846
+ `${item4.name}-${index}`
19847
+ ))
19848
+ }
19849
+ );
19850
+ }
19642
19851
  return /* @__PURE__ */ jsxRuntime.jsx(
19643
19852
  "ul",
19644
19853
  {
@@ -19656,18 +19865,11 @@ function ChartLegend({ items, align = "center", activeIndex, className }) {
19656
19865
  "flex items-center gap-(--cmp-chart-legendItem-gap)",
19657
19866
  "py-(--cmp-chart-legendItem-paddingY)",
19658
19867
  "typo-body-sm-medium text-(--cmp-chart-legendItem-color)",
19659
- "transition-opacity duration-200 ease-out motion-reduce:transition-none",
19868
+ CHART_DIM_OPACITY_TRANSITION,
19660
19869
  activeIndex != null && activeIndex !== index && "opacity-(--opacity-060)"
19661
19870
  ),
19662
19871
  children: [
19663
- /* @__PURE__ */ jsxRuntime.jsx(
19664
- "span",
19665
- {
19666
- "aria-hidden": true,
19667
- className: "shrink-0 rounded-full",
19668
- style: { width: DOT_SIZE, height: DOT_SIZE, background: item4.color }
19669
- }
19670
- ),
19872
+ dot(item4.color),
19671
19873
  item4.name
19672
19874
  ]
19673
19875
  },
@@ -19680,6 +19882,7 @@ function ChartLegend({ items, align = "center", activeIndex, className }) {
19680
19882
  // src/lib/chart/palette.ts
19681
19883
  var V3 = (path) => `var(--cmp-chart-palette-${path})`;
19682
19884
  var DIMMED = (path) => `var(--cmp-chart-line-point-dimmed-palette-${path})`;
19885
+ var VALUE = (path) => `var(--cmp-chart-dataValue-palette-${path})`;
19683
19886
  var colorsOf = (v) => ({
19684
19887
  positivePrimary: v("variation-positivePrimary"),
19685
19888
  positiveSecondary: v("variation-positiveSecondary"),
@@ -19716,6 +19919,31 @@ var CHART_COLORS = colorsOf(V3);
19716
19919
  var CHART_PALETTES = palettesOf(V3);
19717
19920
  var DIMMED_COLORS = colorsOf(DIMMED);
19718
19921
  var DIMMED_PALETTES = palettesOf(DIMMED);
19922
+ var DATA_VALUE_COLORS = colorsOf(VALUE);
19923
+ var DATA_VALUE_PALETTES = {
19924
+ default: [DATA_VALUE_COLORS.positivePrimary],
19925
+ multi: [
19926
+ VALUE("multi-blue"),
19927
+ VALUE("multi-skyblue"),
19928
+ VALUE("multi-yellow"),
19929
+ VALUE("multi-olive"),
19930
+ VALUE("multi-lightRed"),
19931
+ VALUE("multi-warmBlue"),
19932
+ VALUE("multi-orange"),
19933
+ VALUE("multi-green"),
19934
+ VALUE("multi-navy"),
19935
+ VALUE("multi-grey"),
19936
+ VALUE("multi-red")
19937
+ ],
19938
+ gradation: [
19939
+ V3("gradation-1"),
19940
+ V3("gradation-2"),
19941
+ V3("gradation-3"),
19942
+ V3("gradation-4"),
19943
+ V3("gradation-5"),
19944
+ VALUE("gradation-6")
19945
+ ]
19946
+ };
19719
19947
  function pick(names, palettes, palette, index, colors) {
19720
19948
  if (palette === "custom") {
19721
19949
  if (!colors?.length) return palettes.default[0];
@@ -19730,6 +19958,9 @@ function paletteColor(palette, index, colors) {
19730
19958
  function linePointDimmedColor(palette, index, colors) {
19731
19959
  return pick(DIMMED_COLORS, DIMMED_PALETTES, palette, index, colors);
19732
19960
  }
19961
+ function dataValueColor(palette, index, colors) {
19962
+ return pick(DATA_VALUE_COLORS, DATA_VALUE_PALETTES, palette, index, colors);
19963
+ }
19733
19964
  function useElementSize() {
19734
19965
  const ref = react.useRef(null);
19735
19966
  const [size, setSize] = react.useState({ width: 0, height: 0 });
@@ -19863,7 +20094,6 @@ var BAR_OPACITY_HOVER = 1;
19863
20094
  var BAR_DATA_LABEL_COLOR = "var(--cmp-chart-dataLabel-color-default)";
19864
20095
  var BAR_DATA_LABEL_TYPO = "typo-body-sm-medium";
19865
20096
  var BAR_DATA_LABEL_TYPO_HOVER = "typo-body-md-bold";
19866
- var BAR_HOVER_TRANSITION = "transition-opacity duration-200 ease-out motion-reduce:transition-none";
19867
20097
  function bandLayout(size, categoryCount, seriesCount, barSizeMax = BAR_SIZE_MAX) {
19868
20098
  const categories = Math.max(1, categoryCount);
19869
20099
  const series = Math.max(1, seriesCount);
@@ -20130,7 +20360,7 @@ var SBarChart = /* @__PURE__ */ react.forwardRef(function SBarChart2({
20130
20360
  "path",
20131
20361
  {
20132
20362
  d: barPath(x, y, width, barHeight, direction, negative),
20133
- className: BAR_HOVER_TRANSITION,
20363
+ className: CHART_DIM_OPACITY_TRANSITION,
20134
20364
  style: {
20135
20365
  fill: colorAt(seriesIndex, categoryIndex),
20136
20366
  opacity,
@@ -20147,7 +20377,7 @@ var SBarChart = /* @__PURE__ */ react.forwardRef(function SBarChart2({
20147
20377
  y: labelY,
20148
20378
  className: cn(
20149
20379
  hoveredCategory === categoryIndex ? BAR_DATA_LABEL_TYPO_HOVER : BAR_DATA_LABEL_TYPO,
20150
- BAR_HOVER_TRANSITION
20380
+ CHART_DIM_OPACITY_TRANSITION
20151
20381
  ),
20152
20382
  style: {
20153
20383
  fill: BAR_DATA_LABEL_COLOR,
@@ -20228,7 +20458,7 @@ var SBarChart = /* @__PURE__ */ react.forwardRef(function SBarChart2({
20228
20458
  width: box3.width,
20229
20459
  height: box3.height,
20230
20460
  clipPath: `url(#${segment.value < 0 ? negativeClip : positiveClip})`,
20231
- className: BAR_HOVER_TRANSITION,
20461
+ className: CHART_DIM_OPACITY_TRANSITION,
20232
20462
  style: {
20233
20463
  // 조각과 라벨에 따로 건다 — 묶음(<g>)에 걸면 호버가 없을 때의
20234
20464
  // 기본 흐림까지 합계 라벨에 묻어 숫자가 늘 옅어진다.
@@ -20253,7 +20483,7 @@ var SBarChart = /* @__PURE__ */ react.forwardRef(function SBarChart2({
20253
20483
  y: labelY,
20254
20484
  className: cn(
20255
20485
  hoveredCategory === categoryIndex ? BAR_DATA_LABEL_TYPO_HOVER : BAR_DATA_LABEL_TYPO,
20256
- BAR_HOVER_TRANSITION
20486
+ CHART_DIM_OPACITY_TRANSITION
20257
20487
  ),
20258
20488
  style: {
20259
20489
  fill: BAR_DATA_LABEL_COLOR,
@@ -20431,6 +20661,7 @@ var SBarChart = /* @__PURE__ */ react.forwardRef(function SBarChart2({
20431
20661
  // src/components/SLineChart/lineChart.config.ts
20432
20662
  var LINE_WIDTH = "var(--cmp-chart-line-width)";
20433
20663
  var LINE_OPACITY = "var(--cmp-chart-line-opacity)";
20664
+ var LINE_DASH = "11 11";
20434
20665
  var POINT_RADIUS = 5;
20435
20666
  var POINT_HOVER_RADIUS = 6;
20436
20667
  var POINT_HALO_RADIUS = 12;
@@ -20523,6 +20754,7 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20523
20754
  title,
20524
20755
  unit,
20525
20756
  curve = "linear",
20757
+ lineStyle = "solid",
20526
20758
  area = false,
20527
20759
  stacked = false,
20528
20760
  palette = "default",
@@ -20731,14 +20963,15 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20731
20963
  style: {
20732
20964
  stroke: colorAt(seriesIndex),
20733
20965
  strokeWidth: LINE_WIDTH,
20734
- strokeOpacity: LINE_OPACITY
20966
+ strokeOpacity: LINE_OPACITY,
20967
+ strokeDasharray: lineStyle === "dashed" ? LINE_DASH : void 0
20735
20968
  }
20736
20969
  },
20737
20970
  `line-${seriesIndex}-${runIndex}`
20738
20971
  );
20739
20972
  })
20740
20973
  ),
20741
- [plotted, smooth, colorAt]
20974
+ [plotted, smooth, colorAt, lineStyle]
20742
20975
  );
20743
20976
  const { pointHalos, pointDots } = react.useMemo(() => {
20744
20977
  const halos = [];
@@ -20773,6 +21006,7 @@ var SLineChart = /* @__PURE__ */ react.forwardRef(function SLineChart2({
20773
21006
  cx: point.x,
20774
21007
  cy: point.y,
20775
21008
  r: hovered ? POINT_HOVER_RADIUS : POINT_RADIUS,
21009
+ className: CHART_DIM_COLOR_TRANSITION,
20776
21010
  style: {
20777
21011
  fill: dimmed ? dimmedColorAt(seriesIndex) : color,
20778
21012
  cursor: onPointClick ? "pointer" : void 0
@@ -21018,6 +21252,7 @@ var RadialChart = /* @__PURE__ */ react.forwardRef(function RadialChart2({
21018
21252
  showValueLabel = false,
21019
21253
  showLegend = true,
21020
21254
  legendPosition = "top",
21255
+ legendVariant = "simple",
21021
21256
  showTooltip = true,
21022
21257
  formatValue = defaultFormat3,
21023
21258
  onSliceClick,
@@ -21045,7 +21280,8 @@ var RadialChart = /* @__PURE__ */ react.forwardRef(function RadialChart2({
21045
21280
  ratio,
21046
21281
  start,
21047
21282
  end: angle,
21048
- color: paletteColor(effective, slice2.index, colors)
21283
+ color: paletteColor(effective, slice2.index, colors),
21284
+ valueColor: dataValueColor(effective, slice2.index, colors)
21049
21285
  };
21050
21286
  });
21051
21287
  return list;
@@ -21058,8 +21294,14 @@ var RadialChart = /* @__PURE__ */ react.forwardRef(function RadialChart2({
21058
21294
  const legend = showLegend ? /* @__PURE__ */ jsxRuntime.jsx(
21059
21295
  ChartLegend,
21060
21296
  {
21061
- items: arcs.map((arc2) => ({ name: arc2.name, color: arc2.color })),
21062
- activeIndex: hoveredArc ? arcs.indexOf(hoveredArc) : null
21297
+ items: arcs.map((arc2) => ({
21298
+ name: arc2.name,
21299
+ color: arc2.color,
21300
+ value: legendVariant === "default" ? formatValue(arc2.value) : void 0,
21301
+ valueColor: arc2.valueColor
21302
+ })),
21303
+ activeIndex: hoveredArc ? arcs.indexOf(hoveredArc) : null,
21304
+ variant: legendVariant
21063
21305
  }
21064
21306
  ) : null;
21065
21307
  const tooltipAnchor = react.useMemo(() => {
@@ -21119,7 +21361,7 @@ var RadialChart = /* @__PURE__ */ react.forwardRef(function RadialChart2({
21119
21361
  {
21120
21362
  d: slice(arc2),
21121
21363
  fillRule: "evenodd",
21122
- className: "transition-opacity duration-200 ease-out motion-reduce:transition-none",
21364
+ className: CHART_DIM_OPACITY_TRANSITION,
21123
21365
  style: {
21124
21366
  fill: arc2.color,
21125
21367
  opacity,
@@ -21152,7 +21394,10 @@ var RadialChart = /* @__PURE__ */ react.forwardRef(function RadialChart2({
21152
21394
  y: point.y,
21153
21395
  textAnchor: "middle",
21154
21396
  dominantBaseline: "central",
21155
- className: "pointer-events-none typo-body-sm-bold transition-opacity duration-200 ease-out motion-reduce:transition-none",
21397
+ className: cn(
21398
+ "pointer-events-none typo-body-sm-bold",
21399
+ CHART_DIM_OPACITY_TRANSITION
21400
+ ),
21156
21401
  style: {
21157
21402
  fill: "var(--sys-color-fg-inverse)",
21158
21403
  opacity: hovered != null && hovered !== arc2.index ? OPACITY_DIMMED : void 0
@@ -21218,6 +21463,7 @@ var SDonutChart = /* @__PURE__ */ react.forwardRef(function SDonutChart2({
21218
21463
  showValueLabel = false,
21219
21464
  showLegend = true,
21220
21465
  legendPosition = "top",
21466
+ legendVariant = "simple",
21221
21467
  showTooltip = true,
21222
21468
  ...props
21223
21469
  }, ref) {
@@ -21230,6 +21476,7 @@ var SDonutChart = /* @__PURE__ */ react.forwardRef(function SDonutChart2({
21230
21476
  showValueLabel,
21231
21477
  showLegend,
21232
21478
  legendPosition,
21479
+ legendVariant,
21233
21480
  showTooltip,
21234
21481
  innerRatio: DONUT_INNER_RATIO,
21235
21482
  kind: "\uB3C4\uB11B \uADF8\uB798\uD504"
@@ -23167,10 +23414,10 @@ function EditorToolbarBar({
23167
23414
  },
23168
23415
  item4
23169
23416
  );
23170
- return /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: linkOpen, onOpenChange: setLinkOpen, children: [
23171
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { label: "\uB9C1\uD06C", active: state2.link, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(IconLink, { size: ICON_SIZE }) }) }),
23172
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
23173
- RPopover12__namespace.Content,
23417
+ return /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open: linkOpen, onOpenChange: setLinkOpen, children: [
23418
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { label: "\uB9C1\uD06C", active: state2.link, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(IconLink, { size: ICON_SIZE }) }) }),
23419
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
23420
+ RPopover13__namespace.Content,
23174
23421
  {
23175
23422
  sideOffset: 4,
23176
23423
  align: "start",
@@ -24563,8 +24810,8 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
24563
24810
  })(),
24564
24811
  hasRightActions && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
24565
24812
  /* @__PURE__ */ jsxRuntime.jsx(Divider, { inset: true }),
24566
- hasAddButton && /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: addOpen, onOpenChange: setAddOpen, children: [
24567
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
24813
+ hasAddButton && /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open: addOpen, onOpenChange: setAddOpen, children: [
24814
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
24568
24815
  "button",
24569
24816
  {
24570
24817
  type: "button",
@@ -24589,8 +24836,8 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
24589
24836
  ]
24590
24837
  }
24591
24838
  ) }),
24592
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
24593
- RPopover12__namespace.Content,
24839
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
24840
+ RPopover13__namespace.Content,
24594
24841
  {
24595
24842
  side: "bottom",
24596
24843
  align: "start",
@@ -24625,17 +24872,17 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
24625
24872
  )
24626
24873
  ] })
24627
24874
  ] }),
24628
- /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: openKey != null, onOpenChange: (next) => !next && setOpenKey(null), children: [
24875
+ /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open: openKey != null, onOpenChange: (next) => !next && setOpenKey(null), children: [
24629
24876
  /* @__PURE__ */ jsxRuntime.jsx(
24630
- RPopover12__namespace.Anchor,
24877
+ RPopover13__namespace.Anchor,
24631
24878
  {
24632
24879
  virtualRef: {
24633
24880
  current: openKey ? triggerRefs.current.get(openKey) : null
24634
24881
  }
24635
24882
  }
24636
24883
  ),
24637
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
24638
- RPopover12__namespace.Content,
24884
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
24885
+ RPopover13__namespace.Content,
24639
24886
  {
24640
24887
  side: "bottom",
24641
24888
  align: "start",
@@ -25228,8 +25475,8 @@ function InlineDatePresetFilter({
25228
25475
  applied && (rangeValue ? (
25229
25476
  // 뱃지 모양은 그대로 두고, 눌렀을 때 캘린더가 열려 기간을 직접 다시 고를 수 있게 한다.
25230
25477
  // 직접 고르면 프리셋 선택은 해제된다.
25231
- /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
25232
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
25478
+ /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
25479
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
25233
25480
  "button",
25234
25481
  {
25235
25482
  type: "button",
@@ -25238,8 +25485,8 @@ function InlineDatePresetFilter({
25238
25485
  children: badge
25239
25486
  }
25240
25487
  ) }),
25241
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
25242
- RPopover12__namespace.Content,
25488
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
25489
+ RPopover13__namespace.Content,
25243
25490
  {
25244
25491
  side: "bottom",
25245
25492
  align: "start",
@@ -26701,8 +26948,8 @@ function STimePicker({
26701
26948
  disabled,
26702
26949
  className,
26703
26950
  style,
26704
- children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: commitOpen, children: [
26705
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
26951
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open, onOpenChange: commitOpen, children: [
26952
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
26706
26953
  "div",
26707
26954
  {
26708
26955
  ref: triggerRef,
@@ -26762,8 +27009,8 @@ function STimePicker({
26762
27009
  ]
26763
27010
  }
26764
27011
  ) }),
26765
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
26766
- RPopover12__namespace.Content,
27012
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
27013
+ RPopover13__namespace.Content,
26767
27014
  {
26768
27015
  side: "bottom",
26769
27016
  align: "start",
@@ -27171,8 +27418,8 @@ function STimeRangePicker({
27171
27418
  disabled,
27172
27419
  className,
27173
27420
  style,
27174
- children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover12__namespace.Root, { open, onOpenChange: commitOpen, children: [
27175
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
27421
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RPopover13__namespace.Root, { open, onOpenChange: commitOpen, children: [
27422
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
27176
27423
  "div",
27177
27424
  {
27178
27425
  ref: triggerRef,
@@ -27232,8 +27479,8 @@ function STimeRangePicker({
27232
27479
  ]
27233
27480
  }
27234
27481
  ) }),
27235
- /* @__PURE__ */ jsxRuntime.jsx(RPopover12__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
27236
- RPopover12__namespace.Content,
27482
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover13__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
27483
+ RPopover13__namespace.Content,
27237
27484
  {
27238
27485
  side: "bottom",
27239
27486
  align: "start",
@@ -27382,7 +27629,6 @@ exports.SList = SList2;
27382
27629
  exports.SListItem = SListItem2;
27383
27630
  exports.SLoadingContainer = SLoadingContainer;
27384
27631
  exports.SLoadingModal = SLoadingModal;
27385
- exports.SLoadingViewport = SLoadingViewport;
27386
27632
  exports.SLoginCard = SLoginCard2;
27387
27633
  exports.SLogo = SLogo;
27388
27634
  exports.SMeatballButton = SMeatballButton2;