@sia.soul/sia-react-ui 0.1.27 → 0.1.29

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.
@@ -93,6 +93,61 @@ var Checkbox2 = Object.assign(CheckboxRoot, {
93
93
  Group: CheckboxGroup
94
94
  });
95
95
 
96
+ // src/components/treeCheckState.ts
97
+ function affectedKeys(node) {
98
+ if (node.disabled || node.disableCheckbox) return [];
99
+ return [...node.checkable === false ? [] : [node.key], ...node.children?.flatMap(affectedKeys) ?? []];
100
+ }
101
+ function getTreeCheckState(nodes, keys, strictly = false) {
102
+ const checked = new Set(keys);
103
+ const halfChecked = /* @__PURE__ */ new Set();
104
+ if (strictly) return { checked, halfChecked };
105
+ const explicit = new Set(keys);
106
+ function expand(items) {
107
+ for (const node of items) {
108
+ if (explicit.has(node.key)) affectedKeys(node).forEach((key) => checked.add(key));
109
+ if (node.children) expand(node.children);
110
+ }
111
+ }
112
+ expand(nodes);
113
+ function fold(node) {
114
+ const children = node.children?.map(fold).filter((value) => value !== void 0) ?? [];
115
+ if (node.disabled || node.disableCheckbox) return void 0;
116
+ if (!children.length) return { checked: checked.has(node.key), partial: false };
117
+ const all = children.every((child) => child.checked);
118
+ const some = children.some((child) => child.checked || child.partial);
119
+ if (node.checkable !== false) {
120
+ if (all) checked.add(node.key);
121
+ else checked.delete(node.key);
122
+ if (!all && some) halfChecked.add(node.key);
123
+ }
124
+ return { checked: all, partial: !all && some };
125
+ }
126
+ nodes.forEach(fold);
127
+ return { checked, halfChecked };
128
+ }
129
+ function toggleTreeCheck(nodes, keys, node, strictly = false) {
130
+ const state = getTreeCheckState(nodes, keys, strictly);
131
+ const next = new Set(state.checked);
132
+ const checked = !next.has(node.key);
133
+ if (node.disabled || node.disableCheckbox || node.checkable === false) return { ...state, checkedValue: !checked };
134
+ (strictly ? [node.key] : affectedKeys(node)).forEach((key) => checked ? next.add(key) : next.delete(key));
135
+ if (!strictly && !checked) {
136
+ let removeParents2 = function(items) {
137
+ let found = false;
138
+ for (const item of items) {
139
+ const childFound = item.children ? removeParents2(item.children) : false;
140
+ if (childFound) next.delete(item.key);
141
+ if (item.key === node.key || childFound) found = true;
142
+ }
143
+ return found;
144
+ };
145
+ var removeParents = removeParents2;
146
+ removeParents2(nodes);
147
+ }
148
+ return { ...getTreeCheckState(nodes, [...next], strictly), checkedValue: checked };
149
+ }
150
+
96
151
  // src/components/FloatingDisplay.tsx
97
152
  import { cloneElement, useEffect as useEffect2, useId as useId2, useLayoutEffect, useMemo as useMemo2, useRef as useRef2, useState } from "react";
98
153
  import { createPortal } from "react-dom";
@@ -306,9 +361,6 @@ function collectKeys(nodes, branchOnly = false, result = []) {
306
361
  });
307
362
  return result;
308
363
  }
309
- function descendants(node) {
310
- return node.children ? collectKeys(node.children) : [];
311
- }
312
364
  function Tree({
313
365
  treeData,
314
366
  selectedKeys,
@@ -379,12 +431,11 @@ function Tree({
379
431
  setExpanded(next);
380
432
  onExpand?.([...next], { expanded: nextExpanded, node });
381
433
  }
434
+ const checkState = useMemo2(() => getTreeCheckState(treeData, checked, checkStrictly), [treeData, checked, checkStrictly]);
382
435
  function check(node) {
383
- const nodeChecked = checked.includes(node.key);
384
- const affected = checkStrictly ? [node.key] : [node.key, ...descendants(node)];
385
- const next = nodeChecked ? checked.filter((key) => !affected.includes(key)) : [.../* @__PURE__ */ new Set([...checked, ...affected])];
386
- setChecked(next);
387
- onCheck?.([...next], { checked: !nodeChecked, node });
436
+ const next = toggleTreeCheck(treeData, checked, node, checkStrictly);
437
+ setChecked([...next.checked]);
438
+ onCheck?.([...next.checked], { checked: next.checkedValue, halfCheckedKeys: [...next.halfChecked], node });
388
439
  }
389
440
  function select(node, event) {
390
441
  if (!selectable || node.selectable === false || node.disabled) return;
@@ -467,7 +518,8 @@ function Tree({
467
518
  const open = expanded.includes(node.key);
468
519
  const isSelected = selected.includes(node.key);
469
520
  const isSelectedAncestor = selectedAncestorKeys.has(node.key);
470
- const isChecked = checked.includes(node.key);
521
+ const isChecked = checkState.checked.has(node.key);
522
+ const isHalfChecked = checkState.halfChecked.has(node.key);
471
523
  const hasChildren = Boolean(node.children?.length || node.isLeaf === false);
472
524
  const nodeLoading = loading.has(node.key) || controlledLoading.has(node.key);
473
525
  const sticky = stickyAncestors && hasChildren && open;
@@ -502,7 +554,7 @@ function Tree({
502
554
  event.stopPropagation();
503
555
  void toggleExpand(node);
504
556
  }, children: nodeLoading ? /* @__PURE__ */ jsx2(Icon, { name: "loader", className: "sia-spin-icon", size: 13 }) : /* @__PURE__ */ jsx2(Icon, { name: open ? "chevron-down" : "chevron-right", size: 13 }) }) : /* @__PURE__ */ jsx2("span", { className: "sia-tree__switcher", "aria-label": open ? "\u6536\u8D77\u8282\u70B9" : "\u5C55\u5F00\u8282\u70B9", "aria-expanded": open, style: { width: normalizedSwitcherWidth, flexBasis: normalizedSwitcherWidth }, "aria-hidden": "true" }),
505
- checkable || node.checkable ? /* @__PURE__ */ jsx2("span", { onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsx2(Checkbox2, { checked: isChecked, disabled: node.disabled || node.disableCheckbox, onChange: () => check(node) }) }) : null,
557
+ checkable || node.checkable ? /* @__PURE__ */ jsx2("span", { onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsx2(Checkbox2, { checked: isChecked, indeterminate: isHalfChecked, disabled: node.disabled || node.disableCheckbox, onChange: () => check(node) }) }) : null,
506
558
  node.prefix ? /* @__PURE__ */ jsx2("span", { className: "sia-tree__prefix", onClick: (event) => event.stopPropagation(), children: node.prefix }) : null,
507
559
  showIcon ? /* @__PURE__ */ jsx2("span", { className: "sia-tree__icon", children: node.icon ?? /* @__PURE__ */ jsx2(Icon, { name: hasChildren ? "folder" : "file", size: 15 }) }) : null,
508
560
  /* @__PURE__ */ jsx2(