sellmate-design-system-react 9.0.0-beta.31 → 9.0.0-beta.32

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
@@ -270,6 +270,47 @@ var fieldWidthValue = (v) => {
270
270
  if (isFieldWidthGrade(v)) return `var(--cmp-field-width-${v})`;
271
271
  return typeof v === "number" ? `${v}px` : v;
272
272
  };
273
+ var Icon_account = (p) => {
274
+ const { size = 24, ...rest } = p;
275
+ return /* @__PURE__ */ jsxRuntime.jsxs(
276
+ "svg",
277
+ {
278
+ width: size,
279
+ height: size,
280
+ viewBox: "0 0 24 24",
281
+ fill: "none",
282
+ xmlns: "http://www.w3.org/2000/svg",
283
+ ...rest,
284
+ children: [
285
+ /* @__PURE__ */ jsxRuntime.jsx(
286
+ "path",
287
+ {
288
+ d: "M11.75 13.75H9.35547C7.96612 13.75 6.68824 14.3982 5.74609 15.373C4.80587 16.346 4.25975 17.5818 4.25 18.6846C4.25175 18.6862 4.25343 18.6884 4.25586 18.6904C4.28703 18.7161 4.35523 18.75 4.4541 18.75H12.5V20.25H4.4541C3.65662 20.25 2.75016 19.692 2.75 18.7148C2.75 17.144 3.50242 15.5362 4.66699 14.3311C5.83832 13.119 7.48832 12.25 9.35547 12.25H11.75V13.75Z",
289
+ fill: "currentColor"
290
+ }
291
+ ),
292
+ /* @__PURE__ */ jsxRuntime.jsx(
293
+ "path",
294
+ {
295
+ fillRule: "evenodd",
296
+ clipRule: "evenodd",
297
+ d: "M17.4854 11C17.6175 11.0001 17.7358 11.0828 17.7803 11.2061L18.0977 12.0859C18.2115 12.1143 18.3098 12.1432 18.3926 12.1729C18.483 12.2052 18.5994 12.2543 18.7432 12.3213L19.4834 11.9297C19.5436 11.8979 19.6124 11.886 19.6797 11.8965C19.7471 11.9071 19.8098 11.9394 19.8574 11.9883L20.5078 12.6611C20.5942 12.7507 20.6188 12.8818 20.5703 12.9961L20.2236 13.8096C20.2811 13.9152 20.3272 14.0055 20.3623 14.0811C20.4001 14.1633 20.4462 14.2768 20.502 14.4229L21.3105 14.7695C21.432 14.8213 21.5071 14.9432 21.499 15.0732L21.4404 16.0068C21.4363 16.0674 21.4137 16.1255 21.377 16.1738C21.3402 16.2221 21.2906 16.2592 21.2334 16.2793L20.4668 16.5508C20.4447 16.6565 20.4218 16.7477 20.3975 16.8242C20.3583 16.9421 20.3137 17.0582 20.2637 17.1719L20.6484 18.0225C20.6756 18.0822 20.6825 18.1497 20.6689 18.2139C20.6553 18.2779 20.6222 18.3364 20.5732 18.3799L19.8408 19.0332C19.7927 19.0758 19.7328 19.1026 19.6689 19.1104C19.6051 19.1181 19.5403 19.1062 19.4834 19.0762L18.7285 18.6768C18.6106 18.7392 18.4889 18.7943 18.3643 18.8418L18.0352 18.9648L17.7422 19.7744C17.7205 19.8337 17.6813 19.8852 17.6299 19.9219C17.5785 19.9585 17.5172 19.9792 17.4541 19.9805L16.5996 20C16.5348 20.0017 16.4709 19.9833 16.417 19.9473C16.3631 19.9113 16.3221 19.8593 16.2988 19.7988L15.9541 18.8867C15.8365 18.8465 15.7196 18.8026 15.6045 18.7559C15.5104 18.7151 15.4173 18.6711 15.3262 18.624L14.4717 18.9893C14.4154 19.0133 14.3533 19.0204 14.293 19.0098C14.2326 18.9991 14.1766 18.9715 14.1318 18.9297L13.499 18.3359C13.452 18.292 13.4197 18.234 13.4072 18.1709C13.3949 18.1079 13.4031 18.0428 13.4297 17.9844L13.7969 17.1826C13.7481 17.088 13.7027 16.9916 13.6611 16.8936C13.6125 16.7733 13.5677 16.6512 13.5264 16.5283L12.7207 16.2832C12.6554 16.2635 12.5985 16.2224 12.5586 16.167C12.5187 16.1114 12.4978 16.0439 12.5 15.9756L12.5312 15.1113C12.5335 15.0549 12.5519 15.0002 12.583 14.9531C12.6141 14.906 12.657 14.868 12.708 14.8438L13.5527 14.4375C13.5918 14.2943 13.6262 14.1829 13.6562 14.1016C13.6987 13.9929 13.7462 13.8859 13.7979 13.7812L13.4316 13.0068C13.4039 12.9481 13.3952 12.8821 13.4072 12.8184C13.4194 12.7545 13.4516 12.6959 13.499 12.6514L14.1309 12.0547C14.175 12.013 14.2303 11.9847 14.29 11.9736C14.3499 11.9626 14.4125 11.9699 14.4688 11.9932L15.3223 12.3457C15.4168 12.2827 15.5027 12.2314 15.5801 12.1904C15.6722 12.1415 15.7953 12.0904 15.9502 12.0352L16.248 11.207C16.27 11.1465 16.3096 11.0936 16.3623 11.0566C16.4151 11.0197 16.4785 10.9999 16.543 11H17.4854ZM17.0107 14.1582C16.2606 14.1582 15.6523 14.7594 15.6523 15.501C15.6524 16.2425 16.2607 16.8437 17.0107 16.8438C17.7604 16.8438 18.3681 16.2425 18.3682 15.501C18.3682 14.7594 17.7609 14.1582 17.0107 14.1582Z",
298
+ fill: "currentColor"
299
+ }
300
+ ),
301
+ /* @__PURE__ */ jsxRuntime.jsx(
302
+ "path",
303
+ {
304
+ fillRule: "evenodd",
305
+ clipRule: "evenodd",
306
+ d: "M10.5 3.5C12.6875 3.5 14.5 5.3125 14.5 7.5C14.5 9.71875 12.6875 11.5 10.5 11.5C8.28125 11.5 6.5 9.71875 6.5 7.5C6.5 5.3125 8.28125 3.5 10.5 3.5ZM10.5 5C9.11729 5 8 6.13329 8 7.5C8 8.89032 9.10968 10 10.5 10C11.8667 10 13 8.88271 13 7.5C13 6.14093 11.8591 5 10.5 5Z",
307
+ fill: "currentColor"
308
+ }
309
+ )
310
+ ]
311
+ }
312
+ );
313
+ };
273
314
  var Icon_add = (p) => {
274
315
  const { size = 24, ...rest } = p;
275
316
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -599,6 +640,38 @@ var Icon_bell = (p) => {
599
640
  }
600
641
  );
601
642
  };
643
+ var Icon_bellRinging = (p) => {
644
+ const { size = 24, ...rest } = p;
645
+ return /* @__PURE__ */ jsxRuntime.jsxs(
646
+ "svg",
647
+ {
648
+ width: size,
649
+ height: size,
650
+ viewBox: "0 0 24 24",
651
+ fill: "none",
652
+ xmlns: "http://www.w3.org/2000/svg",
653
+ ...rest,
654
+ children: [
655
+ /* @__PURE__ */ jsxRuntime.jsx(
656
+ "path",
657
+ {
658
+ fillRule: "evenodd",
659
+ clipRule: "evenodd",
660
+ d: "M14.7569 2.38727C15.5529 2.61577 16.0134 3.44651 15.7853 4.24262L15.6017 4.88283C18.2685 6.33275 19.6863 9.40776 18.8414 12.3553L17.8242 15.9028L17.7839 16.0822C17.615 17.0352 17.9736 18.7681 18.418 19.5394C18.8918 20.3618 17.8729 20.9656 16.9454 20.6999L12.9492 19.554C12.9484 19.5568 12.9478 19.5597 12.9468 19.5625C12.3934 21.1403 10.776 22.0516 9.24413 21.6125C7.71218 21.1732 6.82362 19.5434 7.19047 17.9119C7.19112 17.909 7.19212 17.9062 7.19289 17.9034L3.19671 16.7575L3.02761 16.6989C2.20629 16.3626 1.77717 15.4116 2.56283 14.993C3.34841 14.5742 4.57093 13.2947 4.93263 12.3972L4.99356 12.2237L6.01078 8.6762C6.85627 5.72841 9.68793 3.8709 12.7182 4.05498L12.9015 3.41571C13.13 2.61953 13.9606 2.15895 14.7569 2.38727ZM13.7922 5.75169C10.9998 4.951 8.19452 6.50346 7.45267 9.08965L6.43545 12.6371C6.2092 13.4258 5.61733 14.2164 5.11212 14.7792C4.88445 15.0328 4.62615 15.2903 4.35646 15.5296L16.6125 19.044C16.5106 18.698 16.4281 18.343 16.3694 18.0071C16.2392 17.2621 16.1562 16.2782 16.3823 15.4893L17.3995 11.9419C18.1408 9.35565 16.5842 6.55254 13.7922 5.75169Z",
661
+ fill: "currentColor"
662
+ }
663
+ ),
664
+ /* @__PURE__ */ jsxRuntime.jsx(
665
+ "path",
666
+ {
667
+ d: "M18.7143 4.09705C19.0365 3.83687 19.5097 3.88767 19.77 4.2098C20.8724 5.57421 21.6644 7.17777 22.0725 8.89915C22.1677 9.30202 21.9178 9.70642 21.515 9.80193C21.1123 9.89711 20.7087 9.64808 20.6129 9.24559C20.2569 7.74423 19.5651 6.34446 18.6025 5.15304C18.3423 4.83086 18.3922 4.35736 18.7143 4.09705Z",
668
+ fill: "currentColor"
669
+ }
670
+ )
671
+ ]
672
+ }
673
+ );
674
+ };
602
675
  var Icon_bill = (p) => {
603
676
  const { size = 24, ...rest } = p;
604
677
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3098,6 +3171,7 @@ var Icon_youtube = (p) => {
3098
3171
  );
3099
3172
  };
3100
3173
  var ICONS = {
3174
+ account: Icon_account,
3101
3175
  add: Icon_add,
3102
3176
  alert: Icon_alert,
3103
3177
  alignKorean: Icon_alignKorean,
@@ -3110,6 +3184,7 @@ var ICONS = {
3110
3184
  attachFile: Icon_attachFile,
3111
3185
  barcode: Icon_barcode,
3112
3186
  bell: Icon_bell,
3187
+ bellRinging: Icon_bellRinging,
3113
3188
  bill: Icon_bill,
3114
3189
  board: Icon_board,
3115
3190
  box: Icon_box,
@@ -4260,7 +4335,7 @@ function moveWithDepth(items, fromIndex, target, getDepth, setDepth, maxDepth) {
4260
4335
  const nextDepth = target.intent === "inside" ? targetDepth + 1 : targetDepth;
4261
4336
  const depthDelta = clampDepth(nextDepth, maxDepth) - sourceDepth;
4262
4337
  const nextMovedItems = setDepth && depthDelta !== 0 ? movedItems.map(
4263
- (item3, index) => setDepth(item3, clampDepth(getDepth(item3, fromIndex + index) + depthDelta, maxDepth))
4338
+ (item4, index) => setDepth(item4, clampDepth(getDepth(item4, fromIndex + index) + depthDelta, maxDepth))
4264
4339
  ) : movedItems;
4265
4340
  return [
4266
4341
  ...remainingItems.slice(0, insertionIndex),
@@ -4308,7 +4383,7 @@ function SDraggableListInner({
4308
4383
  setDropTarget({ index, intent: "before" });
4309
4384
  }, []);
4310
4385
  const readDepth = react.useCallback(
4311
- (item3, index) => clampDepth(getDepth?.(item3, index) ?? 1, maxDepth),
4386
+ (item4, index) => clampDepth(getDepth?.(item4, index) ?? 1, maxDepth),
4312
4387
  [getDepth, maxDepth]
4313
4388
  );
4314
4389
  react.useEffect(() => {
@@ -4343,8 +4418,8 @@ function SDraggableListInner({
4343
4418
  nextDropTarget = ratio < 0.5 ? { index, intent: "before" } : { index, intent: "after" };
4344
4419
  break;
4345
4420
  }
4346
- const item3 = items[index];
4347
- const canHaveChildren = (getCanHaveChildren?.(item3, index) ?? true) && readDepth(item3, index) < maxDepth;
4421
+ const item4 = items[index];
4422
+ const canHaveChildren = (getCanHaveChildren?.(item4, index) ?? true) && readDepth(item4, index) < maxDepth;
4348
4423
  if (ratio < 0.25) {
4349
4424
  nextDropTarget = { index, intent: "before" };
4350
4425
  } else if (ratio > 0.75 || !canHaveChildren) {
@@ -4444,10 +4519,10 @@ function SDraggableListInner({
4444
4519
  "data-drag-active": dragActive || void 0,
4445
4520
  "data-draggable-group": dragContext ? dragGroup : void 0,
4446
4521
  "data-draggable-list-id": dragContext ? listId : void 0,
4447
- children: items.map((item3, index) => {
4448
- const itemKey = getKey(item3, index);
4449
- const disabled = (getDisabled?.(item3, index) ?? false) || isDescendant(items, index, draggedSubtreeStart, depthEnabled ? readDepth : void 0);
4450
- const depth = depthEnabled ? readDepth(item3, index) : 1;
4522
+ children: items.map((item4, index) => {
4523
+ const itemKey = getKey(item4, index);
4524
+ const disabled = (getDisabled?.(item4, index) ?? false) || isDescendant(items, index, draggedSubtreeStart, depthEnabled ? readDepth : void 0);
4525
+ const depth = depthEnabled ? readDepth(item4, index) : 1;
4451
4526
  const showBefore = isDropTarget && currentDropIndex === index && (dragContext || currentDropIntent === "before");
4452
4527
  const showInside = isDropTarget && currentDropIndex === index && !dragContext && depthEnabled && currentDropIntent === "inside";
4453
4528
  const showAfter = isDropTarget && (dragContext ? currentDropIndex === items.length && index === items.length - 1 : currentDropIndex === index && currentDropIntent === "after");
@@ -4501,7 +4576,7 @@ function SDraggableListInner({
4501
4576
  }
4502
4577
  }
4503
4578
  ),
4504
- renderItem(item3, index, {
4579
+ renderItem(item4, index, {
4505
4580
  onDragHandleMouseDown: (event) => {
4506
4581
  if (disabled) return;
4507
4582
  if (dragContext && dragGroup && listId) {
@@ -5074,7 +5149,7 @@ function SGhostButton({
5074
5149
  const contentColor = disabled ? intent === "inverse" ? "var(--cmp-ghostButton-inverse-disabled)" : "var(--cmp-ghostButton-icon-disabled)" : `var(--cmp-ghostButton-${intent}-content)`;
5075
5150
  const text = (tooltipText ?? "").trim();
5076
5151
  const hasTooltip = text !== "";
5077
- const btn = /* @__PURE__ */ jsxRuntime.jsxs(
5152
+ const btn2 = /* @__PURE__ */ jsxRuntime.jsxs(
5078
5153
  "button",
5079
5154
  {
5080
5155
  type: "button",
@@ -5116,7 +5191,7 @@ function SGhostButton({
5116
5191
  ]
5117
5192
  }
5118
5193
  );
5119
- if (!hasTooltip) return btn;
5194
+ if (!hasTooltip) return btn2;
5120
5195
  return /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open, onOpenChange: setOpen, children: [
5121
5196
  /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
5122
5197
  "span",
@@ -5127,7 +5202,7 @@ function SGhostButton({
5127
5202
  onMouseLeave: startHide,
5128
5203
  onFocus: openNow,
5129
5204
  onBlur: startHide,
5130
- children: btn
5205
+ children: btn2
5131
5206
  }
5132
5207
  ) }),
5133
5208
  /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -5426,7 +5501,7 @@ var STreeImpl = /* @__PURE__ */ react.forwardRef(function STree({
5426
5501
  }, ref) {
5427
5502
  const [internalValue, setInternalValue] = react.useState(defaultValue ?? []);
5428
5503
  const [internalExpandedIds, setInternalExpandedIds] = react.useState(
5429
- defaultExpandedIds ?? items.filter((item3) => item3.children?.length).map((item3) => item3.id)
5504
+ defaultExpandedIds ?? items.filter((item4) => item4.children?.length).map((item4) => item4.id)
5430
5505
  );
5431
5506
  const currentValue = value ?? internalValue;
5432
5507
  const currentExpandedIds = expandedIds ?? internalExpandedIds;
@@ -6810,6 +6885,456 @@ function SSwitch({
6810
6885
  );
6811
6886
  }
6812
6887
 
6888
+ // src/lib/is-dev.ts
6889
+ function isDev() {
6890
+ return typeof process === "undefined" || process?.env?.NODE_ENV !== "production";
6891
+ }
6892
+ function SPortal({
6893
+ open,
6894
+ onClose,
6895
+ onOpenChange,
6896
+ anchorRef,
6897
+ placement = "bottom",
6898
+ align = "start",
6899
+ offset = 4,
6900
+ alignOffset = 0,
6901
+ fit = false,
6902
+ maxHeight,
6903
+ autoClose = false,
6904
+ persistent = false,
6905
+ viewportPadding = 0,
6906
+ onOpenAutoFocus,
6907
+ onCloseAutoFocus,
6908
+ onPointerDownOutside,
6909
+ children,
6910
+ className,
6911
+ style,
6912
+ ariaLabel
6913
+ }) {
6914
+ const portalContainer = usePortalContainer();
6915
+ const { minWidth: styleMinWidth, maxWidth: styleMaxWidth, ...restStyle } = style ?? {};
6916
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6917
+ RPopover11__namespace.Root,
6918
+ {
6919
+ open,
6920
+ onOpenChange: (next) => {
6921
+ onOpenChange?.(next);
6922
+ if (!next) onClose?.();
6923
+ },
6924
+ children: [
6925
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Anchor, { virtualRef: anchorRef }),
6926
+ /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
6927
+ RPopover11__namespace.Content,
6928
+ {
6929
+ side: placement,
6930
+ align,
6931
+ sideOffset: offset,
6932
+ alignOffset,
6933
+ collisionPadding: viewportPadding,
6934
+ "aria-label": ariaLabel,
6935
+ onPointerDownOutside: (e) => {
6936
+ if (persistent || anchorRef.current?.contains(e.target)) {
6937
+ e.preventDefault();
6938
+ return;
6939
+ }
6940
+ onPointerDownOutside?.(e);
6941
+ },
6942
+ onFocusOutside: (e) => {
6943
+ if (persistent || anchorRef.current?.contains(e.target)) {
6944
+ e.preventDefault();
6945
+ }
6946
+ },
6947
+ onEscapeKeyDown: persistent ? (e) => e.preventDefault() : void 0,
6948
+ onOpenAutoFocus,
6949
+ onCloseAutoFocus,
6950
+ onClick: autoClose ? () => onClose?.() : void 0,
6951
+ className: cn(
6952
+ "z-50 overflow-hidden rounded-(--cmp-listBox-radius) bg-(--cmp-listBox-bg) shadow-normal-sm",
6953
+ maxHeight != null && "overflow-y-auto",
6954
+ // 앵커가 창보다 넓을 수 있는 자리(가로 스크롤 안의 트리거 등)에서도 하한이 상한을
6955
+ // 이기지 않도록, 앵커 너비 역시 가용 폭으로 가둔다.
6956
+ fit && "min-w-[min(var(--radix-popover-trigger-width),var(--radix-popover-content-available-width))]",
6957
+ FLOATING_SLIDE_ANIM,
6958
+ className
6959
+ ),
6960
+ style: {
6961
+ maxHeight,
6962
+ ...restStyle,
6963
+ ...styleMinWidth != null ? { minWidth: clampToAvailableWidth(styleMinWidth, POPOVER_AVAILABLE_WIDTH) } : {},
6964
+ maxWidth: clampToAvailableWidth(styleMaxWidth, POPOVER_AVAILABLE_WIDTH)
6965
+ },
6966
+ children
6967
+ }
6968
+ ) })
6969
+ ]
6970
+ }
6971
+ );
6972
+ }
6973
+
6974
+ // src/components/SAccountListBox/accountListBox.config.ts
6975
+ var box = (p) => `var(--cmp-gnb-system-accountListBox-${p})`;
6976
+ var btn = (p) => `var(--cmp-gnb-system-accountButton-${p})`;
6977
+ var item = (p) => `var(--cmp-listBoxItem-${p})`;
6978
+ var sys = (p) => `var(--sys-color-${p})`;
6979
+ var ACCOUNT_LIST_BOX_ITEM_TONES = ["default", "negative"];
6980
+ var ACCOUNT_LIST_BOX_ICONS = {
6981
+ accountSetting: "account",
6982
+ language: "global",
6983
+ logout: "logout"
6984
+ };
6985
+ var ACCOUNT_LIST_BOX_LABELS = {
6986
+ accountSetting: "\uACC4\uC815 \uC124\uC815",
6987
+ language: "\uC5B8\uC5B4 \uBCC0\uACBD",
6988
+ logout: "\uACC4\uC815 \uB85C\uADF8\uC544\uC6C3"
6989
+ };
6990
+ var ACCOUNT_LIST_BOX_TONE_CONFIG = {
6991
+ default: {
6992
+ bg: btn("bg-default"),
6993
+ bgHover: btn("bg-hover"),
6994
+ text: btn("content-default"),
6995
+ // TODO: 행 아이콘 전용 색 토큰이 없다. content.default 는 글자색(#222222)이고
6996
+ // 시안의 아이콘은 한 단계 물러난 #555555 라, 그에 맞는 시맨틱 토큰으로 둔다.
6997
+ icon: sys("fg-secondary")
6998
+ },
6999
+ negative: {
7000
+ bg: btn("bg-default"),
7001
+ bgHover: btn("bg-negativeHover"),
7002
+ // 되돌릴 수 없는 행은 글자와 아이콘이 같은 경고색으로 함께 물든다(시안).
7003
+ text: btn("content-negative"),
7004
+ icon: btn("content-negative")
7005
+ }
7006
+ };
7007
+ var ACCOUNT_LIST_BOX_LAYOUT = {
7008
+ /** 패널 고정 폭 */
7009
+ width: box("width"),
7010
+ /** 패널 배경 */
7011
+ bg: box("bg"),
7012
+ /** 패널 라운드 */
7013
+ radius: box("radius"),
7014
+ /** 사용자정보 영역 배경 */
7015
+ userdataBg: box("userdata-bg"),
7016
+ /** 사용자정보 영역 좌우 여백 */
7017
+ userdataPaddingX: box("userdata-paddingX"),
7018
+ /** 사용자정보 영역 상하 여백 */
7019
+ userdataPaddingY: box("userdata-paddingY"),
7020
+ /** 이메일 글자색 */
7021
+ emailColor: box("userdata-email-color"),
7022
+ /** 이름 글자색 */
7023
+ nameColor: box("userdata-name-color"),
7024
+ /** 권한 글자색 */
7025
+ roleColor: box("userdata-role-color"),
7026
+ /** 행 묶음의 상하 여백 */
7027
+ listPaddingY: box("list-paddingY"),
7028
+ /** 행 좌우 여백 */
7029
+ itemPaddingX: btn("paddingX"),
7030
+ /** 행 상하 여백 */
7031
+ itemPaddingY: btn("paddingY"),
7032
+ /** 행 아이콘 ↔ 라벨 간격 */
7033
+ itemGap: btn("gap"),
7034
+ /** 행 아이콘 크기 */
7035
+ itemIcon: btn("icon"),
7036
+ /** 우측 값 ↔ 화살표 간격 */
7037
+ selectDataGap: btn("selectData-gap"),
7038
+ /** 우측 화살표 크기 */
7039
+ selectDataIcon: btn("selectData-icon"),
7040
+ /** 우측 값 글자색 */
7041
+ selectDataText: btn("selectData-text"),
7042
+ /** 시스템 메뉴에서 지금 값인 칸의 글자색 — 계정 행이 아니라 목록 항목이라
7043
+ * listBoxItem 의 선택 색을 그대로 따른다(다른 목록의 선택 표시와 같은 색) */
7044
+ menuSelectedText: item("content-selected"),
7045
+ // TODO: 우측 화살표 전용 색 토큰이 없다. 시안(#888888)에 맞는 시맨틱 토큰으로 둔다.
7046
+ /** 우측 화살표색 */
7047
+ selectDataIconColor: sys("fg-tertiary")
7048
+ };
7049
+ function SystemMenuPortal({
7050
+ open,
7051
+ onOpenChange,
7052
+ anchorRef,
7053
+ placement = "bottom",
7054
+ align,
7055
+ triggerRef,
7056
+ ariaLabel,
7057
+ value,
7058
+ options,
7059
+ onSelect
7060
+ }) {
7061
+ const t = ACCOUNT_LIST_BOX_TONE_CONFIG.default;
7062
+ return /* @__PURE__ */ jsxRuntime.jsx(
7063
+ SPortal,
7064
+ {
7065
+ open,
7066
+ onClose: () => onOpenChange(false),
7067
+ anchorRef,
7068
+ placement,
7069
+ align,
7070
+ offset: 4,
7071
+ viewportPadding: 8,
7072
+ ariaLabel,
7073
+ onPointerDownOutside: (event) => {
7074
+ if (triggerRef?.current?.contains(event.target)) event.preventDefault();
7075
+ },
7076
+ onOpenAutoFocus: (event) => event.preventDefault(),
7077
+ className: "w-auto min-w-[100px] rounded-(--cmp-gnb-system-accountListBox-radius) bg-(--cmp-gnb-system-accountListBox-bg)",
7078
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { role: "menu", className: "flex flex-col", style: { paddingBlock: ACCOUNT_LIST_BOX_LAYOUT.listPaddingY }, children: options.map((option) => {
7079
+ const selected = option.value === value;
7080
+ const color = option.color ? `var(--cmp-tag-${option.color}-content)` : selected ? ACCOUNT_LIST_BOX_LAYOUT.menuSelectedText : t.text;
7081
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7082
+ "button",
7083
+ {
7084
+ type: "button",
7085
+ role: "menuitemradio",
7086
+ "aria-checked": selected,
7087
+ onClick: () => onSelect(option.value),
7088
+ className: cn(
7089
+ selected ? "typo-field-sm-bold" : "typo-field-sm-medium",
7090
+ "flex w-full cursor-pointer items-center whitespace-nowrap border-none bg-(--alb-bg) text-left transition-colors hover:bg-(--alb-bg-hover)"
7091
+ ),
7092
+ style: {
7093
+ "--alb-bg": t.bg,
7094
+ "--alb-bg-hover": t.bgHover,
7095
+ "paddingInline": ACCOUNT_LIST_BOX_LAYOUT.itemPaddingX,
7096
+ "paddingBlock": ACCOUNT_LIST_BOX_LAYOUT.itemPaddingY,
7097
+ "gap": ACCOUNT_LIST_BOX_LAYOUT.itemGap,
7098
+ color
7099
+ },
7100
+ children: [
7101
+ option.color && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center", children: /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "dot", size: "100%", style: { width: ACCOUNT_LIST_BOX_LAYOUT.itemIcon, height: ACCOUNT_LIST_BOX_LAYOUT.itemIcon } }) }),
7102
+ option.label
7103
+ ]
7104
+ },
7105
+ option.value
7106
+ );
7107
+ }) })
7108
+ }
7109
+ );
7110
+ }
7111
+ function TokenIcon({ name, size }) {
7112
+ return /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name, size: "100%", style: { width: size, height: size } });
7113
+ }
7114
+ function Row({
7115
+ tone = "default",
7116
+ icon,
7117
+ label,
7118
+ value,
7119
+ trailingRef,
7120
+ rowRef,
7121
+ hasMenu,
7122
+ expanded,
7123
+ onClick
7124
+ }) {
7125
+ const t = ACCOUNT_LIST_BOX_TONE_CONFIG[tone];
7126
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7127
+ "button",
7128
+ {
7129
+ ref: rowRef,
7130
+ type: "button",
7131
+ "aria-haspopup": hasMenu && "menu",
7132
+ "aria-expanded": hasMenu && expanded,
7133
+ onClick,
7134
+ className: "flex w-full cursor-pointer items-center border-none bg-(--alb-bg) text-left transition-colors hover:bg-(--alb-bg-hover)",
7135
+ style: {
7136
+ "--alb-bg": t.bg,
7137
+ "--alb-bg-hover": t.bgHover,
7138
+ "paddingInline": ACCOUNT_LIST_BOX_LAYOUT.itemPaddingX,
7139
+ "paddingBlock": ACCOUNT_LIST_BOX_LAYOUT.itemPaddingY,
7140
+ "gap": ACCOUNT_LIST_BOX_LAYOUT.itemGap
7141
+ },
7142
+ children: [
7143
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center", style: { color: t.icon }, children: /* @__PURE__ */ jsxRuntime.jsx(TokenIcon, { name: icon, size: ACCOUNT_LIST_BOX_LAYOUT.itemIcon }) }),
7144
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-field-sm-medium min-w-0 flex-1 truncate", style: { color: t.text }, children: label }),
7145
+ (value != null || hasMenu) && /* @__PURE__ */ jsxRuntime.jsxs(
7146
+ "span",
7147
+ {
7148
+ ref: trailingRef,
7149
+ className: "inline-flex shrink-0 items-center",
7150
+ style: { gap: ACCOUNT_LIST_BOX_LAYOUT.selectDataGap },
7151
+ children: [
7152
+ value != null && /* @__PURE__ */ jsxRuntime.jsx(
7153
+ "span",
7154
+ {
7155
+ className: "typo-control-xs-medium whitespace-nowrap",
7156
+ style: { color: ACCOUNT_LIST_BOX_LAYOUT.selectDataText },
7157
+ children: value
7158
+ }
7159
+ ),
7160
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0", style: { color: ACCOUNT_LIST_BOX_LAYOUT.selectDataIconColor }, children: /* @__PURE__ */ jsxRuntime.jsx(TokenIcon, { name: "chevronRight", size: ACCOUNT_LIST_BOX_LAYOUT.selectDataIcon }) })
7161
+ ]
7162
+ }
7163
+ )
7164
+ ]
7165
+ }
7166
+ );
7167
+ }
7168
+ var SAccountListBox = /* @__PURE__ */ react.forwardRef(
7169
+ function SAccountListBox2({ email, name, authority, accountSetting, language, logout, className, style, ...rest }, ref) {
7170
+ const hasUserdata = email != null || name != null || authority != null;
7171
+ const languageOptions = language?.options ?? [];
7172
+ const hasLanguageMenu = languageOptions.length > 0;
7173
+ const [languageMenuOpen, setLanguageMenuOpen] = react.useState(false);
7174
+ const languageValueRef = react.useRef(null);
7175
+ const languageRowRef = react.useRef(null);
7176
+ const languageLabel = language?.label ?? ACCOUNT_LIST_BOX_LABELS.language;
7177
+ const languageDoesNothing = Boolean(language) && !hasLanguageMenu && !language?.onClick;
7178
+ react.useEffect(() => {
7179
+ if (isDev() && languageDoesNothing) {
7180
+ console.warn(
7181
+ "[SAccountListBox] language \uC5D0 options \uB3C4 onClick \uB3C4 \uC5C6\uC2B5\uB2C8\uB2E4. \uC571 \uC548\uC5D0\uC11C \uACE0\uB974\uAC8C \uD558\uB824\uBA74 options \uB97C, \uC5B8\uC5B4 \uD654\uBA74\uC73C\uB85C \uBCF4\uB0BC \uAC83\uC774\uBA74 onClick \uC744 \uC8FC\uC138\uC694 \u2014 \uB458 \uB2E4 \uC5C6\uC73C\uBA74 \uD654\uC0B4\uD45C\uB9CC \uC788\uACE0 \uB20C\uB7EC\uB3C4 \uC544\uBB34 \uC77C\uC774 \uC5C6\uB294 \uD589\uC774 \uB429\uB2C8\uB2E4."
7182
+ );
7183
+ }
7184
+ }, [languageDoesNothing]);
7185
+ const languageText = languageOptions.find((option) => option.value === language?.value)?.label ?? language?.value;
7186
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7187
+ "div",
7188
+ {
7189
+ ref,
7190
+ className: cn("box-border flex flex-col overflow-hidden", className),
7191
+ style: {
7192
+ width: ACCOUNT_LIST_BOX_LAYOUT.width,
7193
+ backgroundColor: ACCOUNT_LIST_BOX_LAYOUT.bg,
7194
+ borderRadius: ACCOUNT_LIST_BOX_LAYOUT.radius,
7195
+ ...style
7196
+ },
7197
+ ...rest,
7198
+ children: [
7199
+ hasUserdata && /* @__PURE__ */ jsxRuntime.jsxs(
7200
+ "div",
7201
+ {
7202
+ className: "flex flex-col",
7203
+ style: {
7204
+ backgroundColor: ACCOUNT_LIST_BOX_LAYOUT.userdataBg,
7205
+ paddingInline: ACCOUNT_LIST_BOX_LAYOUT.userdataPaddingX,
7206
+ paddingBlock: ACCOUNT_LIST_BOX_LAYOUT.userdataPaddingY
7207
+ },
7208
+ children: [
7209
+ email != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-medium truncate", style: { color: ACCOUNT_LIST_BOX_LAYOUT.emailColor }, children: email }),
7210
+ (name != null || authority != null) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", style: { gap: ACCOUNT_LIST_BOX_LAYOUT.itemGap }, children: [
7211
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-bold min-w-0 truncate", style: { color: ACCOUNT_LIST_BOX_LAYOUT.nameColor }, children: name }),
7212
+ authority != null && /* @__PURE__ */ jsxRuntime.jsx(
7213
+ "span",
7214
+ {
7215
+ className: "typo-body-sm-medium shrink-0 whitespace-nowrap",
7216
+ style: { color: ACCOUNT_LIST_BOX_LAYOUT.roleColor },
7217
+ children: authority
7218
+ }
7219
+ )
7220
+ ] })
7221
+ ]
7222
+ }
7223
+ ),
7224
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", style: { paddingBlock: ACCOUNT_LIST_BOX_LAYOUT.listPaddingY }, children: [
7225
+ accountSetting && /* @__PURE__ */ jsxRuntime.jsx(
7226
+ Row,
7227
+ {
7228
+ icon: ACCOUNT_LIST_BOX_ICONS.accountSetting,
7229
+ label: accountSetting.label ?? ACCOUNT_LIST_BOX_LABELS.accountSetting,
7230
+ onClick: accountSetting.onClick
7231
+ }
7232
+ ),
7233
+ language && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7234
+ /* @__PURE__ */ jsxRuntime.jsx(
7235
+ Row,
7236
+ {
7237
+ icon: ACCOUNT_LIST_BOX_ICONS.language,
7238
+ label: languageLabel,
7239
+ value: languageText,
7240
+ trailingRef: languageValueRef,
7241
+ rowRef: languageRowRef,
7242
+ hasMenu: hasLanguageMenu,
7243
+ expanded: languageMenuOpen,
7244
+ onClick: () => {
7245
+ language.onClick?.();
7246
+ if (hasLanguageMenu) setLanguageMenuOpen((open) => !open);
7247
+ }
7248
+ }
7249
+ ),
7250
+ hasLanguageMenu && /* @__PURE__ */ jsxRuntime.jsx(
7251
+ SystemMenuPortal,
7252
+ {
7253
+ open: languageMenuOpen,
7254
+ onOpenChange: setLanguageMenuOpen,
7255
+ anchorRef: languageValueRef,
7256
+ triggerRef: languageRowRef,
7257
+ align: "end",
7258
+ ariaLabel: languageLabel,
7259
+ value: language.value,
7260
+ options: languageOptions,
7261
+ onSelect: (next) => {
7262
+ setLanguageMenuOpen(false);
7263
+ language.onChange?.(next);
7264
+ }
7265
+ }
7266
+ )
7267
+ ] }),
7268
+ /* @__PURE__ */ jsxRuntime.jsx(
7269
+ Row,
7270
+ {
7271
+ tone: "negative",
7272
+ icon: ACCOUNT_LIST_BOX_ICONS.logout,
7273
+ label: logout?.label ?? ACCOUNT_LIST_BOX_LABELS.logout,
7274
+ onClick: logout?.onClick
7275
+ }
7276
+ )
7277
+ ] })
7278
+ ]
7279
+ }
7280
+ );
7281
+ }
7282
+ );
7283
+ var AccountListBoxAnchorContext = /* @__PURE__ */ react.createContext("panel");
7284
+ var AccountListBoxAnchorProvider = AccountListBoxAnchorContext.Provider;
7285
+ var ANCHOR_PLACEMENT = {
7286
+ // 판: 계정 행 위로, 행의 왼쪽 끝에 맞춰
7287
+ panel: { placement: "top", align: "start" },
7288
+ // 상단바: 계정 이름 아래로, 이름의 오른쪽 끝에 맞춰
7289
+ top: { placement: "bottom", align: "end" }
7290
+ };
7291
+ function AccountListBoxPortal({
7292
+ open,
7293
+ onOpenChange,
7294
+ anchorRef,
7295
+ ariaLabel,
7296
+ content
7297
+ }) {
7298
+ const { placement, align } = ANCHOR_PLACEMENT[react.useContext(AccountListBoxAnchorContext)];
7299
+ const closeAfter = (item4) => item4 && {
7300
+ ...item4,
7301
+ onClick: () => {
7302
+ item4.onClick?.();
7303
+ onOpenChange(false);
7304
+ }
7305
+ };
7306
+ return /* @__PURE__ */ jsxRuntime.jsx(
7307
+ SPortal,
7308
+ {
7309
+ open,
7310
+ onClose: () => onOpenChange(false),
7311
+ anchorRef,
7312
+ placement,
7313
+ align,
7314
+ offset: 4,
7315
+ viewportPadding: 8,
7316
+ ariaLabel,
7317
+ onOpenAutoFocus: (event) => event.preventDefault(),
7318
+ className: "w-auto rounded-(--cmp-gnb-system-accountListBox-radius) bg-(--cmp-gnb-system-accountListBox-bg)",
7319
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7320
+ SAccountListBox,
7321
+ {
7322
+ ...content,
7323
+ accountSetting: closeAfter(content.accountSetting),
7324
+ language: content.language && (content.language.options?.length ? {
7325
+ ...content.language,
7326
+ onChange: (next) => {
7327
+ content.language?.onChange?.(next);
7328
+ onOpenChange(false);
7329
+ }
7330
+ } : closeAfter(content.language)),
7331
+ logout: closeAfter(content.logout) ?? { onClick: () => onOpenChange(false) }
7332
+ }
7333
+ )
7334
+ }
7335
+ );
7336
+ }
7337
+
6813
7338
  // src/components/SSystemActionButton/systemActionButton.config.ts
6814
7339
  var SYSTEM_ACTION_BUTTON_COLORS = ["light", "dark", "darker"];
6815
7340
  var SYSTEM_ACTION_BUTTON_TYPES = [
@@ -6819,57 +7344,57 @@ var SYSTEM_ACTION_BUTTON_TYPES = [
6819
7344
  "subSelect",
6820
7345
  "status"
6821
7346
  ];
6822
- var item = (p) => `var(--cmp-gnb-system-item-${p})`;
7347
+ var item2 = (p) => `var(--cmp-gnb-system-item-${p})`;
6823
7348
  var action = (p) => `var(--cmp-gnb-system-actionButton-${p})`;
6824
- var sys = (p) => `var(--sys-color-${p})`;
7349
+ var sys2 = (p) => `var(--sys-color-${p})`;
6825
7350
  var SYSTEM_ACTION_BUTTON_COLOR_CONFIG = {
6826
7351
  light: {
6827
- bg: item("light-bg-default"),
6828
- bgHover: item("light-bg-hover"),
7352
+ bg: item2("light-bg-default"),
7353
+ bgHover: item2("light-bg-hover"),
6829
7354
  // light 의 아이콘 프레임 배경은 기본·hover 공통 한 값이다 (흰 면 위 흰 프레임)
6830
- iconBg: item("light-icon-bg"),
6831
- iconBgHover: item("light-icon-bg"),
6832
- iconGlyph: item("light-icon-default"),
6833
- iconGlyphHover: item("light-icon-default"),
6834
- text: item("light-text"),
7355
+ iconBg: item2("light-icon-bg"),
7356
+ iconBgHover: item2("light-icon-bg"),
7357
+ iconGlyph: item2("light-icon-default"),
7358
+ iconGlyphHover: item2("light-icon-default"),
7359
+ text: item2("light-text"),
6835
7360
  actionText: {
6836
7361
  switch: action("switch-text-light"),
6837
7362
  selectData: action("selectData-text-light")
6838
7363
  },
6839
7364
  // 트레일링 아이콘 전용 색 토큰이 없다. light 는 item.icon.default 가
6840
7365
  // "actionButton/alertButton/setting 공통 글리프색"이라고 토큰에 명시돼 있다.
6841
- actionIcon: item("light-icon-default")
7366
+ actionIcon: item2("light-icon-default")
6842
7367
  },
6843
7368
  dark: {
6844
- bg: item("dark-bg-default"),
6845
- bgHover: item("dark-bg-hover"),
6846
- iconBg: item("dark-icon-bg-default"),
6847
- iconBgHover: item("dark-icon-bg-hover"),
7369
+ bg: item2("dark-bg-default"),
7370
+ bgHover: item2("dark-bg-hover"),
7371
+ iconBg: item2("dark-icon-bg-default"),
7372
+ iconBgHover: item2("dark-icon-bg-hover"),
6848
7373
  // 어두운 면에는 글리프색 토큰이 없다. 기본은 프레임이 배경과 블렌딩되므로 라벨색(흰색),
6849
7374
  // hover 는 프레임이 흰색이 되므로 그 위에 표면색을 그대로 얹는다.
6850
- iconGlyph: item("dark-text"),
6851
- iconGlyphHover: item("dark-bg-hover"),
6852
- text: item("dark-text"),
7375
+ iconGlyph: item2("dark-text"),
7376
+ iconGlyphHover: item2("dark-bg-hover"),
7377
+ text: item2("dark-text"),
6853
7378
  actionText: {
6854
7379
  switch: action("switch-text-dark"),
6855
7380
  selectData: action("selectData-text-dark")
6856
7381
  },
6857
7382
  // TODO: 어두운 면의 트레일링 아이콘 색 토큰이 없다. 시안(#AAAAAA)에 맞는 시맨틱 토큰으로 둔다.
6858
- actionIcon: sys("fg-quaternary")
7383
+ actionIcon: sys2("fg-quaternary")
6859
7384
  },
6860
7385
  darker: {
6861
- bg: item("darker-bg-default"),
6862
- bgHover: item("darker-bg-hover"),
6863
- iconBg: item("darker-icon-bg-default"),
6864
- iconBgHover: item("darker-icon-bg-hover"),
6865
- iconGlyph: item("darker-text"),
6866
- iconGlyphHover: item("darker-bg-hover"),
6867
- text: item("darker-text"),
7386
+ bg: item2("darker-bg-default"),
7387
+ bgHover: item2("darker-bg-hover"),
7388
+ iconBg: item2("darker-icon-bg-default"),
7389
+ iconBgHover: item2("darker-icon-bg-hover"),
7390
+ iconGlyph: item2("darker-text"),
7391
+ iconGlyphHover: item2("darker-bg-hover"),
7392
+ text: item2("darker-text"),
6868
7393
  actionText: {
6869
7394
  switch: action("switch-text-dark"),
6870
7395
  selectData: action("selectData-text-dark")
6871
7396
  },
6872
- actionIcon: sys("fg-quaternary")
7397
+ actionIcon: sys2("fg-quaternary")
6873
7398
  }
6874
7399
  };
6875
7400
  var SYSTEM_ACTION_BUTTON_TYPE_CONFIG = {
@@ -6892,17 +7417,17 @@ var SYSTEM_ACTION_BUTTON_TYPE_CONFIG = {
6892
7417
  };
6893
7418
  var SYSTEM_ACTION_BUTTON_LAYOUT = {
6894
7419
  /** 행 높이 */
6895
- height: item("height"),
7420
+ height: item2("height"),
6896
7421
  /** 행 라운드 */
6897
- radius: item("radius"),
7422
+ radius: item2("radius"),
6898
7423
  /** 아이콘 프레임 한 변 */
6899
- iconFrame: item("icon-frame"),
7424
+ iconFrame: item2("icon-frame"),
6900
7425
  /** 아이콘 글리프 크기 */
6901
- iconGlyph: item("icon-glyph"),
7426
+ iconGlyph: item2("icon-glyph"),
6902
7427
  /** 아이콘 프레임 라운드 */
6903
- iconRadius: item("icon-radius"),
7428
+ iconRadius: item2("icon-radius"),
6904
7429
  /** 아이콘 프레임 ↔ 라벨 간격 */
6905
- iconLabelGap: item("iconLabelGap"),
7430
+ iconLabelGap: item2("iconLabelGap"),
6906
7431
  /** 좌측 여백 */
6907
7432
  paddingLeft: action("paddingLeft"),
6908
7433
  /** 우측 여백 */
@@ -6910,17 +7435,44 @@ var SYSTEM_ACTION_BUTTON_LAYOUT = {
6910
7435
  /** 액션 텍스트 ↔ 액션 아이콘 간격 */
6911
7436
  actionGap: action("selectData-gap")
6912
7437
  };
6913
- function TokenIcon({ name, size }) {
7438
+ function TokenIcon2({ name, size }) {
6914
7439
  return /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name, size: "100%", style: { width: size, height: size } });
6915
7440
  }
6916
7441
  var SSystemActionButton = /* @__PURE__ */ react.forwardRef(
6917
7442
  function SSystemActionButton2({ color = "light", type, label, option, disabled = false, className, style, ...rest }, ref) {
6918
7443
  const c = SYSTEM_ACTION_BUTTON_COLOR_CONFIG[color];
6919
7444
  const spec = SYSTEM_ACTION_BUTTON_TYPE_CONFIG[type];
7445
+ const listBox = type === "account" ? option ?? {} : void 0;
7446
+ const [uncontrolledOpen, setUncontrolledOpen] = react.useState(false);
7447
+ const listBoxOpen = listBox?.open ?? uncontrolledOpen;
7448
+ const commitListBoxOpen = (next) => {
7449
+ setUncontrolledOpen(next);
7450
+ listBox?.onOpenChange?.(next);
7451
+ };
7452
+ const anchorRef = react.useRef(null);
7453
+ const setRefs2 = (node) => {
7454
+ anchorRef.current = node;
7455
+ if (typeof ref === "function") ref(node);
7456
+ else if (ref) ref.current = node;
7457
+ };
6920
7458
  const hoverable = !disabled;
6921
7459
  const status = type === "status" ? option : void 0;
7460
+ const subSelect = type === "subSelect" ? option : void 0;
7461
+ const menu = subSelect ?? status;
7462
+ const menuOptions = menu?.options ?? [];
7463
+ const hasMenu = menuOptions.length > 0;
7464
+ const [menuOpen, setMenuOpen] = react.useState(false);
7465
+ const selected = menuOptions.find((item4) => item4.value === menu?.value);
6922
7466
  const resolvedIcon = spec.fixedIcon ?? option?.icon;
6923
- const actionText = spec.actionText ? option?.text : void 0;
7467
+ const actionText = spec.actionText ? subSelect ? selected?.label ?? subSelect.value : option?.text : void 0;
7468
+ const menuIsEmpty = Boolean(menu) && !hasMenu;
7469
+ react.useEffect(() => {
7470
+ if (isDev() && menuIsEmpty) {
7471
+ console.warn(
7472
+ `[SSystemActionButton] type="${type}" \uC758 option.options \uAC00 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4. \uC774 \uD589\uC740 \uACE0\uB978 \uAC12\uC744 \uBC14\uAFB8\uB294 \uBA54\uB274\uC758 \uD2B8\uB9AC\uAC70\uC774\uBBC0\uB85C \uACE0\uB97C \uBAA9\uB85D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4 \u2014 \uB20C\uB7EC\uC11C \uD654\uBA74\uC73C\uB85C \uBCF4\uB0BC \uAC83\uC774\uBA74 type="select" \uB97C, \uBCF4\uC5EC\uC8FC\uAE30\uB9CC \uD560 \uAC83\uC774\uBA74 STag \uB97C \uC4F0\uC138\uC694.`
7473
+ );
7474
+ }
7475
+ }, [menuIsEmpty, type]);
6924
7476
  const cssVars = {
6925
7477
  "--sab-bg": c.bg,
6926
7478
  "--sab-bg-hover": hoverable ? c.bgHover : c.bg,
@@ -6938,12 +7490,14 @@ var SSystemActionButton = /* @__PURE__ */ react.forwardRef(
6938
7490
  "gap": SYSTEM_ACTION_BUTTON_LAYOUT.iconLabelGap,
6939
7491
  ...style
6940
7492
  };
6941
- return /* @__PURE__ */ jsxRuntime.jsxs(
7493
+ const button = /* @__PURE__ */ jsxRuntime.jsxs(
6942
7494
  "button",
6943
7495
  {
6944
- ref,
7496
+ ref: setRefs2,
6945
7497
  type: "button",
6946
7498
  disabled,
7499
+ "aria-haspopup": listBox ? "dialog" : hasMenu ? "menu" : void 0,
7500
+ "aria-expanded": listBox ? listBoxOpen : hasMenu ? menuOpen : void 0,
6947
7501
  className: cn(
6948
7502
  "group box-border flex w-full items-center border-none bg-(--sab-bg) text-left transition-colors",
6949
7503
  "hover:bg-(--sab-bg-hover)",
@@ -6952,16 +7506,28 @@ var SSystemActionButton = /* @__PURE__ */ react.forwardRef(
6952
7506
  ),
6953
7507
  style: cssVars,
6954
7508
  ...rest,
7509
+ onClick: (event) => {
7510
+ rest.onClick?.(event);
7511
+ if (listBox) commitListBoxOpen(!listBoxOpen);
7512
+ else if (hasMenu) setMenuOpen((open) => !open);
7513
+ },
6955
7514
  children: [
6956
7515
  resolvedIcon && /* @__PURE__ */ jsxRuntime.jsx(
6957
7516
  "span",
6958
7517
  {
6959
7518
  className: "inline-flex shrink-0 items-center justify-center bg-(--sab-icon-bg) text-(--sab-icon-glyph) transition-colors group-hover:bg-(--sab-icon-bg-hover) group-hover:text-(--sab-icon-glyph-hover)",
6960
7519
  style: { width: SYSTEM_ACTION_BUTTON_LAYOUT.iconFrame, height: SYSTEM_ACTION_BUTTON_LAYOUT.iconFrame, borderRadius: SYSTEM_ACTION_BUTTON_LAYOUT.iconRadius },
6961
- children: /* @__PURE__ */ jsxRuntime.jsx(TokenIcon, { name: resolvedIcon, size: SYSTEM_ACTION_BUTTON_LAYOUT.iconGlyph })
7520
+ children: /* @__PURE__ */ jsxRuntime.jsx(TokenIcon2, { name: resolvedIcon, size: SYSTEM_ACTION_BUTTON_LAYOUT.iconGlyph })
6962
7521
  }
6963
7522
  ),
6964
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-semibold flex min-w-0 flex-1 items-center text-(--sab-text)", children: status ? /* @__PURE__ */ jsxRuntime.jsx(STag, { color: status.color ?? "blue", icon: "dot", label: status.label }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: label }) }),
7523
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typo-body-sm-semibold flex min-w-0 flex-1 items-center text-(--sab-text)", children: status ? /* @__PURE__ */ jsxRuntime.jsx(
7524
+ STag,
7525
+ {
7526
+ color: selected?.color ?? "blue",
7527
+ icon: "dot",
7528
+ label: selected?.label ?? status.value
7529
+ }
7530
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: label }) }),
6965
7531
  (actionText != null || spec.actionIcon) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex shrink-0 items-center", style: { gap: SYSTEM_ACTION_BUTTON_LAYOUT.actionGap }, children: [
6966
7532
  actionText != null && spec.actionText && /* @__PURE__ */ jsxRuntime.jsx(
6967
7533
  "span",
@@ -6970,11 +7536,48 @@ var SSystemActionButton = /* @__PURE__ */ react.forwardRef(
6970
7536
  children: actionText
6971
7537
  }
6972
7538
  ),
6973
- spec.actionIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center text-(--sab-action-icon)", children: /* @__PURE__ */ jsxRuntime.jsx(TokenIcon, { name: spec.actionIcon.name, size: spec.actionIcon.size }) })
7539
+ spec.actionIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center text-(--sab-action-icon)", children: /* @__PURE__ */ jsxRuntime.jsx(TokenIcon2, { name: spec.actionIcon.name, size: spec.actionIcon.size }) })
6974
7540
  ] })
6975
7541
  ]
6976
7542
  }
6977
7543
  );
7544
+ if (!listBox) {
7545
+ if (!hasMenu) return button;
7546
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7547
+ button,
7548
+ /* @__PURE__ */ jsxRuntime.jsx(
7549
+ SystemMenuPortal,
7550
+ {
7551
+ open: menuOpen,
7552
+ onOpenChange: setMenuOpen,
7553
+ anchorRef,
7554
+ placement: "right",
7555
+ align: "start",
7556
+ ariaLabel: label ?? selected?.label ?? menu?.value,
7557
+ value: menu?.value,
7558
+ options: menuOptions,
7559
+ onSelect: (next) => {
7560
+ setMenuOpen(false);
7561
+ menu?.onChange?.(next);
7562
+ }
7563
+ }
7564
+ )
7565
+ ] });
7566
+ }
7567
+ const { open: _open, onOpenChange: _onOpenChange, ...content } = listBox;
7568
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7569
+ button,
7570
+ /* @__PURE__ */ jsxRuntime.jsx(
7571
+ AccountListBoxPortal,
7572
+ {
7573
+ open: listBoxOpen,
7574
+ onOpenChange: commitListBoxOpen,
7575
+ anchorRef,
7576
+ ariaLabel: label,
7577
+ content
7578
+ }
7579
+ )
7580
+ ] });
6978
7581
  }
6979
7582
  );
6980
7583
  var SIZE_CLASSES = {
@@ -7129,87 +7732,6 @@ function SPopover({
7129
7732
  ) })
7130
7733
  ] });
7131
7734
  }
7132
- function SPortal({
7133
- open,
7134
- onClose,
7135
- onOpenChange,
7136
- anchorRef,
7137
- placement = "bottom",
7138
- align = "start",
7139
- offset = 4,
7140
- alignOffset = 0,
7141
- fit = false,
7142
- maxHeight,
7143
- autoClose = false,
7144
- persistent = false,
7145
- viewportPadding = 0,
7146
- onOpenAutoFocus,
7147
- onCloseAutoFocus,
7148
- onPointerDownOutside,
7149
- children,
7150
- className,
7151
- style,
7152
- ariaLabel
7153
- }) {
7154
- const portalContainer = usePortalContainer();
7155
- const { minWidth: styleMinWidth, maxWidth: styleMaxWidth, ...restStyle } = style ?? {};
7156
- return /* @__PURE__ */ jsxRuntime.jsxs(
7157
- RPopover11__namespace.Root,
7158
- {
7159
- open,
7160
- onOpenChange: (next) => {
7161
- onOpenChange?.(next);
7162
- if (!next) onClose?.();
7163
- },
7164
- children: [
7165
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Anchor, { virtualRef: anchorRef }),
7166
- /* @__PURE__ */ jsxRuntime.jsx(RPopover11__namespace.Portal, { container: portalContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
7167
- RPopover11__namespace.Content,
7168
- {
7169
- side: placement,
7170
- align,
7171
- sideOffset: offset,
7172
- alignOffset,
7173
- collisionPadding: viewportPadding,
7174
- "aria-label": ariaLabel,
7175
- onPointerDownOutside: (e) => {
7176
- if (persistent || anchorRef.current?.contains(e.target)) {
7177
- e.preventDefault();
7178
- return;
7179
- }
7180
- onPointerDownOutside?.(e);
7181
- },
7182
- onFocusOutside: (e) => {
7183
- if (persistent || anchorRef.current?.contains(e.target)) {
7184
- e.preventDefault();
7185
- }
7186
- },
7187
- onEscapeKeyDown: persistent ? (e) => e.preventDefault() : void 0,
7188
- onOpenAutoFocus,
7189
- onCloseAutoFocus,
7190
- onClick: autoClose ? () => onClose?.() : void 0,
7191
- className: cn(
7192
- "z-50 overflow-hidden rounded-(--cmp-listBox-radius) bg-(--cmp-listBox-bg) shadow-normal-sm",
7193
- maxHeight != null && "overflow-y-auto",
7194
- // 앵커가 창보다 넓을 수 있는 자리(가로 스크롤 안의 트리거 등)에서도 하한이 상한을
7195
- // 이기지 않도록, 앵커 너비 역시 가용 폭으로 가둔다.
7196
- fit && "min-w-[min(var(--radix-popover-trigger-width),var(--radix-popover-content-available-width))]",
7197
- FLOATING_SLIDE_ANIM,
7198
- className
7199
- ),
7200
- style: {
7201
- maxHeight,
7202
- ...restStyle,
7203
- ...styleMinWidth != null ? { minWidth: clampToAvailableWidth(styleMinWidth, POPOVER_AVAILABLE_WIDTH) } : {},
7204
- maxWidth: clampToAvailableWidth(styleMaxWidth, POPOVER_AVAILABLE_WIDTH)
7205
- },
7206
- children
7207
- }
7208
- ) })
7209
- ]
7210
- }
7211
- );
7212
- }
7213
7735
  var SPopup = /* @__PURE__ */ react.forwardRef(function SPopup2({
7214
7736
  popupTitle = "",
7215
7737
  type = "default",
@@ -8157,11 +8679,6 @@ function SDrawer({
8157
8679
  ] }) }) });
8158
8680
  }
8159
8681
 
8160
- // src/lib/is-dev.ts
8161
- function isDev() {
8162
- return typeof process === "undefined" || process?.env?.NODE_ENV !== "production";
8163
- }
8164
-
8165
8682
  // src/lib/modal-outlet.ts
8166
8683
  var EMPTY = [];
8167
8684
  var entries2 = EMPTY;
@@ -8622,7 +9139,7 @@ var SLayout = /* @__PURE__ */ react.forwardRef(function SLayout2({
8622
9139
 
8623
9140
  // src/components/SGnb/gnb.config.ts
8624
9141
  var gnb = (p) => `var(--cmp-gnb-${p})`;
8625
- var box = (p) => `var(--cmp-gnb-box-${p})`;
9142
+ var box2 = (p) => `var(--cmp-gnb-box-${p})`;
8626
9143
  var belt = (p) => `var(--cmp-gnb-belt-${p})`;
8627
9144
  var light = (p) => `var(--cmp-gnb-light-${p})`;
8628
9145
  var dark = (p) => `var(--cmp-gnb-dark-${p})`;
@@ -8643,14 +9160,14 @@ var GNB_MENU = {
8643
9160
  itemMarginX: gnb("body-padding"),
8644
9161
  // 전방향 토큰 → 아이템 좌우 여백에도 사용
8645
9162
  itemPaddingY: gnb("item-paddingY"),
8646
- itemPaddingRight: box("item-paddingRight"),
8647
- itemGap: box("item-gap"),
8648
- itemRadius: box("item-radius"),
9163
+ itemPaddingRight: box2("item-paddingRight"),
9164
+ itemGap: box2("item-gap"),
9165
+ itemRadius: box2("item-radius"),
8649
9166
  itemArrow: gnb("item-chevron-size"),
8650
- depth1PaddingLeft: box("item-depth1-paddingLeft"),
8651
- depth2PaddingLeft: box("item-depth2-paddingLeft"),
8652
- depth3PaddingLeft: box("item-depth3-paddingLeft"),
8653
- depth1Icon: box("item-depth1-icon"),
9167
+ depth1PaddingLeft: box2("item-depth1-paddingLeft"),
9168
+ depth2PaddingLeft: box2("item-depth2-paddingLeft"),
9169
+ depth3PaddingLeft: box2("item-depth3-paddingLeft"),
9170
+ depth1Icon: box2("item-depth1-icon"),
8654
9171
  // box 는 depth1 전용 타이포 토큰이 없어 depth1 도 selected 타이포를 따른다
8655
9172
  depth1FontSize: 14,
8656
9173
  // token: gnb.box.item.typography.selected.fontSize
@@ -8763,17 +9280,17 @@ var GNB_TOP_ICON_GAP = 8;
8763
9280
  var GNB_TOP_ICON_SIZE = 24;
8764
9281
  var GNB_FULL_LOGO_WIDTH_NO_LAUNCHER = GNB_FULL_LOGO_WIDTH + GNB_TOP_ICON_SIZE + GNB_TOP_ICON_GAP;
8765
9282
  function findGnbRailValue(items, value) {
8766
- if (items.some((item3) => item3.value === value)) return value;
9283
+ if (items.some((item4) => item4.value === value)) return value;
8767
9284
  return findGnbAncestors(items, value)[0];
8768
9285
  }
8769
9286
  function findGnbSiblingValues(items, value) {
8770
9287
  const walk = (list) => {
8771
- if (list.some((item3) => item3.value === value)) {
8772
- return list.filter((item3) => item3.value !== value).map((item3) => item3.value);
9288
+ if (list.some((item4) => item4.value === value)) {
9289
+ return list.filter((item4) => item4.value !== value).map((item4) => item4.value);
8773
9290
  }
8774
- for (const item3 of list) {
8775
- if (item3.children) {
8776
- const found = walk(item3.children);
9291
+ for (const item4 of list) {
9292
+ if (item4.children) {
9293
+ const found = walk(item4.children);
8777
9294
  if (found) return found;
8778
9295
  }
8779
9296
  }
@@ -8783,10 +9300,10 @@ function findGnbSiblingValues(items, value) {
8783
9300
  }
8784
9301
  function findGnbAncestors(items, value) {
8785
9302
  const walk = (list, trail) => {
8786
- for (const item3 of list) {
8787
- if (item3.value === value) return trail;
8788
- if (item3.children) {
8789
- const found = walk(item3.children, [...trail, item3.value]);
9303
+ for (const item4 of list) {
9304
+ if (item4.value === value) return trail;
9305
+ if (item4.children) {
9306
+ const found = walk(item4.children, [...trail, item4.value]);
8790
9307
  if (found) return found;
8791
9308
  }
8792
9309
  }
@@ -8796,20 +9313,20 @@ function findGnbAncestors(items, value) {
8796
9313
  }
8797
9314
  function findGnbDescendantBranchValues(items, value) {
8798
9315
  const find = (list) => {
8799
- for (const item3 of list) {
8800
- if (item3.value === value) return item3;
8801
- if (item3.children) {
8802
- const found = find(item3.children);
9316
+ for (const item4 of list) {
9317
+ if (item4.value === value) return item4;
9318
+ if (item4.children) {
9319
+ const found = find(item4.children);
8803
9320
  if (found) return found;
8804
9321
  }
8805
9322
  }
8806
9323
  return void 0;
8807
9324
  };
8808
9325
  const collect = (list, acc) => {
8809
- for (const item3 of list) {
8810
- if (item3.children && item3.children.length > 0) {
8811
- acc.push(item3.value);
8812
- collect(item3.children, acc);
9326
+ for (const item4 of list) {
9327
+ if (item4.children && item4.children.length > 0) {
9328
+ acc.push(item4.value);
9329
+ collect(item4.children, acc);
8813
9330
  }
8814
9331
  }
8815
9332
  return acc;
@@ -8854,7 +9371,7 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
8854
9371
  const type = typeProp ?? layout?.type ?? "box";
8855
9372
  const folded = foldedProp ?? layout?.folded ?? false;
8856
9373
  const useRail = useRailProp ?? layout?.useRail ?? false;
8857
- const railHasLeaf = useRail && items.some((item3) => !item3.children || item3.children.length === 0);
9374
+ const railHasLeaf = useRail && items.some((item4) => !item4.children || item4.children.length === 0);
8858
9375
  const header = railHasLeaf ? "full" : headerProp ?? layout?.header ?? "fix";
8859
9376
  const H = GNB_HEADER[header];
8860
9377
  const M = GNB_MENU[type];
@@ -8897,13 +9414,13 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
8897
9414
  labelTipHideRef.current = setTimeout(() => setLabelTip(null), LABEL_TIP_HIDE_DELAY_MS);
8898
9415
  };
8899
9416
  react.useEffect(() => cancelLabelTipHide, []);
8900
- const rowHoverProps = (item3) => ({
9417
+ const rowHoverProps = (item4) => ({
8901
9418
  onMouseEnter: (event) => {
8902
- setHoveredKey(item3.value);
8903
- showLabelTipIfTruncated(event.currentTarget, item3.label);
9419
+ setHoveredKey(item4.value);
9420
+ showLabelTipIfTruncated(event.currentTarget, item4.label);
8904
9421
  },
8905
9422
  onMouseLeave: () => {
8906
- setHoveredKey((prev) => prev === item3.value ? null : prev);
9423
+ setHoveredKey((prev) => prev === item4.value ? null : prev);
8907
9424
  startLabelTipHide();
8908
9425
  }
8909
9426
  });
@@ -8929,7 +9446,7 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
8929
9446
  }, [items, value]);
8930
9447
  react.useEffect(() => {
8931
9448
  setActiveRail(
8932
- (prev) => prev !== void 0 && items.some((item3) => item3.value === prev) ? prev : items[0]?.value
9449
+ (prev) => prev !== void 0 && items.some((item4) => item4.value === prev) ? prev : items[0]?.value
8933
9450
  );
8934
9451
  }, [items]);
8935
9452
  const toggleExpand = (key) => {
@@ -8946,33 +9463,33 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
8946
9463
  return next;
8947
9464
  });
8948
9465
  };
8949
- const handleItemClick = (item3) => {
8950
- if (item3.disabled) return;
8951
- if (item3.children && item3.children.length > 0) {
8952
- toggleExpand(item3.value);
9466
+ const handleItemClick = (item4) => {
9467
+ if (item4.disabled) return;
9468
+ if (item4.children && item4.children.length > 0) {
9469
+ toggleExpand(item4.value);
8953
9470
  return;
8954
9471
  }
8955
- onValueChange?.(item3.value);
9472
+ onValueChange?.(item4.value);
8956
9473
  };
8957
- const handleRailClick = (item3) => {
8958
- if (item3.disabled) return;
8959
- setActiveRail(item3.value);
8960
- onRailChange?.(item3.value);
8961
- if (!item3.children || item3.children.length === 0) onValueChange?.(item3.value);
9474
+ const handleRailClick = (item4) => {
9475
+ if (item4.disabled) return;
9476
+ setActiveRail(item4.value);
9477
+ onRailChange?.(item4.value);
9478
+ if (!item4.children || item4.children.length === 0) onValueChange?.(item4.value);
8962
9479
  };
8963
9480
  const handleFoldToggle = () => {
8964
9481
  const next = !folded;
8965
9482
  onFoldChange?.(next);
8966
9483
  if (foldedProp === void 0) layout?.setFolded(next);
8967
9484
  };
8968
- const renderRailItem = (item3) => {
8969
- const isActive = item3.value === activeRail;
8970
- const isHovered = hoveredKey === item3.value && !item3.disabled;
9485
+ const renderRailItem = (item4) => {
9486
+ const isActive = item4.value === activeRail;
9487
+ const isHovered = hoveredKey === item4.value && !item4.disabled;
8971
9488
  return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
8972
9489
  "button",
8973
9490
  {
8974
9491
  type: "button",
8975
- disabled: item3.disabled,
9492
+ disabled: item4.disabled,
8976
9493
  "aria-current": isActive ? "true" : void 0,
8977
9494
  className: "box-border flex select-none flex-col items-center border-none bg-transparent transition-colors duration-150",
8978
9495
  style: {
@@ -8987,31 +9504,31 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
8987
9504
  fontSize: GNB_RAIL.itemFontSize,
8988
9505
  lineHeight: `${GNB_RAIL.itemLineHeight}px`,
8989
9506
  fontWeight: isActive ? GNB_RAIL.itemFontWeightSelected : GNB_RAIL.itemFontWeight,
8990
- opacity: item3.disabled ? 0.4 : 1,
8991
- cursor: item3.disabled ? "not-allowed" : "pointer"
9507
+ opacity: item4.disabled ? 0.4 : 1,
9508
+ cursor: item4.disabled ? "not-allowed" : "pointer"
8992
9509
  },
8993
- onClick: () => handleRailClick(item3),
8994
- ...rowHoverProps(item3),
9510
+ onClick: () => handleRailClick(item4),
9511
+ ...rowHoverProps(item4),
8995
9512
  children: [
8996
- item3.icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: item3.icon, size: GNB_RAIL.itemIcon, className: "shrink-0" }),
9513
+ item4.icon && /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: item4.icon, size: GNB_RAIL.itemIcon, className: "shrink-0" }),
8997
9514
  /* @__PURE__ */ jsxRuntime.jsx(
8998
9515
  "span",
8999
9516
  {
9000
9517
  "data-gnb-label": true,
9001
9518
  className: "w-full overflow-hidden text-ellipsis whitespace-nowrap text-center",
9002
- children: item3.label
9519
+ children: item4.label
9003
9520
  }
9004
9521
  )
9005
9522
  ]
9006
9523
  }
9007
- ) }, item3.value);
9524
+ ) }, item4.value);
9008
9525
  };
9009
- const renderItem = (item3, depth, branchHasIcon = false) => {
9010
- const hasChildren = !!(item3.children && item3.children.length > 0);
9011
- const isSelected = !hasChildren && item3.value === value;
9012
- const isExpanded = expandedKeys.has(item3.value);
9013
- const isHovered = hoveredKey === item3.value && !item3.disabled;
9014
- const iconBranch = depth === 1 ? !!item3.icon : branchHasIcon;
9526
+ const renderItem = (item4, depth, branchHasIcon = false) => {
9527
+ const hasChildren = !!(item4.children && item4.children.length > 0);
9528
+ const isSelected = !hasChildren && item4.value === value;
9529
+ const isExpanded = expandedKeys.has(item4.value);
9530
+ const isHovered = hoveredKey === item4.value && !item4.disabled;
9531
+ const iconBranch = depth === 1 ? !!item4.icon : branchHasIcon;
9015
9532
  const itemStyle = {
9016
9533
  gap: M.itemGap,
9017
9534
  paddingTop: M.itemPaddingY,
@@ -9028,8 +9545,8 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
9028
9545
  fontSize: depth === 1 ? M.depth1FontSize : M.itemFontSize,
9029
9546
  lineHeight: `${depth === 1 ? M.depth1LineHeight : M.itemLineHeight}px`,
9030
9547
  fontWeight: depth === 1 ? M.depth1FontWeight : isSelected ? M.itemFontWeightSelected : M.itemFontWeight,
9031
- opacity: item3.disabled ? 0.4 : 1,
9032
- cursor: item3.disabled ? "not-allowed" : "pointer"
9548
+ opacity: item4.disabled ? 0.4 : 1,
9549
+ cursor: item4.disabled ? "not-allowed" : "pointer"
9033
9550
  };
9034
9551
  return (
9035
9552
  // li 를 flex-col 로 둬야 버튼이 좌우 마진만큼 안쪽으로 들어가고,
@@ -9039,18 +9556,18 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
9039
9556
  "button",
9040
9557
  {
9041
9558
  type: "button",
9042
- disabled: item3.disabled,
9559
+ disabled: item4.disabled,
9043
9560
  "aria-expanded": hasChildren ? isExpanded : void 0,
9044
9561
  "aria-current": isSelected ? "page" : void 0,
9045
9562
  className: "box-border flex select-none items-center border-none bg-transparent text-left transition-colors duration-150",
9046
9563
  style: itemStyle,
9047
- onClick: () => handleItemClick(item3),
9048
- ...rowHoverProps(item3),
9564
+ onClick: () => handleItemClick(item4),
9565
+ ...rowHoverProps(item4),
9049
9566
  children: [
9050
- depth === 1 && item3.icon && /* @__PURE__ */ jsxRuntime.jsx(
9567
+ depth === 1 && item4.icon && /* @__PURE__ */ jsxRuntime.jsx(
9051
9568
  SIcon,
9052
9569
  {
9053
- name: item3.icon,
9570
+ name: item4.icon,
9054
9571
  size: M.depth1Icon,
9055
9572
  color: isSelected ? C.itemColorActive : C.itemIcon,
9056
9573
  className: "shrink-0"
@@ -9070,17 +9587,17 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
9070
9587
  {
9071
9588
  "data-gnb-label": true,
9072
9589
  className: "min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap",
9073
- children: item3.label
9590
+ children: item4.label
9074
9591
  }
9075
9592
  )
9076
9593
  ] }),
9077
- item3.tag !== void 0 && item3.tag !== "" && /* @__PURE__ */ jsxRuntime.jsx(
9594
+ item4.tag !== void 0 && item4.tag !== "" && /* @__PURE__ */ jsxRuntime.jsx(
9078
9595
  STag,
9079
9596
  {
9080
9597
  shape: "square",
9081
9598
  size: "xs",
9082
- color: item3.tagColor ?? "blue",
9083
- label: item3.tag,
9599
+ color: item4.tagColor ?? "blue",
9600
+ label: item4.tag,
9084
9601
  className: "shrink-0"
9085
9602
  }
9086
9603
  ),
@@ -9113,16 +9630,16 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
9113
9630
  visibility: isExpanded ? "visible" : "hidden",
9114
9631
  transition: `visibility 0s linear ${isExpanded ? "0s" : `${GNB_EXPAND_MS}ms`}`
9115
9632
  },
9116
- children: item3.children.map((child) => renderItem(child, depth + 1, iconBranch))
9633
+ children: item4.children.map((child) => renderItem(child, depth + 1, iconBranch))
9117
9634
  }
9118
9635
  )
9119
9636
  }
9120
9637
  )
9121
- ] }, item3.value)
9638
+ ] }, item4.value)
9122
9639
  );
9123
9640
  };
9124
9641
  const railItems = useRail ? items : [];
9125
- const menuItems = useRail ? items.find((item3) => item3.value === activeRail)?.children ?? [] : items;
9642
+ const menuItems = useRail ? items.find((item4) => item4.value === activeRail)?.children ?? [] : items;
9126
9643
  const showMenu = !useRail || menuItems.length > 0;
9127
9644
  const [uncontrolledMenuWidth, setUncontrolledMenuWidth] = react.useState(
9128
9645
  () => defaultMenuWidth ?? GNB_MENU_WIDTH
@@ -9313,15 +9830,15 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
9313
9830
  "topContent"
9314
9831
  ) : null;
9315
9832
  const systemMenuContext = react.useMemo(
9316
- () => ({ color, folded: false, placement: "panel" }),
9317
- [color]
9833
+ () => ({ color, folded: false, placement: "panel", active: !railFolded }),
9834
+ [color, railFolded]
9318
9835
  );
9319
9836
  const systemFoldedContext = react.useMemo(
9320
- () => ({ color, folded: true, placement: "panel" }),
9837
+ () => ({ color, folded: true, placement: "panel", active: true }),
9321
9838
  [color]
9322
9839
  );
9323
9840
  const systemTopContext = react.useMemo(
9324
- () => ({ color, folded: false, placement: "top" }),
9841
+ () => ({ color, folded: false, placement: "top", active: true }),
9325
9842
  [color]
9326
9843
  );
9327
9844
  const systemTopBox = header === "full" && system ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -9451,7 +9968,7 @@ var SGnb = /* @__PURE__ */ react.forwardRef(function SGnb2({
9451
9968
  paddingTop: M.bodyPaddingY,
9452
9969
  paddingBottom: M.bodyPaddingY
9453
9970
  },
9454
- children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "m-0 flex list-none flex-col p-0", children: menuItems.map((item3) => renderItem(item3, 1)) })
9971
+ children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "m-0 flex list-none flex-col p-0", children: menuItems.map((item4) => renderItem(item4, 1)) })
9455
9972
  }
9456
9973
  ),
9457
9974
  menuFooter && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: menuFooter }),
@@ -9495,7 +10012,7 @@ var GNB_SYSTEM_COLORS = ["light", "dark"];
9495
10012
  var GNB_SYSTEM_PLACEMENTS = ["panel", "top"];
9496
10013
  var panel = (p) => `var(--cmp-gnb-system-panel-${p})`;
9497
10014
  var domain = (p) => `var(--cmp-gnb-system-domainTag-${p})`;
9498
- var item2 = (p) => `var(--cmp-gnb-system-item-${p})`;
10015
+ var item3 = (p) => `var(--cmp-gnb-system-item-${p})`;
9499
10016
  var alert = (p) => `var(--cmp-gnb-system-alertButton-${p})`;
9500
10017
  var GNB_SYSTEM_COLOR_CONFIG = {
9501
10018
  light: {
@@ -9555,17 +10072,17 @@ var GNB_SYSTEM_LAYOUT = {
9555
10072
  */
9556
10073
  gap: panel("gap"),
9557
10074
  /** 행 높이 */
9558
- itemHeight: item2("height"),
10075
+ itemHeight: item3("height"),
9559
10076
  /** 행 라운드 */
9560
- itemRadius: item2("radius"),
10077
+ itemRadius: item3("radius"),
9561
10078
  /** 아이콘 프레임 한 변 */
9562
- iconFrame: item2("icon-frame"),
10079
+ iconFrame: item3("icon-frame"),
9563
10080
  /** 아이콘 글리프 크기 */
9564
- iconGlyph: item2("icon-glyph"),
10081
+ iconGlyph: item3("icon-glyph"),
9565
10082
  /** 아이콘 프레임 라운드 */
9566
- iconRadius: item2("icon-radius"),
10083
+ iconRadius: item3("icon-radius"),
9567
10084
  /** 아이콘 프레임 ↔ 라벨 간격 */
9568
- iconLabelGap: item2("iconLabelGap"),
10085
+ iconLabelGap: item3("iconLabelGap"),
9569
10086
  /** 알림 버튼 좌우 여백 */
9570
10087
  alertPaddingX: alert("paddingX"),
9571
10088
  /** 설정 버튼 좌우 여백 */
@@ -9578,7 +10095,7 @@ var GNB_SYSTEM_LAYOUT = {
9578
10095
  var GNB_SYSTEM_ALERT_DOT_SIZE = 6;
9579
10096
  var GNB_SYSTEM_ALERT_LABEL = "\uC54C\uB9BC";
9580
10097
  var GNB_SYSTEM_SETTING_LABEL = "\uC124\uC815";
9581
- function TokenIcon2({ name, size }) {
10098
+ function TokenIcon3({ name, size }) {
9582
10099
  return /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name, size: "100%", style: { width: size, height: size } });
9583
10100
  }
9584
10101
  function SystemButton({
@@ -9593,14 +10110,20 @@ function SystemButton({
9593
10110
  dot,
9594
10111
  accentColor,
9595
10112
  stretch,
10113
+ buttonRef,
10114
+ hasPopup,
10115
+ expanded,
9596
10116
  onClick
9597
10117
  }) {
9598
10118
  const c = SYSTEM_ACTION_BUTTON_COLOR_CONFIG[color];
9599
10119
  return /* @__PURE__ */ jsxRuntime.jsxs(
9600
10120
  "button",
9601
10121
  {
10122
+ ref: buttonRef,
9602
10123
  type: "button",
9603
10124
  "aria-label": label ? void 0 : ariaLabel,
10125
+ "aria-haspopup": hasPopup ? "dialog" : void 0,
10126
+ "aria-expanded": hasPopup ? expanded : void 0,
9604
10127
  onClick,
9605
10128
  className: cn(
9606
10129
  "group box-border flex cursor-pointer items-center border-none bg-(--gsb-bg) text-(--gsb-text) transition-colors hover:bg-(--gsb-bg-hover)",
@@ -9629,7 +10152,7 @@ function SystemButton({
9629
10152
  className: "relative inline-flex shrink-0 items-center justify-center bg-(--gsb-icon-bg) text-(--gsb-icon) transition-colors group-hover:bg-(--gsb-icon-bg-hover) group-hover:text-(--gsb-icon-hover)",
9630
10153
  style: { width: GNB_SYSTEM_LAYOUT.iconFrame, height: GNB_SYSTEM_LAYOUT.iconFrame, borderRadius: GNB_SYSTEM_LAYOUT.iconRadius },
9631
10154
  children: [
9632
- /* @__PURE__ */ jsxRuntime.jsx(TokenIcon2, { name: icon, size: GNB_SYSTEM_LAYOUT.iconGlyph }),
10155
+ /* @__PURE__ */ jsxRuntime.jsx(TokenIcon3, { name: icon, size: GNB_SYSTEM_LAYOUT.iconGlyph }),
9633
10156
  dot && /* @__PURE__ */ jsxRuntime.jsx(
9634
10157
  "span",
9635
10158
  {
@@ -9656,7 +10179,6 @@ function SystemButton({
9656
10179
  var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
9657
10180
  color: colorProp,
9658
10181
  folded: foldedProp,
9659
- placement: placementProp,
9660
10182
  actions,
9661
10183
  domain: domain2,
9662
10184
  alert: alert2,
@@ -9668,9 +10190,10 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
9668
10190
  }, ref) {
9669
10191
  const gnb2 = react.useContext(SGnbSystemContext);
9670
10192
  const color = colorProp ?? gnb2?.color ?? "light";
9671
- const placement = placementProp ?? gnb2?.placement ?? "panel";
10193
+ const placement = gnb2?.placement ?? "panel";
9672
10194
  const isTop = placement === "top";
9673
10195
  const folded = !isTop && (foldedProp ?? gnb2?.folded ?? false);
10196
+ const active = gnb2?.active ?? true;
9674
10197
  const c = GNB_SYSTEM_COLOR_CONFIG[color];
9675
10198
  const t = GNB_SYSTEM_TOP_COLOR_CONFIG[color];
9676
10199
  const itemColor = isTop ? t.item : color;
@@ -9683,6 +10206,17 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
9683
10206
  const hasActions = (actions?.length ?? 0) > 0;
9684
10207
  const hasDomain = domain2 != null;
9685
10208
  const hasUserBlock = Boolean(alert2 || setting || account);
10209
+ const foldedAccountRef = react.useRef(null);
10210
+ const [accountOpen, setAccountOpen] = react.useState(false);
10211
+ const commitAccountOpen = (next) => {
10212
+ setAccountOpen(next);
10213
+ account?.onOpenChange?.(next);
10214
+ };
10215
+ react.useEffect(() => {
10216
+ if (active || !accountOpen) return;
10217
+ setAccountOpen(false);
10218
+ account?.onOpenChange?.(false);
10219
+ }, [active, accountOpen, account]);
9686
10220
  const alertCount = alert2?.count ?? 0;
9687
10221
  const notified = alertCount > 0;
9688
10222
  const alertLabel = alert2?.label ?? GNB_SYSTEM_ALERT_LABEL;
@@ -9691,7 +10225,7 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
9691
10225
  SystemButton,
9692
10226
  {
9693
10227
  color: itemColor,
9694
- icon: notified ? "alert" : "bell",
10228
+ icon: notified ? "bellRinging" : "bell",
9695
10229
  label: folded || isTop ? void 0 : alertLabel,
9696
10230
  ariaLabel: alertLabel,
9697
10231
  paddingX: GNB_SYSTEM_LAYOUT.alertPaddingX,
@@ -9723,6 +10257,7 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
9723
10257
  type: "account",
9724
10258
  label: account.label,
9725
10259
  onClick: account.onClick,
10260
+ option: { ...account.listBox, open: accountOpen, onOpenChange: commitAccountOpen },
9726
10261
  className: isTop ? "w-auto shrink-0" : void 0
9727
10262
  }
9728
10263
  );
@@ -9752,8 +10287,8 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
9752
10287
  SSystemActionButton,
9753
10288
  {
9754
10289
  color: itemColor,
9755
- className: "w-auto shrink-0",
9756
- ...action2
10290
+ ...action2,
10291
+ className: cn("w-auto shrink-0", action2.className)
9757
10292
  }
9758
10293
  )
9759
10294
  })
@@ -9770,27 +10305,30 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
9770
10305
  });
9771
10306
  }
9772
10307
  if (segments.length === 0) return null;
9773
- return /* @__PURE__ */ jsxRuntime.jsx(
9774
- "div",
9775
- {
9776
- ref,
9777
- className: cn("flex items-center", className),
9778
- style: { gap: GNB_SYSTEM_LAYOUT.gap, ...style },
9779
- "data-color": color,
9780
- "data-placement": "top",
9781
- ...rest,
9782
- children: segments.map(({ key, node }, index) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
9783
- index > 0 && /* @__PURE__ */ jsxRuntime.jsx(
9784
- "span",
9785
- {
9786
- className: "h-sd-16 w-px shrink-0",
9787
- style: { backgroundColor: dividerColor },
9788
- "aria-hidden": true
9789
- }
9790
- ),
9791
- node
9792
- ] }, key))
9793
- }
10308
+ return (
10309
+ // 상단바 줄은 화면 맨 위에 있다 — 계정 리스트박스가 위가 아니라 아래로 펼쳐져야 한다.
10310
+ /* @__PURE__ */ jsxRuntime.jsx(AccountListBoxAnchorProvider, { value: "top", children: /* @__PURE__ */ jsxRuntime.jsx(
10311
+ "div",
10312
+ {
10313
+ ref,
10314
+ className: cn("flex items-center", className),
10315
+ style: { gap: GNB_SYSTEM_LAYOUT.gap, ...style },
10316
+ "data-color": color,
10317
+ "data-placement": "top",
10318
+ ...rest,
10319
+ children: segments.map(({ key, node }, index) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
10320
+ index > 0 && /* @__PURE__ */ jsxRuntime.jsx(
10321
+ "span",
10322
+ {
10323
+ className: "h-sd-16 w-px shrink-0",
10324
+ style: { backgroundColor: dividerColor },
10325
+ "aria-hidden": true
10326
+ }
10327
+ ),
10328
+ node
10329
+ ] }, key))
10330
+ }
10331
+ ) })
9794
10332
  );
9795
10333
  }
9796
10334
  const panelStyle = {
@@ -9821,7 +10359,23 @@ var SGnbSystem = /* @__PURE__ */ react.forwardRef(function SGnbSystem2({
9821
10359
  icon: "user",
9822
10360
  ariaLabel: account.label ?? "account",
9823
10361
  paddingX: GNB_SYSTEM_LAYOUT.alertPaddingX,
9824
- onClick: account.onClick
10362
+ buttonRef: foldedAccountRef,
10363
+ hasPopup: true,
10364
+ expanded: accountOpen,
10365
+ onClick: () => {
10366
+ account.onClick?.();
10367
+ commitAccountOpen(!accountOpen);
10368
+ }
10369
+ }
10370
+ ),
10371
+ account && /* @__PURE__ */ jsxRuntime.jsx(
10372
+ AccountListBoxPortal,
10373
+ {
10374
+ open: accountOpen,
10375
+ onOpenChange: commitAccountOpen,
10376
+ anchorRef: foldedAccountRef,
10377
+ ariaLabel: account.label,
10378
+ content: account.listBox ?? {}
9825
10379
  }
9826
10380
  )
9827
10381
  ]
@@ -10483,19 +11037,19 @@ var STEPPER_VERTICAL_COLORS = {
10483
11037
  errorBadge: "#FB4444"
10484
11038
  };
10485
11039
  var ERROR_TOOLTIP_MESSAGE = "\uD655\uC778\uC774 \uD544\uC694\uD55C \uD56D\uBAA9\uC774 \uC788\uC2B5\uB2C8\uB2E4.";
10486
- function getItemValue(item3, index) {
10487
- return item3.value ?? String(index + 1);
11040
+ function getItemValue(item4, index) {
11041
+ return item4.value ?? String(index + 1);
10488
11042
  }
10489
11043
  function groupAdjacentItems(items) {
10490
11044
  return items.reduce(
10491
- (groups, item3, index) => {
10492
- const currentGroup = item3.group;
11045
+ (groups, item4, index) => {
11046
+ const currentGroup = item4.group;
10493
11047
  const previous = groups[groups.length - 1];
10494
11048
  if (currentGroup && previous?.group === currentGroup) {
10495
- previous.items.push(item3);
11049
+ previous.items.push(item4);
10496
11050
  return groups;
10497
11051
  }
10498
- groups.push({ group: currentGroup, startIndex: index, items: [item3] });
11052
+ groups.push({ group: currentGroup, startIndex: index, items: [item4] });
10499
11053
  return groups;
10500
11054
  },
10501
11055
  []
@@ -10525,15 +11079,15 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10525
11079
  const verticalItemRefs = react.useRef([]);
10526
11080
  const activeIndex = Math.max(
10527
11081
  0,
10528
- items.findIndex((item3, index) => getItemValue(item3, index) === value)
11082
+ items.findIndex((item4, index) => getItemValue(item4, index) === value)
10529
11083
  );
10530
11084
  const lastCompletedIndex = items.reduce(
10531
- (lastIndex, item3, index) => item3.completed === true ? index : lastIndex,
11085
+ (lastIndex, item4, index) => item4.completed === true ? index : lastIndex,
10532
11086
  -1
10533
11087
  );
10534
11088
  const resolvedClickableIndex = lastCompletedIndex + 1;
10535
11089
  const [visitedMaxIndex, setVisitedMaxIndex] = react.useState(activeIndex);
10536
- const firstErrorIndex = items.findIndex((item3) => item3.error === true);
11090
+ const firstErrorIndex = items.findIndex((item4) => item4.error === true);
10537
11091
  react.useImperativeHandle(
10538
11092
  ref,
10539
11093
  () => ({
@@ -10561,18 +11115,18 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10561
11115
  transform: `translateY(${activeItem.offsetTop}px)`
10562
11116
  });
10563
11117
  }, [activeIndex, vertical, items]);
10564
- const getState = (item3, index) => {
11118
+ const getState = (item4, index) => {
10565
11119
  if (index === activeIndex) return "active";
10566
- if (item3.completed != null) return item3.completed ? "completed" : "default";
11120
+ if (item4.completed != null) return item4.completed ? "completed" : "default";
10567
11121
  return "default";
10568
11122
  };
10569
- const emitValueChange = (item3, index) => {
10570
- onValueChange?.(getItemValue(item3, index), item3, index);
11123
+ const emitValueChange = (item4, index) => {
11124
+ onValueChange?.(getItemValue(item4, index), item4, index);
10571
11125
  };
10572
11126
  const isWithinClickableIndex = (index) => index <= resolvedClickableIndex;
10573
- const renderStepContent = (item3, index, options = {}) => {
11127
+ const renderStepContent = (item4, index, options = {}) => {
10574
11128
  const { isVertical = false, roleListItem = true, hovered = false } = options;
10575
- const state2 = getState(item3, index);
11129
+ const state2 = getState(item4, index);
10576
11130
  const isHorizontalCompleted = !isVertical && state2 === "completed";
10577
11131
  const isVerticalCompleted = isVertical && state2 === "completed";
10578
11132
  const isVerticalLastActive = isVertical && state2 === "default" && index === visitedMaxIndex;
@@ -10647,12 +11201,12 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10647
11201
  children: showsCheckIcon ? /* @__PURE__ */ jsxRuntime.jsx(SIcon, { name: "check", size: STEPPER_LAYOUT.sequenceIcon, color: "currentColor" }) : index + 1
10648
11202
  }
10649
11203
  ),
10650
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: item3.label })
11204
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item4.label })
10651
11205
  ]
10652
11206
  }
10653
11207
  );
10654
11208
  };
10655
- const renderClickableStepContent = (item3, index, isVertical = false) => {
11209
+ const renderClickableStepContent = (item4, index, isVertical = false) => {
10656
11210
  const isDisabled = !isWithinClickableIndex(index);
10657
11211
  return /* @__PURE__ */ jsxRuntime.jsx(
10658
11212
  "button",
@@ -10665,9 +11219,9 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10665
11219
  ),
10666
11220
  style: { font: "inherit", color: "inherit" },
10667
11221
  onClick: () => {
10668
- if (!isDisabled) emitValueChange(item3, index);
11222
+ if (!isDisabled) emitValueChange(item4, index);
10669
11223
  },
10670
- children: renderStepContent(item3, index, { isVertical, roleListItem: false })
11224
+ children: renderStepContent(item4, index, { isVertical, roleListItem: false })
10671
11225
  }
10672
11226
  );
10673
11227
  };
@@ -10726,10 +11280,10 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10726
11280
  children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap", children: group.group })
10727
11281
  }
10728
11282
  ),
10729
- group.items.map((item3, itemIndex) => {
11283
+ group.items.map((item4, itemIndex) => {
10730
11284
  const index = group.startIndex + itemIndex;
10731
- const state2 = getState(item3, index);
10732
- const itemValue = getItemValue(item3, index);
11285
+ const state2 = getState(item4, index);
11286
+ const itemValue = getItemValue(item4, index);
10733
11287
  const canClickItem = isClickable && isWithinClickableIndex(index);
10734
11288
  const isDisabled = !canClickItem;
10735
11289
  const isHovered = hoveredIndex === index && canClickItem && state2 !== "active";
@@ -10747,12 +11301,12 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10747
11301
  const handleMouseLeave = () => {
10748
11302
  setHoveredIndex((current) => current === index ? null : current);
10749
11303
  };
10750
- const stepContent = renderStepContent(item3, index, {
11304
+ const stepContent = renderStepContent(item4, index, {
10751
11305
  isVertical: true,
10752
11306
  roleListItem: false,
10753
11307
  hovered: isHovered
10754
11308
  });
10755
- const errorBadge = item3.error ? /* @__PURE__ */ jsxRuntime.jsx(
11309
+ const errorBadge = item4.error ? /* @__PURE__ */ jsxRuntime.jsx(
10756
11310
  "span",
10757
11311
  {
10758
11312
  "aria-hidden": "true",
@@ -10767,7 +11321,7 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10767
11321
  ) : null;
10768
11322
  const isTooltipHovered = tooltipHoverValue === itemValue;
10769
11323
  const isCustomTooltipOpen = customTooltipOpen && index === firstErrorIndex;
10770
- const showTooltip = item3.error === true && (isTooltipHovered || isCustomTooltipOpen);
11324
+ const showTooltip = item4.error === true && (isTooltipHovered || isCustomTooltipOpen);
10771
11325
  const handleTooltipMouseEnter = () => setTooltipHoverValue(itemValue);
10772
11326
  const handleTooltipMouseLeave = () => {
10773
11327
  setTooltipHoverValue((current) => current === itemValue ? null : current);
@@ -10791,7 +11345,7 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10791
11345
  onMouseEnter: handleTooltipMouseEnter,
10792
11346
  onMouseLeave: handleTooltipMouseLeave,
10793
11347
  onClick: isClickable ? () => {
10794
- if (!isDisabled) emitValueChange(item3, index);
11348
+ if (!isDisabled) emitValueChange(item4, index);
10795
11349
  } : void 0,
10796
11350
  children: [
10797
11351
  stepContent,
@@ -10823,13 +11377,13 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10823
11377
  {
10824
11378
  type: "button",
10825
11379
  disabled: isDisabled,
10826
- "aria-label": item3.label,
11380
+ "aria-label": item4.label,
10827
11381
  className: cn(
10828
11382
  "absolute inset-0 z-[2] m-0 border-0 bg-transparent p-0 text-left outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-(--sys-color-border-accent)",
10829
11383
  isDisabled ? "cursor-default" : "cursor-pointer"
10830
11384
  ),
10831
11385
  onClick: () => {
10832
- if (!isDisabled) emitValueChange(item3, index);
11386
+ if (!isDisabled) emitValueChange(item4, index);
10833
11387
  }
10834
11388
  }
10835
11389
  ),
@@ -10880,9 +11434,9 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10880
11434
  lineHeight: config.lineHeight,
10881
11435
  ...style
10882
11436
  },
10883
- children: items.map((item3, index) => {
10884
- const state2 = getState(item3, index);
10885
- const content = isClickable ? /* @__PURE__ */ jsxRuntime.jsx("span", { role: "listitem", "aria-current": state2 === "active" ? "step" : void 0, children: renderClickableStepContent(item3, index) }) : renderStepContent(item3, index);
11437
+ children: items.map((item4, index) => {
11438
+ const state2 = getState(item4, index);
11439
+ const content = isClickable ? /* @__PURE__ */ jsxRuntime.jsx("span", { role: "listitem", "aria-current": state2 === "active" ? "step" : void 0, children: renderClickableStepContent(item4, index) }) : renderStepContent(item4, index);
10886
11440
  return /* @__PURE__ */ jsxRuntime.jsxs(
10887
11441
  "span",
10888
11442
  {
@@ -10916,7 +11470,7 @@ var SStepper = /* @__PURE__ */ react.forwardRef(function SStepper2({
10916
11470
  )
10917
11471
  ]
10918
11472
  },
10919
- getItemValue(item3, index)
11473
+ getItemValue(item4, index)
10920
11474
  );
10921
11475
  })
10922
11476
  }
@@ -11467,7 +12021,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
11467
12021
  const selectedAnchorIndex = react.useMemo(() => {
11468
12022
  if (selected.length === 0) return -1;
11469
12023
  const selectedSet = new Set(selected);
11470
- return navigableItems.findIndex((item3) => item3.value != null && selectedSet.has(item3.value));
12024
+ return navigableItems.findIndex((item4) => item4.value != null && selectedSet.has(item4.value));
11471
12025
  }, [navigableItems, selected]);
11472
12026
  selectedAnchorRef.current = selectedAnchorIndex;
11473
12027
  const triggerText = (() => {
@@ -11761,7 +12315,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
11761
12315
  setFocusedIndex(-1);
11762
12316
  return;
11763
12317
  }
11764
- const index = navigableItems.findIndex((item3) => item3.key === key);
12318
+ const index = navigableItems.findIndex((item4) => item4.key === key);
11765
12319
  if (index >= 0) setFocusedIndex(index);
11766
12320
  }
11767
12321
  }
@@ -13531,7 +14085,9 @@ function SRadio({
13531
14085
  {
13532
14086
  ...labelInteractiveProps,
13533
14087
  className: cn(
13534
- "inline-flex items-center gap-[8px]",
14088
+ // align-middle: 텍스트 baseline 이 아니라 줄 중앙에 맞춘다 — SCheckbox 와 같은 규칙.
14089
+ // td 처럼 strut(셀 폰트의 줄 상자)이 라디오보다 큰 곳에서 위로 치우치지 않게 한다.
14090
+ "inline-flex items-center gap-(--cmp-radio-gap) align-middle",
13535
14091
  disabled ? "cursor-not-allowed" : "cursor-pointer",
13536
14092
  className
13537
14093
  ),
@@ -13553,17 +14109,21 @@ function SRadio({
13553
14109
  "span",
13554
14110
  {
13555
14111
  className: cn(
13556
- "flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center rounded-full border border-solid border-[color:var(--rd-border)] bg-[var(--rd-bg)]",
13557
- !disabled && !checked && "hover:border-[color:var(--cmp-radio-border-hover)] hover:bg-[var(--cmp-radio-bg-hover)]"
14112
+ "relative flex h-(--cmp-radio-size) w-(--cmp-radio-size) shrink-0 items-center justify-center rounded-(--cmp-radio-radius) border-(length:--cmp-radio-borderWidth) border-solid border-(--rd-border) bg-(--rd-bg)",
14113
+ !disabled && !checked && "hover:border-(--cmp-radio-border-hover) hover:bg-(--cmp-radio-bg-hover)"
13558
14114
  ),
13559
14115
  style: {
13560
14116
  "--rd-bg": disabled ? "var(--cmp-radio-bg-disabled)" : "var(--cmp-radio-bg-default)",
13561
14117
  "--rd-border": disabled ? "var(--cmp-radio-border-disabled)" : checked ? "var(--cmp-radio-border-active)" : "var(--cmp-radio-border-default)"
13562
14118
  },
13563
- children: checked && /* @__PURE__ */ jsxRuntime.jsx(
14119
+ children: checked && // dot 은 반드시 flow 밖(absolute)에 둔다. in-flow 자식으로 넣으면 동그라미(flex 컨테이너)의
14120
+ // 합성 baseline 이 "border-box 하단"에서 "dot 하단"으로 옮겨가고, inline-flex 인 SRadio·
14121
+ // SRadioGroup 의 baseline 까지 따라 움직여 선택할 때마다 줄 상자가 3px 흔들린다
14122
+ // (SKeyValueTable 의 td 처럼 baseline 정렬되는 곳에서 눈에 띈다).
14123
+ /* @__PURE__ */ jsxRuntime.jsx(
13564
14124
  "span",
13565
14125
  {
13566
- className: "h-[10px] w-[10px] rounded-full",
14126
+ className: "absolute top-1/2 left-1/2 h-(--cmp-radio-dot-size) w-(--cmp-radio-dot-size) -translate-x-1/2 -translate-y-1/2 rounded-(--cmp-radio-radius)",
13567
14127
  style: {
13568
14128
  background: disabled ? "var(--cmp-radio-dot-disabled)" : "var(--cmp-radio-dot-default)"
13569
14129
  }
@@ -13574,13 +14134,20 @@ function SRadio({
13574
14134
  label && /* @__PURE__ */ jsxRuntime.jsxs(
13575
14135
  "span",
13576
14136
  {
13577
- className: "grid text-[12px] leading-[20px]",
14137
+ className: "grid",
13578
14138
  style: {
13579
14139
  color: disabled ? "var(--cmp-radio-label-disabled)" : "var(--cmp-radio-label-default)"
13580
14140
  },
13581
14141
  children: [
13582
- /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "invisible font-medium", style: { gridArea: "1 / 1" }, children: label }),
13583
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { gridArea: "1 / 1", fontWeight: checked ? 500 : 400 }, children: label })
14142
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "typo-body-sm-medium invisible", style: { gridArea: "1 / 1" }, children: label }),
14143
+ /* @__PURE__ */ jsxRuntime.jsx(
14144
+ "span",
14145
+ {
14146
+ className: checked ? "typo-body-sm-medium" : "typo-body-sm-default",
14147
+ style: { gridArea: "1 / 1" },
14148
+ children: label
14149
+ }
14150
+ )
13584
14151
  ]
13585
14152
  }
13586
14153
  )
@@ -13603,7 +14170,8 @@ function SRadioGroup({
13603
14170
  {
13604
14171
  role: "radiogroup",
13605
14172
  className: cn(
13606
- "inline-flex",
14173
+ // align-middle 은 SRadio 와 같은 이유 — inline 문맥(td 등)에서 줄 중앙에 맞춘다.
14174
+ "inline-flex align-middle",
13607
14175
  direction === "vertical" ? "flex-col gap-[var(--cmp-radio-group-gap-vertical)]" : "flex-row gap-[var(--cmp-radio-group-gap-horizontal)]",
13608
14176
  className
13609
14177
  ),
@@ -13839,7 +14407,7 @@ function SCalendar({
13839
14407
  }) }),
13840
14408
  legend.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13841
14409
  /* @__PURE__ */ jsxRuntime.jsx(SDivider, {}),
13842
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center justify-center gap-x-[var(--cmp-datepicker-calendar-legend-group-gap)] gap-y-[4px] text-[11px] leading-[18px]", children: legend.map((item3) => /* @__PURE__ */ jsxRuntime.jsxs(
14410
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center justify-center gap-x-[var(--cmp-datepicker-calendar-legend-group-gap)] gap-y-[4px] text-[11px] leading-[18px]", children: legend.map((item4) => /* @__PURE__ */ jsxRuntime.jsxs(
13843
14411
  "span",
13844
14412
  {
13845
14413
  className: "inline-flex items-center gap-[var(--cmp-datepicker-calendar-legend-gap)]",
@@ -13848,14 +14416,14 @@ function SCalendar({
13848
14416
  "span",
13849
14417
  {
13850
14418
  className: "h-[var(--cmp-datepicker-calendar-day-dot-size)] w-[var(--cmp-datepicker-calendar-day-dot-size)] rounded-full",
13851
- style: { backgroundColor: resolveColor(item3.color) },
14419
+ style: { backgroundColor: resolveColor(item4.color) },
13852
14420
  "aria-hidden": true
13853
14421
  }
13854
14422
  ),
13855
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: item3.label })
14423
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item4.label })
13856
14424
  ]
13857
14425
  },
13858
- `${item3.color}|${item3.label}`
14426
+ `${item4.color}|${item4.label}`
13859
14427
  )) })
13860
14428
  ] })
13861
14429
  ]
@@ -16977,19 +17545,19 @@ function EditorToolbarBar({
16977
17545
  closeLinkEditor();
16978
17546
  };
16979
17547
  const visible = [];
16980
- for (const item3 of items) {
16981
- if (item3 === "image" && !onImageUpload) continue;
16982
- if (item3 === "|" && (visible.length === 0 || visible[visible.length - 1] === "|")) continue;
16983
- visible.push(item3);
17548
+ for (const item4 of items) {
17549
+ if (item4 === "image" && !onImageUpload) continue;
17550
+ if (item4 === "|" && (visible.length === 0 || visible[visible.length - 1] === "|")) continue;
17551
+ visible.push(item4);
16984
17552
  }
16985
17553
  while (visible.length > 0 && visible[visible.length - 1] === "|") visible.pop();
16986
17554
  const groups = [[]];
16987
- for (const item3 of visible) {
16988
- if (item3 === "|") groups.push([]);
16989
- else groups[groups.length - 1].push(item3);
17555
+ for (const item4 of visible) {
17556
+ if (item4 === "|") groups.push([]);
17557
+ else groups[groups.length - 1].push(item4);
16990
17558
  }
16991
- const node = (item3) => {
16992
- switch (item3) {
17559
+ const node = (item4) => {
17560
+ switch (item4) {
16993
17561
  case "heading":
16994
17562
  return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown2__namespace.Root, { modal: !insideModal, children: [
16995
17563
  /* @__PURE__ */ jsxRuntime.jsx(RDropdown2__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -17024,7 +17592,7 @@ function EditorToolbarBar({
17024
17592
  level
17025
17593
  ))
17026
17594
  ] }) })
17027
- ] }, item3);
17595
+ ] }, item4);
17028
17596
  case "fontSize":
17029
17597
  return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown2__namespace.Root, { modal: !insideModal, children: [
17030
17598
  /* @__PURE__ */ jsxRuntime.jsx(RDropdown2__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsxs(ToolbarButton, { label: "\uAE00\uC790 \uD06C\uAE30", disabled: off, className: "px-[6px]", children: [
@@ -17063,7 +17631,7 @@ function EditorToolbarBar({
17063
17631
  ]
17064
17632
  }
17065
17633
  ) })
17066
- ] }, item3);
17634
+ ] }, item4);
17067
17635
  case "bold":
17068
17636
  return /* @__PURE__ */ jsxRuntime.jsx(
17069
17637
  ToolbarButton,
@@ -17075,7 +17643,7 @@ function EditorToolbarBar({
17075
17643
  onClick: () => chain()?.toggleBold().run(),
17076
17644
  children: /* @__PURE__ */ jsxRuntime.jsx(IconBold, { size: ICON_SIZE })
17077
17645
  },
17078
- item3
17646
+ item4
17079
17647
  );
17080
17648
  case "italic":
17081
17649
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17088,7 +17656,7 @@ function EditorToolbarBar({
17088
17656
  onClick: () => chain()?.toggleItalic().run(),
17089
17657
  children: /* @__PURE__ */ jsxRuntime.jsx(IconItalic, { size: ICON_SIZE })
17090
17658
  },
17091
- item3
17659
+ item4
17092
17660
  );
17093
17661
  case "underline":
17094
17662
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17101,7 +17669,7 @@ function EditorToolbarBar({
17101
17669
  onClick: () => chain()?.toggleUnderline().run(),
17102
17670
  children: /* @__PURE__ */ jsxRuntime.jsx(IconUnderline, { size: ICON_SIZE })
17103
17671
  },
17104
- item3
17672
+ item4
17105
17673
  );
17106
17674
  case "strike":
17107
17675
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17114,7 +17682,7 @@ function EditorToolbarBar({
17114
17682
  onClick: () => chain()?.toggleStrike().run(),
17115
17683
  children: /* @__PURE__ */ jsxRuntime.jsx(IconStrike, { size: ICON_SIZE })
17116
17684
  },
17117
- item3
17685
+ item4
17118
17686
  );
17119
17687
  case "code":
17120
17688
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17127,7 +17695,7 @@ function EditorToolbarBar({
17127
17695
  onClick: () => chain()?.toggleCode().run(),
17128
17696
  children: /* @__PURE__ */ jsxRuntime.jsx(IconCode, { size: ICON_SIZE })
17129
17697
  },
17130
- item3
17698
+ item4
17131
17699
  );
17132
17700
  case "color":
17133
17701
  if (mobile)
@@ -17139,7 +17707,7 @@ function EditorToolbarBar({
17139
17707
  onClick: () => setMobileView("color"),
17140
17708
  children: /* @__PURE__ */ jsxRuntime.jsx(ColorIndicator, { color: off ? "currentColor" : activeColor, children: /* @__PURE__ */ jsxRuntime.jsx(IconTextColor, { size: ICON_SIZE }) })
17141
17709
  },
17142
- item3
17710
+ item4
17143
17711
  );
17144
17712
  return /* @__PURE__ */ jsxRuntime.jsxs(RDropdown2__namespace.Root, { modal: !insideModal, children: [
17145
17713
  /* @__PURE__ */ jsxRuntime.jsx(RDropdown2__namespace.Trigger, { asChild: true, disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { label: "\uAE00\uC790\uC0C9", disabled: off, children: /* @__PURE__ */ jsxRuntime.jsx(ColorIndicator, { color: off ? "currentColor" : activeColor, children: /* @__PURE__ */ jsxRuntime.jsx(IconTextColor, { size: ICON_SIZE }) }) }) }),
@@ -17154,7 +17722,7 @@ function EditorToolbarBar({
17154
17722
  onClear: clearColor
17155
17723
  }
17156
17724
  ) }) })
17157
- ] }, item3);
17725
+ ] }, item4);
17158
17726
  case "alignLeft":
17159
17727
  return /* @__PURE__ */ jsxRuntime.jsx(
17160
17728
  ToolbarButton,
@@ -17166,7 +17734,7 @@ function EditorToolbarBar({
17166
17734
  onClick: () => chain()?.setTextAlign("left").run(),
17167
17735
  children: /* @__PURE__ */ jsxRuntime.jsx(IconAlignLeft, { size: ICON_SIZE })
17168
17736
  },
17169
- item3
17737
+ item4
17170
17738
  );
17171
17739
  case "alignCenter":
17172
17740
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17179,7 +17747,7 @@ function EditorToolbarBar({
17179
17747
  onClick: () => chain()?.setTextAlign("center").run(),
17180
17748
  children: /* @__PURE__ */ jsxRuntime.jsx(IconAlignCenter, { size: ICON_SIZE })
17181
17749
  },
17182
- item3
17750
+ item4
17183
17751
  );
17184
17752
  case "alignRight":
17185
17753
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17192,7 +17760,7 @@ function EditorToolbarBar({
17192
17760
  onClick: () => chain()?.setTextAlign("right").run(),
17193
17761
  children: /* @__PURE__ */ jsxRuntime.jsx(IconAlignRight, { size: ICON_SIZE })
17194
17762
  },
17195
- item3
17763
+ item4
17196
17764
  );
17197
17765
  case "alignJustify":
17198
17766
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17205,7 +17773,7 @@ function EditorToolbarBar({
17205
17773
  onClick: () => chain()?.setTextAlign("justify").run(),
17206
17774
  children: /* @__PURE__ */ jsxRuntime.jsx(IconAlignJustify, { size: ICON_SIZE })
17207
17775
  },
17208
- item3
17776
+ item4
17209
17777
  );
17210
17778
  case "bulletList":
17211
17779
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17218,7 +17786,7 @@ function EditorToolbarBar({
17218
17786
  onClick: () => chain()?.toggleBulletList().run(),
17219
17787
  children: /* @__PURE__ */ jsxRuntime.jsx(IconBulletList, { size: ICON_SIZE })
17220
17788
  },
17221
- item3
17789
+ item4
17222
17790
  );
17223
17791
  case "orderedList":
17224
17792
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17231,7 +17799,7 @@ function EditorToolbarBar({
17231
17799
  onClick: () => chain()?.toggleOrderedList().run(),
17232
17800
  children: /* @__PURE__ */ jsxRuntime.jsx(IconOrderedList, { size: ICON_SIZE })
17233
17801
  },
17234
- item3
17802
+ item4
17235
17803
  );
17236
17804
  case "taskList":
17237
17805
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17244,7 +17812,7 @@ function EditorToolbarBar({
17244
17812
  onClick: () => chain()?.toggleTaskList().run(),
17245
17813
  children: /* @__PURE__ */ jsxRuntime.jsx(IconTaskList, { size: ICON_SIZE })
17246
17814
  },
17247
- item3
17815
+ item4
17248
17816
  );
17249
17817
  case "list": {
17250
17818
  const ListIcon = state2.orderedList ? IconOrderedList : state2.taskList ? IconTaskList : IconBulletList;
@@ -17289,7 +17857,7 @@ function EditorToolbarBar({
17289
17857
  }
17290
17858
  )
17291
17859
  ] }) })
17292
- ] }, item3);
17860
+ ] }, item4);
17293
17861
  }
17294
17862
  case "blockquote":
17295
17863
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17302,7 +17870,7 @@ function EditorToolbarBar({
17302
17870
  onClick: () => chain()?.toggleBlockquote().run(),
17303
17871
  children: /* @__PURE__ */ jsxRuntime.jsx(IconBlockquote, { size: ICON_SIZE })
17304
17872
  },
17305
- item3
17873
+ item4
17306
17874
  );
17307
17875
  case "codeBlock":
17308
17876
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17315,7 +17883,7 @@ function EditorToolbarBar({
17315
17883
  onClick: () => chain()?.toggleCodeBlock().run(),
17316
17884
  children: /* @__PURE__ */ jsxRuntime.jsx(IconCodeBlock, { size: ICON_SIZE })
17317
17885
  },
17318
- item3
17886
+ item4
17319
17887
  );
17320
17888
  case "horizontalRule":
17321
17889
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17326,7 +17894,7 @@ function EditorToolbarBar({
17326
17894
  onClick: () => chain()?.setHorizontalRule().run(),
17327
17895
  children: /* @__PURE__ */ jsxRuntime.jsx(IconHorizontalRule, { size: ICON_SIZE })
17328
17896
  },
17329
- item3
17897
+ item4
17330
17898
  );
17331
17899
  case "link":
17332
17900
  if (mobile)
@@ -17339,7 +17907,7 @@ function EditorToolbarBar({
17339
17907
  onClick: () => setMobileView("link"),
17340
17908
  children: /* @__PURE__ */ jsxRuntime.jsx(IconLink, { size: ICON_SIZE })
17341
17909
  },
17342
- item3
17910
+ item4
17343
17911
  );
17344
17912
  return /* @__PURE__ */ jsxRuntime.jsxs(RPopover11__namespace.Root, { open: linkOpen, onOpenChange: setLinkOpen, children: [
17345
17913
  /* @__PURE__ */ jsxRuntime.jsx(RPopover11__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 }) }) }),
@@ -17364,7 +17932,7 @@ function EditorToolbarBar({
17364
17932
  )
17365
17933
  }
17366
17934
  ) })
17367
- ] }, item3);
17935
+ ] }, item4);
17368
17936
  case "image":
17369
17937
  return /* @__PURE__ */ jsxRuntime.jsxs(
17370
17938
  ToolbarButton,
@@ -17378,7 +17946,7 @@ function EditorToolbarBar({
17378
17946
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[12px] leading-[20px]", children: "\uC774\uBBF8\uC9C0" })
17379
17947
  ]
17380
17948
  },
17381
- item3
17949
+ item4
17382
17950
  );
17383
17951
  case "table":
17384
17952
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -17499,7 +18067,7 @@ function EditorToolbarBar({
17499
18067
  ] }) })
17500
18068
  ]
17501
18069
  },
17502
- item3
18070
+ item4
17503
18071
  );
17504
18072
  case "undo":
17505
18073
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17510,7 +18078,7 @@ function EditorToolbarBar({
17510
18078
  onClick: () => chain()?.undo().run(),
17511
18079
  children: /* @__PURE__ */ jsxRuntime.jsx(IconUndo, { size: ICON_SIZE })
17512
18080
  },
17513
- item3
18081
+ item4
17514
18082
  );
17515
18083
  case "redo":
17516
18084
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -17521,7 +18089,7 @@ function EditorToolbarBar({
17521
18089
  onClick: () => chain()?.redo().run(),
17522
18090
  children: /* @__PURE__ */ jsxRuntime.jsx(IconRedo, { size: ICON_SIZE })
17523
18091
  },
17524
- item3
18092
+ item4
17525
18093
  );
17526
18094
  default:
17527
18095
  return null;
@@ -18102,6 +18670,13 @@ var keywordEntries = (value) => {
18102
18670
  }
18103
18671
  return [];
18104
18672
  };
18673
+ var CSV_PASTE_SEPARATOR = /[,\r\n\t]+/;
18674
+ var newKeywordEntries = (entries3, candidates) => candidates.reduce((acc, raw) => {
18675
+ const next = raw.trim();
18676
+ if (next === "" || entries3.includes(next) || acc.includes(next)) return acc;
18677
+ return [...acc, next];
18678
+ }, []);
18679
+ var withKeywordEntries = (field, current, nextEntries) => field.matchModes ? { keywords: nextEntries, mode: isKeywordValue(current) ? current.mode : "contains" } : nextEntries;
18105
18680
  var isEmptyValue = (value) => {
18106
18681
  if (value == null) return true;
18107
18682
  if (Array.isArray(value)) return value.length === 0 || value.every((v) => v == null || v === "");
@@ -18160,8 +18735,10 @@ var singleOptionValue = (field) => {
18160
18735
  };
18161
18736
  var resolveFieldDefault = (field) => {
18162
18737
  if (field.defaultValue !== void 0 && isFixedField(field)) return field.defaultValue;
18163
- const only = singleOptionValue(field);
18164
- if (only !== void 0) return field.type === "select-multi" ? [only] : only;
18738
+ if (isFixedField(field)) {
18739
+ const only = singleOptionValue(field);
18740
+ if (only !== void 0) return field.type === "select-multi" ? [only] : only;
18741
+ }
18165
18742
  if (field.type === "datepicker-range") {
18166
18743
  if (!isInlineDateField(field) && !field.required) return void 0;
18167
18744
  const today = todayIso();
@@ -18324,7 +18901,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
18324
18901
  const prevOpenKeyRef = react.useRef(null);
18325
18902
  const valuesRef = react.useRef(values);
18326
18903
  valuesRef.current = values;
18327
- const lastSearchedValuesRef = react.useRef(values);
18904
+ const lastSearchedValuesRef = react.useRef(null);
18328
18905
  const invalidGroups = react.useMemo(() => {
18329
18906
  const invalid = /* @__PURE__ */ new Set();
18330
18907
  groups.forEach((group, groupIndex) => {
@@ -18342,7 +18919,8 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
18342
18919
  );
18343
18920
  const runSearch = react.useCallback(
18344
18921
  (next) => {
18345
- if (valuesMapEqual(lastSearchedValuesRef.current, next)) return;
18922
+ const last = lastSearchedValuesRef.current;
18923
+ if (last != null && valuesMapEqual(last, next)) return;
18346
18924
  if (!isGroupsValid(next)) return;
18347
18925
  if (!isRequiredSatisfied(next)) return;
18348
18926
  lastSearchedValuesRef.current = next;
@@ -18350,13 +18928,36 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
18350
18928
  },
18351
18929
  [isGroupsValid, isRequiredSatisfied, onSearch]
18352
18930
  );
18931
+ const keywordDraftRef = react.useRef(null);
18932
+ const commitKeywordDraft = react.useCallback(
18933
+ (key) => {
18934
+ const draft = keywordDraftRef.current;
18935
+ keywordDraftRef.current = null;
18936
+ if (draft == null || draft.key !== key) return null;
18937
+ const field = fields.find((f) => f.key === key);
18938
+ if (field == null || field.type !== "keyword" || disabled || field.disabled) return null;
18939
+ const current = valuesRef.current[key];
18940
+ const entries3 = keywordEntries(current);
18941
+ const added = newKeywordEntries(
18942
+ entries3,
18943
+ field.input === "csv" ? draft.text.split(CSV_PASTE_SEPARATOR) : [draft.text]
18944
+ );
18945
+ if (added.length === 0) return null;
18946
+ const nextValue = withKeywordEntries(field, current, [...entries3, ...added]);
18947
+ const next = { ...valuesRef.current, [key]: nextValue };
18948
+ onValueChange?.(next);
18949
+ onFilterChange?.({ key, value: nextValue, values: next });
18950
+ return next;
18951
+ },
18952
+ [disabled, fields, onFilterChange, onValueChange]
18953
+ );
18353
18954
  react.useEffect(() => {
18354
18955
  const prevKey = prevOpenKeyRef.current;
18355
18956
  if (prevKey != null && prevKey !== openKey) {
18356
- runSearch(valuesRef.current);
18957
+ runSearch(commitKeywordDraft(prevKey) ?? valuesRef.current);
18357
18958
  }
18358
18959
  prevOpenKeyRef.current = openKey;
18359
- }, [openKey, runSearch]);
18960
+ }, [commitKeywordDraft, openKey, runSearch]);
18360
18961
  react.useEffect(() => {
18361
18962
  fields.forEach((field) => {
18362
18963
  if (isEmptyValue(values[field.key])) dismissedRef.current.delete(field.key);
@@ -18455,6 +19056,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
18455
19056
  runSearch(emitValue(key, def !== void 0 ? def : null));
18456
19057
  };
18457
19058
  const removeField = (key) => {
19059
+ keywordDraftRef.current = null;
18458
19060
  const nextValues = emitValue(key, null);
18459
19061
  dismissedRef.current.add(key);
18460
19062
  setInternalActiveKeys((current) => current.filter((activeKey) => activeKey !== key));
@@ -18467,6 +19069,7 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
18467
19069
  return acc;
18468
19070
  }, {});
18469
19071
  dismissedRef.current.clear();
19072
+ keywordDraftRef.current = null;
18470
19073
  setInternalActiveKeys(fields.filter(isFixedField).map((field) => field.key));
18471
19074
  setOpenKey(null);
18472
19075
  onValueChange?.(next);
@@ -18734,6 +19337,9 @@ var SChipFilter = /* @__PURE__ */ react.forwardRef(function SChipFilter2({
18734
19337
  disabled: disabled || currentOpenField.disabled,
18735
19338
  onValueChange: (next) => emitValue(currentOpenField.key, next),
18736
19339
  onValueCommit: (next) => emitValueAndSearch(currentOpenField.key, next),
19340
+ onDraftChange: (text) => {
19341
+ keywordDraftRef.current = text.trim() === "" ? null : { key: currentOpenField.key, text };
19342
+ },
18737
19343
  onClose: () => setOpenKey(null)
18738
19344
  }
18739
19345
  )
@@ -18885,6 +19491,7 @@ function EditorPanel({
18885
19491
  disabled,
18886
19492
  onValueChange,
18887
19493
  onValueCommit,
19494
+ onDraftChange,
18888
19495
  onClose
18889
19496
  }) {
18890
19497
  const wrapsInPaddedTop = field.type === "datepicker-day" || field.type === "datepicker-range" || field.type === "datepicker-statistics";
@@ -18906,7 +19513,8 @@ function EditorPanel({
18906
19513
  value,
18907
19514
  disabled,
18908
19515
  onValueChange,
18909
- onValueCommit
19516
+ onValueCommit,
19517
+ onDraftChange
18910
19518
  }
18911
19519
  ) }) : /* @__PURE__ */ jsxRuntime.jsx(
18912
19520
  FilterEditor,
@@ -18915,7 +19523,8 @@ function EditorPanel({
18915
19523
  value,
18916
19524
  disabled,
18917
19525
  onValueChange,
18918
- onValueCommit
19526
+ onValueCommit,
19527
+ onDraftChange
18919
19528
  }
18920
19529
  ),
18921
19530
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -18968,7 +19577,8 @@ function FilterEditor({
18968
19577
  value,
18969
19578
  disabled,
18970
19579
  onValueChange,
18971
- onValueCommit
19580
+ onValueCommit,
19581
+ onDraftChange
18972
19582
  }) {
18973
19583
  if (field.type === "datepicker-statistics") {
18974
19584
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -19014,7 +19624,8 @@ function FilterEditor({
19014
19624
  value: isKeywordValue(value) ? value : keywordEntries(value),
19015
19625
  disabled,
19016
19626
  onValueChange,
19017
- onValueCommit
19627
+ onValueCommit,
19628
+ onDraftChange
19018
19629
  }
19019
19630
  );
19020
19631
  }
@@ -19337,7 +19948,6 @@ function InlineDatePresetFilter({
19337
19948
  ) : badge)
19338
19949
  ] });
19339
19950
  }
19340
- var CSV_PASTE_SEPARATOR = /[,\r\n\t]+/;
19341
19951
  var MATCH_MODE_OPTIONS = [
19342
19952
  { value: "contains", label: "\uD3EC\uD568" },
19343
19953
  { value: "exact", label: "\uC77C\uCE58" }
@@ -19351,14 +19961,19 @@ function KeywordEditor({
19351
19961
  value,
19352
19962
  disabled,
19353
19963
  onValueChange,
19354
- onValueCommit
19964
+ onValueCommit,
19965
+ onDraftChange
19355
19966
  }) {
19356
19967
  const entries3 = keywordEntries(value);
19357
- const [draft, setDraft] = react.useState("");
19968
+ const [draftText, setDraftText] = react.useState("");
19358
19969
  const [mode, setMode] = react.useState(
19359
19970
  isKeywordValue(value) ? value.mode : "contains"
19360
19971
  );
19361
19972
  const inputRef = react.useRef(null);
19973
+ const setDraft = (next) => {
19974
+ setDraftText(next);
19975
+ onDraftChange(next);
19976
+ };
19362
19977
  react.useEffect(() => {
19363
19978
  if (disabled) return;
19364
19979
  inputRef.current?.focus();
@@ -19373,11 +19988,7 @@ function KeywordEditor({
19373
19988
  setMode(next);
19374
19989
  emit3(entries3, next);
19375
19990
  };
19376
- const newEntries = (candidates) => candidates.reduce((acc, raw) => {
19377
- const next = raw.trim();
19378
- if (next === "" || entries3.includes(next) || acc.includes(next)) return acc;
19379
- return [...acc, next];
19380
- }, []);
19991
+ const newEntries = (candidates) => newKeywordEntries(entries3, candidates);
19381
19992
  const addEntry = (raw) => {
19382
19993
  const added = newEntries([raw]);
19383
19994
  if (added.length === 0) {
@@ -19403,7 +20014,7 @@ function KeywordEditor({
19403
20014
  const text = event.clipboardData.getData("text");
19404
20015
  if (!CSV_PASTE_SEPARATOR.test(text)) return;
19405
20016
  event.preventDefault();
19406
- const added = newEntries((draft + text).split(CSV_PASTE_SEPARATOR));
20017
+ const added = newEntries((draftText + text).split(CSV_PASTE_SEPARATOR));
19407
20018
  if (added.length > 0) commit([...entries3, ...added]);
19408
20019
  setDraft("");
19409
20020
  };
@@ -19414,7 +20025,7 @@ function KeywordEditor({
19414
20025
  if (event.key === "Enter") {
19415
20026
  if (event.nativeEvent.isComposing) return;
19416
20027
  event.preventDefault();
19417
- addEntry(draft);
20028
+ addEntry(draftText);
19418
20029
  }
19419
20030
  };
19420
20031
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -19446,7 +20057,7 @@ function KeywordEditor({
19446
20057
  "input",
19447
20058
  {
19448
20059
  ref: inputRef,
19449
- value: draft,
20060
+ value: draftText,
19450
20061
  disabled,
19451
20062
  placeholder: field.placeholder ?? (field.input === "csv" ? "\uB2E4\uC911 \uD0A4\uC6CC\uB4DC\uB294 \uCF64\uB9C8(,)\uB85C \uAD6C\uBD84" : "\uC785\uB825 \uD6C4 Enter\uB85C \uCD94\uAC00"),
19452
20063
  onChange: (event) => changeDraft(event.target.value),
@@ -20049,8 +20660,8 @@ var SChipInput = /* @__PURE__ */ react.forwardRef(function SChipInput2({
20049
20660
  onMouseDown: (e) => e.preventDefault(),
20050
20661
  children: [
20051
20662
  loading2 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "s-chip-input__suggestions-empty p-sd-12 text-center text-12 leading-sd-20 text-(--color-grey-65)", children: "\uBD88\uB7EC\uC624\uB294 \uC911..." }),
20052
- !effectiveAutocomplete ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-sd-8 px-sd-12 py-sd-6", children: items.map((item3, i) => {
20053
- const selected = values.includes(item3);
20663
+ !effectiveAutocomplete ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-sd-8 px-sd-12 py-sd-6", children: items.map((item4, i) => {
20664
+ const selected = values.includes(item4);
20054
20665
  const active = i === activeIndex && !selected;
20055
20666
  return /* @__PURE__ */ jsxRuntime.jsx(
20056
20667
  "div",
@@ -20061,14 +20672,14 @@ var SChipInput = /* @__PURE__ */ react.forwardRef(function SChipInput2({
20061
20672
  style: active ? { outline: "2px solid var(--color-border-accent)", outlineOffset: 1 } : void 0,
20062
20673
  onMouseDown: (e) => {
20063
20674
  e.preventDefault();
20064
- if (!selected) addChip(item3);
20675
+ if (!selected) addChip(item4);
20065
20676
  },
20066
- children: /* @__PURE__ */ jsxRuntime.jsx(SChip2, { value: item3, disabled: selected, editable: false, showRemove: false })
20677
+ children: /* @__PURE__ */ jsxRuntime.jsx(SChip2, { value: item4, disabled: selected, editable: false, showRemove: false })
20067
20678
  },
20068
- item3
20679
+ item4
20069
20680
  );
20070
- }) }) : items.map((item3, i) => {
20071
- const selected = values.includes(item3);
20681
+ }) }) : items.map((item4, i) => {
20682
+ const selected = values.includes(item4);
20072
20683
  const active = i === activeIndex && !selected;
20073
20684
  return /* @__PURE__ */ jsxRuntime.jsxs(
20074
20685
  "div",
@@ -20081,10 +20692,10 @@ var SChipInput = /* @__PURE__ */ react.forwardRef(function SChipInput2({
20081
20692
  ),
20082
20693
  onMouseDown: (e) => {
20083
20694
  e.preventDefault();
20084
- if (!selected) addChip(item3);
20695
+ if (!selected) addChip(item4);
20085
20696
  },
20086
20697
  children: [
20087
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: item3 }),
20698
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: item4 }),
20088
20699
  selected && /* @__PURE__ */ jsxRuntime.jsx(
20089
20700
  SIcon,
20090
20701
  {
@@ -20095,7 +20706,7 @@ var SChipInput = /* @__PURE__ */ react.forwardRef(function SChipInput2({
20095
20706
  )
20096
20707
  ]
20097
20708
  },
20098
- item3
20709
+ item4
20099
20710
  );
20100
20711
  })
20101
20712
  ]
@@ -20479,22 +21090,22 @@ function TimeSelector({
20479
21090
  style: {
20480
21091
  padding: "var(--cmp-timepicker-selector-section-paddingY) var(--cmp-timepicker-selector-section-paddingX)"
20481
21092
  },
20482
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "isolate flex", children: ["AM", "PM"].map((item3, index) => {
20483
- const selected = item3 === meridiem;
21093
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "isolate flex", children: ["AM", "PM"].map((item4, index) => {
21094
+ const selected = item4 === meridiem;
20484
21095
  return /* @__PURE__ */ jsxRuntime.jsx(
20485
21096
  "button",
20486
21097
  {
20487
21098
  type: "button",
20488
- onClick: () => setMeridiem(item3),
21099
+ onClick: () => setMeridiem(item4),
20489
21100
  className: cn(
20490
21101
  "box-border h-[var(--cmp-textinput-sm-height)] w-[61px] cursor-pointer border border-solid bg-white text-center text-[12px] font-medium leading-[20px]",
20491
21102
  index === 0 ? "rounded-l-[var(--cmp-select-sm-radius)]" : "rounded-r-[var(--cmp-select-sm-radius)]",
20492
21103
  index === 0 ? "-mr-px" : "",
20493
21104
  selected ? "z-[1] border-[var(--cmp-timepicker-border-focus)] text-[var(--cmp-timepicker-border-focus)]" : "border-[var(--cmp-timepicker-border-default)] text-[var(--cmp-field-hint-color)]"
20494
21105
  ),
20495
- children: item3 === "AM" ? "\uC624\uC804" : "\uC624\uD6C4"
21106
+ children: item4 === "AM" ? "\uC624\uC804" : "\uC624\uD6C4"
20496
21107
  },
20497
- item3
21108
+ item4
20498
21109
  );
20499
21110
  }) })
20500
21111
  }
@@ -20715,8 +21326,8 @@ function getTimeMinutes(value) {
20715
21326
  }
20716
21327
  function normalizeTimeRangeValue(value, rangeOrder = "strict") {
20717
21328
  if (value == null) return null;
20718
- const normalized = value.map((item3) => {
20719
- const parsed = parseTimeValue(item3);
21329
+ const normalized = value.map((item4) => {
21330
+ const parsed = parseTimeValue(item4);
20720
21331
  return formatTimeValue(parsed.hour, parsed.minute);
20721
21332
  });
20722
21333
  if (rangeOrder === "strict" && getTimeMinutes(normalized[0]) > getTimeMinutes(normalized[1])) {
@@ -20926,21 +21537,21 @@ function RangeTimeSelector({
20926
21537
  style: { gap: "var(--cmp-timepicker-selector-range-heading-gap)" },
20927
21538
  children: [
20928
21539
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-nowrap text-center text-[12px] font-bold leading-[20px] text-[var(--cmp-timepicker-selector-range-heading-color)]", children: title }),
20929
- useMeridiem && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "isolate flex", children: ["AM", "PM"].map((item3, index) => {
20930
- const selected = item3 === getMeridiem(side);
21540
+ useMeridiem && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "isolate flex", children: ["AM", "PM"].map((item4, index) => {
21541
+ const selected = item4 === getMeridiem(side);
20931
21542
  return /* @__PURE__ */ jsxRuntime.jsx(
20932
21543
  "button",
20933
21544
  {
20934
21545
  type: "button",
20935
- onClick: () => setMeridiem(side, item3),
21546
+ onClick: () => setMeridiem(side, item4),
20936
21547
  className: cn(
20937
21548
  "box-border h-[var(--cmp-textinput-sm-height)] w-[61px] cursor-pointer border border-solid bg-white text-center text-[12px] font-medium leading-[20px]",
20938
21549
  index === 0 ? "rounded-l-[var(--cmp-select-sm-radius)] -mr-px" : "rounded-r-[var(--cmp-select-sm-radius)]",
20939
21550
  selected ? "z-[1] border-[var(--cmp-timepicker-border-focus)] text-[var(--cmp-timepicker-border-focus)]" : "border-[var(--cmp-timepicker-border-default)] text-[var(--cmp-field-hint-color)]"
20940
21551
  ),
20941
- children: item3 === "AM" ? "\uC624\uC804" : "\uC624\uD6C4"
21552
+ children: item4 === "AM" ? "\uC624\uC804" : "\uC624\uD6C4"
20942
21553
  },
20943
- item3
21554
+ item4
20944
21555
  );
20945
21556
  }) })
20946
21557
  ]
@@ -21176,6 +21787,11 @@ function STimeRangePicker({
21176
21787
  );
21177
21788
  }
21178
21789
 
21790
+ exports.ACCOUNT_LIST_BOX_ICONS = ACCOUNT_LIST_BOX_ICONS;
21791
+ exports.ACCOUNT_LIST_BOX_ITEM_TONES = ACCOUNT_LIST_BOX_ITEM_TONES;
21792
+ exports.ACCOUNT_LIST_BOX_LABELS = ACCOUNT_LIST_BOX_LABELS;
21793
+ exports.ACCOUNT_LIST_BOX_LAYOUT = ACCOUNT_LIST_BOX_LAYOUT;
21794
+ exports.ACCOUNT_LIST_BOX_TONE_CONFIG = ACCOUNT_LIST_BOX_TONE_CONFIG;
21179
21795
  exports.BADGE_COLORS = BADGE_COLORS;
21180
21796
  exports.BUTTON_COLORS = BUTTON_COLORS;
21181
21797
  exports.BUTTON_SIZES = BUTTON_SIZES;
@@ -21200,6 +21816,7 @@ exports.IMAGE_FITS = IMAGE_FITS;
21200
21816
  exports.PAGE_BACKGROUNDS = PAGE_BACKGROUNDS;
21201
21817
  exports.PAGE_CONTENT_HEIGHTS = PAGE_CONTENT_HEIGHTS;
21202
21818
  exports.RangeCalendar = RangeCalendar;
21819
+ exports.SAccountListBox = SAccountListBox;
21203
21820
  exports.SActionModal = SActionModal;
21204
21821
  exports.SBadge = SBadge;
21205
21822
  exports.SBarcodeInput = SBarcodeInput;