sellmate-design-system-react 9.0.0-beta.41 → 9.0.0-beta.42

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
@@ -5103,7 +5103,11 @@ var STag = /* @__PURE__ */ react.forwardRef(function STag2({
5103
5103
  ...rest,
5104
5104
  children: [
5105
5105
  icon && iconLeft && iconNode,
5106
- label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex min-w-0 items-center justify-center", children: label }),
5106
+ label && // leading-none: 태그는 min-height 높이가 정해지고 flex 세로 중앙 정렬하므로
5107
+ // 레이블에 line-height 가 필요 없다. 오히려 line-height 를 주면 브라우저가
5108
+ // 폰트 ascent/descent 를 정수 px 로 반올림한 뒤 남는 half-leading 을 내림 처리해
5109
+ // 베이스라인이 최대 1px 위로 밀린다(xs 에서 특히 눈에 띈다).
5110
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex min-w-0 items-center justify-center leading-none", children: label }),
5107
5111
  icon && !iconLeft && iconNode
5108
5112
  ]
5109
5113
  }
@@ -12764,6 +12768,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
12764
12768
  const dismissedByPointerRef = react.useRef(false);
12765
12769
  const alignSelectedTopRef = react.useRef(false);
12766
12770
  const selectedAnchorRef = react.useRef(-1);
12771
+ const rangeAnchorRef = react.useRef(null);
12767
12772
  const flat = react.useMemo(() => flattenOptions(options), [options]);
12768
12773
  const selectable = react.useMemo(() => selectableOptions(flat), [flat]);
12769
12774
  const hasLeaf = react.useMemo(() => flat.some((o) => !o.isGroup), [flat]);
@@ -12864,7 +12869,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
12864
12869
  if (leafValues.length === 0) return;
12865
12870
  items.push({ key: `__group_${i}__`, isGroup: true, leafValues });
12866
12871
  } else {
12867
- items.push({ key: o.value, value: o.value });
12872
+ items.push({ key: o.value, value: o.value, index: i });
12868
12873
  }
12869
12874
  });
12870
12875
  return items;
@@ -12889,20 +12894,36 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
12889
12894
  emit3([]);
12890
12895
  if (rules && rules.length > 0) setRuleError(runRules(multi ? [] : "", rules));
12891
12896
  };
12892
- const handleSelect = (nextValue) => {
12897
+ const handleSelect = (nextValue, index, extend = false) => {
12893
12898
  if (multi) {
12894
- const next = selected.includes(nextValue) ? selected.filter((v) => v !== nextValue) : [...selected, nextValue];
12895
- emit3(next);
12899
+ const anchor = rangeAnchorRef.current;
12900
+ if (extend && anchor != null && anchor !== index && filtered[anchor]?.isGroup === false) {
12901
+ const [from, to] = anchor < index ? [anchor, index] : [index, anchor];
12902
+ const selectedSet = new Set(selected);
12903
+ const shouldSelect = selectedSet.has(filtered[anchor].value);
12904
+ const rangeValues = filtered.slice(from, to + 1).filter((o) => !o.isGroup && !o.disabled).map((o) => o.value);
12905
+ const inRange = new Set(rangeValues);
12906
+ emit3(
12907
+ shouldSelect ? [...selected, ...rangeValues.filter((v) => !selectedSet.has(v))] : selected.filter((v) => !inRange.has(v))
12908
+ );
12909
+ return;
12910
+ }
12911
+ rangeAnchorRef.current = index;
12912
+ emit3(
12913
+ selected.includes(nextValue) ? selected.filter((v) => v !== nextValue) : [...selected, nextValue]
12914
+ );
12896
12915
  return;
12897
12916
  }
12898
12917
  emit3([nextValue]);
12899
12918
  commitOpen(false, [nextValue]);
12900
12919
  };
12901
12920
  const handleSelectAll = () => {
12921
+ rangeAnchorRef.current = null;
12902
12922
  emit3(allSelected ? [] : allValues);
12903
12923
  };
12904
12924
  const handleToggleGroup = (leafValues) => {
12905
12925
  if (leafValues.length === 0) return;
12926
+ rangeAnchorRef.current = null;
12906
12927
  const selectedSet = new Set(selected);
12907
12928
  const allSelectedInGroup = leafValues.every((v) => selectedSet.has(v));
12908
12929
  if (allSelectedInGroup) {
@@ -12920,6 +12941,9 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
12920
12941
  const anchor = alignSelectedTopRef.current ? selectedAnchorRef.current : -1;
12921
12942
  setFocusedIndex(anchor >= 0 ? anchor : 0);
12922
12943
  }, [open, search, navigableItems.length]);
12944
+ react.useEffect(() => {
12945
+ rangeAnchorRef.current = null;
12946
+ }, [open, search]);
12923
12947
  react.useLayoutEffect(() => {
12924
12948
  if (!open || focusedIndex < 0 || !listEl) return;
12925
12949
  const focusedEl = listEl.querySelector('[data-select-focused="true"]');
@@ -12947,7 +12971,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
12947
12971
  return current <= 0 ? navigableItems.length - 1 : current - 1;
12948
12972
  });
12949
12973
  };
12950
- const selectFocusedItem = () => {
12974
+ const selectFocusedItem = (extend = false) => {
12951
12975
  if (focusedIndex < 0 || focusedIndex >= navigableItems.length) return;
12952
12976
  const focused = navigableItems[focusedIndex];
12953
12977
  if (focused.isSelectAll) {
@@ -12958,7 +12982,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
12958
12982
  handleToggleGroup(focused.leafValues ?? []);
12959
12983
  return;
12960
12984
  }
12961
- handleSelect(focused.value);
12985
+ handleSelect(focused.value, focused.index, extend);
12962
12986
  };
12963
12987
  const handleKeyDown = (event) => {
12964
12988
  if (!open) {
@@ -12980,7 +13004,7 @@ var SSelectImpl = /* @__PURE__ */ react.forwardRef(function SSelect({
12980
13004
  }
12981
13005
  if (event.key === "Enter") {
12982
13006
  event.preventDefault();
12983
- selectFocusedItem();
13007
+ selectFocusedItem(event.shiftKey);
12984
13008
  return;
12985
13009
  }
12986
13010
  if (event.key === "Escape") {
@@ -13325,7 +13349,7 @@ function ItemList({
13325
13349
  style: { paddingTop: 4, paddingBottom: 4, paddingRight: 12, paddingLeft: padLeft },
13326
13350
  onMouseEnter: () => onHoverValue(o.value),
13327
13351
  onMouseLeave: () => onHoverValue(null),
13328
- onClick: () => onSelect(o.value),
13352
+ onClick: (event) => onSelect(o.value, idx, event.shiftKey),
13329
13353
  children: [
13330
13354
  multi && /* @__PURE__ */ jsxRuntime.jsx(
13331
13355
  CheckboxBox,
@@ -13505,6 +13529,8 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
13505
13529
  setColumnWidths(visibleCols.map(colWidthFromDef));
13506
13530
  }, [colSignature]);
13507
13531
  const selectedKeys = react.useMemo(() => new Set(selected.map((r) => r[rowKey])), [selected, rowKey]);
13532
+ const rangeAnchorRef = react.useRef(null);
13533
+ const shiftPressedRef = react.useRef(false);
13508
13534
  const isRowSelected = react.useCallback(
13509
13535
  (row) => selectedKeys.has(row[rowKey]),
13510
13536
  [selectedKeys, rowKey]
@@ -13686,18 +13712,24 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
13686
13712
  let bodyRows = rows;
13687
13713
  let topSpacer = 0;
13688
13714
  let bottomSpacer = 0;
13715
+ let rowOffset = 0;
13689
13716
  if (virtualScroll) {
13690
13717
  bodyRows = rows.slice(vsRange.start, vsRange.end);
13718
+ rowOffset = vsRange.start;
13691
13719
  topSpacer = vsRange.start * effectiveRowHeight;
13692
13720
  bottomSpacer = Math.max(0, (rowCount - vsRange.end) * effectiveRowHeight);
13693
13721
  } else if (pageInfo) {
13694
13722
  bodyRows = rows.slice(pageInfo.startIndex, pageInfo.endIndex);
13723
+ rowOffset = pageInfo.startIndex;
13695
13724
  }
13696
13725
  const isNoData = rowCount === 0 && !loading2;
13697
13726
  const showNoDataSlot = isNoData && emptySlot != null;
13698
13727
  const showPagination = !virtualScroll && (pagination != null || internalPagination);
13699
13728
  const lastPage = internalPagination ? Math.max(1, Math.ceil(rowCount / (innerRowsPerPage || 1))) : pagination?.lastPage ?? Math.max(1, Math.ceil(rowCount / (pagination?.rowsPerPage ?? 10)));
13700
13729
  const displayPage = internalPagination ? currentPage : pagination?.page ?? 1;
13730
+ react.useEffect(() => {
13731
+ rangeAnchorRef.current = null;
13732
+ }, [displayPage]);
13701
13733
  const changePage = (p) => {
13702
13734
  if (internalPagination) setCurrentPage(p);
13703
13735
  onPageChange?.(p);
@@ -13712,6 +13744,7 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
13712
13744
  };
13713
13745
  const headerCheck = getIsAllChecked(bodyRows);
13714
13746
  const toggleAll = () => {
13747
+ rangeAnchorRef.current = null;
13715
13748
  if (headerCheck === true) {
13716
13749
  const pageKeys = new Set(bodyRows.map((r) => r[rowKey]));
13717
13750
  onSelectedChange?.(selected.filter((r) => !pageKeys.has(r[rowKey])));
@@ -13720,7 +13753,23 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
13720
13753
  onSelectedChange?.([...selected, ...add]);
13721
13754
  }
13722
13755
  };
13723
- const toggleRow = (row) => {
13756
+ const toggleRow = (row, index) => {
13757
+ const anchor = rangeAnchorRef.current;
13758
+ const anchorAlive = anchor != null && anchor.index !== index && rows[anchor.index]?.[rowKey] === anchor.key;
13759
+ if (shiftPressedRef.current && anchor != null && anchorAlive) {
13760
+ const [from, to] = anchor.index < index ? [anchor.index, index] : [index, anchor.index];
13761
+ const shouldSelect = selectedKeys.has(anchor.key);
13762
+ const range = rows.slice(from, to + 1);
13763
+ if (shouldSelect) {
13764
+ const add = range.filter((r) => !selectedKeys.has(r[rowKey]));
13765
+ onSelectedChange?.([...selected, ...add]);
13766
+ } else {
13767
+ const keys = new Set(range.map((r) => r[rowKey]));
13768
+ onSelectedChange?.(selected.filter((r) => !keys.has(r[rowKey])));
13769
+ }
13770
+ return;
13771
+ }
13772
+ rangeAnchorRef.current = { index, key: row[rowKey] };
13724
13773
  if (selectedKeys.has(row[rowKey]))
13725
13774
  onSelectedChange?.(selected.filter((r) => r[rowKey] !== row[rowKey]));
13726
13775
  else onSelectedChange?.([...selected, row]);
@@ -14078,7 +14127,17 @@ var STable = /* @__PURE__ */ react.forwardRef(function STable2({
14078
14127
  maxWidth: SELECTABLE_COLUMN_WIDTH
14079
14128
  },
14080
14129
  onClick: (e) => e.stopPropagation(),
14081
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(SCheckbox, { value: isSel, onValueChange: () => toggleRow(row) }) })
14130
+ onClickCapture: (e) => {
14131
+ shiftPressedRef.current = e.shiftKey;
14132
+ if (e.shiftKey) window.getSelection()?.removeAllRanges();
14133
+ },
14134
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex select-none items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
14135
+ SCheckbox,
14136
+ {
14137
+ value: isSel,
14138
+ onValueChange: () => toggleRow(row, rowOffset + ri)
14139
+ }
14140
+ ) })
14082
14141
  }
14083
14142
  ),
14084
14143
  visibleCols.map((col, i) => {