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.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import { clsx } from 'clsx';
3
3
  import { extendTailwindMerge } from 'tailwind-merge';
4
- import { forwardRef, useState, useRef, useEffect, createContext, useCallback, useImperativeHandle, useLayoutEffect, useContext, useMemo, useId, Children, cloneElement, Fragment as Fragment$1, isValidElement, useSyncExternalStore, Component } from 'react';
4
+ import { forwardRef, createContext, useState, useRef, useEffect, useCallback, useImperativeHandle, useLayoutEffect, useContext, useMemo, useId, Children, cloneElement, Fragment as Fragment$1, isValidElement, useSyncExternalStore, Component } from 'react';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
- import * as RPopover12 from '@radix-ui/react-popover';
6
+ import * as RPopover13 from '@radix-ui/react-popover';
7
7
  import { createPortal } from 'react-dom';
8
8
  import * as RCheckbox from '@radix-ui/react-checkbox';
9
9
  import { createRoot } from 'react-dom/client';
@@ -3707,6 +3707,57 @@ var SIcon = /* @__PURE__ */ forwardRef(function SIcon2({ name, size = 24, color,
3707
3707
  }
3708
3708
  );
3709
3709
  });
3710
+
3711
+ // src/lib/display-name.ts
3712
+ function withDisplayName(component, name) {
3713
+ component.displayName = name;
3714
+ return component;
3715
+ }
3716
+
3717
+ // src/lib/floating-anim.ts
3718
+ var FLOATING_SLIDE_ANIM = [
3719
+ "data-[state=open]:data-[side=top]:animate-floating-in-top",
3720
+ "data-[state=delayed-open]:data-[side=top]:animate-floating-in-top",
3721
+ "data-[state=instant-open]:data-[side=top]:animate-floating-in-top",
3722
+ "data-[state=closed]:data-[side=top]:animate-floating-out-top",
3723
+ "data-[state=open]:data-[side=bottom]:animate-floating-in-bottom",
3724
+ "data-[state=delayed-open]:data-[side=bottom]:animate-floating-in-bottom",
3725
+ "data-[state=instant-open]:data-[side=bottom]:animate-floating-in-bottom",
3726
+ "data-[state=closed]:data-[side=bottom]:animate-floating-out-bottom",
3727
+ "data-[state=open]:data-[side=left]:animate-floating-in-left",
3728
+ "data-[state=delayed-open]:data-[side=left]:animate-floating-in-left",
3729
+ "data-[state=instant-open]:data-[side=left]:animate-floating-in-left",
3730
+ "data-[state=closed]:data-[side=left]:animate-floating-out-left",
3731
+ "data-[state=open]:data-[side=right]:animate-floating-in-right",
3732
+ "data-[state=delayed-open]:data-[side=right]:animate-floating-in-right",
3733
+ "data-[state=instant-open]:data-[side=right]:animate-floating-in-right",
3734
+ "data-[state=closed]:data-[side=right]:animate-floating-out-right"
3735
+ ].join(" ");
3736
+
3737
+ // src/lib/hover-preview.ts
3738
+ function hoverPreviewOrigin({
3739
+ anchor,
3740
+ size,
3741
+ viewportWidth,
3742
+ viewportHeight,
3743
+ padding = 8
3744
+ }) {
3745
+ const startX = anchor.left + anchor.width / 2;
3746
+ const startY = anchor.top + anchor.height / 2;
3747
+ const x = Math.max(padding, Math.min(startX, viewportWidth - size - padding));
3748
+ const y = Math.max(padding, Math.min(startY, viewportHeight - size - padding));
3749
+ return { x, y };
3750
+ }
3751
+ var PortalContainerContext = /* @__PURE__ */ createContext(null);
3752
+ var InsideModalContext = /* @__PURE__ */ createContext(false);
3753
+ var PortalContainerProvider = PortalContainerContext.Provider;
3754
+ var InsideModalProvider = InsideModalContext.Provider;
3755
+ function usePortalContainer() {
3756
+ return useContext(PortalContainerContext) ?? void 0;
3757
+ }
3758
+ function useInsideModal() {
3759
+ return useContext(InsideModalContext);
3760
+ }
3710
3761
  var VIEWBOX = 80;
3711
3762
  var RADIUS = 34;
3712
3763
  var STROKE = 12;
@@ -3824,7 +3875,10 @@ var SCircleProgress = /* @__PURE__ */ forwardRef(
3824
3875
  var IMAGE_FITS = ["cover", "contain", "fill", "none", "scale-down"];
3825
3876
  var EMPTY_ICON_SIZE = "60cqh";
3826
3877
  var SPINNER_SIZE = "45cqh";
3827
- var SImage = /* @__PURE__ */ forwardRef(function SImage2({
3878
+ var PREVIEW_HIDE_DELAY_MS = 100;
3879
+ var PREVIEW_MAX_SIZE = 200;
3880
+ var PREVIEW_VIEWPORT_PADDING = 8;
3881
+ var SImageImpl = /* @__PURE__ */ forwardRef(function SImageImpl2({
3828
3882
  src,
3829
3883
  alt = "",
3830
3884
  ratio = 1,
@@ -3836,6 +3890,9 @@ var SImage = /* @__PURE__ */ forwardRef(function SImage2({
3836
3890
  loadingSlot,
3837
3891
  errorSlot,
3838
3892
  imgProps,
3893
+ previewOnHover = false,
3894
+ previewSrc,
3895
+ previewSize = PREVIEW_MAX_SIZE,
3839
3896
  onLoad,
3840
3897
  onError,
3841
3898
  className,
@@ -3866,16 +3923,94 @@ var SImage = /* @__PURE__ */ forwardRef(function SImage2({
3866
3923
  const timer = setTimeout(() => setSpinnerVisible(true), loadingShowDelay);
3867
3924
  return () => clearTimeout(timer);
3868
3925
  }, [status, loadingShowDelay, src]);
3926
+ const portalContainer = usePortalContainer();
3927
+ const [previewOpen, setPreviewOpen] = useState(false);
3928
+ const previewHideTimer = useRef(void 0);
3929
+ const boxRef = useRef(null);
3930
+ const previewSource = previewSrc ?? src;
3931
+ const previewEnabled = previewOnHover && !!previewSource;
3932
+ const previewBoxSize = Math.min(previewSize, PREVIEW_MAX_SIZE);
3933
+ const previewBoxSizeRef = useRef(previewBoxSize);
3934
+ previewBoxSizeRef.current = previewBoxSize;
3935
+ const previewAnchorRef = useRef(null);
3936
+ if (previewAnchorRef.current == null) {
3937
+ previewAnchorRef.current = {
3938
+ getBoundingClientRect: () => {
3939
+ const anchor = boxRef.current?.getBoundingClientRect();
3940
+ if (!anchor) return new DOMRect(0, 0, 0, 0);
3941
+ const { x, y } = hoverPreviewOrigin({
3942
+ anchor,
3943
+ size: previewBoxSizeRef.current,
3944
+ viewportWidth: window.innerWidth,
3945
+ viewportHeight: window.innerHeight,
3946
+ padding: PREVIEW_VIEWPORT_PADDING
3947
+ });
3948
+ return new DOMRect(x, y, 0, 0);
3949
+ },
3950
+ // autoUpdate 가 스크롤 조상을 찾는 기준 — 없으면 표 안에서 스크롤할 때 위치가 굳는다
3951
+ get contextElement() {
3952
+ return boxRef.current ?? void 0;
3953
+ }
3954
+ };
3955
+ }
3956
+ const cancelPreviewHide = useCallback(() => {
3957
+ if (previewHideTimer.current) {
3958
+ clearTimeout(previewHideTimer.current);
3959
+ previewHideTimer.current = void 0;
3960
+ }
3961
+ }, []);
3962
+ const openPreview = () => {
3963
+ cancelPreviewHide();
3964
+ setPreviewOpen(true);
3965
+ };
3966
+ const startPreviewHide = () => {
3967
+ cancelPreviewHide();
3968
+ previewHideTimer.current = setTimeout(() => setPreviewOpen(false), PREVIEW_HIDE_DELAY_MS);
3969
+ };
3970
+ useEffect(() => {
3971
+ if (!previewEnabled) {
3972
+ cancelPreviewHide();
3973
+ setPreviewOpen(false);
3974
+ }
3975
+ }, [previewEnabled, cancelPreviewHide]);
3976
+ useEffect(() => cancelPreviewHide, [cancelPreviewHide]);
3977
+ const previewContentRef = useCallback((node) => {
3978
+ node?.parentElement?.style.setProperty("pointer-events", "none");
3979
+ }, []);
3980
+ const previewHandlers = previewEnabled ? {
3981
+ onMouseEnter: (event) => {
3982
+ rest.onMouseEnter?.(event);
3983
+ openPreview();
3984
+ },
3985
+ onMouseLeave: (event) => {
3986
+ rest.onMouseLeave?.(event);
3987
+ startPreviewHide();
3988
+ },
3989
+ // 소비자가 tabIndex 를 준 썸네일에서는 키보드로도 열린다
3990
+ onFocus: (event) => {
3991
+ rest.onFocus?.(event);
3992
+ openPreview();
3993
+ },
3994
+ onBlur: (event) => {
3995
+ rest.onBlur?.(event);
3996
+ startPreviewHide();
3997
+ }
3998
+ } : void 0;
3869
3999
  const isEmpty = !src;
3870
4000
  const showFallback = isEmpty || status === "error";
3871
4001
  const spinnerShown = !isEmpty && status === "loading" && showSpinner && spinnerVisible;
3872
- return /* @__PURE__ */ jsxs(
4002
+ const box3 = /* @__PURE__ */ jsxs(
3873
4003
  "div",
3874
4004
  {
3875
- ref,
4005
+ ref: (node) => {
4006
+ boxRef.current = node;
4007
+ if (typeof ref === "function") ref(node);
4008
+ else if (ref) ref.current = node;
4009
+ },
3876
4010
  className: cn("relative overflow-hidden bg-(--cmp-image-bg)", className),
3877
4011
  style: { containerType: "size", aspectRatio: ratio, ...style },
3878
4012
  ...rest,
4013
+ ...previewHandlers,
3879
4014
  children: [
3880
4015
  !isEmpty && /* @__PURE__ */ jsx(
3881
4016
  "img",
@@ -3911,7 +4046,47 @@ var SImage = /* @__PURE__ */ forwardRef(function SImage2({
3911
4046
  ]
3912
4047
  }
3913
4048
  );
4049
+ if (!previewEnabled) return box3;
4050
+ return /* @__PURE__ */ jsxs(RPopover13.Root, { open: previewOpen, onOpenChange: setPreviewOpen, children: [
4051
+ box3,
4052
+ /* @__PURE__ */ jsx(RPopover13.Anchor, { virtualRef: previewAnchorRef }),
4053
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
4054
+ RPopover13.Content,
4055
+ {
4056
+ ref: previewContentRef,
4057
+ side: "bottom",
4058
+ align: "start",
4059
+ sideOffset: 0,
4060
+ alignOffset: 0,
4061
+ avoidCollisions: false,
4062
+ role: "presentation",
4063
+ "aria-hidden": true,
4064
+ className: cn(
4065
+ "z-50 overflow-hidden rounded-[6px] shadow-normal-sm",
4066
+ // 읽기 전용이라 호버 브릿지를 두지 않는다. 그 대신 마우스를 통과시켜,
4067
+ // 목록 위로 뜬 미리보기가 아래 행의 클릭을 가로채지 않게 한다.
4068
+ // (래퍼 쪽은 previewContentRef 가 함께 끈다 — 둘 다 꺼야 깜빡이지 않는다)
4069
+ "pointer-events-none",
4070
+ FLOATING_SLIDE_ANIM
4071
+ ),
4072
+ onOpenAutoFocus: (event) => event.preventDefault(),
4073
+ onCloseAutoFocus: (event) => event.preventDefault(),
4074
+ children: /* @__PURE__ */ jsx(
4075
+ SImage,
4076
+ {
4077
+ src: previewSource,
4078
+ alt: "",
4079
+ ratio: 1,
4080
+ fit: "contain",
4081
+ loading: "eager",
4082
+ style: { width: previewBoxSize }
4083
+ }
4084
+ )
4085
+ }
4086
+ ) })
4087
+ ] });
3914
4088
  });
4089
+ var SImage = /* @__PURE__ */ withDisplayName(SImageImpl, "SImage");
3915
4090
  var BADGE_COLORS = [
3916
4091
  "red",
3917
4092
  "orange",
@@ -4180,42 +4355,6 @@ var SCard = /* @__PURE__ */ forwardRef(function SCard2({ bordered = false, foote
4180
4355
  );
4181
4356
  });
4182
4357
 
4183
- // src/lib/display-name.ts
4184
- function withDisplayName(component, name) {
4185
- component.displayName = name;
4186
- return component;
4187
- }
4188
-
4189
- // src/lib/floating-anim.ts
4190
- var FLOATING_SLIDE_ANIM = [
4191
- "data-[state=open]:data-[side=top]:animate-floating-in-top",
4192
- "data-[state=delayed-open]:data-[side=top]:animate-floating-in-top",
4193
- "data-[state=instant-open]:data-[side=top]:animate-floating-in-top",
4194
- "data-[state=closed]:data-[side=top]:animate-floating-out-top",
4195
- "data-[state=open]:data-[side=bottom]:animate-floating-in-bottom",
4196
- "data-[state=delayed-open]:data-[side=bottom]:animate-floating-in-bottom",
4197
- "data-[state=instant-open]:data-[side=bottom]:animate-floating-in-bottom",
4198
- "data-[state=closed]:data-[side=bottom]:animate-floating-out-bottom",
4199
- "data-[state=open]:data-[side=left]:animate-floating-in-left",
4200
- "data-[state=delayed-open]:data-[side=left]:animate-floating-in-left",
4201
- "data-[state=instant-open]:data-[side=left]:animate-floating-in-left",
4202
- "data-[state=closed]:data-[side=left]:animate-floating-out-left",
4203
- "data-[state=open]:data-[side=right]:animate-floating-in-right",
4204
- "data-[state=delayed-open]:data-[side=right]:animate-floating-in-right",
4205
- "data-[state=instant-open]:data-[side=right]:animate-floating-in-right",
4206
- "data-[state=closed]:data-[side=right]:animate-floating-out-right"
4207
- ].join(" ");
4208
- var PortalContainerContext = /* @__PURE__ */ createContext(null);
4209
- var InsideModalContext = /* @__PURE__ */ createContext(false);
4210
- var PortalContainerProvider = PortalContainerContext.Provider;
4211
- var InsideModalProvider = InsideModalContext.Provider;
4212
- function usePortalContainer() {
4213
- return useContext(PortalContainerContext) ?? void 0;
4214
- }
4215
- function useInsideModal() {
4216
- return useContext(InsideModalContext);
4217
- }
4218
-
4219
4358
  // src/components/STag/tag.config.ts
4220
4359
  var TAG_SHAPES = ["square", "pill"];
4221
4360
  var TAG_SIZES = ["xs", "sm", "md"];
@@ -4403,8 +4542,8 @@ var SGhostButton = /* @__PURE__ */ forwardRef(function SGhostButton2({
4403
4542
  }
4404
4543
  );
4405
4544
  if (!hasTooltip) return btn2;
4406
- return /* @__PURE__ */ jsxs(RPopover12.Root, { open, onOpenChange: setOpen, children: [
4407
- /* @__PURE__ */ jsx(RPopover12.Anchor, { asChild: true, children: /* @__PURE__ */ jsx(
4545
+ return /* @__PURE__ */ jsxs(RPopover13.Root, { open, onOpenChange: setOpen, children: [
4546
+ /* @__PURE__ */ jsx(RPopover13.Anchor, { asChild: true, children: /* @__PURE__ */ jsx(
4408
4547
  "span",
4409
4548
  {
4410
4549
  className: cn("inline-flex", anchorClassName),
@@ -4416,8 +4555,8 @@ var SGhostButton = /* @__PURE__ */ forwardRef(function SGhostButton2({
4416
4555
  children: btn2
4417
4556
  }
4418
4557
  ) }),
4419
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
4420
- RPopover12.Content,
4558
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
4559
+ RPopover13.Content,
4421
4560
  {
4422
4561
  side: "top",
4423
4562
  sideOffset: 4,
@@ -4606,14 +4745,14 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
4606
4745
  ...style,
4607
4746
  ...contentPropsStyle
4608
4747
  };
4609
- return /* @__PURE__ */ jsxs(RPopover12.Root, { open, onOpenChange: setOpenState, children: [
4748
+ return /* @__PURE__ */ jsxs(RPopover13.Root, { open, onOpenChange: setOpenState, children: [
4610
4749
  isNone ? (
4611
4750
  // 트리거 없음: children 을 래퍼 없이 그대로 앵커로 쓴다 (소비자 레이아웃 보존).
4612
4751
  // mouse/focus 핸들러가 없으므로 showClose 없이도 자동 닫힘이 발생하지 않는다.
4613
- /* @__PURE__ */ jsx(RPopover12.Anchor, { asChild: true, children: triggerNode })
4752
+ /* @__PURE__ */ jsx(RPopover13.Anchor, { asChild: true, children: triggerNode })
4614
4753
  ) : isHover ? (
4615
4754
  // hover: Anchor(위치 기준) + 직접 mouse 핸들러 — 클릭으로 토글되지 않도록 Trigger 미사용
4616
- /* @__PURE__ */ jsx(RPopover12.Anchor, { asChild: true, children: /* @__PURE__ */ jsx(
4755
+ /* @__PURE__ */ jsx(RPopover13.Anchor, { asChild: true, children: /* @__PURE__ */ jsx(
4617
4756
  "span",
4618
4757
  {
4619
4758
  className: "inline-flex",
@@ -4624,9 +4763,9 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
4624
4763
  children: triggerNode
4625
4764
  }
4626
4765
  ) })
4627
- ) : /* @__PURE__ */ jsx(RPopover12.Trigger, { asChild: true, children: triggerNode }),
4628
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
4629
- RPopover12.Content,
4766
+ ) : /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: triggerNode }),
4767
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
4768
+ RPopover13.Content,
4630
4769
  {
4631
4770
  side: placement,
4632
4771
  sideOffset,
@@ -4660,7 +4799,7 @@ var STooltipImpl = /* @__PURE__ */ forwardRef(function STooltip({
4660
4799
  }
4661
4800
  )
4662
4801
  ] }),
4663
- /* @__PURE__ */ jsx(RPopover12.Arrow, { width: 16, height: 12, style: { fill: bg } })
4802
+ /* @__PURE__ */ jsx(RPopover13.Arrow, { width: 16, height: 12, style: { fill: bg } })
4664
4803
  ]
4665
4804
  }
4666
4805
  ) })
@@ -8309,12 +8448,18 @@ var release = (id) => {
8309
8448
  entries = next;
8310
8449
  sync();
8311
8450
  };
8451
+ var updateEntry = (id, message) => {
8452
+ const index = entries.findIndex((e) => e.id === id);
8453
+ if (index === -1) return;
8454
+ entries = entries.map((e, i) => i === index ? { ...e, message } : e);
8455
+ sync();
8456
+ };
8312
8457
  var subscribe = (cb) => {
8313
8458
  listeners.add(cb);
8314
8459
  return () => listeners.delete(cb);
8315
8460
  };
8316
8461
  var getSnapshot = () => state;
8317
- function SLoadingViewport() {
8462
+ function LoadingViewport() {
8318
8463
  const s = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
8319
8464
  return /* @__PURE__ */ jsx(SLoadingContainer, { open: s.open, message: s.message });
8320
8465
  }
@@ -8325,39 +8470,56 @@ function ensureMounted() {
8325
8470
  const host = document.createElement("div");
8326
8471
  host.setAttribute("data-sd-loading-root", "");
8327
8472
  document.body.appendChild(host);
8328
- createRoot(host).render(/* @__PURE__ */ jsx(SLoadingViewport, {}));
8473
+ createRoot(host).render(/* @__PURE__ */ jsx(LoadingViewport, {}));
8474
+ }
8475
+ function showEntry(options = {}) {
8476
+ ensureMounted();
8477
+ const id = ++seq;
8478
+ entries = [...entries, { id, message: options.message }];
8479
+ sync();
8480
+ let released = false;
8481
+ const handle = (() => {
8482
+ if (released) return;
8483
+ released = true;
8484
+ release(id);
8485
+ });
8486
+ handle.update = (next) => {
8487
+ if (released) return;
8488
+ updateEntry(id, next.message);
8489
+ };
8490
+ return handle;
8329
8491
  }
8330
8492
  var loading = {
8331
8493
  /**
8332
8494
  * 로딩 오버레이 표시. 겹쳐 부르면 그만큼 쌓이고 **마지막 하나가 걷힐 때** 닫힌다.
8333
- * 반환값은 이 호출 하나만 걷는 함수다(두 번 불러도 한 번만 걷힌다) — `hide()` 대신 이것을
8334
- * 쓰면 짝이 어긋나지 않는다.
8495
+ * 반환값은 이 호출 하나를 걷고 갱신하는 핸들이다(두 번 걷어도 한 번만 걷힌다).
8496
+ *
8497
+ * **걷는 것은 `finally` 에 둔다.** 빠뜨리면 그 즉시 화면이 갇히고, 정상 경로에서는 아무
8498
+ * 표시가 없다.
8335
8499
  *
8336
- * ⚠️ 메시지만 바꾸려면 `update()` 를 쓴다. `show()` 를 다시 부르면 하나 더 쌓여
8337
- * `hide()` 한 번으로는 닫히지 않는다.
8500
+ * ```ts
8501
+ * const done = loading.show({ message: '1/2 ...' });
8502
+ * try {
8503
+ * done.update({ message: '2/2 ...' }); // 이 호출의 메시지만 바뀐다
8504
+ * await api.submit(payload);
8505
+ * } finally {
8506
+ * done(); // 이 호출만 걷는다
8507
+ * }
8508
+ * ```
8509
+ *
8510
+ * ⚠️ **메시지를 바꾸려고 `show()` 를 다시 부르지 않는다.** 하나 더 쌓여 한 번 걷는 것으로는
8511
+ * 닫히지 않는다. 핸들의 `update()` 를 쓴다. (참조 카운트 이전에는 `show()` 를 다시 부르는
8512
+ * 것이 갱신이었다 — Quasar 도 같은 그룹에 다시 show 하면 갱신이다. 그 시절 관행대로 쓰인
8513
+ * 코드는 지금 오버레이를 하나 남긴다.)
8338
8514
  */
8339
8515
  show(options = {}) {
8340
- ensureMounted();
8341
- const id = ++seq;
8342
- entries = [...entries, { id, message: options.message }];
8343
- sync();
8344
- return () => release(id);
8345
- },
8346
- /** 표시 중인 메시지 갱신 — 쌓인 수는 그대로다 */
8347
- update(options) {
8348
- const top = entries[entries.length - 1];
8349
- if (!top) return;
8350
- entries = [...entries.slice(0, -1), { ...top, message: options.message }];
8351
- sync();
8352
- },
8353
- /** 가장 나중의 show 하나를 걷는다. 남은 것이 없을 때만 오버레이가 닫힌다 */
8354
- hide() {
8355
- const top = entries[entries.length - 1];
8356
- if (top) release(top.id);
8516
+ return showEntry(options);
8357
8517
  },
8358
8518
  /**
8359
- * 쌓인 것을 모두 걷고 즉시 닫는다. 화면 전환·에러 복구처럼 진행 중이던 작업의 짝을 더는
8360
- * 맞출 수 없을 때만 쓴다 — 평소에는 `hide()` 나 `show()` 가 준 함수로 하나씩 걷는다.
8519
+ * 쌓인 것을 모두 걷고 즉시 닫는다. **원본(Quasar)의 인자 없는 `hide()` 가 이것이다.**
8520
+ * 화면 전환·에러 복구처럼 진행 중이던 작업의 짝을 더는 맞출 수 없을 때만 쓴다 — 평소에는
8521
+ * `show()` 가 준 핸들로 걷는다.
8522
+ * 이걸로 걷힌 항목의 주인이 뒤늦게 자기 핸들을 불러도 아무 일도 일어나지 않는다.
8361
8523
  */
8362
8524
  hideAll() {
8363
8525
  if (entries.length === 0) return;
@@ -8879,7 +9041,7 @@ function SPortal({
8879
9041
  const portalContainer = usePortalContainer();
8880
9042
  const { minWidth: styleMinWidth, maxWidth: styleMaxWidth, ...restStyle } = style ?? {};
8881
9043
  return /* @__PURE__ */ jsxs(
8882
- RPopover12.Root,
9044
+ RPopover13.Root,
8883
9045
  {
8884
9046
  open,
8885
9047
  onOpenChange: (next) => {
@@ -8887,9 +9049,9 @@ function SPortal({
8887
9049
  if (!next) onClose?.();
8888
9050
  },
8889
9051
  children: [
8890
- /* @__PURE__ */ jsx(RPopover12.Anchor, { virtualRef: anchorRef }),
8891
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
8892
- RPopover12.Content,
9052
+ /* @__PURE__ */ jsx(RPopover13.Anchor, { virtualRef: anchorRef }),
9053
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
9054
+ RPopover13.Content,
8893
9055
  {
8894
9056
  side: placement,
8895
9057
  align,
@@ -9640,10 +9802,10 @@ function SPopover({
9640
9802
  const descColor = type === "default" ? "var(--cmp-popover-default-description)" : "var(--cmp-popover-light-description)";
9641
9803
  const leftLinkLabelClass = type === "default" ? "text-[color:var(--cmp-popover-default-subAction)]" : "text-[color:var(--cmp-popover-light-subAction)]";
9642
9804
  const triggerNode = trigger ?? /* @__PURE__ */ jsx("span", { className: "inline-flex cursor-pointer", "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(SIcon, { name: icon, size: iconSize, color }) });
9643
- return /* @__PURE__ */ jsxs(RPopover12.Root, { open: actualOpen, onOpenChange: setOpen, children: [
9644
- /* @__PURE__ */ jsx(RPopover12.Trigger, { asChild: true, children: triggerNode }),
9645
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
9646
- RPopover12.Content,
9805
+ return /* @__PURE__ */ jsxs(RPopover13.Root, { open: actualOpen, onOpenChange: setOpen, children: [
9806
+ /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: triggerNode }),
9807
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
9808
+ RPopover13.Content,
9647
9809
  {
9648
9810
  side: placement,
9649
9811
  sideOffset: 8,
@@ -9709,7 +9871,7 @@ function SPopover({
9709
9871
  ]
9710
9872
  }
9711
9873
  ),
9712
- /* @__PURE__ */ jsx(RPopover12.Arrow, { width: 16, height: 12, style: { fill: bg } })
9874
+ /* @__PURE__ */ jsx(RPopover13.Arrow, { width: 16, height: 12, style: { fill: bg } })
9713
9875
  ]
9714
9876
  }
9715
9877
  ) })
@@ -9827,10 +9989,10 @@ function SGuide({
9827
9989
  );
9828
9990
  if (isNotion)
9829
9991
  return /* @__PURE__ */ jsx("span", { className, style, children: trigger });
9830
- return /* @__PURE__ */ jsxs(RPopover12.Root, { open, onOpenChange: setOpen, children: [
9831
- /* @__PURE__ */ jsx(RPopover12.Trigger, { asChild: true, children: trigger }),
9832
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
9833
- RPopover12.Content,
9992
+ return /* @__PURE__ */ jsxs(RPopover13.Root, { open, onOpenChange: setOpen, children: [
9993
+ /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: trigger }),
9994
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxs(
9995
+ RPopover13.Content,
9834
9996
  {
9835
9997
  side: "bottom",
9836
9998
  align: "start",
@@ -12323,10 +12485,10 @@ var SGnb = /* @__PURE__ */ forwardRef(function SGnb2({
12323
12485
  ),
12324
12486
  header === "fix" && menuResizeHandle,
12325
12487
  launcherListBox,
12326
- /* @__PURE__ */ jsxs(RPopover12.Root, { open: labelTip !== null, onOpenChange: (open) => !open && setLabelTip(null), children: [
12327
- /* @__PURE__ */ jsx(RPopover12.Anchor, { virtualRef: labelTipAnchorRef }),
12328
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
12329
- RPopover12.Content,
12488
+ /* @__PURE__ */ jsxs(RPopover13.Root, { open: labelTip !== null, onOpenChange: (open) => !open && setLabelTip(null), children: [
12489
+ /* @__PURE__ */ jsx(RPopover13.Anchor, { virtualRef: labelTipAnchorRef }),
12490
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
12491
+ RPopover13.Content,
12330
12492
  {
12331
12493
  side: "right",
12332
12494
  sideOffset: 4,
@@ -14421,7 +14583,7 @@ function SCalendarBoard({
14421
14583
  }
14422
14584
  ),
14423
14585
  /* @__PURE__ */ jsxs(
14424
- RPopover12.Root,
14586
+ RPopover13.Root,
14425
14587
  {
14426
14588
  open: openDate !== null,
14427
14589
  onOpenChange: (open) => {
@@ -14465,12 +14627,12 @@ function SCalendarBoard({
14465
14627
  },
14466
14628
  cell.date
14467
14629
  );
14468
- return cell.date === openDate ? /* @__PURE__ */ jsx(RPopover12.Anchor, { asChild: true, children: card }, cell.date) : card;
14630
+ return cell.date === openDate ? /* @__PURE__ */ jsx(RPopover13.Anchor, { asChild: true, children: card }, cell.date) : card;
14469
14631
  })
14470
14632
  }
14471
14633
  ),
14472
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
14473
- RPopover12.Content,
14634
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
14635
+ RPopover13.Content,
14474
14636
  {
14475
14637
  onInteractOutside: (e) => {
14476
14638
  const target = e.detail.originalEvent.target;
@@ -16973,10 +17135,10 @@ function useTruncatedValueTooltip({
16973
17135
  valueRef: elRef,
16974
17136
  onMouseEnter: active ? onMouseEnter : cancelHide,
16975
17137
  onMouseLeave: active ? startHide : cancelHide,
16976
- tooltip: active ? /* @__PURE__ */ jsxs(RPopover12.Root, { open, onOpenChange: setOpen, children: [
16977
- /* @__PURE__ */ jsx(RPopover12.Anchor, { virtualRef: elRef }),
16978
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
16979
- RPopover12.Content,
17138
+ tooltip: active ? /* @__PURE__ */ jsxs(RPopover13.Root, { open, onOpenChange: setOpen, children: [
17139
+ /* @__PURE__ */ jsx(RPopover13.Anchor, { virtualRef: elRef }),
17140
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
17141
+ RPopover13.Content,
16980
17142
  {
16981
17143
  side: "top",
16982
17144
  sideOffset: 4,
@@ -18230,8 +18392,8 @@ function SDatePicker({
18230
18392
  disabled,
18231
18393
  className,
18232
18394
  style,
18233
- children: /* @__PURE__ */ jsxs(RPopover12.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
18234
- /* @__PURE__ */ jsx(RPopover12.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
18395
+ children: /* @__PURE__ */ jsxs(RPopover13.Root, { open, onOpenChange: (o) => !disabled && setOpen(o), children: [
18396
+ /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
18235
18397
  "div",
18236
18398
  {
18237
18399
  role: "button",
@@ -18290,8 +18452,8 @@ function SDatePicker({
18290
18452
  ]
18291
18453
  }
18292
18454
  ) }),
18293
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
18294
- RPopover12.Content,
18455
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
18456
+ RPopover13.Content,
18295
18457
  {
18296
18458
  side: "bottom",
18297
18459
  align: mode === "date" ? "start" : "center",
@@ -18767,7 +18929,7 @@ function SDateRangePicker({
18767
18929
  className,
18768
18930
  style,
18769
18931
  children: /* @__PURE__ */ jsxs(
18770
- RPopover12.Root,
18932
+ RPopover13.Root,
18771
18933
  {
18772
18934
  open,
18773
18935
  onOpenChange: (o) => {
@@ -18776,7 +18938,7 @@ function SDateRangePicker({
18776
18938
  if (!o) setPendingStart(null);
18777
18939
  },
18778
18940
  children: [
18779
- /* @__PURE__ */ jsx(RPopover12.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
18941
+ /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
18780
18942
  "div",
18781
18943
  {
18782
18944
  role: "button",
@@ -18840,8 +19002,8 @@ function SDateRangePicker({
18840
19002
  ]
18841
19003
  }
18842
19004
  ) }),
18843
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
18844
- RPopover12.Content,
19005
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
19006
+ RPopover13.Content,
18845
19007
  {
18846
19008
  side: "bottom",
18847
19009
  align: "start",
@@ -19608,9 +19770,56 @@ var ChartFrame = /* @__PURE__ */ forwardRef(function ChartFrame2({ title, unit,
19608
19770
  }
19609
19771
  );
19610
19772
  });
19773
+
19774
+ // src/lib/chart/hover-dim.ts
19775
+ var CHART_DIM_OPACITY_TRANSITION = "transition-opacity duration-200 ease-out motion-reduce:transition-none";
19776
+ var CHART_DIM_COLOR_TRANSITION = "transition-colors duration-200 ease-out motion-reduce:transition-none";
19611
19777
  var DOT_SIZE = 6;
19612
- function ChartLegend({ items, align = "center", activeIndex, className }) {
19778
+ function ChartLegend({
19779
+ items,
19780
+ align = "center",
19781
+ activeIndex,
19782
+ className,
19783
+ variant = "simple"
19784
+ }) {
19613
19785
  if (items.length === 0) return null;
19786
+ const dot = (color) => /* @__PURE__ */ jsx(
19787
+ "span",
19788
+ {
19789
+ "aria-hidden": true,
19790
+ className: "shrink-0 rounded-full",
19791
+ style: { width: DOT_SIZE, height: DOT_SIZE, background: color }
19792
+ }
19793
+ );
19794
+ if (variant === "default") {
19795
+ return /* @__PURE__ */ jsx(
19796
+ "ul",
19797
+ {
19798
+ className: cn(
19799
+ "flex list-none flex-col gap-(--cmp-chart-doughnut-legend-data-default-gap) p-0",
19800
+ className
19801
+ ),
19802
+ children: items.map((item4, index) => /* @__PURE__ */ jsxs(
19803
+ "li",
19804
+ {
19805
+ className: cn(
19806
+ "flex items-center gap-(--cmp-chart-legendItem-gap)",
19807
+ "py-(--cmp-chart-legendItem-paddingY)",
19808
+ "typo-body-sm-medium text-(--cmp-chart-legendItem-color)",
19809
+ CHART_DIM_OPACITY_TRANSITION,
19810
+ activeIndex != null && activeIndex !== index && "opacity-(--opacity-060)"
19811
+ ),
19812
+ children: [
19813
+ dot(item4.color),
19814
+ /* @__PURE__ */ jsx("span", { children: item4.name }),
19815
+ item4.value != null && /* @__PURE__ */ jsx("span", { className: "ml-auto typo-body-sm-bold", style: { color: item4.valueColor }, children: item4.value })
19816
+ ]
19817
+ },
19818
+ `${item4.name}-${index}`
19819
+ ))
19820
+ }
19821
+ );
19822
+ }
19614
19823
  return /* @__PURE__ */ jsx(
19615
19824
  "ul",
19616
19825
  {
@@ -19628,18 +19837,11 @@ function ChartLegend({ items, align = "center", activeIndex, className }) {
19628
19837
  "flex items-center gap-(--cmp-chart-legendItem-gap)",
19629
19838
  "py-(--cmp-chart-legendItem-paddingY)",
19630
19839
  "typo-body-sm-medium text-(--cmp-chart-legendItem-color)",
19631
- "transition-opacity duration-200 ease-out motion-reduce:transition-none",
19840
+ CHART_DIM_OPACITY_TRANSITION,
19632
19841
  activeIndex != null && activeIndex !== index && "opacity-(--opacity-060)"
19633
19842
  ),
19634
19843
  children: [
19635
- /* @__PURE__ */ jsx(
19636
- "span",
19637
- {
19638
- "aria-hidden": true,
19639
- className: "shrink-0 rounded-full",
19640
- style: { width: DOT_SIZE, height: DOT_SIZE, background: item4.color }
19641
- }
19642
- ),
19844
+ dot(item4.color),
19643
19845
  item4.name
19644
19846
  ]
19645
19847
  },
@@ -19652,6 +19854,7 @@ function ChartLegend({ items, align = "center", activeIndex, className }) {
19652
19854
  // src/lib/chart/palette.ts
19653
19855
  var V3 = (path) => `var(--cmp-chart-palette-${path})`;
19654
19856
  var DIMMED = (path) => `var(--cmp-chart-line-point-dimmed-palette-${path})`;
19857
+ var VALUE = (path) => `var(--cmp-chart-dataValue-palette-${path})`;
19655
19858
  var colorsOf = (v) => ({
19656
19859
  positivePrimary: v("variation-positivePrimary"),
19657
19860
  positiveSecondary: v("variation-positiveSecondary"),
@@ -19688,6 +19891,31 @@ var CHART_COLORS = colorsOf(V3);
19688
19891
  var CHART_PALETTES = palettesOf(V3);
19689
19892
  var DIMMED_COLORS = colorsOf(DIMMED);
19690
19893
  var DIMMED_PALETTES = palettesOf(DIMMED);
19894
+ var DATA_VALUE_COLORS = colorsOf(VALUE);
19895
+ var DATA_VALUE_PALETTES = {
19896
+ default: [DATA_VALUE_COLORS.positivePrimary],
19897
+ multi: [
19898
+ VALUE("multi-blue"),
19899
+ VALUE("multi-skyblue"),
19900
+ VALUE("multi-yellow"),
19901
+ VALUE("multi-olive"),
19902
+ VALUE("multi-lightRed"),
19903
+ VALUE("multi-warmBlue"),
19904
+ VALUE("multi-orange"),
19905
+ VALUE("multi-green"),
19906
+ VALUE("multi-navy"),
19907
+ VALUE("multi-grey"),
19908
+ VALUE("multi-red")
19909
+ ],
19910
+ gradation: [
19911
+ V3("gradation-1"),
19912
+ V3("gradation-2"),
19913
+ V3("gradation-3"),
19914
+ V3("gradation-4"),
19915
+ V3("gradation-5"),
19916
+ VALUE("gradation-6")
19917
+ ]
19918
+ };
19691
19919
  function pick(names, palettes, palette, index, colors) {
19692
19920
  if (palette === "custom") {
19693
19921
  if (!colors?.length) return palettes.default[0];
@@ -19702,6 +19930,9 @@ function paletteColor(palette, index, colors) {
19702
19930
  function linePointDimmedColor(palette, index, colors) {
19703
19931
  return pick(DIMMED_COLORS, DIMMED_PALETTES, palette, index, colors);
19704
19932
  }
19933
+ function dataValueColor(palette, index, colors) {
19934
+ return pick(DATA_VALUE_COLORS, DATA_VALUE_PALETTES, palette, index, colors);
19935
+ }
19705
19936
  function useElementSize() {
19706
19937
  const ref = useRef(null);
19707
19938
  const [size, setSize] = useState({ width: 0, height: 0 });
@@ -19835,7 +20066,6 @@ var BAR_OPACITY_HOVER = 1;
19835
20066
  var BAR_DATA_LABEL_COLOR = "var(--cmp-chart-dataLabel-color-default)";
19836
20067
  var BAR_DATA_LABEL_TYPO = "typo-body-sm-medium";
19837
20068
  var BAR_DATA_LABEL_TYPO_HOVER = "typo-body-md-bold";
19838
- var BAR_HOVER_TRANSITION = "transition-opacity duration-200 ease-out motion-reduce:transition-none";
19839
20069
  function bandLayout(size, categoryCount, seriesCount, barSizeMax = BAR_SIZE_MAX) {
19840
20070
  const categories = Math.max(1, categoryCount);
19841
20071
  const series = Math.max(1, seriesCount);
@@ -20102,7 +20332,7 @@ var SBarChart = /* @__PURE__ */ forwardRef(function SBarChart2({
20102
20332
  "path",
20103
20333
  {
20104
20334
  d: barPath(x, y, width, barHeight, direction, negative),
20105
- className: BAR_HOVER_TRANSITION,
20335
+ className: CHART_DIM_OPACITY_TRANSITION,
20106
20336
  style: {
20107
20337
  fill: colorAt(seriesIndex, categoryIndex),
20108
20338
  opacity,
@@ -20119,7 +20349,7 @@ var SBarChart = /* @__PURE__ */ forwardRef(function SBarChart2({
20119
20349
  y: labelY,
20120
20350
  className: cn(
20121
20351
  hoveredCategory === categoryIndex ? BAR_DATA_LABEL_TYPO_HOVER : BAR_DATA_LABEL_TYPO,
20122
- BAR_HOVER_TRANSITION
20352
+ CHART_DIM_OPACITY_TRANSITION
20123
20353
  ),
20124
20354
  style: {
20125
20355
  fill: BAR_DATA_LABEL_COLOR,
@@ -20200,7 +20430,7 @@ var SBarChart = /* @__PURE__ */ forwardRef(function SBarChart2({
20200
20430
  width: box3.width,
20201
20431
  height: box3.height,
20202
20432
  clipPath: `url(#${segment.value < 0 ? negativeClip : positiveClip})`,
20203
- className: BAR_HOVER_TRANSITION,
20433
+ className: CHART_DIM_OPACITY_TRANSITION,
20204
20434
  style: {
20205
20435
  // 조각과 라벨에 따로 건다 — 묶음(<g>)에 걸면 호버가 없을 때의
20206
20436
  // 기본 흐림까지 합계 라벨에 묻어 숫자가 늘 옅어진다.
@@ -20225,7 +20455,7 @@ var SBarChart = /* @__PURE__ */ forwardRef(function SBarChart2({
20225
20455
  y: labelY,
20226
20456
  className: cn(
20227
20457
  hoveredCategory === categoryIndex ? BAR_DATA_LABEL_TYPO_HOVER : BAR_DATA_LABEL_TYPO,
20228
- BAR_HOVER_TRANSITION
20458
+ CHART_DIM_OPACITY_TRANSITION
20229
20459
  ),
20230
20460
  style: {
20231
20461
  fill: BAR_DATA_LABEL_COLOR,
@@ -20403,6 +20633,7 @@ var SBarChart = /* @__PURE__ */ forwardRef(function SBarChart2({
20403
20633
  // src/components/SLineChart/lineChart.config.ts
20404
20634
  var LINE_WIDTH = "var(--cmp-chart-line-width)";
20405
20635
  var LINE_OPACITY = "var(--cmp-chart-line-opacity)";
20636
+ var LINE_DASH = "11 11";
20406
20637
  var POINT_RADIUS = 5;
20407
20638
  var POINT_HOVER_RADIUS = 6;
20408
20639
  var POINT_HALO_RADIUS = 12;
@@ -20495,6 +20726,7 @@ var SLineChart = /* @__PURE__ */ forwardRef(function SLineChart2({
20495
20726
  title,
20496
20727
  unit,
20497
20728
  curve = "linear",
20729
+ lineStyle = "solid",
20498
20730
  area = false,
20499
20731
  stacked = false,
20500
20732
  palette = "default",
@@ -20703,14 +20935,15 @@ var SLineChart = /* @__PURE__ */ forwardRef(function SLineChart2({
20703
20935
  style: {
20704
20936
  stroke: colorAt(seriesIndex),
20705
20937
  strokeWidth: LINE_WIDTH,
20706
- strokeOpacity: LINE_OPACITY
20938
+ strokeOpacity: LINE_OPACITY,
20939
+ strokeDasharray: lineStyle === "dashed" ? LINE_DASH : void 0
20707
20940
  }
20708
20941
  },
20709
20942
  `line-${seriesIndex}-${runIndex}`
20710
20943
  );
20711
20944
  })
20712
20945
  ),
20713
- [plotted, smooth, colorAt]
20946
+ [plotted, smooth, colorAt, lineStyle]
20714
20947
  );
20715
20948
  const { pointHalos, pointDots } = useMemo(() => {
20716
20949
  const halos = [];
@@ -20745,6 +20978,7 @@ var SLineChart = /* @__PURE__ */ forwardRef(function SLineChart2({
20745
20978
  cx: point.x,
20746
20979
  cy: point.y,
20747
20980
  r: hovered ? POINT_HOVER_RADIUS : POINT_RADIUS,
20981
+ className: CHART_DIM_COLOR_TRANSITION,
20748
20982
  style: {
20749
20983
  fill: dimmed ? dimmedColorAt(seriesIndex) : color,
20750
20984
  cursor: onPointClick ? "pointer" : void 0
@@ -20990,6 +21224,7 @@ var RadialChart = /* @__PURE__ */ forwardRef(function RadialChart2({
20990
21224
  showValueLabel = false,
20991
21225
  showLegend = true,
20992
21226
  legendPosition = "top",
21227
+ legendVariant = "simple",
20993
21228
  showTooltip = true,
20994
21229
  formatValue = defaultFormat3,
20995
21230
  onSliceClick,
@@ -21017,7 +21252,8 @@ var RadialChart = /* @__PURE__ */ forwardRef(function RadialChart2({
21017
21252
  ratio,
21018
21253
  start,
21019
21254
  end: angle,
21020
- color: paletteColor(effective, slice2.index, colors)
21255
+ color: paletteColor(effective, slice2.index, colors),
21256
+ valueColor: dataValueColor(effective, slice2.index, colors)
21021
21257
  };
21022
21258
  });
21023
21259
  return list;
@@ -21030,8 +21266,14 @@ var RadialChart = /* @__PURE__ */ forwardRef(function RadialChart2({
21030
21266
  const legend = showLegend ? /* @__PURE__ */ jsx(
21031
21267
  ChartLegend,
21032
21268
  {
21033
- items: arcs.map((arc2) => ({ name: arc2.name, color: arc2.color })),
21034
- activeIndex: hoveredArc ? arcs.indexOf(hoveredArc) : null
21269
+ items: arcs.map((arc2) => ({
21270
+ name: arc2.name,
21271
+ color: arc2.color,
21272
+ value: legendVariant === "default" ? formatValue(arc2.value) : void 0,
21273
+ valueColor: arc2.valueColor
21274
+ })),
21275
+ activeIndex: hoveredArc ? arcs.indexOf(hoveredArc) : null,
21276
+ variant: legendVariant
21035
21277
  }
21036
21278
  ) : null;
21037
21279
  const tooltipAnchor = useMemo(() => {
@@ -21091,7 +21333,7 @@ var RadialChart = /* @__PURE__ */ forwardRef(function RadialChart2({
21091
21333
  {
21092
21334
  d: slice(arc2),
21093
21335
  fillRule: "evenodd",
21094
- className: "transition-opacity duration-200 ease-out motion-reduce:transition-none",
21336
+ className: CHART_DIM_OPACITY_TRANSITION,
21095
21337
  style: {
21096
21338
  fill: arc2.color,
21097
21339
  opacity,
@@ -21124,7 +21366,10 @@ var RadialChart = /* @__PURE__ */ forwardRef(function RadialChart2({
21124
21366
  y: point.y,
21125
21367
  textAnchor: "middle",
21126
21368
  dominantBaseline: "central",
21127
- className: "pointer-events-none typo-body-sm-bold transition-opacity duration-200 ease-out motion-reduce:transition-none",
21369
+ className: cn(
21370
+ "pointer-events-none typo-body-sm-bold",
21371
+ CHART_DIM_OPACITY_TRANSITION
21372
+ ),
21128
21373
  style: {
21129
21374
  fill: "var(--sys-color-fg-inverse)",
21130
21375
  opacity: hovered != null && hovered !== arc2.index ? OPACITY_DIMMED : void 0
@@ -21190,6 +21435,7 @@ var SDonutChart = /* @__PURE__ */ forwardRef(function SDonutChart2({
21190
21435
  showValueLabel = false,
21191
21436
  showLegend = true,
21192
21437
  legendPosition = "top",
21438
+ legendVariant = "simple",
21193
21439
  showTooltip = true,
21194
21440
  ...props
21195
21441
  }, ref) {
@@ -21202,6 +21448,7 @@ var SDonutChart = /* @__PURE__ */ forwardRef(function SDonutChart2({
21202
21448
  showValueLabel,
21203
21449
  showLegend,
21204
21450
  legendPosition,
21451
+ legendVariant,
21205
21452
  showTooltip,
21206
21453
  innerRatio: DONUT_INNER_RATIO,
21207
21454
  kind: "\uB3C4\uB11B \uADF8\uB798\uD504"
@@ -23139,10 +23386,10 @@ function EditorToolbarBar({
23139
23386
  },
23140
23387
  item4
23141
23388
  );
23142
- return /* @__PURE__ */ jsxs(RPopover12.Root, { open: linkOpen, onOpenChange: setLinkOpen, children: [
23143
- /* @__PURE__ */ jsx(RPopover12.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsx(ToolbarButton, { label: "\uB9C1\uD06C", active: state2.link, disabled: off, children: /* @__PURE__ */ jsx(IconLink, { size: ICON_SIZE }) }) }),
23144
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
23145
- RPopover12.Content,
23389
+ return /* @__PURE__ */ jsxs(RPopover13.Root, { open: linkOpen, onOpenChange: setLinkOpen, children: [
23390
+ /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsx(ToolbarButton, { label: "\uB9C1\uD06C", active: state2.link, disabled: off, children: /* @__PURE__ */ jsx(IconLink, { size: ICON_SIZE }) }) }),
23391
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
23392
+ RPopover13.Content,
23146
23393
  {
23147
23394
  sideOffset: 4,
23148
23395
  align: "start",
@@ -24535,8 +24782,8 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
24535
24782
  })(),
24536
24783
  hasRightActions && /* @__PURE__ */ jsxs(Fragment, { children: [
24537
24784
  /* @__PURE__ */ jsx(Divider, { inset: true }),
24538
- hasAddButton && /* @__PURE__ */ jsxs(RPopover12.Root, { open: addOpen, onOpenChange: setAddOpen, children: [
24539
- /* @__PURE__ */ jsx(RPopover12.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
24785
+ hasAddButton && /* @__PURE__ */ jsxs(RPopover13.Root, { open: addOpen, onOpenChange: setAddOpen, children: [
24786
+ /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
24540
24787
  "button",
24541
24788
  {
24542
24789
  type: "button",
@@ -24561,8 +24808,8 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
24561
24808
  ]
24562
24809
  }
24563
24810
  ) }),
24564
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
24565
- RPopover12.Content,
24811
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
24812
+ RPopover13.Content,
24566
24813
  {
24567
24814
  side: "bottom",
24568
24815
  align: "start",
@@ -24597,17 +24844,17 @@ var SChipFilter = /* @__PURE__ */ forwardRef(function SChipFilter2({
24597
24844
  )
24598
24845
  ] })
24599
24846
  ] }),
24600
- /* @__PURE__ */ jsxs(RPopover12.Root, { open: openKey != null, onOpenChange: (next) => !next && setOpenKey(null), children: [
24847
+ /* @__PURE__ */ jsxs(RPopover13.Root, { open: openKey != null, onOpenChange: (next) => !next && setOpenKey(null), children: [
24601
24848
  /* @__PURE__ */ jsx(
24602
- RPopover12.Anchor,
24849
+ RPopover13.Anchor,
24603
24850
  {
24604
24851
  virtualRef: {
24605
24852
  current: openKey ? triggerRefs.current.get(openKey) : null
24606
24853
  }
24607
24854
  }
24608
24855
  ),
24609
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
24610
- RPopover12.Content,
24856
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
24857
+ RPopover13.Content,
24611
24858
  {
24612
24859
  side: "bottom",
24613
24860
  align: "start",
@@ -25200,8 +25447,8 @@ function InlineDatePresetFilter({
25200
25447
  applied && (rangeValue ? (
25201
25448
  // 뱃지 모양은 그대로 두고, 눌렀을 때 캘린더가 열려 기간을 직접 다시 고를 수 있게 한다.
25202
25449
  // 직접 고르면 프리셋 선택은 해제된다.
25203
- /* @__PURE__ */ jsxs(RPopover12.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
25204
- /* @__PURE__ */ jsx(RPopover12.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
25450
+ /* @__PURE__ */ jsxs(RPopover13.Root, { open: pickerOpen, onOpenChange: setPickerOpen, children: [
25451
+ /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
25205
25452
  "button",
25206
25453
  {
25207
25454
  type: "button",
@@ -25210,8 +25457,8 @@ function InlineDatePresetFilter({
25210
25457
  children: badge
25211
25458
  }
25212
25459
  ) }),
25213
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
25214
- RPopover12.Content,
25460
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
25461
+ RPopover13.Content,
25215
25462
  {
25216
25463
  side: "bottom",
25217
25464
  align: "start",
@@ -26673,8 +26920,8 @@ function STimePicker({
26673
26920
  disabled,
26674
26921
  className,
26675
26922
  style,
26676
- children: /* @__PURE__ */ jsxs(RPopover12.Root, { open, onOpenChange: commitOpen, children: [
26677
- /* @__PURE__ */ jsx(RPopover12.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
26923
+ children: /* @__PURE__ */ jsxs(RPopover13.Root, { open, onOpenChange: commitOpen, children: [
26924
+ /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
26678
26925
  "div",
26679
26926
  {
26680
26927
  ref: triggerRef,
@@ -26734,8 +26981,8 @@ function STimePicker({
26734
26981
  ]
26735
26982
  }
26736
26983
  ) }),
26737
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
26738
- RPopover12.Content,
26984
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
26985
+ RPopover13.Content,
26739
26986
  {
26740
26987
  side: "bottom",
26741
26988
  align: "start",
@@ -27143,8 +27390,8 @@ function STimeRangePicker({
27143
27390
  disabled,
27144
27391
  className,
27145
27392
  style,
27146
- children: /* @__PURE__ */ jsxs(RPopover12.Root, { open, onOpenChange: commitOpen, children: [
27147
- /* @__PURE__ */ jsx(RPopover12.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
27393
+ children: /* @__PURE__ */ jsxs(RPopover13.Root, { open, onOpenChange: commitOpen, children: [
27394
+ /* @__PURE__ */ jsx(RPopover13.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
27148
27395
  "div",
27149
27396
  {
27150
27397
  ref: triggerRef,
@@ -27204,8 +27451,8 @@ function STimeRangePicker({
27204
27451
  ]
27205
27452
  }
27206
27453
  ) }),
27207
- /* @__PURE__ */ jsx(RPopover12.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
27208
- RPopover12.Content,
27454
+ /* @__PURE__ */ jsx(RPopover13.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx(
27455
+ RPopover13.Content,
27209
27456
  {
27210
27457
  side: "bottom",
27211
27458
  align: "start",
@@ -27232,6 +27479,6 @@ function STimeRangePicker({
27232
27479
  );
27233
27480
  }
27234
27481
 
27235
- export { ACCOUNT_LIST_BOX_ICONS, ACCOUNT_LIST_BOX_ITEM_TONES, ACCOUNT_LIST_BOX_LABELS, ACCOUNT_LIST_BOX_LAYOUT, ACCOUNT_LIST_BOX_TONE_CONFIG, BADGE_COLORS, BAR_GAP, BAR_SIZE_MAX, BAR_SIZE_MIN, BUTTON_COLORS, BUTTON_SIZES, CALENDAR_BOARD_DAY_BG, CALENDAR_BOARD_DAY_COLORS, CALENDAR_BOARD_EVENT_COLORS, CALENDAR_BOARD_EVENT_PRESETS, CALENDAR_BOARD_MAX_VISIBLE_EVENTS, CHAT_ATTACHED_FILE_CONFIG, CHAT_FILE_CONFIG, CHAT_MESSAGE_DIRECTIONS, CHAT_MESSAGE_READ_STATUSES, CHAT_MESSAGE_VARIANTS, CHIP_COLORS, COLOR_KEYS, CONTEXT_ALERT_DEFAULT_ICON, CONTEXT_ALERT_ICON_COLOR, CONTEXT_ALERT_INTENTS, CONTEXT_ALERT_SURFACE, FIELD_WIDTH_GRADES, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_FULL_LOGO_WIDTH, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, GNB_SYSTEM_COLORS, GNB_SYSTEM_COLOR_CONFIG, GNB_SYSTEM_LAYOUT, GNB_SYSTEM_PLACEMENTS, GNB_SYSTEM_TOP_COLOR_CONFIG, ICONS, IMAGE_FITS, LAUNCHER_LIST_BOX_LAYOUT, LAUNCHER_LIST_BOX_LOGO_HEIGHT, LAUNCHER_LIST_BOX_LOGO_SERVICE_GAP, LAUNCHER_LIST_BOX_TRAILING_ICON, LAUNCHER_LIST_BOX_WIDTH, LAUNCHER_SERVICES, LAUNCHER_SERVICE_CATALOG, LOGO_DEFAULT_SIZE, LOGO_NAMES, PAGE_BACKGROUNDS, PAGE_CONTENT_HEIGHTS, PAGE_CONTENT_WIDTHS, PAGE_HEADER_VARIANTS, PAGE_PADDINGS, RangeCalendar, SAccountListBox, SActionModal, SBadge, SBarChart, SBarcodeInput, SButton, SCROLL_AREA_AXES, SCalendar, SCalendarBoard, SCallout, SCard, SChatAttachedFile2 as SChatAttachedFile, SChatFile2 as SChatFile, SChatInput2 as SChatInput, SChatMessage2 as SChatMessage, SChatSystemMessage2 as SChatSystemMessage, SCheckbox, SChip2 as SChip, SChipFilter, SChipInput, SCircleProgress, SConfirmModal, SContextAlert, SDatePicker, SDatePickerMonthListbox, SDatePickerYearListbox, SDateRangePicker, SDivider, SDonutChart, SDraggableGroup, SDraggableItem2 as SDraggableItem, SDraggableList, SDraggableProvider, SDrawer, SDropdownButton2 as SDropdownButton, SEDITOR_DEFAULT_FONT_SIZE, SEDITOR_HEADING_LABELS, SEDITOR_HEADING_LEVELS, SEditor, SExpansionItem, SExpansionList2 as SExpansionList, SField, SFilePicker, SForm, SGhostButton, SGnb, SGnbSystem, SGnbSystemContext, SGuide, SIcon, SImage, SInput, SKeyValueTable, SLAYOUT_MIN_WIDTH, SLauncherListBox, SLayout, SLayoutContext, SLineChart, SLinearProgress, SList2 as SList, SListItem2 as SListItem, SLoadingContainer, SLoadingModal, SLoadingViewport, SLoginCard2 as SLoginCard, SLogo, SMeatballButton2 as SMeatballButton, SModal, SModalOutlet, SNumberInput, SPage, SPageHeader, SPagination, SPieChart, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioCard, SRadioCardGroup, SRadioGroup, SSPLITTER_UNITS, SScrollArea, SSearchInput, SSectionHeaderCard2 as SSectionHeaderCard, SSelect2 as SSelect, SSplitter2 as SSplitter, SStepper, SSwitch, SSystemActionButton, STEPPER_SIZES, STable, STableBar, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip2 as STooltip, STree2 as STree, STreeItem2 as STreeItem, SYSTEM_ACTION_BUTTON_COLORS, SYSTEM_ACTION_BUTTON_COLOR_CONFIG, SYSTEM_ACTION_BUTTON_LAYOUT, SYSTEM_ACTION_BUTTON_TYPES, SYSTEM_ACTION_BUTTON_TYPE_CONFIG, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, fieldWidthValue, fileExtension, findGnbAncestors, findGnbRailValue, formatFileSize, isColorKey, isFieldWidthGrade, loading, normalizeExtension, resolveColor, useSLayout };
27482
+ export { ACCOUNT_LIST_BOX_ICONS, ACCOUNT_LIST_BOX_ITEM_TONES, ACCOUNT_LIST_BOX_LABELS, ACCOUNT_LIST_BOX_LAYOUT, ACCOUNT_LIST_BOX_TONE_CONFIG, BADGE_COLORS, BAR_GAP, BAR_SIZE_MAX, BAR_SIZE_MIN, BUTTON_COLORS, BUTTON_SIZES, CALENDAR_BOARD_DAY_BG, CALENDAR_BOARD_DAY_COLORS, CALENDAR_BOARD_EVENT_COLORS, CALENDAR_BOARD_EVENT_PRESETS, CALENDAR_BOARD_MAX_VISIBLE_EVENTS, CHAT_ATTACHED_FILE_CONFIG, CHAT_FILE_CONFIG, CHAT_MESSAGE_DIRECTIONS, CHAT_MESSAGE_READ_STATUSES, CHAT_MESSAGE_VARIANTS, CHIP_COLORS, COLOR_KEYS, CONTEXT_ALERT_DEFAULT_ICON, CONTEXT_ALERT_ICON_COLOR, CONTEXT_ALERT_INTENTS, CONTEXT_ALERT_SURFACE, FIELD_WIDTH_GRADES, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_FULL_LOGO_WIDTH, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, GNB_SYSTEM_COLORS, GNB_SYSTEM_COLOR_CONFIG, GNB_SYSTEM_LAYOUT, GNB_SYSTEM_PLACEMENTS, GNB_SYSTEM_TOP_COLOR_CONFIG, ICONS, IMAGE_FITS, LAUNCHER_LIST_BOX_LAYOUT, LAUNCHER_LIST_BOX_LOGO_HEIGHT, LAUNCHER_LIST_BOX_LOGO_SERVICE_GAP, LAUNCHER_LIST_BOX_TRAILING_ICON, LAUNCHER_LIST_BOX_WIDTH, LAUNCHER_SERVICES, LAUNCHER_SERVICE_CATALOG, LOGO_DEFAULT_SIZE, LOGO_NAMES, PAGE_BACKGROUNDS, PAGE_CONTENT_HEIGHTS, PAGE_CONTENT_WIDTHS, PAGE_HEADER_VARIANTS, PAGE_PADDINGS, RangeCalendar, SAccountListBox, SActionModal, SBadge, SBarChart, SBarcodeInput, SButton, SCROLL_AREA_AXES, SCalendar, SCalendarBoard, SCallout, SCard, SChatAttachedFile2 as SChatAttachedFile, SChatFile2 as SChatFile, SChatInput2 as SChatInput, SChatMessage2 as SChatMessage, SChatSystemMessage2 as SChatSystemMessage, SCheckbox, SChip2 as SChip, SChipFilter, SChipInput, SCircleProgress, SConfirmModal, SContextAlert, SDatePicker, SDatePickerMonthListbox, SDatePickerYearListbox, SDateRangePicker, SDivider, SDonutChart, SDraggableGroup, SDraggableItem2 as SDraggableItem, SDraggableList, SDraggableProvider, SDrawer, SDropdownButton2 as SDropdownButton, SEDITOR_DEFAULT_FONT_SIZE, SEDITOR_HEADING_LABELS, SEDITOR_HEADING_LEVELS, SEditor, SExpansionItem, SExpansionList2 as SExpansionList, SField, SFilePicker, SForm, SGhostButton, SGnb, SGnbSystem, SGnbSystemContext, SGuide, SIcon, SImage, SInput, SKeyValueTable, SLAYOUT_MIN_WIDTH, SLauncherListBox, SLayout, SLayoutContext, SLineChart, SLinearProgress, SList2 as SList, SListItem2 as SListItem, SLoadingContainer, SLoadingModal, SLoginCard2 as SLoginCard, SLogo, SMeatballButton2 as SMeatballButton, SModal, SModalOutlet, SNumberInput, SPage, SPageHeader, SPagination, SPieChart, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioCard, SRadioCardGroup, SRadioGroup, SSPLITTER_UNITS, SScrollArea, SSearchInput, SSectionHeaderCard2 as SSectionHeaderCard, SSelect2 as SSelect, SSplitter2 as SSplitter, SStepper, SSwitch, SSystemActionButton, STEPPER_SIZES, STable, STableBar, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip2 as STooltip, STree2 as STree, STreeItem2 as STreeItem, SYSTEM_ACTION_BUTTON_COLORS, SYSTEM_ACTION_BUTTON_COLOR_CONFIG, SYSTEM_ACTION_BUTTON_LAYOUT, SYSTEM_ACTION_BUTTON_TYPES, SYSTEM_ACTION_BUTTON_TYPE_CONFIG, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, fieldWidthValue, fileExtension, findGnbAncestors, findGnbRailValue, formatFileSize, isColorKey, isFieldWidthGrade, loading, normalizeExtension, resolveColor, useSLayout };
27236
27483
  //# sourceMappingURL=index.js.map
27237
27484
  //# sourceMappingURL=index.js.map