@canvas-components/react-components 0.3.7 → 0.3.9

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
@@ -734,7 +734,7 @@ var ReactVirtualList = React.forwardRef(function ReactVirtualListInner(props, re
734
734
  });
735
735
 
736
736
  // src/components/select/style.css
737
- styleInject('@import "../../styles/variables.css";\n.canvas-react-select-wrap {\n position: relative;\n display: inline-flex;\n width: 100%;\n height: 100%;\n}\n.canvas-react-select {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: var(--canvas-react-control-height);\n padding: var(--canvas-react-control-padding-block, 0px) var(--canvas-react-control-padding-inline, 11px);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n outline: none;\n cursor: pointer;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-select-input-wrap {\n flex: 1 1 auto;\n width: 100%;\n height: 100%;\n border: none;\n background: transparent;\n box-shadow: none;\n}\n.canvas-react-select .canvas-react-input-affix-wrapper {\n height: 100%;\n min-height: 0;\n}\n.canvas-react-select-input-wrap:hover,\n.canvas-react-select-input-wrap:focus-within {\n border-color: transparent;\n box-shadow: none;\n}\n.canvas-react-select-input {\n width: 100%;\n min-width: 0;\n height: 100%;\n padding: 0;\n line-height: normal;\n}\n.canvas-react-select-input::placeholder {\n color: #9ca3af;\n}\n.canvas-react-select:hover {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-select:focus {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-select-open {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-select-disabled {\n color: #9ca3af;\n background: #fafafa;\n cursor: not-allowed;\n}\n.canvas-react-select-actions {\n position: relative;\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n width: 1em;\n min-width: 12px;\n height: 1em;\n min-height: 12px;\n margin-left: max(6px, calc(var(--canvas-react-control-padding-inline, 11px) * 0.5));\n}\n.canvas-react-select-arrow {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 0.5em;\n height: 0.5em;\n min-width: 6px;\n min-height: 6px;\n border-right: 1.5px solid var(--canvas-react-color-text-muted);\n border-bottom: 1.5px solid var(--canvas-react-color-text-muted);\n transform: translate(-50%, -58%) rotate(45deg);\n opacity: 1;\n transition:\n opacity 0.18s ease,\n transform 0.18s ease,\n border-color 0.18s ease;\n}\n.canvas-react-select:hover .canvas-react-select-arrow,\n.canvas-react-select-open .canvas-react-select-arrow {\n border-color: #6b7280;\n}\n.canvas-react-select-arrow-open {\n border-color: #6b7280;\n transform: translate(-50%, -42%) rotate(225deg);\n}\n.canvas-react-select-clear {\n position: absolute;\n top: 50%;\n left: 50%;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 12px;\n height: 12px;\n padding: 0;\n border: none;\n background: transparent;\n color: #9ca3af;\n opacity: 0;\n pointer-events: none;\n cursor: pointer;\n transform: translate(-50%, -50%) rotate(0deg);\n transition:\n color 0.2s ease,\n opacity 0.2s ease,\n transform 0.18s ease;\n}\n.canvas-react-select-clear:hover {\n color: #6b7280;\n transform: translate(-50%, -50%) rotate(90deg);\n}\n.canvas-react-select:hover .canvas-react-select-clear,\n.canvas-react-select-open .canvas-react-select-clear,\n.canvas-react-select:focus-within .canvas-react-select-clear {\n opacity: 1;\n pointer-events: auto;\n}\n.canvas-react-select:hover .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-select-open .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-select:focus-within .canvas-react-select-actions-clearable .canvas-react-select-arrow {\n opacity: 0;\n}\n.canvas-react-select-clear-icon,\n.canvas-react-select-clear-icon::before {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 8px;\n height: 1.25px;\n margin-top: -0.625px;\n margin-left: -4px;\n border-radius: 999px;\n background: currentColor;\n content: "";\n}\n.canvas-react-select-clear-icon {\n transform: rotate(45deg);\n}\n.canvas-react-select-clear-icon::before {\n transform: rotate(90deg);\n}\n.canvas-react-select-dropdown {\n padding: 4px;\n}\n.canvas-react-select-list {\n position: relative;\n overflow-y: auto;\n}\n.canvas-react-select-list-inner {\n position: relative;\n}\n.canvas-react-select-option {\n display: flex;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n padding: 0 11px;\n border-radius: var(--canvas-react-radius-sm);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n cursor: pointer;\n}\n.canvas-react-select-option:hover,\n.canvas-react-select-option-active {\n background: var(--canvas-react-color-bg-hover);\n}\n.canvas-react-select-option-selected {\n background: var(--canvas-react-color-bg-active);\n}\n.canvas-react-select-option-searching {\n color: var(--canvas-react-color-text);\n}\n.canvas-react-select-option-searching:hover,\n.canvas-react-select-option-searching.canvas-react-select-option-active {\n background: var(--canvas-react-color-bg-active);\n}\n.canvas-react-select-option-disabled {\n color: #9ca3af;\n cursor: not-allowed;\n}\n.canvas-react-select-option-highlight {\n color: var(--canvas-react-color-primary);\n font-weight: 600;\n}\n.canvas-react-select-option-disabled .canvas-react-select-option-highlight {\n color: inherit;\n}\n.canvas-react-select-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 0 11px;\n color: #9ca3af;\n font-size: var(--canvas-react-font-size);\n}\n');
737
+ styleInject('@import "../../styles/variables.css";\n.canvas-react-select-wrap {\n position: relative;\n display: inline-flex;\n width: 100%;\n height: 100%;\n}\n.canvas-react-select {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: var(--canvas-react-control-height);\n padding: var(--canvas-react-control-padding-block, 0px) var(--canvas-react-control-padding-inline, 11px);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n outline: none;\n cursor: pointer;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-select-input-wrap {\n flex: 1 1 auto;\n width: 100%;\n height: 100%;\n border: none;\n background: transparent;\n box-shadow: none;\n}\n.canvas-react-select .canvas-react-input-affix-wrapper {\n height: 100%;\n min-height: 0;\n}\n.canvas-react-select-input-wrap:hover,\n.canvas-react-select-input-wrap:focus-within {\n border-color: transparent;\n box-shadow: none;\n}\n.canvas-react-select-input {\n width: 100%;\n min-width: 0;\n height: 100%;\n padding: 0;\n line-height: normal;\n}\n.canvas-react-select-input::placeholder {\n color: #9ca3af;\n}\n.canvas-react-select:hover {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-select:focus {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-select-open {\n border-color: var(--canvas-react-color-primary);\n box-shadow: var(--canvas-react-shadow-focus);\n}\n.canvas-react-select-disabled {\n color: #9ca3af;\n background: #fafafa;\n cursor: not-allowed;\n}\n.canvas-react-select-actions {\n position: relative;\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n width: 1em;\n min-width: 12px;\n height: 1em;\n min-height: 12px;\n margin-left: max(6px, calc(var(--canvas-react-control-padding-inline, 11px) * 0.5));\n}\n.canvas-react-select-arrow {\n pointer-events: none;\n position: absolute;\n top: 50%;\n left: 50%;\n width: 0.5em;\n height: 0.5em;\n min-width: 6px;\n min-height: 6px;\n border-right: 1.5px solid var(--canvas-react-color-text-muted);\n border-bottom: 1.5px solid var(--canvas-react-color-text-muted);\n transform: translate(-50%, -58%) rotate(45deg);\n opacity: 1;\n transition:\n opacity 0.18s ease,\n transform 0.18s ease,\n border-color 0.18s ease;\n}\n.canvas-react-select:hover .canvas-react-select-arrow,\n.canvas-react-select-open .canvas-react-select-arrow {\n border-color: #6b7280;\n}\n.canvas-react-select-arrow-open {\n border-color: #6b7280;\n transform: translate(-50%, -42%) rotate(225deg);\n}\n.canvas-react-select-clear {\n position: absolute;\n top: 50%;\n left: 50%;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 12px;\n height: 12px;\n padding: 0;\n border: none;\n background: transparent;\n color: #9ca3af;\n opacity: 0;\n pointer-events: none;\n cursor: pointer;\n transform: translate(-50%, -50%) rotate(0deg);\n transition:\n color 0.2s ease,\n opacity 0.2s ease,\n transform 0.18s ease;\n}\n.canvas-react-select-clear:hover {\n color: #6b7280;\n transform: translate(-50%, -50%) rotate(90deg);\n}\n.canvas-react-select:hover .canvas-react-select-clear,\n.canvas-react-select-open .canvas-react-select-clear,\n.canvas-react-select:focus-within .canvas-react-select-clear,\n.canvas-react-cascader:hover .canvas-react-select-clear,\n.canvas-react-cascader-open .canvas-react-select-clear,\n.canvas-react-cascader:focus-within .canvas-react-select-clear {\n opacity: 1;\n pointer-events: auto;\n}\n.canvas-react-select:hover .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-select-open .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-select:focus-within .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-cascader:hover .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-cascader-open .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-cascader:focus-within .canvas-react-select-actions-clearable .canvas-react-select-arrow {\n opacity: 0;\n}\n.canvas-react-select-clear-icon,\n.canvas-react-select-clear-icon::before {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 8px;\n height: 1.25px;\n margin-top: -0.625px;\n margin-left: -4px;\n border-radius: 999px;\n background: currentColor;\n content: "";\n}\n.canvas-react-select-clear-icon {\n transform: rotate(45deg);\n}\n.canvas-react-select-clear-icon::before {\n transform: rotate(90deg);\n}\n.canvas-react-select-dropdown {\n padding: 4px;\n}\n.canvas-react-select-list {\n position: relative;\n overflow-y: auto;\n}\n.canvas-react-select-list-inner {\n position: relative;\n}\n.canvas-react-select-option {\n display: flex;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n padding: 0 11px;\n border-radius: var(--canvas-react-radius-sm);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n cursor: pointer;\n}\n.canvas-react-select-option:hover,\n.canvas-react-select-option-active {\n background: var(--canvas-react-color-bg-hover);\n}\n.canvas-react-select-option-selected {\n background: var(--canvas-react-color-bg-active);\n}\n.canvas-react-select-option-searching {\n color: var(--canvas-react-color-text);\n}\n.canvas-react-select-option-searching:hover,\n.canvas-react-select-option-searching.canvas-react-select-option-active {\n background: var(--canvas-react-color-bg-active);\n}\n.canvas-react-select-option-disabled {\n color: #9ca3af;\n cursor: not-allowed;\n}\n.canvas-react-select-option-highlight {\n color: var(--canvas-react-color-primary);\n font-weight: 600;\n}\n.canvas-react-select-option-disabled .canvas-react-select-option-highlight {\n color: inherit;\n}\n.canvas-react-select-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 0 11px;\n color: #9ca3af;\n font-size: var(--canvas-react-font-size);\n}\n');
738
738
  var ReactSelect = React.forwardRef(
739
739
  function ReactSelect2(props, ref) {
740
740
  const {
@@ -7259,6 +7259,836 @@ function clamp3(value, min, max) {
7259
7259
  }
7260
7260
  return Math.min(Math.max(value, min), max);
7261
7261
  }
7262
+
7263
+ // src/components/cascader/cascader-selection.ts
7264
+ function createCascaderSelection(options) {
7265
+ const entries = /* @__PURE__ */ new Map();
7266
+ const visit = (items, parents, disabled = false) => items.map((item) => {
7267
+ const nodes = [...parents, item];
7268
+ const path = nodes.map((node) => node.value);
7269
+ const key = JSON.stringify(path);
7270
+ const entry = {
7271
+ path,
7272
+ children: [],
7273
+ leaves: [],
7274
+ disabled: disabled || !!item.disabled
7275
+ };
7276
+ entries.set(key, entry);
7277
+ entry.children = visit(item.children ?? [], nodes, entry.disabled);
7278
+ entry.leaves = entry.disabled ? [] : entry.children.length ? entry.children.flatMap((child) => child.leaves) : [key];
7279
+ return entry;
7280
+ });
7281
+ const roots = visit(options, []);
7282
+ const expand = (value) => {
7283
+ const checked = /* @__PURE__ */ new Set();
7284
+ const preserved = /* @__PURE__ */ new Map();
7285
+ for (const path of value) {
7286
+ const key = JSON.stringify(path);
7287
+ const entry = entries.get(key);
7288
+ if (!entry || entry.disabled || !entry.leaves.length)
7289
+ preserved.set(key, path);
7290
+ else entry.leaves.forEach((leaf) => checked.add(leaf));
7291
+ }
7292
+ return { checked, preserved };
7293
+ };
7294
+ const state = (entry, checked) => {
7295
+ const count = entry?.leaves.filter((leaf) => checked.has(leaf)).length ?? 0;
7296
+ return {
7297
+ checked: count > 0 && count === entry?.leaves.length,
7298
+ indeterminate: count > 0 && count < (entry?.leaves.length ?? 0)
7299
+ };
7300
+ };
7301
+ const collect = (checked, preserved, strategy) => {
7302
+ const paths = [];
7303
+ const walk = (entry) => {
7304
+ if (entry.disabled) return;
7305
+ if (state(entry, checked).checked && (strategy === "SHOW_PARENT" || !entry.children.length))
7306
+ paths.push(entry.path);
7307
+ else entry.children.forEach(walk);
7308
+ };
7309
+ roots.forEach(walk);
7310
+ return [...paths, ...preserved.values()];
7311
+ };
7312
+ return {
7313
+ /** 归一化回填值,去重并应用父级/末级策略。 */
7314
+ normalize(value, strategy) {
7315
+ const { checked, preserved } = expand(value);
7316
+ return collect(checked, preserved, strategy);
7317
+ },
7318
+ /** 计算某一路径的全选和半选状态。 */
7319
+ getState(value, path) {
7320
+ const { checked, preserved } = expand(value);
7321
+ if (preserved.has(JSON.stringify(path)))
7322
+ return { checked: true, indeterminate: false };
7323
+ return state(entries.get(JSON.stringify(path)), checked);
7324
+ },
7325
+ /** 切换某个节点以及全部可用后代,不修改入参。 */
7326
+ toggle(value, path, strategy) {
7327
+ const entry = entries.get(JSON.stringify(path));
7328
+ if (!entry || entry.disabled || !entry.leaves.length) return value;
7329
+ const { checked, preserved } = expand(value);
7330
+ const remove = state(entry, checked).checked;
7331
+ entry.leaves.forEach(
7332
+ (leaf) => remove ? checked.delete(leaf) : checked.add(leaf)
7333
+ );
7334
+ return collect(checked, preserved, strategy);
7335
+ }
7336
+ };
7337
+ }
7338
+
7339
+ // src/components/cascader/style.css
7340
+ styleInject('@import "../../styles/variables.css";\n.canvas-react-cascader {\n width: 100%;\n min-width: 0;\n}\n.canvas-react-cascader > .canvas-react-input-affix-wrapper {\n width: 100%;\n}\n.canvas-react-cascader-menus {\n display: flex;\n max-width: calc(100vw - 24px);\n overflow: auto;\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n}\n.canvas-react-cascader-menu {\n flex: 0 0 auto;\n min-width: 120px;\n max-width: 320px;\n max-height: min(256px, calc(100vh - 48px));\n overflow: auto;\n padding: 4px;\n}\n.canvas-react-cascader-menu + .canvas-react-cascader-menu {\n border-left: 1px solid var(--canvas-react-color-border);\n}\n.canvas-react-cascader-option {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 20px;\n padding: 5px 10px;\n line-height: 22px;\n border-radius: var(--canvas-react-radius-sm);\n cursor: pointer;\n white-space: nowrap;\n}\n.canvas-react-cascader-check {\n display: inline-flex;\n flex: 0 0 auto;\n margin-right: -12px;\n}\n.canvas-react-cascader-check > * {\n pointer-events: none;\n}\n.canvas-react-cascader-option > span:not(.canvas-react-cascader-check):not(.canvas-react-cascader-chevron) {\n flex: 1;\n}\n.canvas-react-cascader-option[aria-selected=true] {\n color: var(--canvas-react-color-primary);\n background: var(--canvas-react-color-bg-active);\n}\n.canvas-react-cascader-option[data-active=true] {\n background: var(--canvas-react-color-bg-hover, #f5f5f5);\n}\n.canvas-react-cascader-option[aria-disabled=true] {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.canvas-react-cascader-empty {\n padding: 8px 10px;\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-cascader-chevron {\n width: 7px;\n height: 7px;\n flex: 0 0 auto;\n margin-left: 8px;\n border-top: 1.5px solid #9ca3af;\n border-right: 1.5px solid #9ca3af;\n transform: rotate(45deg);\n transform-origin: center;\n transition: transform 0.18s ease, border-color 0.18s ease;\n}\n.canvas-react-cascader-option:not([aria-disabled=true]):hover .canvas-react-cascader-chevron,\n.canvas-react-cascader-option[data-expanded=true] .canvas-react-cascader-chevron {\n border-color: #6b7280;\n transform: rotate(135deg);\n}\n');
7341
+ function resolvePath(options, value) {
7342
+ const path = [];
7343
+ for (const part of value) {
7344
+ const item = options.find((option) => option.value === part);
7345
+ if (!item) break;
7346
+ path.push(item);
7347
+ options = item.children ?? [];
7348
+ }
7349
+ return path;
7350
+ }
7351
+ var EMPTY_OPTIONS = [];
7352
+ var EMPTY_VALUE = [];
7353
+ function ReactCascader(props) {
7354
+ const {
7355
+ value = EMPTY_VALUE,
7356
+ options = EMPTY_OPTIONS,
7357
+ showSearch = false,
7358
+ multiple = false,
7359
+ showCheckedStrategy = "SHOW_PARENT",
7360
+ changeOnSelect = false,
7361
+ expandTrigger = "click",
7362
+ displayRender,
7363
+ onChange,
7364
+ allowClear = true,
7365
+ disabled,
7366
+ readOnly,
7367
+ onFocus,
7368
+ onBlur,
7369
+ onClick,
7370
+ onKeyDown,
7371
+ ...inputProps
7372
+ } = props;
7373
+ const anchorRef = React.useRef(null);
7374
+ const inputRef = React.useRef(null);
7375
+ const popupRef = React.useRef(null);
7376
+ const popupId = React.useId();
7377
+ const selection = React.useMemo(() => createCascaderSelection(options), [options]);
7378
+ const singleValue = multiple ? EMPTY_VALUE : value;
7379
+ const multipleValue = multiple ? value.filter(Array.isArray) : [];
7380
+ const selected = React.useMemo(
7381
+ () => resolvePath(options, singleValue),
7382
+ [options, singleValue]
7383
+ );
7384
+ const [path, setPath] = React.useState(selected);
7385
+ const [open, setOpen] = React.useState(false);
7386
+ const [keyword, setKeyword] = React.useState("");
7387
+ const [typing, setTyping] = React.useState(false);
7388
+ const [focus, setFocus] = React.useState({ column: 0, index: -1 });
7389
+ const interactive = !disabled && !readOnly;
7390
+ React.useEffect(() => {
7391
+ setPath(selected);
7392
+ }, [selected]);
7393
+ const displayPath = (valuePath) => {
7394
+ const nodes = resolvePath(options, valuePath);
7395
+ const labels = valuePath.map(
7396
+ (part, index) => nodes[index]?.label ?? String(part)
7397
+ );
7398
+ return displayRender?.(labels, nodes) ?? labels.join(" / ");
7399
+ };
7400
+ const text = multiple ? selection.normalize(multipleValue, showCheckedStrategy).map(displayPath).join("\uFF1B") : displayPath(singleValue);
7401
+ const columns = [options];
7402
+ for (const item of path) {
7403
+ if (!item.children?.length) break;
7404
+ columns.push(item.children);
7405
+ }
7406
+ const searching = showSearch && keyword.trim().length > 0;
7407
+ const results = React.useMemo(() => {
7408
+ if (!keyword.trim()) return [];
7409
+ const matches = [];
7410
+ const visit = (items, parents) => {
7411
+ for (const item of items) {
7412
+ if (item.disabled) continue;
7413
+ const next = [...parents, item];
7414
+ if ((!item.children?.length || changeOnSelect || multiple) && next.map((part) => part.label).join(" / ").toLocaleLowerCase().includes(keyword.trim().toLocaleLowerCase()))
7415
+ matches.push(next);
7416
+ if (item.children?.length) visit(item.children, next);
7417
+ }
7418
+ };
7419
+ visit(options, []);
7420
+ return matches;
7421
+ }, [options, keyword, changeOnSelect, multiple]);
7422
+ React.useEffect(() => {
7423
+ popupRef.current?.querySelector("[data-active='true']")?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
7424
+ }, [focus, open]);
7425
+ const toggle = (next, trigger) => {
7426
+ const updated = selection.toggle(
7427
+ multipleValue,
7428
+ next.map((item) => item.value),
7429
+ showCheckedStrategy
7430
+ );
7431
+ onChange?.(
7432
+ updated,
7433
+ updated.map((parts) => resolvePath(options, parts)),
7434
+ { trigger, complete: false }
7435
+ );
7436
+ };
7437
+ const choose = (next, trigger, fromSearch = false) => {
7438
+ const item = next[next.length - 1];
7439
+ if (!item || next.some((option) => option.disabled)) return;
7440
+ setPath(next);
7441
+ if (multiple) {
7442
+ if (!item.children?.length || fromSearch) toggle(next, trigger);
7443
+ return;
7444
+ }
7445
+ const complete = !item.children?.length || fromSearch;
7446
+ if (complete || changeOnSelect)
7447
+ onChange?.(
7448
+ next.map((option) => option.value),
7449
+ next,
7450
+ { trigger, complete }
7451
+ );
7452
+ if (complete) {
7453
+ setOpen(false);
7454
+ setKeyword("");
7455
+ setTyping(false);
7456
+ }
7457
+ };
7458
+ const show = () => {
7459
+ if (!interactive) return;
7460
+ setOpen(true);
7461
+ if (!multiple) setPath(selected);
7462
+ };
7463
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7464
+ "div",
7465
+ {
7466
+ ref: anchorRef,
7467
+ className: `canvas-react-cascader${open && interactive ? " canvas-react-cascader-open" : ""}`,
7468
+ children: [
7469
+ /* @__PURE__ */ jsxRuntime.jsx(
7470
+ ReactInput,
7471
+ {
7472
+ ref: inputRef,
7473
+ ...inputProps,
7474
+ disabled,
7475
+ readOnly: readOnly || !showSearch,
7476
+ allowClear: false,
7477
+ role: "combobox",
7478
+ "aria-haspopup": "listbox",
7479
+ "aria-expanded": open,
7480
+ "aria-controls": open ? popupId : void 0,
7481
+ "aria-activedescendant": open && focus.index >= 0 ? `${popupId}-${searching ? 0 : focus.column}-${focus.index}` : void 0,
7482
+ value: open && showSearch && typing ? keyword : text,
7483
+ onFocus: (event) => {
7484
+ show();
7485
+ onFocus?.(event);
7486
+ },
7487
+ onClick: (event) => {
7488
+ show();
7489
+ onClick?.(event);
7490
+ },
7491
+ onBlur: (event) => {
7492
+ setOpen(false);
7493
+ setKeyword("");
7494
+ setTyping(false);
7495
+ onBlur?.(event);
7496
+ },
7497
+ onChange: (event) => {
7498
+ setTyping(true);
7499
+ setKeyword(event.target.value);
7500
+ setOpen(true);
7501
+ setFocus({ column: 0, index: -1 });
7502
+ },
7503
+ onKeyDown: (event) => {
7504
+ onKeyDown?.(event);
7505
+ if (event.defaultPrevented || !interactive) return;
7506
+ if (event.key === "Escape") {
7507
+ event.preventDefault();
7508
+ setOpen(false);
7509
+ setKeyword("");
7510
+ setTyping(false);
7511
+ return;
7512
+ }
7513
+ if (!(multiple && event.key === " " && (!showSearch || !typing)) && ![
7514
+ "ArrowDown",
7515
+ "ArrowUp",
7516
+ "ArrowRight",
7517
+ "ArrowLeft",
7518
+ "Enter"
7519
+ ].includes(event.key))
7520
+ return;
7521
+ event.preventDefault();
7522
+ setOpen(true);
7523
+ const column = searching ? 0 : Math.min(focus.column, columns.length - 1);
7524
+ const items = searching ? results.map((result) => result[result.length - 1]) : columns[column];
7525
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
7526
+ const direction = event.key === "ArrowDown" ? 1 : -1;
7527
+ let index = focus.index;
7528
+ if (index < 0) index = direction === 1 ? -1 : 0;
7529
+ for (let count = 0; count < items.length; count++) {
7530
+ index = (index + direction + items.length) % items.length;
7531
+ if (!items[index].disabled) {
7532
+ setFocus({ column, index });
7533
+ break;
7534
+ }
7535
+ }
7536
+ } else if (event.key === "ArrowLeft" && !searching) {
7537
+ const previous = Math.max(0, column - 1);
7538
+ setFocus({
7539
+ column: previous,
7540
+ index: columns[previous].indexOf(path[previous])
7541
+ });
7542
+ } else {
7543
+ const item = items[focus.index];
7544
+ if (!item || item.disabled) return;
7545
+ const next = searching ? results[focus.index] : [...path.slice(0, column), item];
7546
+ if (multiple && (event.key === "Enter" || event.key === " "))
7547
+ toggle(next, "keyboard");
7548
+ else if (event.key === "Enter") choose(next, "keyboard", searching);
7549
+ else if (event.key !== "ArrowRight") return;
7550
+ if (!searching && item.children?.length) {
7551
+ setPath(next);
7552
+ setFocus({
7553
+ column: column + 1,
7554
+ index: item.children.findIndex((child) => !child.disabled)
7555
+ });
7556
+ }
7557
+ }
7558
+ },
7559
+ suffix: /* @__PURE__ */ jsxRuntime.jsxs(
7560
+ "span",
7561
+ {
7562
+ className: `canvas-react-select-actions${allowClear && interactive && value.length > 0 ? " canvas-react-select-actions-clearable" : ""}`,
7563
+ onPointerDown: (event) => {
7564
+ if (!interactive) return;
7565
+ event.preventDefault();
7566
+ event.stopPropagation();
7567
+ },
7568
+ onMouseDown: (event) => {
7569
+ if (!interactive) return;
7570
+ event.preventDefault();
7571
+ event.stopPropagation();
7572
+ },
7573
+ onClick: (event) => {
7574
+ if (!interactive) return;
7575
+ event.stopPropagation();
7576
+ inputRef.current?.focus({ preventScroll: true });
7577
+ show();
7578
+ },
7579
+ children: [
7580
+ allowClear && interactive && value.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
7581
+ "button",
7582
+ {
7583
+ type: "button",
7584
+ className: "canvas-react-select-clear",
7585
+ tabIndex: -1,
7586
+ "aria-label": "\u6E05\u7A7A\u7EA7\u8054\u9009\u62E9",
7587
+ onPointerDown: (event) => {
7588
+ event.preventDefault();
7589
+ event.stopPropagation();
7590
+ },
7591
+ onMouseDown: (event) => {
7592
+ event.preventDefault();
7593
+ event.stopPropagation();
7594
+ },
7595
+ onClick: (event) => {
7596
+ event.preventDefault();
7597
+ event.stopPropagation();
7598
+ inputRef.current?.focus({ preventScroll: true });
7599
+ setKeyword("");
7600
+ setTyping(false);
7601
+ setPath([]);
7602
+ setFocus({ column: 0, index: -1 });
7603
+ setOpen(true);
7604
+ onChange?.([], [], { trigger: "clear", complete: false });
7605
+ },
7606
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7607
+ "span",
7608
+ {
7609
+ className: "canvas-react-select-clear-icon",
7610
+ "aria-hidden": "true"
7611
+ }
7612
+ )
7613
+ }
7614
+ ) : null,
7615
+ /* @__PURE__ */ jsxRuntime.jsx(
7616
+ "span",
7617
+ {
7618
+ className: `canvas-react-select-arrow${open && interactive ? " canvas-react-select-arrow-open" : ""}`,
7619
+ "aria-hidden": "true"
7620
+ }
7621
+ )
7622
+ ]
7623
+ }
7624
+ )
7625
+ }
7626
+ ),
7627
+ /* @__PURE__ */ jsxRuntime.jsx(
7628
+ ReactPopup,
7629
+ {
7630
+ constrainHeight: true,
7631
+ open: open && interactive,
7632
+ anchorRef,
7633
+ onOpenChange: setOpen,
7634
+ surfaceClassName: "canvas-react-cascader-popup",
7635
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7636
+ "div",
7637
+ {
7638
+ ref: popupRef,
7639
+ id: popupId,
7640
+ className: "canvas-react-cascader-menus",
7641
+ children: (searching ? [results.map((result) => result[result.length - 1])] : columns).map((items, column) => /* @__PURE__ */ jsxRuntime.jsx(
7642
+ "div",
7643
+ {
7644
+ role: "listbox",
7645
+ "aria-multiselectable": multiple || void 0,
7646
+ "aria-label": searching ? "\u641C\u7D22\u7ED3\u679C" : `\u7B2C ${column + 1} \u7EA7\u9009\u9879`,
7647
+ className: "canvas-react-cascader-menu",
7648
+ children: items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-react-cascader-empty", children: "\u6682\u65E0\u6570\u636E" }) : items.map((item, index) => {
7649
+ const next = searching ? results[index] : [...path.slice(0, column), item];
7650
+ const active = focus.column === column && focus.index === index;
7651
+ const checkedState = multiple ? selection.getState(
7652
+ multipleValue,
7653
+ next.map((node) => node.value)
7654
+ ) : { checked: false, indeterminate: false };
7655
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7656
+ "div",
7657
+ {
7658
+ id: `${popupId}-${column}-${index}`,
7659
+ role: "option",
7660
+ "aria-selected": multiple ? checkedState.checked : path[column] === item,
7661
+ "aria-disabled": !!item.disabled,
7662
+ "data-active": active,
7663
+ className: "canvas-react-cascader-option",
7664
+ "data-expanded": !!item.children?.length && path[column] === item,
7665
+ onMouseDown: (event) => event.preventDefault(),
7666
+ onMouseEnter: () => {
7667
+ if (item.disabled) return;
7668
+ setFocus({ column, index });
7669
+ if (expandTrigger === "hover" && !searching && item.children?.length)
7670
+ setPath(next);
7671
+ },
7672
+ onClick: () => {
7673
+ setFocus({ column, index });
7674
+ choose(next, "mouse", searching);
7675
+ },
7676
+ children: [
7677
+ multiple ? /* @__PURE__ */ jsxRuntime.jsx(
7678
+ "span",
7679
+ {
7680
+ className: "canvas-react-cascader-check",
7681
+ role: "checkbox",
7682
+ "aria-checked": checkedState.indeterminate ? "mixed" : checkedState.checked,
7683
+ "aria-label": `\u9009\u62E9 ${next.map((node) => node.label).join(" / ")}`,
7684
+ "aria-disabled": !!item.disabled,
7685
+ onClick: (event) => {
7686
+ event.preventDefault();
7687
+ event.stopPropagation();
7688
+ if (!item.disabled) toggle(next, "mouse");
7689
+ },
7690
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7691
+ ReactCheckbox,
7692
+ {
7693
+ tabIndex: -1,
7694
+ "aria-hidden": "true",
7695
+ readOnly: true,
7696
+ checked: checkedState.checked,
7697
+ indeterminate: checkedState.indeterminate,
7698
+ disabled: item.disabled
7699
+ }
7700
+ )
7701
+ }
7702
+ ) : null,
7703
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: searching ? next.map((part) => part.label).join(" / ") : item.label }),
7704
+ !searching && item.children?.length ? /* @__PURE__ */ jsxRuntime.jsx(
7705
+ "span",
7706
+ {
7707
+ className: "canvas-react-cascader-chevron",
7708
+ "aria-hidden": "true"
7709
+ }
7710
+ ) : null
7711
+ ]
7712
+ },
7713
+ index
7714
+ );
7715
+ })
7716
+ },
7717
+ column
7718
+ ))
7719
+ }
7720
+ )
7721
+ }
7722
+ )
7723
+ ]
7724
+ }
7725
+ );
7726
+ }
7727
+
7728
+ // src/components/tree-select/tree-select-utils.ts
7729
+ function createTreeSelectIndex(treeData) {
7730
+ const entries = [];
7731
+ const byValue = /* @__PURE__ */ new Map();
7732
+ const visit = (nodes, parents) => {
7733
+ for (const node of nodes) {
7734
+ const entry = {
7735
+ node,
7736
+ key: node.key ?? node.value,
7737
+ parents,
7738
+ depth: parents.length
7739
+ };
7740
+ entries.push(entry);
7741
+ byValue.set(node.value, entry);
7742
+ if (node.children?.length) visit(node.children, [...parents, entry]);
7743
+ }
7744
+ };
7745
+ visit(treeData, []);
7746
+ return { entries, byValue };
7747
+ }
7748
+ function normalizeTreeSelectValue(value, multiple) {
7749
+ const values = multiple ? Array.isArray(value) ? value : [] : [value];
7750
+ return [
7751
+ ...new Set(
7752
+ values.filter(
7753
+ (part) => typeof part === "string" || typeof part === "number"
7754
+ )
7755
+ )
7756
+ ];
7757
+ }
7758
+
7759
+ // src/components/tree-select/style.css
7760
+ styleInject('@import "../../styles/variables.css";\n.canvas-react-tree-select {\n width: 100%;\n min-width: 0;\n}\n.canvas-react-tree-select-tree {\n max-height: min(280px, calc(100vh - 48px));\n overflow: auto;\n padding: 4px;\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n}\n.canvas-react-tree-select-node {\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: 30px;\n padding: 2px 10px 2px 6px;\n box-sizing: border-box;\n line-height: 22px;\n border-radius: var(--canvas-react-radius-sm);\n cursor: pointer;\n}\n.canvas-react-tree-select-node[data-active=true] {\n background: var(--canvas-react-color-bg-hover);\n}\n.canvas-react-tree-select-node[aria-selected=true] {\n background: var(--canvas-react-color-bg-active);\n color: var(--canvas-react-color-primary);\n}\n.canvas-react-tree-select-node[aria-disabled=true] .canvas-react-tree-select-title {\n opacity: 0.4;\n cursor: not-allowed;\n}\n.canvas-react-tree-select-switcher {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 18px;\n width: 18px;\n height: 24px;\n border: 0;\n padding: 0;\n background: transparent;\n cursor: pointer;\n}\n.canvas-react-tree-select-chevron {\n width: 7px;\n height: 7px;\n border-top: 1.5px solid #9ca3af;\n border-right: 1.5px solid #9ca3af;\n transform: rotate(45deg);\n transition: transform 0.18s ease, border-color 0.18s ease;\n pointer-events: none;\n}\n.canvas-react-tree-select-chevron-open {\n transform: rotate(135deg);\n border-color: #6b7280;\n}\n.canvas-react-tree-select-title {\n flex: 1;\n white-space: nowrap;\n}\n.canvas-react-tree-select-check {\n color: var(--canvas-react-color-primary);\n}\n.canvas-react-tree-select-empty {\n padding: 8px 10px;\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-tree-select:hover .canvas-react-select-clear,\n.canvas-react-tree-select-open .canvas-react-select-clear,\n.canvas-react-tree-select:focus-within .canvas-react-select-clear {\n opacity: 1;\n pointer-events: auto;\n}\n.canvas-react-tree-select:hover .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-tree-select-open .canvas-react-select-actions-clearable .canvas-react-select-arrow,\n.canvas-react-tree-select:focus-within .canvas-react-select-actions-clearable .canvas-react-select-arrow {\n opacity: 0;\n}\n');
7761
+ var EMPTY_TREE = [];
7762
+ function ReactTreeSelect(props) {
7763
+ const {
7764
+ value = null,
7765
+ treeData = EMPTY_TREE,
7766
+ multiple = false,
7767
+ showSearch = multiple,
7768
+ treeDefaultExpandAll = false,
7769
+ treeDefaultExpandedKeys,
7770
+ allowClear = true,
7771
+ onChange,
7772
+ disabled,
7773
+ readOnly,
7774
+ onFocus,
7775
+ onBlur,
7776
+ onClick,
7777
+ onKeyDown,
7778
+ ...inputProps
7779
+ } = props;
7780
+ const index = React.useMemo(() => createTreeSelectIndex(treeData), [treeData]);
7781
+ const selected = React.useMemo(
7782
+ () => normalizeTreeSelectValue(value, multiple),
7783
+ [value, multiple]
7784
+ );
7785
+ const selectedSet = React.useMemo(() => new Set(selected), [selected]);
7786
+ const [expanded, setExpanded] = React.useState(
7787
+ () => /* @__PURE__ */ new Set([
7788
+ ...treeDefaultExpandAll ? index.entries.filter((entry) => entry.node.children?.length).map((entry) => entry.key) : treeDefaultExpandedKeys ?? [],
7789
+ ...selected.flatMap(
7790
+ (part) => index.byValue.get(part)?.parents.map((parent) => parent.key) ?? []
7791
+ )
7792
+ ])
7793
+ );
7794
+ const [open, setOpen] = React.useState(false);
7795
+ const [keyword, setKeyword] = React.useState(null);
7796
+ const [active, setActive] = React.useState(
7797
+ selected[0] ?? null
7798
+ );
7799
+ const anchorRef = React.useRef(null);
7800
+ const inputRef = React.useRef(null);
7801
+ const treeRef = React.useRef(null);
7802
+ const treeId = React.useId();
7803
+ const interactive = !disabled && !readOnly;
7804
+ const query = (keyword ?? "").trim().toLocaleLowerCase();
7805
+ const text = selected.map((part) => index.byValue.get(part)?.node.title ?? String(part)).join("\uFF1B");
7806
+ const visible = React.useMemo(() => {
7807
+ if (!query)
7808
+ return index.entries.filter(
7809
+ (entry) => entry.parents.every((parent) => expanded.has(parent.key))
7810
+ );
7811
+ const matches = /* @__PURE__ */ new Set();
7812
+ for (const entry of index.entries) {
7813
+ if (!entry.node.title.toLocaleLowerCase().includes(query)) continue;
7814
+ matches.add(entry);
7815
+ entry.parents.forEach((parent) => matches.add(parent));
7816
+ }
7817
+ return index.entries.filter((entry) => matches.has(entry));
7818
+ }, [index, query, expanded]);
7819
+ React.useEffect(() => {
7820
+ setExpanded((previous) => {
7821
+ const next = new Set(previous);
7822
+ selected.forEach(
7823
+ (part) => index.byValue.get(part)?.parents.forEach((parent) => next.add(parent.key))
7824
+ );
7825
+ return next;
7826
+ });
7827
+ }, [index, selected]);
7828
+ React.useEffect(() => {
7829
+ treeRef.current?.querySelector('[data-active="true"]')?.scrollIntoView?.({ block: "nearest" });
7830
+ }, [active, open]);
7831
+ const expand = (entry, next) => {
7832
+ if (!entry.node.children?.length || query) return;
7833
+ setExpanded((previous) => {
7834
+ const keys = new Set(previous);
7835
+ if (next ?? !keys.has(entry.key)) keys.add(entry.key);
7836
+ else keys.delete(entry.key);
7837
+ return keys;
7838
+ });
7839
+ };
7840
+ const choose = (entry, trigger) => {
7841
+ if (entry.node.disabled) return;
7842
+ if (entry.node.selectable === false) {
7843
+ expand(entry);
7844
+ return;
7845
+ }
7846
+ const next = multiple ? selectedSet.has(entry.node.value) ? selected.filter((part) => part !== entry.node.value) : [...selected, entry.node.value] : [entry.node.value];
7847
+ onChange?.(
7848
+ multiple ? next : entry.node.value,
7849
+ next.flatMap((part) => index.byValue.get(part)?.node ?? []),
7850
+ { trigger, complete: !multiple }
7851
+ );
7852
+ if (!multiple) {
7853
+ setOpen(false);
7854
+ setKeyword(null);
7855
+ }
7856
+ };
7857
+ const show = () => {
7858
+ if (interactive) setOpen(true);
7859
+ };
7860
+ const activeIndex = visible.findIndex((entry) => entry.node.value === active);
7861
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7862
+ "div",
7863
+ {
7864
+ ref: anchorRef,
7865
+ className: `canvas-react-tree-select${open && interactive ? " canvas-react-tree-select-open" : ""}`,
7866
+ children: [
7867
+ /* @__PURE__ */ jsxRuntime.jsx(
7868
+ ReactInput,
7869
+ {
7870
+ ...inputProps,
7871
+ ref: inputRef,
7872
+ disabled,
7873
+ readOnly: readOnly || !showSearch,
7874
+ allowClear: false,
7875
+ role: "combobox",
7876
+ "aria-haspopup": "tree",
7877
+ "aria-expanded": open && interactive,
7878
+ "aria-controls": open ? treeId : void 0,
7879
+ "aria-activedescendant": open && activeIndex >= 0 ? `${treeId}-${activeIndex}` : void 0,
7880
+ value: open && keyword !== null ? keyword : text,
7881
+ onFocus: (event) => {
7882
+ show();
7883
+ onFocus?.(event);
7884
+ },
7885
+ onClick: (event) => {
7886
+ show();
7887
+ onClick?.(event);
7888
+ },
7889
+ onBlur: (event) => {
7890
+ setOpen(false);
7891
+ setKeyword(null);
7892
+ onBlur?.(event);
7893
+ },
7894
+ onChange: (event) => {
7895
+ setKeyword(event.target.value);
7896
+ setActive(null);
7897
+ show();
7898
+ },
7899
+ onKeyDown: (event) => {
7900
+ onKeyDown?.(event);
7901
+ if (event.defaultPrevented || !interactive) return;
7902
+ if (event.key === "Escape") {
7903
+ event.preventDefault();
7904
+ setOpen(false);
7905
+ setKeyword(null);
7906
+ return;
7907
+ }
7908
+ const space = event.key === " " && (!showSearch || keyword === null);
7909
+ if (!space && ![
7910
+ "ArrowDown",
7911
+ "ArrowUp",
7912
+ "ArrowLeft",
7913
+ "ArrowRight",
7914
+ "Enter",
7915
+ "Home",
7916
+ "End"
7917
+ ].includes(event.key))
7918
+ return;
7919
+ event.preventDefault();
7920
+ show();
7921
+ if (!visible.length) return;
7922
+ const entry = visible[activeIndex];
7923
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
7924
+ const next = activeIndex < 0 ? event.key === "ArrowDown" ? 0 : visible.length - 1 : (activeIndex + (event.key === "ArrowDown" ? 1 : -1) + visible.length) % visible.length;
7925
+ setActive(visible[next].node.value);
7926
+ } else if (event.key === "Home" || event.key === "End")
7927
+ setActive(
7928
+ visible[event.key === "Home" ? 0 : visible.length - 1].node.value
7929
+ );
7930
+ else if (entry) {
7931
+ if (event.key === "ArrowRight") {
7932
+ if (entry.node.children?.length && !expanded.has(entry.key) && !query)
7933
+ expand(entry, true);
7934
+ else if (visible[activeIndex + 1]?.depth > entry.depth)
7935
+ setActive(visible[activeIndex + 1].node.value);
7936
+ } else if (event.key === "ArrowLeft") {
7937
+ if (expanded.has(entry.key) && !query) expand(entry, false);
7938
+ else
7939
+ setActive(
7940
+ entry.parents[entry.parents.length - 1]?.node.value ?? entry.node.value
7941
+ );
7942
+ } else choose(entry, "keyboard");
7943
+ }
7944
+ },
7945
+ suffix: /* @__PURE__ */ jsxRuntime.jsxs(
7946
+ "span",
7947
+ {
7948
+ className: `canvas-react-select-actions${allowClear && interactive && selected.length ? " canvas-react-select-actions-clearable" : ""}`,
7949
+ onPointerDown: (event) => {
7950
+ if (interactive) {
7951
+ event.preventDefault();
7952
+ event.stopPropagation();
7953
+ }
7954
+ },
7955
+ onMouseDown: (event) => {
7956
+ if (interactive) {
7957
+ event.preventDefault();
7958
+ event.stopPropagation();
7959
+ }
7960
+ },
7961
+ onClick: (event) => {
7962
+ event.stopPropagation();
7963
+ if (interactive) {
7964
+ inputRef.current?.focus({ preventScroll: true });
7965
+ show();
7966
+ }
7967
+ },
7968
+ children: [
7969
+ allowClear && interactive && selected.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
7970
+ "button",
7971
+ {
7972
+ type: "button",
7973
+ tabIndex: -1,
7974
+ "aria-label": "\u6E05\u7A7A\u6811\u9009\u62E9",
7975
+ className: "canvas-react-select-clear",
7976
+ onClick: (event) => {
7977
+ event.preventDefault();
7978
+ event.stopPropagation();
7979
+ inputRef.current?.focus({ preventScroll: true });
7980
+ setKeyword(null);
7981
+ setActive(null);
7982
+ setOpen(true);
7983
+ onChange?.(multiple ? [] : null, [], {
7984
+ trigger: "clear",
7985
+ complete: false
7986
+ });
7987
+ },
7988
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7989
+ "span",
7990
+ {
7991
+ className: "canvas-react-select-clear-icon",
7992
+ "aria-hidden": "true"
7993
+ }
7994
+ )
7995
+ }
7996
+ ) : null,
7997
+ /* @__PURE__ */ jsxRuntime.jsx(
7998
+ "span",
7999
+ {
8000
+ className: `canvas-react-select-arrow${open ? " canvas-react-select-arrow-open" : ""}`,
8001
+ "aria-hidden": "true"
8002
+ }
8003
+ )
8004
+ ]
8005
+ }
8006
+ )
8007
+ }
8008
+ ),
8009
+ /* @__PURE__ */ jsxRuntime.jsx(
8010
+ ReactPopup,
8011
+ {
8012
+ open: open && interactive,
8013
+ anchorRef,
8014
+ onOpenChange: setOpen,
8015
+ matchAnchorWidth: true,
8016
+ constrainHeight: true,
8017
+ surfaceClassName: "canvas-react-tree-select-popup",
8018
+ children: /* @__PURE__ */ jsxRuntime.jsx(
8019
+ "div",
8020
+ {
8021
+ ref: treeRef,
8022
+ id: treeId,
8023
+ role: "tree",
8024
+ "aria-label": "\u6811\u9009\u62E9\u9009\u9879",
8025
+ "aria-multiselectable": multiple || void 0,
8026
+ className: "canvas-react-tree-select-tree",
8027
+ children: visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-react-tree-select-empty", children: "\u6682\u65E0\u6570\u636E" }) : visible.map((entry, position) => {
8028
+ const isExpanded = !!query || expanded.has(entry.key);
8029
+ const hasChildren = !!entry.node.children?.length;
8030
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8031
+ "div",
8032
+ {
8033
+ id: `${treeId}-${position}`,
8034
+ role: "treeitem",
8035
+ "aria-level": entry.depth + 1,
8036
+ "aria-expanded": hasChildren ? isExpanded : void 0,
8037
+ "aria-selected": selectedSet.has(entry.node.value),
8038
+ "aria-disabled": !!entry.node.disabled,
8039
+ "data-active": entry.node.value === active,
8040
+ className: "canvas-react-tree-select-node",
8041
+ style: { paddingLeft: 6 + entry.depth * 18 },
8042
+ onMouseDown: (event) => event.preventDefault(),
8043
+ onMouseEnter: () => setActive(entry.node.value),
8044
+ onClick: () => {
8045
+ setActive(entry.node.value);
8046
+ choose(entry, "mouse");
8047
+ },
8048
+ children: [
8049
+ hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
8050
+ "button",
8051
+ {
8052
+ type: "button",
8053
+ tabIndex: -1,
8054
+ "aria-label": `${isExpanded ? "\u6536\u8D77" : "\u5C55\u5F00"} ${entry.node.title}`,
8055
+ className: "canvas-react-tree-select-switcher",
8056
+ onClick: (event) => {
8057
+ event.preventDefault();
8058
+ event.stopPropagation();
8059
+ expand(entry);
8060
+ },
8061
+ children: /* @__PURE__ */ jsxRuntime.jsx(
8062
+ "span",
8063
+ {
8064
+ className: `canvas-react-tree-select-chevron${isExpanded ? " canvas-react-tree-select-chevron-open" : ""}`,
8065
+ "aria-hidden": "true"
8066
+ }
8067
+ )
8068
+ }
8069
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "canvas-react-tree-select-switcher" }),
8070
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "canvas-react-tree-select-title", children: entry.node.title }),
8071
+ multiple && selectedSet.has(entry.node.value) ? /* @__PURE__ */ jsxRuntime.jsx(
8072
+ "span",
8073
+ {
8074
+ className: "canvas-react-tree-select-check",
8075
+ "aria-hidden": "true",
8076
+ children: "\u2713"
8077
+ }
8078
+ ) : null
8079
+ ]
8080
+ },
8081
+ JSON.stringify(entry.node.value)
8082
+ );
8083
+ })
8084
+ }
8085
+ )
8086
+ }
8087
+ )
8088
+ ]
8089
+ }
8090
+ );
8091
+ }
7262
8092
  var ReactAutoComplete = React.forwardRef(function ReactAutoComplete2(props, ref) {
7263
8093
  const {
7264
8094
  onChange,
@@ -8549,6 +9379,7 @@ var reactMessage = {
8549
9379
  exports.REACT_COMPONENT_PREFIX = REACT_COMPONENT_PREFIX;
8550
9380
  exports.ReactAutoComplete = ReactAutoComplete;
8551
9381
  exports.ReactButton = ReactButton;
9382
+ exports.ReactCascader = ReactCascader;
8552
9383
  exports.ReactCheckbox = ReactCheckbox;
8553
9384
  exports.ReactCol = ReactCol;
8554
9385
  exports.ReactColorPicker = ReactColorPicker;
@@ -8580,6 +9411,7 @@ exports.ReactTimePicker = ReactTimePicker;
8580
9411
  exports.ReactTimeRangePicker = ReactTimeRangePicker;
8581
9412
  exports.ReactTooltip = ReactTooltip;
8582
9413
  exports.ReactTransition = ReactTransition;
9414
+ exports.ReactTreeSelect = ReactTreeSelect;
8583
9415
  exports.ReactVirtualList = ReactVirtualList;
8584
9416
  exports.ReactYearPicker = ReactYearPicker;
8585
9417
  exports.reactMessage = reactMessage;