sellmate-design-system-react 9.0.0-beta.75 → 9.0.0-beta.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/AGENTS.md +35 -0
  2. package/README.md +5 -5
  3. package/bin/sellmate-ds.mjs +91 -59
  4. package/dist/components/SCircleProgress/README.md +6 -3
  5. package/dist/components/SCircleProgress/SCircleProgress.d.ts +11 -3
  6. package/dist/components/SLinearProgress/README.md +2 -2
  7. package/dist/components/SLinearProgress/SLinearProgress.d.ts +8 -2
  8. package/dist/components/SSelect/README.md +18 -2
  9. package/dist/components/SSelect/SSelect.d.ts +28 -5
  10. package/dist/components/SSelect/index.d.ts +1 -1
  11. package/dist/components/STable/README.md +30 -20
  12. package/dist/components/STable/STable.d.ts +57 -31
  13. package/dist/components/STable/index.d.ts +1 -1
  14. package/dist/index.cjs +115 -51
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.js +115 -51
  17. package/dist/index.js.map +1 -1
  18. package/dist/llms-full.txt +91 -28
  19. package/dist/llms.txt +37 -1
  20. package/dist/styles.css +16 -0
  21. package/dist/theme.css +3 -0
  22. package/eslint/index.mjs +42 -42
  23. package/eslint/lib/class-names.mjs +23 -25
  24. package/eslint/lib/table-column.mjs +11 -11
  25. package/eslint/rules/component-group-gap.mjs +32 -30
  26. package/eslint/rules/divider-vertical-height.mjs +22 -22
  27. package/eslint/rules/field-width-grade.mjs +50 -50
  28. package/eslint/rules/no-arbitrary-class.mjs +63 -20
  29. package/eslint/rules/no-off-scale-spacing.mjs +61 -41
  30. package/eslint/rules/no-raw-html-control.mjs +38 -36
  31. package/eslint/rules/prefer-typo-preset.mjs +23 -17
  32. package/eslint/rules/require-locale-number.mjs +14 -19
  33. package/eslint/rules/table-column-width.mjs +21 -17
  34. package/eslint/rules/table-numeric-align.mjs +14 -14
  35. package/eslint/scale.gen.mjs +1 -1
  36. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -3764,43 +3764,46 @@ var STROKE = 12;
3764
3764
  var CIRCUMFERENCE = 2 * Math.PI * RADIUS;
3765
3765
  var COLOR_MAP = {
3766
3766
  primary: { arc: "var(--cmp-progress-color-active)", track: "var(--cmp-progress-color-track)" },
3767
- // inverse: 어두운 배경용 — arc 흰색, track 은 흰색 40%(회색 링)
3768
- inverse: { arc: "var(--color-white)", track: "rgba(255,255,255,0.4)" },
3769
- error: { arc: "var(--color-red-75)", track: "var(--cmp-progress-color-track)" },
3770
- complete: { arc: "#01BB4B", track: "var(--cmp-progress-color-track)" },
3767
+ // inverse: 어두운 배경용 — arc 는 반전색, track 은 반전색을 inverse-opacity 만큼만(회색 링)
3768
+ inverse: {
3769
+ arc: "var(--cmp-progress-inverse-color)",
3770
+ track: "color-mix(in srgb, var(--cmp-progress-inverse-color) var(--cmp-progress-inverse-opacity), transparent)"
3771
+ },
3772
+ warning: { arc: "var(--cmp-progress-color-warning)", track: "var(--cmp-progress-color-track)" },
3773
+ error: { arc: "var(--cmp-progress-color-error)", track: "var(--cmp-progress-color-track)" },
3774
+ complete: { arc: "var(--cmp-progress-color-success)", track: "var(--cmp-progress-color-track)" },
3771
3775
  // neutral: 콘텐츠가 아직 없는 자리를 채우는 용도 — arc 도 회색이라 진행률보다 "대기"로 읽힌다
3772
- neutral: { arc: "var(--color-grey-35)", track: "var(--cmp-progress-color-track)" }
3776
+ neutral: { arc: "var(--cmp-progress-color-neutral)", track: "var(--cmp-progress-color-track)" }
3773
3777
  };
3774
- var DEFAULT_SIZE = 80;
3775
3778
  var clamp = (v) => Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0;
3776
3779
  var SCircleProgress = /* @__PURE__ */ forwardRef(
3777
3780
  function SCircleProgress2({
3778
3781
  value = 0,
3779
3782
  type = "primary",
3780
3783
  indeterminate = false,
3781
- size = DEFAULT_SIZE,
3784
+ size,
3782
3785
  label,
3783
3786
  innerValue = false,
3784
3787
  className,
3785
3788
  style
3786
3789
  }, ref) {
3787
3790
  const v = clamp(value);
3788
- const dimension = typeof size === "number" ? `${size}px` : size;
3791
+ const dimension = size === void 0 ? "var(--cmp-progress-circular-size)" : typeof size === "number" ? `${size}px` : size;
3789
3792
  const colors = COLOR_MAP[type];
3790
3793
  const c = VIEWBOX / 2;
3791
- const percentColor = v === 0 ? "var(--sys-color-fg-tertiary, #888888)" : colors.arc;
3794
+ const percentColor = v === 0 ? "var(--sys-color-fg-tertiary)" : colors.arc;
3792
3795
  const filled = v / 100 * CIRCUMFERENCE;
3793
3796
  const showPercent = !indeterminate;
3794
3797
  const percentNode = /* @__PURE__ */ jsxs(
3795
3798
  "span",
3796
3799
  {
3797
3800
  className: cn(
3798
- "text-center text-[16px] font-bold",
3801
+ "typo-heading-md text-center",
3799
3802
  innerValue ? (
3800
3803
  // leading-[normal]: 26px leading 은 폰트 content(19px) 위아래로 홀수(7px)만큼 남아
3801
3804
  // 3px/4px 로 쪼개지고 글자가 링 중심보다 위로 뜬다. (leading-normal 은 1.5 라 동일 문제)
3802
3805
  "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 leading-[normal]"
3803
- ) : "leading-[26px]"
3806
+ ) : void 0
3804
3807
  ),
3805
3808
  style: { color: percentColor },
3806
3809
  children: [
@@ -3866,7 +3869,7 @@ var SCircleProgress = /* @__PURE__ */ forwardRef(
3866
3869
  showPercent && innerValue && percentNode
3867
3870
  ] }),
3868
3871
  showPercent && !innerValue && percentNode,
3869
- label && /* @__PURE__ */ jsx("span", { className: "text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]", children: label })
3872
+ label && /* @__PURE__ */ jsx("span", { className: "typo-feedback-sm-regular text-center text-[color:var(--cmp-progress-color-label)]", children: label })
3870
3873
  ]
3871
3874
  }
3872
3875
  );
@@ -7603,6 +7606,10 @@ function TreeBranch({ expanded, children }) {
7603
7606
  }
7604
7607
  );
7605
7608
  }
7609
+ function isRowControlClick(event) {
7610
+ const control = event.target.closest("[data-tree-control]");
7611
+ return control != null && event.currentTarget.contains(control);
7612
+ }
7606
7613
  function STreeAllItem({
7607
7614
  selected,
7608
7615
  indeterminate,
@@ -7625,14 +7632,16 @@ function STreeAllItem({
7625
7632
  "data-tree-row": rowId,
7626
7633
  tabIndex,
7627
7634
  onKeyDown,
7628
- onClick: onSelect,
7635
+ onClick: (event) => {
7636
+ if (!isRowControlClick(event)) onSelect(event);
7637
+ },
7629
7638
  className: cn(
7630
7639
  "group/tree-item box-border flex w-full cursor-pointer items-center overflow-hidden bg-(--cmp-tree-item-bg-default) px-(--cmp-tree-item-paddingX) text-left hover:bg-(--cmp-tree-item-bg-hover)",
7631
7640
  typography.rowHeight,
7632
7641
  border && "border-b border-(--cmp-tree-item-border-default)"
7633
7642
  ),
7634
7643
  children: /* @__PURE__ */ jsxs("div", { className: "box-border flex min-w-0 flex-1 items-center gap-(--cmp-tree-item-contentGap)", children: [
7635
- /* @__PURE__ */ jsx("span", { onClick: (event) => event.stopPropagation(), className: "flex shrink-0", children: /* @__PURE__ */ jsx(SCheckbox, { value: checkboxValue, onValueChange: () => onSelect() }) }),
7644
+ /* @__PURE__ */ jsx("span", { "data-tree-control": true, className: "flex shrink-0", children: /* @__PURE__ */ jsx(SCheckbox, { value: checkboxValue, onValueChange: () => onSelect() }) }),
7636
7645
  /* @__PURE__ */ jsx(
7637
7646
  "span",
7638
7647
  {
@@ -7663,6 +7672,10 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
7663
7672
  trailing,
7664
7673
  onToggle,
7665
7674
  onTreeSelect,
7675
+ // treeitem 은 포커스를 받을 수 있어야 한다. tab 순서는 STree 가 한 줄에만 0 을 줘서 정한다(roving).
7676
+ tabIndex = -1,
7677
+ // 줄 단위 키보드 조작(화살표·Enter·Space)은 줄 사이를 오가야 해서 STree 가 쥐고 내려준다
7678
+ onKeyDown,
7666
7679
  className,
7667
7680
  ...rest
7668
7681
  }, ref) {
@@ -7687,6 +7700,11 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
7687
7700
  onTreeSelect?.(node, event);
7688
7701
  };
7689
7702
  const handleRowClick = (event) => {
7703
+ if (isRowControlClick(event)) return;
7704
+ if (selectable && event.target.closest("[data-tree-label]")) {
7705
+ handleSelect(event);
7706
+ return;
7707
+ }
7690
7708
  if (hasChildren) onToggle?.(node, event);
7691
7709
  };
7692
7710
  return /* @__PURE__ */ jsxs(
@@ -7698,6 +7716,8 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
7698
7716
  "aria-expanded": hasChildren ? expanded : void 0,
7699
7717
  "aria-selected": selectable ? selected : void 0,
7700
7718
  "aria-disabled": node.disabled || void 0,
7719
+ tabIndex,
7720
+ onKeyDown,
7701
7721
  onClick: handleRowClick,
7702
7722
  className: cn(
7703
7723
  "group/tree-item box-border flex w-full items-center gap-(--cmp-tree-item-rowGap) overflow-hidden bg-(--cmp-tree-item-bg-default) px-(--cmp-tree-item-paddingX) text-left",
@@ -7743,7 +7763,7 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
7743
7763
  selectable && /* @__PURE__ */ jsx(
7744
7764
  "span",
7745
7765
  {
7746
- onClick: (event) => event.stopPropagation(),
7766
+ "data-tree-control": true,
7747
7767
  className: "flex shrink-0",
7748
7768
  "aria-hidden": node.disabled ? "true" : void 0,
7749
7769
  children: /* @__PURE__ */ jsx(
@@ -7759,11 +7779,7 @@ var STreeItemImpl = /* @__PURE__ */ forwardRef(function STreeItem({
7759
7779
  /* @__PURE__ */ jsx(
7760
7780
  "span",
7761
7781
  {
7762
- onClick: (event) => {
7763
- if (!selectable) return;
7764
- event.stopPropagation();
7765
- if (!node.disabled && selectable) onTreeSelect?.(node, event);
7766
- },
7782
+ "data-tree-label": true,
7767
7783
  className: cn(
7768
7784
  "block min-w-0 flex-1 truncate py-(--cmp-tree-item-paddingY) text-(--cmp-tree-item-text-default)",
7769
7785
  labelTypo,
@@ -8767,6 +8783,7 @@ var SContextAlert = /* @__PURE__ */ forwardRef(function SContextAlert2({ intent
8767
8783
  });
8768
8784
  var FILL_COLOR = {
8769
8785
  primary: "var(--cmp-progress-color-active)",
8786
+ warning: "var(--cmp-progress-color-warning)",
8770
8787
  error: "var(--cmp-progress-color-error)",
8771
8788
  complete: "var(--cmp-progress-color-success)"
8772
8789
  };
@@ -8775,20 +8792,20 @@ var SLinearProgress = /* @__PURE__ */ forwardRef(
8775
8792
  function SLinearProgress2({ value = 0, type = "primary", size = "sm", indeterminate = false, label, className, style }, ref) {
8776
8793
  const v = clamp2(value);
8777
8794
  const fill = FILL_COLOR[type];
8778
- const valueColor = v === 0 ? "var(--sys-color-fg-tertiary, #888888)" : fill;
8795
+ const valueColor = v === 0 ? "var(--sys-color-fg-tertiary)" : fill;
8779
8796
  const valueText = `${Math.round(v)}%`;
8780
8797
  const showValue = !indeterminate && size !== "xs";
8781
8798
  return /* @__PURE__ */ jsxs(
8782
8799
  "div",
8783
8800
  {
8784
8801
  ref,
8785
- className: cn("flex w-full flex-col gap-[12px]", className),
8802
+ className: cn("flex w-full flex-col gap-[var(--cmp-progress-linear-gap)]", className),
8786
8803
  style,
8787
8804
  children: [
8788
8805
  /* @__PURE__ */ jsxs(
8789
8806
  "div",
8790
8807
  {
8791
- className: "relative w-full overflow-hidden rounded-full bg-[var(--cmp-progress-color-track)]",
8808
+ className: "relative w-full overflow-hidden rounded-[var(--cmp-progress-linear-radius)] bg-[var(--cmp-progress-color-track)]",
8792
8809
  style: { height: `var(--cmp-progress-linear-height-${size})` },
8793
8810
  children: [
8794
8811
  /* @__PURE__ */ jsx(
@@ -8805,7 +8822,7 @@ var SLinearProgress = /* @__PURE__ */ forwardRef(
8805
8822
  /* @__PURE__ */ jsx(
8806
8823
  "span",
8807
8824
  {
8808
- className: "pointer-events-none absolute inset-x-0 top-1/2 -translate-y-1/2 select-none text-center text-[12px] font-bold leading-[20px]",
8825
+ className: "pointer-events-none absolute inset-x-0 top-1/2 -translate-y-1/2 typo-feedback-sm-bold select-none text-center",
8809
8826
  style: { color: valueColor },
8810
8827
  children: valueText
8811
8828
  }
@@ -8813,7 +8830,7 @@ var SLinearProgress = /* @__PURE__ */ forwardRef(
8813
8830
  /* @__PURE__ */ jsx(
8814
8831
  "span",
8815
8832
  {
8816
- className: "pointer-events-none absolute inset-x-0 top-1/2 -translate-y-1/2 select-none text-center text-[12px] font-bold leading-[20px] text-[color:var(--cmp-progress-bar-text)]",
8833
+ className: "pointer-events-none absolute inset-x-0 top-1/2 -translate-y-1/2 typo-feedback-sm-bold select-none text-center text-[color:var(--cmp-progress-bar-text)]",
8817
8834
  style: { clipPath: `inset(0 ${100 - v}% 0 0)` },
8818
8835
  children: valueText
8819
8836
  }
@@ -8822,7 +8839,7 @@ var SLinearProgress = /* @__PURE__ */ forwardRef(
8822
8839
  ]
8823
8840
  }
8824
8841
  ),
8825
- label && /* @__PURE__ */ jsx("span", { className: "text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]", children: label })
8842
+ label && /* @__PURE__ */ jsx("span", { className: "typo-feedback-sm-regular text-center text-[color:var(--cmp-progress-color-label)]", children: label })
8826
8843
  ]
8827
8844
  }
8828
8845
  );
@@ -15700,10 +15717,12 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
15700
15717
  }
15701
15718
  commitOpen(next);
15702
15719
  };
15720
+ const commitOpenRef = useRef(commitOpen);
15721
+ commitOpenRef.current = commitOpen;
15703
15722
  useEffect(() => {
15704
15723
  if (!insideModal || portalContainer == null || !pendingOpen) return;
15705
15724
  setPendingOpen(false);
15706
- commitOpen(true);
15725
+ commitOpenRef.current(true);
15707
15726
  }, [insideModal, pendingOpen, portalContainer]);
15708
15727
  const requestOpenRef = useRef(requestOpen);
15709
15728
  requestOpenRef.current = requestOpen;
@@ -15905,6 +15924,7 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
15905
15924
  return labelByValue.get(selected[0]) ?? valueOptions.get(selected[0])?.label ?? selected[0];
15906
15925
  })();
15907
15926
  const isPlaceholder = selected.length === 0;
15927
+ const showTriggerSpinner = loading2 && !effectiveDisabled;
15908
15928
  const showClear = clearable && !effectiveDisabled && !isPlaceholder;
15909
15929
  const handleClear = () => {
15910
15930
  emit3([]);
@@ -16079,6 +16099,7 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16079
16099
  "aria-expanded": open,
16080
16100
  "aria-controls": open ? listboxId : void 0,
16081
16101
  "aria-activedescendant": open && focusedIndex >= 0 ? activeOptionId : void 0,
16102
+ "aria-busy": showTriggerSpinner || void 0,
16082
16103
  onClick: () => requestOpen(!open),
16083
16104
  onKeyDown: handleKeyDown,
16084
16105
  className: "flex h-full w-full cursor-pointer items-center justify-between gap-[8px] bg-transparent px-[12px] text-left text-[12px] leading-[20px] outline-none disabled:cursor-not-allowed",
@@ -16130,7 +16151,7 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16130
16151
  ]
16131
16152
  }
16132
16153
  ),
16133
- /* @__PURE__ */ jsx(
16154
+ showTriggerSpinner ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "inline-flex shrink-0", "data-select-trigger-spinner": true, children: /* @__PURE__ */ jsx(SCircleProgress, { indeterminate: true, type: "neutral", size: 12 }) }) : /* @__PURE__ */ jsx(
16134
16155
  SIcon,
16135
16156
  {
16136
16157
  name: "chevronDown",
@@ -16246,12 +16267,15 @@ var SSelectImpl = /* @__PURE__ */ forwardRef(function SSelect({
16246
16267
  // 첫 페이지를 받는 중에는 "없다"고 단정하지 않는다 — 아래 로딩 표시가 대신 나온다.
16247
16268
  /* @__PURE__ */ jsx("div", { className: "px-[12px] py-[12px] text-left text-[12px] leading-[20px] text-[color:var(--cmp-listBoxItem-content-disabled)]", children: "\uD45C\uC2DC\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." })
16248
16269
  ),
16249
- loading2 && /* @__PURE__ */ jsx(
16270
+ loading2 && /* @__PURE__ */ jsxs(
16250
16271
  "div",
16251
16272
  {
16252
16273
  role: "status",
16253
- className: "px-[12px] py-[12px] text-center text-[12px] leading-[20px] text-[color:var(--cmp-listBoxItem-content-disabled)]",
16254
- children: "\uBD88\uB7EC\uC624\uB294 \uC911..."
16274
+ className: "flex items-center justify-center gap-[8px] px-[12px] py-[12px] text-[12px] leading-[20px] text-[color:var(--cmp-listBoxItem-content-disabled)]",
16275
+ children: [
16276
+ /* @__PURE__ */ jsx(SCircleProgress, { indeterminate: true, type: "neutral", size: 16 }),
16277
+ "\uBD88\uB7EC\uC624\uB294 \uC911..."
16278
+ ]
16255
16279
  }
16256
16280
  )
16257
16281
  ]
@@ -16521,7 +16545,7 @@ var colWidthFromDef = (c) => {
16521
16545
  const px = typeof c.width === "number" ? c.width : parseInt(c.width, 10);
16522
16546
  return Number.isFinite(px) ? px : DEFAULT_COLUMN_WIDTH;
16523
16547
  };
16524
- var STable = /* @__PURE__ */ forwardRef(function STable2({
16548
+ var STableImpl = /* @__PURE__ */ forwardRef(function STable({
16525
16549
  columns = [],
16526
16550
  headerGroups,
16527
16551
  rows = [],
@@ -16562,6 +16586,7 @@ var STable = /* @__PURE__ */ forwardRef(function STable2({
16562
16586
  onVirtualReachEnd,
16563
16587
  tableId,
16564
16588
  onRowClick,
16589
+ onRowDoubleClick,
16565
16590
  className,
16566
16591
  style
16567
16592
  }, ref) {
@@ -17414,13 +17439,18 @@ var STable = /* @__PURE__ */ forwardRef(function STable2({
17414
17439
  {
17415
17440
  "data-row-index": rowIndex,
17416
17441
  onClick: () => onRowClick?.(row),
17442
+ onDoubleClick: onRowDoubleClick ? (event) => {
17443
+ const target = event.target;
17444
+ if (target.closest(ROW_INTERACTIVE_SELECTOR)) return;
17445
+ onRowDoubleClick(row);
17446
+ } : void 0,
17417
17447
  onMouseDown: dragSelectOn ? (event) => startDragSelect(rowIndex, event) : void 0,
17418
17448
  onMouseEnter: dragSelectOn ? () => extendDragSelect(rowIndex) : void 0,
17419
17449
  onContextMenu: contextMenuOn ? (event) => openContextMenu(row, event) : void 0,
17420
17450
  className: cn(
17421
17451
  "group/table-row",
17422
17452
  rowHover && "hover:bg-[var(--color-grey-05)]",
17423
- onRowClick && "cursor-pointer",
17453
+ (onRowClick || onRowDoubleClick) && "cursor-pointer",
17424
17454
  dragSelectOn && "select-none"
17425
17455
  ),
17426
17456
  style: { height: virtualScroll ? effectiveRowHeight : rowH },
@@ -17443,6 +17473,7 @@ var STable = /* @__PURE__ */ forwardRef(function STable2({
17443
17473
  background: rowLocked ? LOCKED_BG : void 0
17444
17474
  },
17445
17475
  onClick: (e) => e.stopPropagation(),
17476
+ onDoubleClick: (e) => e.stopPropagation(),
17446
17477
  onClickCapture: (e) => {
17447
17478
  shiftPressedRef.current = e.shiftKey;
17448
17479
  if (e.shiftKey) window.getSelection()?.removeAllRanges();
@@ -17631,6 +17662,7 @@ var STable = /* @__PURE__ */ forwardRef(function STable2({
17631
17662
  }
17632
17663
  );
17633
17664
  });
17665
+ var STable2 = STableImpl;
17634
17666
  var COUNT_NULL = "var(--cmp-table-bar-count-null)";
17635
17667
  var totalColor = (n) => n > 0 ? "var(--cmp-table-bar-count-total)" : COUNT_NULL;
17636
17668
  var selectedColor = (n) => n > 0 ? "var(--color-brilliantblue-75)" : COUNT_NULL;
@@ -18437,11 +18469,13 @@ function SCalendar({
18437
18469
  const base = value || today;
18438
18470
  const [y, setY] = useState(() => Number(base.split("-")[0]));
18439
18471
  const [m, setM] = useState(() => Number(base.split("-")[1]));
18440
- useEffect(() => {
18472
+ const [syncedValue, setSyncedValue] = useState(value);
18473
+ if (syncedValue !== value) {
18474
+ setSyncedValue(value);
18441
18475
  const b = value || today;
18442
18476
  setY(Number(b.split("-")[0]));
18443
18477
  setM(Number(b.split("-")[1]));
18444
- }, [value]);
18478
+ }
18445
18479
  const cells = useMemo(() => monthCells(y, m), [y, m]);
18446
18480
  const eventMap = useMemo(() => {
18447
18481
  const map = /* @__PURE__ */ new Map();
@@ -19764,6 +19798,7 @@ var SChipImpl = /* @__PURE__ */ forwardRef(function SChip({
19764
19798
  {
19765
19799
  ref: inputRef,
19766
19800
  role: "textbox",
19801
+ tabIndex: 0,
19767
19802
  contentEditable: !disabled,
19768
19803
  suppressContentEditableWarning: true,
19769
19804
  spellCheck: false,
@@ -22188,6 +22223,7 @@ var SToastContainer = /* @__PURE__ */ forwardRef(
22188
22223
  const [mounted2, setMounted] = useState(false);
22189
22224
  const timers = useRef(/* @__PURE__ */ new Map());
22190
22225
  const elRefs = useRef(/* @__PURE__ */ new Map());
22226
+ const resizeObserverRef = useRef(null);
22191
22227
  const [heights, setHeights] = useState(/* @__PURE__ */ new Map());
22192
22228
  const onShowRef = useRef(onShow);
22193
22229
  const onDismissRef = useRef(onDismiss);
@@ -22201,6 +22237,8 @@ var SToastContainer = /* @__PURE__ */ forwardRef(
22201
22237
  if (!liveIds.current.has(id)) return;
22202
22238
  liveIds.current.delete(id);
22203
22239
  setToasts((prev) => prev.filter((t) => t.id !== id));
22240
+ const el = elRefs.current.get(id);
22241
+ if (el) resizeObserverRef.current?.unobserve(el);
22204
22242
  elRefs.current.delete(id);
22205
22243
  setHeights((prev) => {
22206
22244
  if (!prev.has(id)) return prev;
@@ -22234,21 +22272,31 @@ var SToastContainer = /* @__PURE__ */ forwardRef(
22234
22272
  });
22235
22273
  return () => cancelAnimationFrame(raf);
22236
22274
  }, [toasts]);
22237
- useLayoutEffect(() => {
22238
- let changed = false;
22239
- const next = new Map(heights);
22240
- toasts.forEach((t) => {
22241
- const el = elRefs.current.get(t.id);
22242
- if (el) {
22275
+ useEffect(() => {
22276
+ if (typeof ResizeObserver === "undefined") return;
22277
+ const observer = new ResizeObserver((entries4) => {
22278
+ const measured = [];
22279
+ for (const entry of entries4) {
22280
+ const el = entry.target;
22281
+ const id = el.dataset.toastId;
22243
22282
  const h = el.offsetHeight;
22244
- if (h > 0 && next.get(t.id) !== h) {
22245
- next.set(t.id, h);
22246
- changed = true;
22247
- }
22283
+ if (id != null && h > 0 && liveIds.current.has(id)) measured.push([id, h]);
22248
22284
  }
22285
+ if (measured.length === 0) return;
22286
+ setHeights((prev) => {
22287
+ if (measured.every(([id, h]) => prev.get(id) === h)) return prev;
22288
+ const next = new Map(prev);
22289
+ for (const [id, h] of measured) next.set(id, h);
22290
+ return next;
22291
+ });
22249
22292
  });
22250
- if (changed) setHeights(next);
22251
- });
22293
+ resizeObserverRef.current = observer;
22294
+ elRefs.current.forEach((el) => observer.observe(el));
22295
+ return () => {
22296
+ observer.disconnect();
22297
+ resizeObserverRef.current = null;
22298
+ };
22299
+ }, []);
22252
22300
  const scheduleAutoClose = useCallback(
22253
22301
  (id, duration) => {
22254
22302
  if (duration > 0)
@@ -22387,8 +22435,11 @@ var SToastContainer = /* @__PURE__ */ forwardRef(
22387
22435
  children: toasts.map((entry) => /* @__PURE__ */ jsx(
22388
22436
  "div",
22389
22437
  {
22438
+ "data-toast-id": entry.id,
22390
22439
  ref: (el) => {
22391
- if (el) elRefs.current.set(entry.id, el);
22440
+ if (el == null || elRefs.current.get(entry.id) === el) return;
22441
+ elRefs.current.set(entry.id, el);
22442
+ resizeObserverRef.current?.observe(el);
22392
22443
  },
22393
22444
  style: itemStyle(entry),
22394
22445
  children: /* @__PURE__ */ jsx(SToast, { ...entry.options, onClose: () => startDismiss(entry.id) })
@@ -26709,7 +26760,16 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
26709
26760
  const loading2 = effectiveAutocomplete ? loadingSuggestions && suggestions.length === 0 : loadingRecommendedItems && recommendedItems.length === 0;
26710
26761
  const isFieldEmpty = inputValue === "" && values.length > 0 && !focused;
26711
26762
  const isFieldFilled = inputValue !== "";
26763
+ const reopenDropdown = () => {
26764
+ setSuppressSuggestions(false);
26765
+ setSuppressRecommendations(false);
26766
+ };
26712
26767
  const onKeyDown = (e) => {
26768
+ if (e.key === "ArrowDown" && !showDropdown && (inputValue === "" ? suppressRecommendations : suppressSuggestions)) {
26769
+ e.preventDefault();
26770
+ reopenDropdown();
26771
+ return;
26772
+ }
26713
26773
  if (showDropdown && items.length > 0) {
26714
26774
  if (e.key === "ArrowDown") {
26715
26775
  e.preventDefault();
@@ -26787,10 +26847,10 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
26787
26847
  "relative box-border flex w-full flex-wrap content-center items-center gap-(--cmp-chipInput-chip-gap)",
26788
26848
  size === "md" ? "min-h-(--cmp-chipInput-md-minHeight) px-(--cmp-chipInput-md-paddingX) py-(--cmp-chipInput-md-paddingY)" : "min-h-(--cmp-chipInput-sm-minHeight) px-(--cmp-chipInput-sm-paddingX) py-(--cmp-chipInput-sm-paddingY)"
26789
26849
  ),
26850
+ role: "presentation",
26790
26851
  onClick: () => {
26791
26852
  if (!disabled) {
26792
- setSuppressSuggestions(false);
26793
- setSuppressRecommendations(false);
26853
+ reopenDropdown();
26794
26854
  inputRef.current?.focus();
26795
26855
  }
26796
26856
  },
@@ -26921,6 +26981,7 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
26921
26981
  metaPlacement === "end" && "ml-auto"
26922
26982
  ),
26923
26983
  "data-placement": metaPlacement,
26984
+ role: "presentation",
26924
26985
  onMouseDown: (e) => e.preventDefault(),
26925
26986
  children: [
26926
26987
  /* @__PURE__ */ jsx(
@@ -26977,6 +27038,7 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
26977
27038
  {
26978
27039
  id: listboxId,
26979
27040
  role: "listbox",
27041
+ tabIndex: -1,
26980
27042
  className: "s-chip-input__suggestions flex w-full flex-col outline-none",
26981
27043
  onMouseDown: (e) => e.preventDefault(),
26982
27044
  children: [
@@ -26990,6 +27052,7 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
26990
27052
  id: active ? activeOptionId : void 0,
26991
27053
  role: "option",
26992
27054
  "aria-selected": selected || active,
27055
+ tabIndex: -1,
26993
27056
  className: "rounded-full",
26994
27057
  style: active ? { outline: "2px solid var(--color-border-accent)", outlineOffset: 1 } : void 0,
26995
27058
  onMouseDown: (e) => {
@@ -27009,6 +27072,7 @@ var SChipInput = /* @__PURE__ */ forwardRef(function SChipInput2({
27009
27072
  id: active ? activeOptionId : void 0,
27010
27073
  role: "option",
27011
27074
  "aria-selected": selected || active,
27075
+ tabIndex: -1,
27012
27076
  className: cn(
27013
27077
  "s-chip-input__suggestion-item flex shrink-0 cursor-pointer items-center gap-sd-8 overflow-hidden text-ellipsis whitespace-nowrap px-sd-12 py-sd-4 text-12 leading-sd-20",
27014
27078
  selected ? "cursor-default overflow-visible font-bold text-(--cmp-listBoxItem-content-selected)" : active ? "bg-(--cmp-listBoxItem-bg-hover) font-medium text-(--cmp-listBoxItem-content-hover)" : "text-(--cmp-listBoxItem-content-default)"
@@ -28124,6 +28188,6 @@ function STimeRangePicker({
28124
28188
  );
28125
28189
  }
28126
28190
 
28127
- export { ACCOUNT_LIST_BOX_ICONS, ACCOUNT_LIST_BOX_ITEM_TONES, ACCOUNT_LIST_BOX_LABELS, ACCOUNT_LIST_BOX_LAYOUT, ACCOUNT_LIST_BOX_TONE_CONFIG, BADGE_COLORS, BAR_GAP, BAR_SIZE_MAX, BAR_SIZE_MIN, BUTTON_COLORS, BUTTON_SIZES, CALENDAR_BOARD_DAY_BG, CALENDAR_BOARD_DAY_COLORS, CALENDAR_BOARD_EVENT_COLORS, CALENDAR_BOARD_EVENT_PRESETS, CALENDAR_BOARD_MAX_VISIBLE_EVENTS, CHAT_ATTACHED_FILE_CONFIG, CHAT_FILE_CONFIG, CHAT_MESSAGE_DIRECTIONS, CHAT_MESSAGE_READ_STATUSES, CHAT_MESSAGE_VARIANTS, CHIP_COLORS, COLOR_KEYS, CONTEXT_ALERT_ICON_COLOR, CONTEXT_ALERT_INTENTS, CONTEXT_ALERT_SURFACE, FIELD_WIDTH_GRADES, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_FULL_LOGO_WIDTH, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, GNB_SYSTEM_COLORS, GNB_SYSTEM_COLOR_CONFIG, GNB_SYSTEM_LAYOUT, GNB_SYSTEM_PLACEMENTS, GNB_SYSTEM_TOP_COLOR_CONFIG, ICONS, IMAGE_FITS, LAUNCHER_LIST_BOX_CONSOLE_HEIGHT, LAUNCHER_LIST_BOX_CONSOLE_ICON, LAUNCHER_LIST_BOX_CONSOLE_LABEL, LAUNCHER_LIST_BOX_LAYOUT, LAUNCHER_LIST_BOX_LOGO_HEIGHT, LAUNCHER_LIST_BOX_TRAILING_ICON, LAUNCHER_LIST_BOX_WIDTH, LAUNCHER_SERVICES, LAUNCHER_SERVICE_CATALOG, LOGO_DEFAULT_SIZE, LOGO_DIRECTIONS, LOGO_MODES, LOGO_NAMES, PAGE_BACKGROUNDS, PAGE_CONTENT_HEIGHTS, PAGE_CONTENT_WIDTHS, PAGE_HEADER_VARIANTS, PAGE_PADDINGS, RangeCalendar, SAccountListBox, SActionModal, SBadge, SBarChart, SBarcodeInput, SButton, SCROLL_AREA_AXES, SCalendar, SCalendarBoard, SCallout, SCard, SChatAttachedFile2 as SChatAttachedFile, SChatFile2 as SChatFile, SChatInput2 as SChatInput, SChatMessage2 as SChatMessage, SChatSystemMessage2 as SChatSystemMessage, SCheckbox, SChip2 as SChip, SChipFilter, SChipInput, SCircleProgress, SConfirmModal, SContextAlert, SDatePicker, SDatePickerMonthListbox, SDatePickerYearListbox, SDateRangePicker, SDivider, SDonutChart, SDraggableGroup, SDraggableItem2 as SDraggableItem, SDraggableList, SDraggableProvider, SDrawer, SDropdownButton2 as SDropdownButton, SEDITOR_DEFAULT_FONT_SIZE, SEDITOR_HEADING_LABELS, SEDITOR_HEADING_LEVELS, SEditor, SExpansionItem, SExpansionList2 as SExpansionList, SField, SFilePicker, SForm, SGhostButton, SGnb, SGnbSystem, SGnbSystemContext, SGuide, SIcon, SImage, SInput, SKeyValueTable, SLAYOUT_MIN_WIDTH, SLauncherListBox, SLayout, SLayoutContext, SLineChart, SLinearProgress, SList2 as SList, SListItem2 as SListItem, SLoadingContainer, SLoadingModal, SLoginCard2 as SLoginCard, SLogo, SMeatballButton2 as SMeatballButton, SModal, SModalOutlet, SNumberInput, SPage, SPageHeader, SPagination, SPieChart, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioCard, SRadioCardGroup, SRadioGroup, SSPLITTER_UNITS, SScrollArea, SSearchInput, SSectionHeaderCard2 as SSectionHeaderCard, SSelect2 as SSelect, SSplitter2 as SSplitter, SStepper, SSwitch, SSystemActionButton, STEPPER_SIZES, STable, STableBar, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip2 as STooltip, STree2 as STree, STreeItem2 as STreeItem, SYSTEM_ACTION_BUTTON_COLORS, SYSTEM_ACTION_BUTTON_COLOR_CONFIG, SYSTEM_ACTION_BUTTON_LAYOUT, SYSTEM_ACTION_BUTTON_TYPES, SYSTEM_ACTION_BUTTON_TYPE_CONFIG, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, fieldWidthValue, fileExtension, findGnbAncestors, findGnbRailValue, formatFileSize, isColorKey, isFieldWidthGrade, loading, normalizeExtension, resolveColor, useSLayout };
28191
+ export { ACCOUNT_LIST_BOX_ICONS, ACCOUNT_LIST_BOX_ITEM_TONES, ACCOUNT_LIST_BOX_LABELS, ACCOUNT_LIST_BOX_LAYOUT, ACCOUNT_LIST_BOX_TONE_CONFIG, BADGE_COLORS, BAR_GAP, BAR_SIZE_MAX, BAR_SIZE_MIN, BUTTON_COLORS, BUTTON_SIZES, CALENDAR_BOARD_DAY_BG, CALENDAR_BOARD_DAY_COLORS, CALENDAR_BOARD_EVENT_COLORS, CALENDAR_BOARD_EVENT_PRESETS, CALENDAR_BOARD_MAX_VISIBLE_EVENTS, CHAT_ATTACHED_FILE_CONFIG, CHAT_FILE_CONFIG, CHAT_MESSAGE_DIRECTIONS, CHAT_MESSAGE_READ_STATUSES, CHAT_MESSAGE_VARIANTS, CHIP_COLORS, COLOR_KEYS, CONTEXT_ALERT_ICON_COLOR, CONTEXT_ALERT_INTENTS, CONTEXT_ALERT_SURFACE, FIELD_WIDTH_GRADES, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_FULL_LOGO_WIDTH, GNB_HEADER, GNB_MENU, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, GNB_SYSTEM_COLORS, GNB_SYSTEM_COLOR_CONFIG, GNB_SYSTEM_LAYOUT, GNB_SYSTEM_PLACEMENTS, GNB_SYSTEM_TOP_COLOR_CONFIG, ICONS, IMAGE_FITS, LAUNCHER_LIST_BOX_CONSOLE_HEIGHT, LAUNCHER_LIST_BOX_CONSOLE_ICON, LAUNCHER_LIST_BOX_CONSOLE_LABEL, LAUNCHER_LIST_BOX_LAYOUT, LAUNCHER_LIST_BOX_LOGO_HEIGHT, LAUNCHER_LIST_BOX_TRAILING_ICON, LAUNCHER_LIST_BOX_WIDTH, LAUNCHER_SERVICES, LAUNCHER_SERVICE_CATALOG, LOGO_DEFAULT_SIZE, LOGO_DIRECTIONS, LOGO_MODES, LOGO_NAMES, PAGE_BACKGROUNDS, PAGE_CONTENT_HEIGHTS, PAGE_CONTENT_WIDTHS, PAGE_HEADER_VARIANTS, PAGE_PADDINGS, RangeCalendar, SAccountListBox, SActionModal, SBadge, SBarChart, SBarcodeInput, SButton, SCROLL_AREA_AXES, SCalendar, SCalendarBoard, SCallout, SCard, SChatAttachedFile2 as SChatAttachedFile, SChatFile2 as SChatFile, SChatInput2 as SChatInput, SChatMessage2 as SChatMessage, SChatSystemMessage2 as SChatSystemMessage, SCheckbox, SChip2 as SChip, SChipFilter, SChipInput, SCircleProgress, SConfirmModal, SContextAlert, SDatePicker, SDatePickerMonthListbox, SDatePickerYearListbox, SDateRangePicker, SDivider, SDonutChart, SDraggableGroup, SDraggableItem2 as SDraggableItem, SDraggableList, SDraggableProvider, SDrawer, SDropdownButton2 as SDropdownButton, SEDITOR_DEFAULT_FONT_SIZE, SEDITOR_HEADING_LABELS, SEDITOR_HEADING_LEVELS, SEditor, SExpansionItem, SExpansionList2 as SExpansionList, SField, SFilePicker, SForm, SGhostButton, SGnb, SGnbSystem, SGnbSystemContext, SGuide, SIcon, SImage, SInput, SKeyValueTable, SLAYOUT_MIN_WIDTH, SLauncherListBox, SLayout, SLayoutContext, SLineChart, SLinearProgress, SList2 as SList, SListItem2 as SListItem, SLoadingContainer, SLoadingModal, SLoginCard2 as SLoginCard, SLogo, SMeatballButton2 as SMeatballButton, SModal, SModalOutlet, SNumberInput, SPage, SPageHeader, SPagination, SPieChart, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioCard, SRadioCardGroup, SRadioGroup, SSPLITTER_UNITS, SScrollArea, SSearchInput, SSectionHeaderCard2 as SSectionHeaderCard, SSelect2 as SSelect, SSplitter2 as SSplitter, SStepper, SSwitch, SSystemActionButton, STEPPER_SIZES, STable2 as STable, STableBar, STabs, STag, STextLink, STextarea, STimePicker, STimeRangePicker, SToast, SToastContainer, SToggle, STooltip2 as STooltip, STree2 as STree, STreeItem2 as STreeItem, SYSTEM_ACTION_BUTTON_COLORS, SYSTEM_ACTION_BUTTON_COLOR_CONFIG, SYSTEM_ACTION_BUTTON_LAYOUT, SYSTEM_ACTION_BUTTON_TYPES, SYSTEM_ACTION_BUTTON_TYPE_CONFIG, TAG_COLORS, TAG_SHAPES, TAG_SIZES, TIMEPICKER_SIZES, TIMEPICKER_SIZE_CONFIG, buttonPreset, cn, fieldWidthValue, fileExtension, findGnbAncestors, findGnbRailValue, formatFileSize, isColorKey, isFieldWidthGrade, loading, normalizeExtension, resolveColor, useSLayout };
28128
28192
  //# sourceMappingURL=index.js.map
28129
28193
  //# sourceMappingURL=index.js.map