@sia.soul/sia-react-ui 0.1.0 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -87,7 +87,7 @@ import {
87
87
  message,
88
88
  notification,
89
89
  useOverlayLifecycle
90
- } from "./chunk-ULEGTKXR.js";
90
+ } from "./chunk-Q4XNFMUH.js";
91
91
  import {
92
92
  TextArea
93
93
  } from "./chunk-NZAT2RUM.js";
@@ -97,14 +97,14 @@ import {
97
97
  import {
98
98
  RichTextContent,
99
99
  RichTextEditor
100
- } from "./chunk-OMA75YLM.js";
100
+ } from "./chunk-OQLDEVCF.js";
101
101
  import {
102
102
  Dropdown,
103
103
  Input,
104
104
  Menu,
105
105
  Segmented,
106
106
  Steps
107
- } from "./chunk-DZ45HRVP.js";
107
+ } from "./chunk-IMZT6VCU.js";
108
108
  import {
109
109
  Button
110
110
  } from "./chunk-MBS2HXLZ.js";
@@ -112,17 +112,17 @@ import {
112
112
  DatePicker,
113
113
  SelectDateRange,
114
114
  TimePanel
115
- } from "./chunk-34TTF4Y7.js";
115
+ } from "./chunk-R4OWKIXJ.js";
116
116
  import {
117
117
  Select
118
- } from "./chunk-JKZGAZMB.js";
118
+ } from "./chunk-OAC7BSUR.js";
119
119
  import {
120
120
  FILLED_ICON_NAMES,
121
121
  ICON_NAMES,
122
122
  Icon,
123
123
  PopupPortal,
124
124
  useControllableState
125
- } from "./chunk-YCVXUMGP.js";
125
+ } from "./chunk-2RRTDU3N.js";
126
126
 
127
127
  // src/components/Alert.tsx
128
128
  import { useState } from "react";
@@ -1376,6 +1376,21 @@ function setValue(source, path, value) {
1376
1376
  function isEmpty(value) {
1377
1377
  return value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0;
1378
1378
  }
1379
+ function cloneFormValue(value, seen = /* @__PURE__ */ new WeakMap()) {
1380
+ if (!value || typeof value !== "object") return value;
1381
+ if (seen.has(value)) return seen.get(value);
1382
+ if (value instanceof Date) return new Date(value.getTime());
1383
+ if (value instanceof RegExp) return new RegExp(value.source, value.flags);
1384
+ const cloneable = value;
1385
+ if (typeof cloneable.clone === "function") return cloneable.clone();
1386
+ if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) return value;
1387
+ const next = Array.isArray(value) ? [] : {};
1388
+ seen.set(value, next);
1389
+ Object.keys(value).forEach((key) => {
1390
+ next[key] = cloneFormValue(value[key], seen);
1391
+ });
1392
+ return next;
1393
+ }
1379
1394
  var FormStore = class {
1380
1395
  values = {};
1381
1396
  initialValues = {};
@@ -1384,11 +1399,13 @@ var FormStore = class {
1384
1399
  listeners = /* @__PURE__ */ new Set();
1385
1400
  callbacks = {};
1386
1401
  version = 0;
1402
+ initialized = false;
1387
1403
  configure(initialValues, callbacks) {
1388
1404
  this.callbacks = callbacks;
1389
- if (initialValues && Object.keys(this.initialValues).length === 0) {
1390
- this.initialValues = structuredClone(initialValues);
1391
- this.values = structuredClone(initialValues);
1405
+ if (!this.initialized) {
1406
+ this.initialized = true;
1407
+ this.initialValues = cloneFormValue(initialValues ?? {});
1408
+ this.values = cloneFormValue(initialValues ?? {});
1392
1409
  }
1393
1410
  }
1394
1411
  subscribe = (listener) => {
@@ -1410,7 +1427,7 @@ var FormStore = class {
1410
1427
  };
1411
1428
  }
1412
1429
  getFieldValue = (name) => getValue(this.values, pathArray(name));
1413
- getFieldsValue = () => structuredClone(this.values);
1430
+ getFieldsValue = () => cloneFormValue(this.values);
1414
1431
  getFieldError = (name) => this.errors.get(pathKey2(name)) ?? [];
1415
1432
  setFieldValue = (name, value) => {
1416
1433
  const path = pathArray(name);
@@ -1428,7 +1445,7 @@ var FormStore = class {
1428
1445
  };
1429
1446
  resetFields = (names) => {
1430
1447
  if (!names) {
1431
- this.values = structuredClone(this.initialValues);
1448
+ this.values = cloneFormValue(this.initialValues);
1432
1449
  this.errors.clear();
1433
1450
  } else {
1434
1451
  names.forEach((name) => {
@@ -1617,7 +1634,7 @@ function FormItem({
1617
1634
  content = children;
1618
1635
  }
1619
1636
  }
1620
- if (noStyle) return content;
1637
+ if (noStyle) return /* @__PURE__ */ jsx9(Fragment3, { children: content });
1621
1638
  const inputWrap = /* @__PURE__ */ jsx9("div", { className: "sia-form-item__input-wrap", children: content });
1622
1639
  const hasError = status === "error" && Boolean(helpContent);
1623
1640
  return /* @__PURE__ */ jsxs9("div", { ref: itemRef, className: `sia-form-item${status ? ` sia-form-item--${status}` : ""} ${className}`.trim(), "data-sia-form-field": key || void 0, children: [
@@ -2360,14 +2377,14 @@ function TimeRangePicker({ value, defaultValue = ["", ""], placeholder = ["\u5F0
2360
2377
  // src/components/TreeSelect.tsx
2361
2378
  import { useEffect as useEffect6, useMemo as useMemo6, useRef as useRef7, useState as useState10 } from "react";
2362
2379
  import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
2363
- function flattenTree(nodes, expanded, search, depth = 0, parents = []) {
2380
+ function flattenTree(nodes, expanded, search, filter, depth = 0, parents = [], ancestorMatched = false) {
2364
2381
  const result = [];
2365
2382
  for (const node of nodes) {
2366
- const matches = !search || String(node.title).toLowerCase().includes(search.toLowerCase());
2367
- const childMatches = search && node.children ? flattenTree(node.children, new Set(node.children.map((child) => child.value)), search, depth + 1, [...parents, node.value]) : [];
2383
+ const matches = !search || ancestorMatched || filter === false || (filter ? filter(search, node) : String(node.title).toLowerCase().includes(search.toLowerCase()));
2384
+ const childMatches = search && node.children ? flattenTree(node.children, expanded, search, filter, depth + 1, [...parents, node.value], matches) : [];
2368
2385
  if (matches || childMatches.length) result.push({ ...node, depth, parentValues: parents });
2369
- if (node.children && (expanded.has(node.value) || search)) {
2370
- result.push(...search ? childMatches : flattenTree(node.children, expanded, search, depth + 1, [...parents, node.value]));
2386
+ if (node.children && (expanded.has(node.key ?? node.value) || search)) {
2387
+ result.push(...search ? childMatches : flattenTree(node.children, expanded, search, filter, depth + 1, [...parents, node.value]));
2371
2388
  }
2372
2389
  }
2373
2390
  return result;
@@ -2398,25 +2415,54 @@ function TreeSelect({
2398
2415
  onChange,
2399
2416
  onSearch,
2400
2417
  onDropdownVisibleChange,
2418
+ open: controlledOpen,
2419
+ defaultOpen = false,
2420
+ searchValue,
2421
+ treeExpandedKeys,
2422
+ treeDefaultExpandedKeys = [],
2423
+ onTreeExpand,
2424
+ filterTreeNode,
2425
+ treeCheckStrictly = true,
2426
+ showCheckedStrategy = "all",
2427
+ loading = false,
2428
+ listHeight = 300,
2429
+ popupClassName = "",
2430
+ popupStyle,
2431
+ dropdownFooter,
2432
+ displayRender,
2433
+ renderTrigger,
2434
+ onClear,
2435
+ onSelect,
2436
+ onDeselect,
2401
2437
  ...props
2402
2438
  }) {
2403
2439
  const rootRef = useRef7(null);
2404
2440
  const popupRef = useRef7(null);
2441
+ const nodeIndex = useMemo6(() => {
2442
+ const index = /* @__PURE__ */ new Map();
2443
+ const visit = (nodes) => nodes.forEach((node) => {
2444
+ index.set(node.value, node);
2445
+ if (node.children) visit(node.children);
2446
+ });
2447
+ visit(treeData);
2448
+ return index;
2449
+ }, [treeData]);
2450
+ const resolveNodes = (values) => values.map((value2) => nodeIndex.get(value2) ?? { value: value2, title: String(value2) });
2405
2451
  const multi = multiple || treeCheckable;
2406
2452
  const initial = defaultValue ?? (multi ? [] : void 0);
2407
2453
  const [currentValue, setCurrentValue] = useControllableState({
2408
- value,
2454
+ value: value === null ? [] : value,
2409
2455
  defaultValue: initial,
2410
- onChange: (next) => onChange?.(next, findNodes(treeData, Array.isArray(next) ? [...next] : next === void 0 ? [] : [next]))
2456
+ onChange: (next) => onChange?.(next, resolveNodes(Array.isArray(next) ? [...next] : next === void 0 ? [] : [next]))
2411
2457
  });
2412
- const [open, setOpen] = useState10(false);
2413
- const [search, setSearch] = useState10("");
2458
+ const [open, setOpen] = useControllableState({ value: controlledOpen, defaultValue: defaultOpen, onChange: onDropdownVisibleChange });
2459
+ const [search, setSearch] = useControllableState({ value: searchValue, defaultValue: "", onChange: onSearch });
2414
2460
  const [expanded, setExpanded] = useState10(() => {
2415
- if (!treeDefaultExpandAll) return /* @__PURE__ */ new Set();
2461
+ if (!treeDefaultExpandAll) return new Set(treeDefaultExpandedKeys);
2416
2462
  const values = [];
2417
2463
  const collect = (nodes) => nodes.forEach((node) => {
2418
2464
  if (node.children?.length) {
2419
- values.push(node.value);
2465
+ values.push(node.key ?? node.value);
2420
2466
  collect(node.children);
2421
2467
  }
2422
2468
  });
@@ -2424,99 +2470,229 @@ function TreeSelect({
2424
2470
  return new Set(values);
2425
2471
  });
2426
2472
  const selectedValues = Array.isArray(currentValue) ? [...currentValue] : currentValue === void 0 ? [] : [currentValue];
2427
- const selectedNodes = useMemo6(() => findNodes(treeData, selectedValues), [treeData, selectedValues.join("|")]);
2428
- const visibleNodes = useMemo6(() => flattenTree(treeData, expanded, search), [expanded, search, treeData]);
2473
+ const expandedSet = treeExpandedKeys ? new Set(treeExpandedKeys) : expanded;
2474
+ const selectedNodes = resolveNodes(selectedValues);
2475
+ const visibleNodes = flattenTree(treeData, expandedSet, search, filterTreeNode);
2476
+ useEffect6(() => {
2477
+ if (!open || treeExpandedKeys) return;
2478
+ const keys = new Set(expanded);
2479
+ const walk = (nodes, parents) => nodes.forEach((node) => {
2480
+ if (selectedValues.includes(node.value)) parents.forEach((key) => keys.add(key));
2481
+ if (node.children) walk(node.children, [...parents, node.key ?? node.value]);
2482
+ });
2483
+ walk(treeData, []);
2484
+ if (keys.size !== expanded.size) setExpanded(keys);
2485
+ const frame = requestAnimationFrame(() => popupRef.current?.querySelector('[aria-selected="true"]')?.scrollIntoView({ block: "nearest" }));
2486
+ return () => cancelAnimationFrame(frame);
2487
+ }, [open, treeData, currentValue, treeExpandedKeys]);
2488
+ function toggleNode(node) {
2489
+ const key = node.key ?? node.value;
2490
+ const next = new Set(expandedSet);
2491
+ if (next.has(key)) next.delete(key);
2492
+ else next.add(key);
2493
+ if (!treeExpandedKeys) setExpanded(next);
2494
+ onTreeExpand?.([...next]);
2495
+ }
2496
+ const cascade = treeCheckable && !treeCheckStrictly;
2497
+ function checkState(values) {
2498
+ const checked2 = new Set(values);
2499
+ const affected2 = (node) => node.disabled || node.disableCheckbox ? [] : [
2500
+ ...node.checkable === false ? [] : [node.value],
2501
+ ...node.children?.flatMap(affected2) ?? []
2502
+ ];
2503
+ if (cascade) {
2504
+ findNodes(treeData, values).forEach((node) => affected2(node).forEach((value2) => checked2.add(value2)));
2505
+ const fold = (nodes) => nodes.forEach((node) => {
2506
+ if (node.disabled || node.disableCheckbox) return;
2507
+ if (node.children) fold(node.children);
2508
+ const children = node.children?.filter((child) => !child.disabled && !child.disableCheckbox && child.checkable !== false) ?? [];
2509
+ if (children.length && node.checkable !== false) {
2510
+ if (children.every((child) => checked2.has(child.value))) checked2.add(node.value);
2511
+ else checked2.delete(node.value);
2512
+ }
2513
+ });
2514
+ fold(treeData);
2515
+ }
2516
+ return { checked: checked2, affected: affected2 };
2517
+ }
2518
+ const { checked, affected } = checkState(selectedValues);
2519
+ function outputValues(values) {
2520
+ if (!cascade || showCheckedStrategy === "all") return [...values];
2521
+ const output = [...values].filter((value2) => !nodeIndex.has(value2));
2522
+ const walk = (nodes, parentChecked = false) => nodes.forEach((node) => {
2523
+ const selected = values.has(node.value);
2524
+ const enabledChildren = node.children?.filter((child) => !child.disabled && !child.disableCheckbox) ?? [];
2525
+ if (selected && (showCheckedStrategy === "parent" ? !parentChecked : !enabledChildren.length)) output.push(node.value);
2526
+ if (node.children) walk(node.children, selected && !node.disabled && !node.disableCheckbox);
2527
+ });
2528
+ walk(treeData);
2529
+ return output;
2530
+ }
2531
+ function clear() {
2532
+ if (disabled || loading) return;
2533
+ setCurrentValue(multi ? [] : void 0);
2534
+ onClear?.();
2535
+ }
2429
2536
  useEffect6(() => {
2430
2537
  if (!open) return void 0;
2431
2538
  const close = (event) => {
2432
2539
  const target = event.target;
2433
2540
  if (!rootRef.current?.contains(target) && !popupRef.current?.contains(target)) {
2434
2541
  setOpen(false);
2435
- onDropdownVisibleChange?.(false);
2542
+ setSearch("");
2436
2543
  }
2437
2544
  };
2438
2545
  document.addEventListener("pointerdown", close);
2439
2546
  return () => document.removeEventListener("pointerdown", close);
2440
2547
  }, [onDropdownVisibleChange, open]);
2441
2548
  function changeOpen(next) {
2549
+ if (disabled) return;
2442
2550
  setOpen(next);
2443
- onDropdownVisibleChange?.(next);
2551
+ if (!next) setSearch("");
2444
2552
  }
2445
2553
  function select(node) {
2446
- if (node.disabled || node.selectable === false) return;
2554
+ if (disabled || loading || node.disabled) return;
2555
+ if (treeCheckable ? node.disableCheckbox || node.checkable === false : node.selectable === false) {
2556
+ if (node.children?.length) toggleNode(node);
2557
+ return;
2558
+ }
2447
2559
  if (multi) {
2448
- const next = selectedValues.includes(node.value) ? selectedValues.filter((item) => item !== node.value) : [...selectedValues, node.value];
2449
- setCurrentValue(next);
2560
+ const exists = checked.has(node.value);
2561
+ const next = new Set(checked);
2562
+ (cascade ? affected(node) : [node.value]).forEach((value2) => {
2563
+ if (exists) next.delete(value2);
2564
+ else next.add(value2);
2565
+ });
2566
+ if (cascade && exists) {
2567
+ const removeParents = (nodes) => {
2568
+ let found = false;
2569
+ nodes.forEach((item) => {
2570
+ const childFound = item.children ? removeParents(item.children) : false;
2571
+ if (childFound) next.delete(item.value);
2572
+ if (item.value === node.value || childFound) found = true;
2573
+ });
2574
+ return found;
2575
+ };
2576
+ removeParents(treeData);
2577
+ }
2578
+ setCurrentValue(outputValues(checkState([...next]).checked));
2579
+ if (exists) onDeselect?.(node.value, node);
2580
+ else onSelect?.(node.value, node);
2450
2581
  } else {
2451
2582
  setCurrentValue(node.value);
2583
+ onSelect?.(node.value, node);
2452
2584
  changeOpen(false);
2453
2585
  }
2454
2586
  }
2455
- return /* @__PURE__ */ jsxs14("div", { ref: rootRef, className: `sia-tree-select sia-tree-select--${size} sia-tree-select--${status}${open ? " is-open" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), ...props, children: [
2456
- /* @__PURE__ */ jsxs14(
2457
- "button",
2458
- {
2459
- type: "button",
2460
- className: "sia-tree-select__trigger",
2461
- disabled,
2462
- "aria-haspopup": "tree",
2463
- "aria-expanded": open,
2464
- onClick: () => changeOpen(!open),
2465
- onKeyDown: (event) => {
2466
- if (event.key === "ArrowDown") changeOpen(true);
2467
- if (event.key === "Escape") changeOpen(false);
2468
- },
2469
- children: [
2470
- /* @__PURE__ */ jsx14("span", { className: "sia-tree-select__value", children: selectedNodes.length ? multi ? /* @__PURE__ */ jsxs14(Fragment4, { children: [
2471
- selectedNodes.slice(0, maxTagCount).map((node) => /* @__PURE__ */ jsx14("span", { className: "sia-tree-select__tag", children: node.title }, node.value)),
2472
- selectedNodes.length > maxTagCount ? /* @__PURE__ */ jsxs14("span", { className: "sia-tree-select__tag", children: [
2473
- "+",
2474
- selectedNodes.length - maxTagCount
2475
- ] }) : null
2476
- ] }) : selectedNodes[0]?.title : /* @__PURE__ */ jsx14("span", { className: "sia-tree-select__placeholder", children: placeholder }) }),
2477
- allowClear && selectedValues.length && !disabled ? /* @__PURE__ */ jsx14("span", { role: "button", tabIndex: -1, className: "sia-tree-select__clear", "aria-label": "\u6E05\u9664\u9009\u62E9", onClick: (event) => {
2478
- event.stopPropagation();
2479
- setCurrentValue(multi ? [] : void 0);
2480
- }, children: /* @__PURE__ */ jsx14(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
2481
- /* @__PURE__ */ jsx14(Icon, { name: open ? "chevron-up" : "chevron-down", size: 14 })
2482
- ]
2587
+ return /* @__PURE__ */ jsxs14(
2588
+ "div",
2589
+ {
2590
+ ref: rootRef,
2591
+ className: `sia-tree-select sia-tree-select--${size} sia-tree-select--${status}${open ? " is-open" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(),
2592
+ ...props,
2593
+ onKeyDown: (event) => {
2594
+ props.onKeyDown?.(event);
2595
+ if (event.key === "Escape") {
2596
+ event.stopPropagation();
2597
+ changeOpen(false);
2598
+ }
2599
+ },
2600
+ children: [
2601
+ renderTrigger ? renderTrigger({ open, toggle: () => changeOpen(!open), clear }) : /* @__PURE__ */ jsxs14(Fragment4, { children: [
2602
+ /* @__PURE__ */ jsxs14(
2603
+ "button",
2604
+ {
2605
+ type: "button",
2606
+ className: "sia-tree-select__trigger",
2607
+ disabled,
2608
+ "aria-haspopup": "tree",
2609
+ "aria-expanded": open,
2610
+ "aria-label": props["aria-label"],
2611
+ onClick: () => changeOpen(!open),
2612
+ onKeyDown: (event) => {
2613
+ if (event.key === "ArrowDown") {
2614
+ event.preventDefault();
2615
+ changeOpen(true);
2616
+ }
2617
+ if (event.key === "Escape") changeOpen(false);
2618
+ },
2619
+ children: [
2620
+ /* @__PURE__ */ jsx14("span", { className: "sia-tree-select__value", children: selectedNodes.length ? displayRender ? displayRender(selectedNodes) : multi ? /* @__PURE__ */ jsxs14(Fragment4, { children: [
2621
+ selectedNodes.slice(0, maxTagCount).map((node) => /* @__PURE__ */ jsx14("span", { className: "sia-tree-select__tag", children: node.title }, node.value)),
2622
+ selectedNodes.length > maxTagCount ? /* @__PURE__ */ jsxs14("span", { className: "sia-tree-select__tag", children: [
2623
+ "+",
2624
+ selectedNodes.length - maxTagCount
2625
+ ] }) : null
2626
+ ] }) : selectedNodes[0]?.title : /* @__PURE__ */ jsx14("span", { className: "sia-tree-select__placeholder", children: placeholder }) }),
2627
+ /* @__PURE__ */ jsx14(Icon, { name: open ? "chevron-up" : "chevron-down", size: 14 })
2628
+ ]
2629
+ }
2630
+ ),
2631
+ allowClear && selectedValues.length > 0 && !disabled ? /* @__PURE__ */ jsx14("button", { type: "button", className: "sia-tree-select__clear", "aria-label": "\u6E05\u9664\u9009\u62E9", onClick: clear, children: /* @__PURE__ */ jsx14(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null
2632
+ ] }),
2633
+ /* @__PURE__ */ jsxs14(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && !disabled, className: `sia-tree-select__dropdown ${popupClassName}`, style: popupStyle, children: [
2634
+ showSearch ? /* @__PURE__ */ jsxs14("label", { className: "sia-tree-select__search", children: [
2635
+ /* @__PURE__ */ jsx14(Icon, { name: "search", size: 15 }),
2636
+ /* @__PURE__ */ jsx14("input", { "aria-label": searchPlaceholder, autoFocus: true, value: search, placeholder: searchPlaceholder, onChange: (event) => setSearch(event.currentTarget.value) })
2637
+ ] }) : null,
2638
+ /* @__PURE__ */ jsx14("div", { className: "sia-tree-select__tree", role: "tree", "aria-multiselectable": multi || void 0, style: { maxHeight: listHeight }, children: loading ? /* @__PURE__ */ jsx14("div", { role: "status", className: "sia-tree-select__empty", children: "\u52A0\u8F7D\u4E2D\u2026" }) : visibleNodes.length ? visibleNodes.map((node) => {
2639
+ const hasChildren = Boolean(node.children?.length);
2640
+ const selected = checked.has(node.value);
2641
+ const partial = cascade && !selected && affected(node).some((value2) => checked.has(value2));
2642
+ return /* @__PURE__ */ jsxs14(
2643
+ "div",
2644
+ {
2645
+ className: `sia-tree-select__node${selected ? " is-selected" : ""}${node.disabled ? " is-disabled" : ""}`,
2646
+ style: { paddingInlineStart: 8 + node.depth * 20 },
2647
+ role: "treeitem",
2648
+ "aria-level": node.depth + 1,
2649
+ "aria-disabled": node.disabled || void 0,
2650
+ "aria-selected": selected,
2651
+ "aria-expanded": hasChildren ? !!search || expandedSet.has(node.key ?? node.value) : void 0,
2652
+ "aria-checked": treeCheckable ? partial ? "mixed" : selected : void 0,
2653
+ children: [
2654
+ hasChildren ? /* @__PURE__ */ jsx14("button", { type: "button", className: "sia-tree-select__expand", "aria-label": expandedSet.has(node.key ?? node.value) ? "\u6536\u8D77\u8282\u70B9" : "\u5C55\u5F00\u8282\u70B9", disabled: node.disabled, onClick: () => toggleNode(node), children: /* @__PURE__ */ jsx14(Icon, { name: expandedSet.has(node.key ?? node.value) ? "chevron-down" : "chevron-right", size: 13 }) }) : /* @__PURE__ */ jsx14("span", { className: "sia-tree-select__indent" }),
2655
+ treeCheckable && node.checkable !== false ? /* @__PURE__ */ jsx14(Checkbox, { "aria-label": typeof node.title === "string" ? node.title : void 0, checked: selected, indeterminate: partial, disabled: node.disabled || node.disableCheckbox, onChange: () => select(node) }) : null,
2656
+ /* @__PURE__ */ jsx14("button", { type: "button", className: "sia-tree-select__title", disabled: node.disabled, onClick: () => select(node), children: node.title })
2657
+ ]
2658
+ },
2659
+ node.key ?? node.value
2660
+ );
2661
+ }) : /* @__PURE__ */ jsx14("div", { className: "sia-tree-select__empty", children: "\u6682\u65E0\u5339\u914D\u8282\u70B9" }) }),
2662
+ dropdownFooter
2663
+ ] })
2664
+ ]
2665
+ }
2666
+ );
2667
+ }
2668
+
2669
+ // src/components/flatTree.ts
2670
+ function buildFlatTree(items, options = {}) {
2671
+ const { idField = "id", parentIdField = "pId", rootParentId } = options;
2672
+ const keyOf = (value) => String(value ?? "");
2673
+ const nodes = new Map(items.map((item) => [keyOf(item[idField]), { ...item, children: [] }]));
2674
+ const roots = [];
2675
+ const isRoot = (parent) => rootParentId !== void 0 ? keyOf(parent) === keyOf(rootParentId) : parent === null || parent === void 0 || parent === "" || parent === 0;
2676
+ for (const node of nodes.values()) {
2677
+ const parentKey = keyOf(node[parentIdField]);
2678
+ const parent = nodes.get(parentKey);
2679
+ let cyclic = false;
2680
+ const visited = /* @__PURE__ */ new Set([keyOf(node[idField])]);
2681
+ let ancestor = parent;
2682
+ while (ancestor) {
2683
+ const key = keyOf(ancestor[idField]);
2684
+ if (visited.has(key)) {
2685
+ cyclic = true;
2686
+ break;
2483
2687
  }
2484
- ),
2485
- /* @__PURE__ */ jsxs14(PopupPortal, { ref: popupRef, anchorRef: rootRef, open, className: "sia-tree-select__dropdown", children: [
2486
- showSearch ? /* @__PURE__ */ jsxs14("label", { className: "sia-tree-select__search", children: [
2487
- /* @__PURE__ */ jsx14(Icon, { name: "search", size: 15 }),
2488
- /* @__PURE__ */ jsx14("input", { value: search, placeholder: searchPlaceholder, onChange: (event) => {
2489
- setSearch(event.currentTarget.value);
2490
- onSearch?.(event.currentTarget.value);
2491
- } })
2492
- ] }) : null,
2493
- /* @__PURE__ */ jsx14("div", { className: "sia-tree-select__tree", role: "tree", "aria-multiselectable": multi || void 0, children: visibleNodes.length ? visibleNodes.map((node) => {
2494
- const hasChildren = Boolean(node.children?.length);
2495
- const selected = selectedValues.includes(node.value);
2496
- return /* @__PURE__ */ jsxs14(
2497
- "div",
2498
- {
2499
- className: `sia-tree-select__node${selected ? " is-selected" : ""}${node.disabled ? " is-disabled" : ""}`,
2500
- style: { paddingInlineStart: 8 + node.depth * 20 },
2501
- role: "treeitem",
2502
- "aria-selected": selected,
2503
- "aria-expanded": hasChildren ? expanded.has(node.value) : void 0,
2504
- children: [
2505
- hasChildren ? /* @__PURE__ */ jsx14("button", { type: "button", className: "sia-tree-select__expand", "aria-label": expanded.has(node.value) ? "\u6536\u8D77\u8282\u70B9" : "\u5C55\u5F00\u8282\u70B9", onClick: () => setExpanded((current) => {
2506
- const next = new Set(current);
2507
- if (next.has(node.value)) next.delete(node.value);
2508
- else next.add(node.value);
2509
- return next;
2510
- }), children: /* @__PURE__ */ jsx14(Icon, { name: expanded.has(node.value) ? "chevron-down" : "chevron-right", size: 13 }) }) : /* @__PURE__ */ jsx14("span", { className: "sia-tree-select__indent" }),
2511
- treeCheckable ? /* @__PURE__ */ jsx14(Checkbox, { checked: selected, disabled: node.disabled, onChange: () => select(node) }) : null,
2512
- /* @__PURE__ */ jsx14("button", { type: "button", className: "sia-tree-select__title", disabled: node.disabled, onClick: () => select(node), children: node.title })
2513
- ]
2514
- },
2515
- node.key ?? node.value
2516
- );
2517
- }) : /* @__PURE__ */ jsx14("div", { className: "sia-tree-select__empty", children: "\u6682\u65E0\u5339\u914D\u8282\u70B9" }) })
2518
- ] })
2519
- ] });
2688
+ visited.add(key);
2689
+ if (isRoot(ancestor[parentIdField])) break;
2690
+ ancestor = nodes.get(keyOf(ancestor[parentIdField]));
2691
+ }
2692
+ if (isRoot(node[parentIdField]) || !parent || cyclic) roots.push(node);
2693
+ else parent.children.push(node);
2694
+ }
2695
+ return roots;
2520
2696
  }
2521
2697
 
2522
2698
  // src/components/Editor.tsx
@@ -5837,10 +6013,13 @@ function TableInner(props, ref) {
5837
6013
  const [autoColumnWidths, setAutoColumnWidths] = useState16({});
5838
6014
  const getRowKey = useCallback2((record, index) => typeof rowKey === "function" ? rowKey(record, index) : record[String(rowKey)] ?? index, [rowKey]);
5839
6015
  const builtInResizePlugin = useMemo9(() => createResizePlugin(), []);
6016
+ const builtInHighlightPlugin = useMemo9(() => createHighlightPlugin(), []);
5840
6017
  const activePlugins = useMemo9(() => {
5841
6018
  const plugins = providedPlugins.filter((plugin) => resizable || plugin.id !== "resize");
5842
- return resizable && !plugins.some((plugin) => plugin.id === "resize") ? [...plugins, builtInResizePlugin] : plugins;
5843
- }, [builtInResizePlugin, providedPlugins, resizable]);
6019
+ if (!plugins.some((plugin) => plugin.id === "highlight")) plugins.push(builtInHighlightPlugin);
6020
+ if (resizable && !plugins.some((plugin) => plugin.id === "resize")) plugins.push(builtInResizePlugin);
6021
+ return plugins;
6022
+ }, [builtInHighlightPlugin, builtInResizePlugin, providedPlugins, resizable]);
5844
6023
  const sortedPlugins = useMemo9(() => [...activePlugins].sort((a, b) => (a.order ?? 100) - (b.order ?? 100)), [activePlugins]);
5845
6024
  const pluginsByIdRef = useRef13(/* @__PURE__ */ new Map());
5846
6025
  pluginsByIdRef.current = new Map(sortedPlugins.map((plugin) => [plugin.id, plugin]));
@@ -6287,7 +6466,7 @@ function TableInner(props, ref) {
6287
6466
  summaries.length > 0 ? /* @__PURE__ */ jsx20("tfoot", { className: "sia-table__summary", children: summaries.map(renderSummaryRow) }) : null
6288
6467
  ] }) }),
6289
6468
  pipeline.rows.length === 0 ? /* @__PURE__ */ jsx20("div", { className: "sia-table__empty", role: "status", children: emptyText }) : null,
6290
- /* @__PURE__ */ jsx20("div", { className: "sia-table__scrollbar sia-table__scrollbar--horizontal", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(
6469
+ /* @__PURE__ */ jsx20("div", { className: "sia-scrollbar-track sia-table__scrollbar sia-table__scrollbar--horizontal", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(
6291
6470
  "div",
6292
6471
  {
6293
6472
  className: "sia-table__scrollbar-thumb",
@@ -6297,7 +6476,7 @@ function TableInner(props, ref) {
6297
6476
  onPointerCancel: handleScrollbarPointerEnd
6298
6477
  }
6299
6478
  ) }),
6300
- /* @__PURE__ */ jsx20("div", { className: "sia-table__scrollbar sia-table__scrollbar--vertical", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(
6479
+ /* @__PURE__ */ jsx20("div", { className: "sia-scrollbar-track sia-table__scrollbar sia-table__scrollbar--vertical", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(
6301
6480
  "div",
6302
6481
  {
6303
6482
  className: "sia-table__scrollbar-thumb",
@@ -6415,7 +6594,7 @@ function visibleRect(target) {
6415
6594
  function createTrack(axis) {
6416
6595
  const track = document.createElement("div");
6417
6596
  const thumb = document.createElement("div");
6418
- track.className = `sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
6597
+ track.className = `sia-scrollbar-track sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
6419
6598
  thumb.className = "sia-floating-scrollbar__thumb";
6420
6599
  track.dataset.axis = axis;
6421
6600
  track.setAttribute("aria-hidden", "true");
@@ -6690,6 +6869,378 @@ function applySiaTheme(mode, target = document.documentElement) {
6690
6869
  target.dataset.siaTheme = mode;
6691
6870
  target.style.colorScheme = mode;
6692
6871
  }
6872
+
6873
+ // src/components/SelectionPanel.tsx
6874
+ import { useEffect as useEffect14, useId as useId7, useMemo as useMemo10, useRef as useRef14, useState as useState17 } from "react";
6875
+ import { jsx as jsx22, jsxs as jsxs22 } from "react/jsx-runtime";
6876
+ function SelectionPanel({
6877
+ options,
6878
+ value,
6879
+ onChange,
6880
+ multiple = false,
6881
+ disabled = false,
6882
+ loading = false,
6883
+ showSearch = true,
6884
+ searchValue,
6885
+ onSearch,
6886
+ selectedOnly = false,
6887
+ showValue = false,
6888
+ displayField = "label",
6889
+ columns = 1,
6890
+ maxHeight = 250,
6891
+ autoFocusSearch = false
6892
+ }) {
6893
+ const [localSearch, setLocalSearch] = useState17("");
6894
+ const search = searchValue ?? localSearch;
6895
+ const [scrollTop, setScrollTop] = useState17(0);
6896
+ const [active, setActive] = useState17();
6897
+ const listRef = useRef14(null);
6898
+ const id = useId7();
6899
+ const selected = useMemo10(() => new Set(value), [value]);
6900
+ const count = Math.max(1, Math.floor(columns));
6901
+ const allOptions = useMemo10(() => {
6902
+ const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
6903
+ return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
6904
+ }, [options, value]);
6905
+ const filtered = useMemo10(
6906
+ () => allOptions.filter((option) => (!selectedOnly || selected.has(option.value)) && (!search || option.optionType !== "divider" && [option.label, option.value].some((text) => String(text ?? "").toLowerCase().includes(search.toLowerCase())))),
6907
+ [allOptions, selectedOnly, selected, search]
6908
+ );
6909
+ const rows = useMemo10(() => {
6910
+ const groups = /* @__PURE__ */ new Map();
6911
+ filtered.forEach((option) => {
6912
+ const items = groups.get(option.group) ?? [];
6913
+ items.push(option);
6914
+ groups.set(option.group, items);
6915
+ });
6916
+ const rows2 = [];
6917
+ let top = 0;
6918
+ for (const [group, items] of groups) {
6919
+ if (group) {
6920
+ rows2.push({ key: `group-${rows2.length}`, title: group, top, height: 30 });
6921
+ top += 30;
6922
+ }
6923
+ for (let index = 0; index < items.length; index += count) {
6924
+ const height = showValue ? 48 : 34;
6925
+ rows2.push({ key: `row-${rows2.length}`, items: items.slice(index, index + count), top, height });
6926
+ top += height;
6927
+ }
6928
+ }
6929
+ return rows2;
6930
+ }, [filtered, count, showValue]);
6931
+ const totalHeight = rows.length ? rows[rows.length - 1].top + rows[rows.length - 1].height : 0;
6932
+ const virtual = filtered.length > 100;
6933
+ const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
6934
+ const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
6935
+ useEffect14(() => {
6936
+ setScrollTop(0);
6937
+ if (listRef.current) listRef.current.scrollTop = 0;
6938
+ setActive(void 0);
6939
+ }, [search, selectedOnly, count]);
6940
+ function toggle(option) {
6941
+ if (disabled || loading || option.disabled || option.optionType === "divider") return;
6942
+ setActive(option.value);
6943
+ onChange(multiple ? selected.has(option.value) ? value.filter((item) => item !== option.value) : [...value, option.value] : [option.value]);
6944
+ }
6945
+ function batch(operation) {
6946
+ if (disabled || loading) return;
6947
+ if (operation === "clear") {
6948
+ onChange([]);
6949
+ return;
6950
+ }
6951
+ const editable = new Set(enabled.map((option) => option.value));
6952
+ const retained = value.filter((item) => !editable.has(item));
6953
+ const add = enabled.filter((option) => operation === "all" || !selected.has(option.value)).map((option) => option.value);
6954
+ onChange([...retained, ...add]);
6955
+ }
6956
+ return /* @__PURE__ */ jsxs22("div", { className: "sia-selection-panel", children: [
6957
+ showSearch && /* @__PURE__ */ jsx22(
6958
+ Input,
6959
+ {
6960
+ "aria-label": "\u641C\u7D22\u9009\u9879",
6961
+ placeholder: "\u641C\u7D22",
6962
+ autoFocus: autoFocusSearch,
6963
+ value: search,
6964
+ allowClear: true,
6965
+ onChange: (event) => {
6966
+ setLocalSearch(event.target.value);
6967
+ onSearch?.(event.target.value);
6968
+ }
6969
+ }
6970
+ ),
6971
+ multiple && /* @__PURE__ */ jsxs22("div", { className: "sia-selection-panel__actions", children: [
6972
+ /* @__PURE__ */ jsx22(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("all"), children: "\u5168\u9009" }),
6973
+ /* @__PURE__ */ jsx22(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("invert"), children: "\u53CD\u9009" }),
6974
+ /* @__PURE__ */ jsx22(Button, { variant: "link", size: "small", disabled: disabled || loading || !value.length, onClick: () => batch("clear"), children: "\u6E05\u7A7A" }),
6975
+ /* @__PURE__ */ jsxs22("span", { children: [
6976
+ "\u5DF2\u9009 ",
6977
+ value.length,
6978
+ " \u9879"
6979
+ ] })
6980
+ ] }),
6981
+ /* @__PURE__ */ jsx22(
6982
+ "div",
6983
+ {
6984
+ ref: listRef,
6985
+ role: "listbox",
6986
+ "aria-label": "\u9009\u9879\u5217\u8868",
6987
+ "aria-multiselectable": multiple || void 0,
6988
+ tabIndex: disabled ? -1 : 0,
6989
+ className: "sia-selection-panel__list",
6990
+ style: { maxHeight },
6991
+ onScroll: (event) => setScrollTop(event.currentTarget.scrollTop),
6992
+ "aria-activedescendant": active !== void 0 ? `${id}-${typeof active}-${active}` : void 0,
6993
+ onKeyDown: (event) => {
6994
+ if (disabled || loading || !enabled.length) return;
6995
+ const index = enabled.findIndex((option) => option.value === active);
6996
+ if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
6997
+ event.preventDefault();
6998
+ const next = event.key === "Home" ? 0 : event.key === "End" ? enabled.length - 1 : Math.max(0, Math.min(enabled.length - 1, index + (event.key === "ArrowDown" ? 1 : -1)));
6999
+ const option = enabled[next];
7000
+ setActive(option.value);
7001
+ const row = rows.find((row2) => row2.items?.includes(option));
7002
+ if (row && listRef.current) {
7003
+ listRef.current.scrollTop = Math.max(0, row.top - maxHeight / 2);
7004
+ setScrollTop(listRef.current.scrollTop);
7005
+ }
7006
+ } else if ((event.key === "Enter" || event.key === " ") && index >= 0) {
7007
+ event.preventDefault();
7008
+ toggle(enabled[index]);
7009
+ }
7010
+ },
7011
+ children: loading ? /* @__PURE__ */ jsx22("div", { role: "status", children: "\u52A0\u8F7D\u4E2D\u2026" }) : !rows.length ? /* @__PURE__ */ jsx22("div", { className: "sia-selection-panel__empty", children: "\u6682\u65E0\u5339\u914D\u9009\u9879" }) : /* @__PURE__ */ jsx22("div", { style: { height: totalHeight, position: "relative" }, children: renderedRows.map((row) => /* @__PURE__ */ jsx22(
7012
+ "div",
7013
+ {
7014
+ className: row.title !== void 0 ? "sia-selection-panel__group" : "sia-selection-panel__row",
7015
+ style: { position: "absolute", top: row.top, height: row.height, width: "100%", gridTemplateColumns: `repeat(${count}, minmax(0, 1fr))` },
7016
+ children: row.title ?? row.items?.map((option, index) => option.optionType === "divider" ? /* @__PURE__ */ jsx22("div", { role: "separator", className: "sia-selection-panel__divider" }, `divider-${index}`) : /* @__PURE__ */ jsx22(Tooltip, { title: option.disabled ? option.disabledTip : void 0, placement: "right", children: /* @__PURE__ */ jsxs22(
7017
+ "button",
7018
+ {
7019
+ type: "button",
7020
+ role: "option",
7021
+ id: `${id}-${typeof option.value}-${option.value}`,
7022
+ tabIndex: -1,
7023
+ "aria-selected": selected.has(option.value),
7024
+ "aria-disabled": disabled || option.disabled || void 0,
7025
+ className: `sia-selection-panel__option${active === option.value ? " is-active" : ""}`,
7026
+ onClick: () => toggle(option),
7027
+ children: [
7028
+ multiple && /* @__PURE__ */ jsx22("span", { "aria-hidden": "true", className: "sia-selection-panel__check", children: selected.has(option.value) ? "\u2713" : "" }),
7029
+ /* @__PURE__ */ jsxs22("span", { className: "sia-selection-panel__text", children: [
7030
+ showValue || displayField === "label" ? option.label : String(option.value),
7031
+ showValue && /* @__PURE__ */ jsx22("small", { children: String(option.value) })
7032
+ ] })
7033
+ ]
7034
+ }
7035
+ ) }, `${typeof option.value}-${option.value}`))
7036
+ },
7037
+ row.key
7038
+ )) })
7039
+ }
7040
+ )
7041
+ ] });
7042
+ }
7043
+
7044
+ // src/components/InputSelect.tsx
7045
+ import { forwardRef as forwardRef7, useEffect as useEffect15, useRef as useRef15, useState as useState18 } from "react";
7046
+ import { jsx as jsx23, jsxs as jsxs23 } from "react/jsx-runtime";
7047
+ var InputSelect = forwardRef7(function InputSelect2({
7048
+ options,
7049
+ value,
7050
+ defaultValue,
7051
+ onChange,
7052
+ multiple = false,
7053
+ displayField = "label",
7054
+ showValue = false,
7055
+ placeholder = "\u8BF7\u9009\u62E9",
7056
+ size = "medium",
7057
+ status,
7058
+ disabled = false,
7059
+ loading = false,
7060
+ allowClear = true,
7061
+ hideSearch,
7062
+ inputMaxLength,
7063
+ parseInput,
7064
+ enableModal,
7065
+ suffix,
7066
+ style,
7067
+ className = "",
7068
+ onOpenChange,
7069
+ ...inputProps
7070
+ }, forwardedRef) {
7071
+ const [internal, setInternal] = useState18(defaultValue);
7072
+ const current = value !== void 0 ? value : internal;
7073
+ const values = current == null ? [] : Array.isArray(current) ? current : [current];
7074
+ const text = values.map((item) => displayField === "label" ? String(options.find((option) => option.optionType !== "divider" && option.value === item)?.label ?? item) : String(item)).join(",");
7075
+ const [draft, setDraft] = useState18(text);
7076
+ useEffect15(() => {
7077
+ setDraft(text);
7078
+ }, [text, current]);
7079
+ const [open, setOpen] = useState18(false);
7080
+ const [search, setSearch] = useState18("");
7081
+ const [modalOpen, setModalOpen] = useState18(false);
7082
+ const [modalValues, setModalValues] = useState18([]);
7083
+ const [selectedOnly, setSelectedOnly] = useState18(false);
7084
+ const rootRef = useRef15(null);
7085
+ const popupRef = useRef15(null);
7086
+ const inputRef = useRef15(null);
7087
+ const config = typeof enableModal === "object" ? enableModal : {};
7088
+ function changeOpen(next) {
7089
+ if (next && (disabled || loading)) return;
7090
+ setOpen(next);
7091
+ if (next !== open) onOpenChange?.(next);
7092
+ if (!next) setSearch("");
7093
+ }
7094
+ function emit(next) {
7095
+ if (disabled || loading) return;
7096
+ if (value === void 0) setInternal(next);
7097
+ onChange?.(next);
7098
+ }
7099
+ function select(next) {
7100
+ emit(multiple ? next : next[0]);
7101
+ if (!multiple) {
7102
+ changeOpen(false);
7103
+ inputRef.current?.focus();
7104
+ }
7105
+ }
7106
+ useEffect15(() => {
7107
+ if (!open) return;
7108
+ const outside = (event) => {
7109
+ if (!rootRef.current?.contains(event.target) && !popupRef.current?.contains(event.target)) changeOpen(false);
7110
+ };
7111
+ document.addEventListener("pointerdown", outside);
7112
+ return () => document.removeEventListener("pointerdown", outside);
7113
+ }, [open, onOpenChange]);
7114
+ useEffect15(() => {
7115
+ if (disabled || loading) {
7116
+ changeOpen(false);
7117
+ setModalOpen(false);
7118
+ }
7119
+ }, [disabled, loading]);
7120
+ function openModal() {
7121
+ if (disabled || loading) return;
7122
+ changeOpen(false);
7123
+ setModalValues([...values]);
7124
+ setSelectedOnly(false);
7125
+ setModalOpen(true);
7126
+ }
7127
+ return /* @__PURE__ */ jsxs23("div", { ref: rootRef, style, className: `sia-input-select ${className}`, onKeyDown: (event) => {
7128
+ if (event.key === "Escape" && open) {
7129
+ event.stopPropagation();
7130
+ changeOpen(false);
7131
+ inputRef.current?.focus();
7132
+ }
7133
+ }, children: [
7134
+ /* @__PURE__ */ jsx23(
7135
+ Input,
7136
+ {
7137
+ ...inputProps,
7138
+ ref: (node) => {
7139
+ inputRef.current = node;
7140
+ if (typeof forwardedRef === "function") forwardedRef(node);
7141
+ else if (forwardedRef) forwardedRef.current = node;
7142
+ },
7143
+ role: "combobox",
7144
+ "aria-label": inputProps["aria-label"] ?? placeholder,
7145
+ "aria-expanded": open,
7146
+ "aria-haspopup": "listbox",
7147
+ size,
7148
+ status,
7149
+ disabled,
7150
+ readOnly: displayField === "label" || loading,
7151
+ placeholder,
7152
+ value: draft,
7153
+ maxLength: inputMaxLength && inputMaxLength > 0 ? inputMaxLength : void 0,
7154
+ showCount: !!inputMaxLength && inputMaxLength > 0,
7155
+ onClick: () => changeOpen(!open),
7156
+ autoComplete: "off",
7157
+ onKeyDown: (event) => {
7158
+ if (event.key === "ArrowDown" || event.key === "Enter" && displayField === "label") {
7159
+ event.preventDefault();
7160
+ if (open) popupRef.current?.querySelector('[role="listbox"]')?.focus();
7161
+ else changeOpen(true);
7162
+ }
7163
+ },
7164
+ onChange: (event) => {
7165
+ const next = event.target.value;
7166
+ setDraft(next);
7167
+ emit(parseInput ? parseInput(next) : multiple ? next.split(",").map((item) => item.trim()).filter(Boolean) : next);
7168
+ changeOpen(true);
7169
+ },
7170
+ suffix: /* @__PURE__ */ jsxs23("span", { className: "sia-input-select__suffix", children: [
7171
+ allowClear && draft && !disabled && /* @__PURE__ */ jsx23(Button, { variant: "text", size: "small", disabled: loading, "aria-label": "\u6E05\u9664\u8F93\u5165\u9009\u62E9", onClick: (event) => {
7172
+ event.stopPropagation();
7173
+ setDraft("");
7174
+ emit(multiple ? [] : void 0);
7175
+ inputRef.current?.focus();
7176
+ }, children: "\xD7" }),
7177
+ suffix,
7178
+ enableModal && /* @__PURE__ */ jsx23(Button, { variant: "text", size: "small", disabled: disabled || loading, "aria-label": "\u6253\u5F00\u9009\u62E9\u5F39\u7A97", onClick: (event) => {
7179
+ event.stopPropagation();
7180
+ openModal();
7181
+ }, children: "\u2026" }),
7182
+ /* @__PURE__ */ jsx23(Button, { variant: "text", size: "small", disabled: disabled || loading, "aria-label": "\u5C55\u5F00\u9009\u9879", onClick: (event) => {
7183
+ event.stopPropagation();
7184
+ changeOpen(!open);
7185
+ }, children: /* @__PURE__ */ jsx23(Icon, { name: loading ? "refresh" : open ? "chevron-up" : "chevron-down", size: 13 }) })
7186
+ ] })
7187
+ }
7188
+ ),
7189
+ /* @__PURE__ */ jsx23(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && !disabled && !loading, className: "sia-input-select__popup", children: /* @__PURE__ */ jsx23(
7190
+ SelectionPanel,
7191
+ {
7192
+ options,
7193
+ value: values,
7194
+ multiple,
7195
+ onChange: select,
7196
+ showValue,
7197
+ displayField,
7198
+ showSearch: !(hideSearch ?? (!multiple && displayField === "value")),
7199
+ autoFocusSearch: displayField === "label",
7200
+ searchValue: search || (!multiple && displayField === "value" ? draft : ""),
7201
+ onSearch: setSearch
7202
+ }
7203
+ ) }),
7204
+ enableModal && /* @__PURE__ */ jsxs23(
7205
+ Modal,
7206
+ {
7207
+ open: modalOpen,
7208
+ title: config.title ?? "\u9009\u62E9",
7209
+ width: config.width ?? 900,
7210
+ onCancel: () => setModalOpen(false),
7211
+ onOpenChange: setModalOpen,
7212
+ onOk: () => {
7213
+ emit(multiple ? modalValues : modalValues[0]);
7214
+ setModalOpen(false);
7215
+ },
7216
+ children: [
7217
+ /* @__PURE__ */ jsxs23("div", { className: "sia-selection-panel__actions", role: "tablist", "aria-label": "\u9009\u9879\u8303\u56F4", children: [
7218
+ /* @__PURE__ */ jsx23(Button, { role: "tab", "aria-selected": !selectedOnly, variant: !selectedOnly ? "primary" : "text", onClick: () => setSelectedOnly(false), children: "\u5168\u90E8" }),
7219
+ /* @__PURE__ */ jsxs23(Button, { role: "tab", "aria-selected": selectedOnly, variant: selectedOnly ? "primary" : "text", onClick: () => setSelectedOnly(true), children: [
7220
+ "\u5DF2\u9009\u9879(",
7221
+ modalValues.length,
7222
+ ")"
7223
+ ] })
7224
+ ] }),
7225
+ modalOpen && /* @__PURE__ */ jsx23(
7226
+ SelectionPanel,
7227
+ {
7228
+ options,
7229
+ value: modalValues,
7230
+ multiple,
7231
+ onChange: setModalValues,
7232
+ selectedOnly,
7233
+ columns: config.columns ?? 3,
7234
+ maxHeight: config.maxHeight ?? 450,
7235
+ showValue,
7236
+ displayField
7237
+ }
7238
+ )
7239
+ ]
7240
+ }
7241
+ )
7242
+ ] });
7243
+ });
6693
7244
  export {
6694
7245
  Alert,
6695
7246
  Badge,
@@ -6747,6 +7298,7 @@ export {
6747
7298
  ImagePreview,
6748
7299
  Input,
6749
7300
  InputNumber,
7301
+ InputSelect,
6750
7302
  KLineChart,
6751
7303
  LineChart,
6752
7304
  LineShareChart,
@@ -6772,6 +7324,7 @@ export {
6772
7324
  Segmented,
6773
7325
  Select,
6774
7326
  SelectDateRange,
7327
+ SelectionPanel,
6775
7328
  SiaChart,
6776
7329
  Slider,
6777
7330
  Space,
@@ -6806,6 +7359,7 @@ export {
6806
7359
  WordCloudChart,
6807
7360
  XYChart,
6808
7361
  applySiaTheme,
7362
+ buildFlatTree,
6809
7363
  chartColor,
6810
7364
  chartTicks,
6811
7365
  createBaiduMapHost,