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

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
@@ -2257,7 +2257,7 @@ var Input = (0, import_react12.forwardRef)(function Input2({
2257
2257
  size: sizeProp,
2258
2258
  prefix,
2259
2259
  suffix,
2260
- allowClear = false,
2260
+ allowClear = true,
2261
2261
  onClear,
2262
2262
  showCount = false,
2263
2263
  placeholderMode,
@@ -2430,7 +2430,7 @@ var Checkbox2 = Object.assign(CheckboxRoot, {
2430
2430
  });
2431
2431
 
2432
2432
  // src/components/SelectionPanel.tsx
2433
- var import_react15 = require("react");
2433
+ var import_react17 = require("react");
2434
2434
 
2435
2435
  // src/components/FloatingDisplay.tsx
2436
2436
  var import_react14 = require("react");
@@ -2881,252 +2881,15 @@ function Tree({
2881
2881
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: `sia-tree${showLine ? " sia-tree--line" : ""}${stickyAncestors ? " sia-tree--sticky-ancestors" : ""} ${className}`.trim(), role: "tree", "aria-multiselectable": multiple || void 0, ...withTitleTooltip(props), children: render(treeData) });
2882
2882
  }
2883
2883
 
2884
- // src/components/SelectionPanel.tsx
2885
- var import_jsx_runtime15 = require("react/jsx-runtime");
2886
- function SelectionPanel({
2887
- options,
2888
- value,
2889
- onChange,
2890
- multiple = false,
2891
- allowDeselect = false,
2892
- disabled = false,
2893
- loading = false,
2894
- showSearch = true,
2895
- showActions = true,
2896
- includeUnknownValues = true,
2897
- searchValue,
2898
- onSearch,
2899
- selectedOnly = false,
2900
- showValue = false,
2901
- displayField = "label",
2902
- columns = 1,
2903
- maxHeight = 250,
2904
- autoFocusSearch = false
2905
- }) {
2906
- const [localSearch, setLocalSearch] = (0, import_react15.useState)("");
2907
- const search = searchValue ?? localSearch;
2908
- const [scrollTop, setScrollTop] = (0, import_react15.useState)(0);
2909
- const [active, setActive] = (0, import_react15.useState)();
2910
- const [keyboardActive, setKeyboardActive] = (0, import_react15.useState)(false);
2911
- const [deselectedHover, setDeselectedHover] = (0, import_react15.useState)();
2912
- const listRef = (0, import_react15.useRef)(null);
2913
- const id = (0, import_react15.useId)();
2914
- const selected = (0, import_react15.useMemo)(() => new Set(value), [value]);
2915
- const count = Math.max(1, Math.floor(columns));
2916
- const allOptions = (0, import_react15.useMemo)(() => {
2917
- if (!includeUnknownValues) return [...options];
2918
- const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
2919
- return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
2920
- }, [options, value, includeUnknownValues]);
2921
- const filtered = (0, import_react15.useMemo)(
2922
- () => allOptions.filter((option) => (!selectedOnly || selected.has(option.value)) && (!search || option.optionType !== "divider" && [option.label, option.value].some((text) => String(text ?? "").toLowerCase().includes(search.toLowerCase())))),
2923
- [allOptions, selectedOnly, selected, search]
2924
- );
2925
- const rows = (0, import_react15.useMemo)(() => {
2926
- const groups = /* @__PURE__ */ new Map();
2927
- filtered.forEach((option) => {
2928
- const items = groups.get(option.group) ?? [];
2929
- items.push(option);
2930
- groups.set(option.group, items);
2931
- });
2932
- const rows2 = [];
2933
- let top = 0;
2934
- for (const [group, items] of groups) {
2935
- if (group) {
2936
- rows2.push({ key: `group-${rows2.length}`, title: group, top, height: 30 });
2937
- top += 30;
2938
- }
2939
- for (let index = 0; index < items.length; index += count) {
2940
- const height = showValue ? 48 : 34;
2941
- rows2.push({ key: `row-${rows2.length}`, items: items.slice(index, index + count), top, height });
2942
- top += height;
2943
- }
2944
- }
2945
- return rows2;
2946
- }, [filtered, count, showValue]);
2947
- const totalHeight = rows.length ? rows[rows.length - 1].top + rows[rows.length - 1].height : 0;
2948
- const virtual = filtered.length > 100;
2949
- const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
2950
- const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
2951
- (0, import_react15.useEffect)(() => {
2952
- setScrollTop(0);
2953
- if (listRef.current) listRef.current.scrollTop = 0;
2954
- setActive(void 0);
2955
- }, [search, selectedOnly, count]);
2956
- function toggle(option, keyboard = false) {
2957
- if (disabled || loading || option.disabled || option.optionType === "divider") return;
2958
- setActive(option.value);
2959
- setKeyboardActive(keyboard);
2960
- setDeselectedHover(!keyboard && !multiple && allowDeselect && selected.has(option.value) ? option.value : void 0);
2961
- onChange(multiple ? selected.has(option.value) ? value.filter((item) => item !== option.value) : [...value, option.value] : allowDeselect && selected.has(option.value) ? [] : [option.value]);
2962
- }
2963
- function batch(operation) {
2964
- if (disabled || loading) return;
2965
- if (operation === "clear") {
2966
- onChange([]);
2967
- return;
2968
- }
2969
- const editable = new Set(enabled.map((option) => option.value));
2970
- const retained = value.filter((item) => !editable.has(item));
2971
- const add = enabled.filter((option) => operation === "all" || !selected.has(option.value)).map((option) => option.value);
2972
- onChange([...retained, ...add]);
2973
- }
2974
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sia-selection-panel", children: [
2975
- showSearch && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2976
- Input,
2977
- {
2978
- "aria-label": "\u641C\u7D22\u9009\u9879",
2979
- placeholder: "\u641C\u7D22",
2980
- autoFocus: autoFocusSearch,
2981
- value: search,
2982
- allowClear: true,
2983
- onChange: (event) => {
2984
- setLocalSearch(event.target.value);
2985
- onSearch?.(event.target.value);
2986
- }
2987
- }
2988
- ),
2989
- multiple && showActions && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sia-selection-panel__actions", children: [
2990
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("all"), children: "\u5168\u9009" }),
2991
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("invert"), children: "\u53CD\u9009" }),
2992
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !value.length, onClick: () => batch("clear"), children: "\u6E05\u7A7A" }),
2993
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { children: [
2994
- "\u5DF2\u9009 ",
2995
- value.length,
2996
- " \u9879"
2997
- ] })
2998
- ] }),
2999
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3000
- "div",
3001
- {
3002
- ref: listRef,
3003
- role: "listbox",
3004
- "aria-label": "\u9009\u9879\u5217\u8868",
3005
- "aria-multiselectable": multiple || void 0,
3006
- tabIndex: disabled ? -1 : 0,
3007
- className: "sia-selection-panel__list",
3008
- style: { maxHeight },
3009
- onScroll: (event) => setScrollTop(event.currentTarget.scrollTop),
3010
- onPointerDown: () => setKeyboardActive(false),
3011
- onBlur: (event) => {
3012
- if (!event.currentTarget.contains(event.relatedTarget)) setKeyboardActive(false);
3013
- },
3014
- "aria-activedescendant": active !== void 0 ? `${id}-${typeof active}-${active}` : void 0,
3015
- onKeyDown: (event) => {
3016
- if (event.target instanceof HTMLInputElement) return;
3017
- if (disabled || loading || !enabled.length) return;
3018
- const index = enabled.findIndex((option) => option.value === active);
3019
- if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
3020
- event.preventDefault();
3021
- setKeyboardActive(true);
3022
- setDeselectedHover(void 0);
3023
- 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)));
3024
- const option = enabled[next];
3025
- setActive(option.value);
3026
- const row = rows.find((row2) => row2.items?.includes(option));
3027
- if (row && listRef.current) {
3028
- listRef.current.scrollTop = Math.max(0, row.top - maxHeight / 2);
3029
- setScrollTop(listRef.current.scrollTop);
3030
- }
3031
- } else if ((event.key === "Enter" || event.key === " ") && index >= 0) {
3032
- event.preventDefault();
3033
- toggle(enabled[index], true);
3034
- }
3035
- },
3036
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { role: "status", children: "\u52A0\u8F7D\u4E2D\u2026" }) : !rows.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "sia-selection-panel__empty", children: "\u6682\u65E0\u5339\u914D\u9009\u9879" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { height: totalHeight, position: "relative" }, children: renderedRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3037
- "div",
3038
- {
3039
- className: row.title !== void 0 ? "sia-selection-panel__group" : "sia-selection-panel__row",
3040
- style: { position: "absolute", top: row.top, height: row.height, width: "100%", gridTemplateColumns: `repeat(${count}, minmax(0, 1fr))` },
3041
- children: row.title ?? row.items?.map((option, index) => option.optionType === "divider" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { role: "separator", className: "sia-selection-panel__divider" }, `divider-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Tooltip, { title: option.disabled ? option.disabledTip : void 0, placement: "right", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3042
- "div",
3043
- {
3044
- role: "option",
3045
- id: `${id}-${typeof option.value}-${option.value}`,
3046
- tabIndex: -1,
3047
- "aria-selected": selected.has(option.value),
3048
- "aria-disabled": disabled || option.disabled || void 0,
3049
- className: `sia-selection-panel__option${keyboardActive && active === option.value ? " is-active" : ""}`,
3050
- "data-deselected-hover": deselectedHover === option.value || void 0,
3051
- onPointerLeave: () => {
3052
- if (deselectedHover === option.value) setDeselectedHover(void 0);
3053
- },
3054
- onClick: (event) => {
3055
- if (!event.target.closest(".sia-checkbox")) toggle(option);
3056
- },
3057
- children: multiple ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Checkbox2, { checked: selected.has(option.value), disabled: disabled || loading || option.disabled, tabIndex: -1, onChange: () => toggle(option), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "sia-selection-panel__text", children: [
3058
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
3059
- showValue && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("small", { children: String(option.value) })
3060
- ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "sia-selection-panel__text", children: [
3061
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
3062
- showValue && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("small", { children: String(option.value) })
3063
- ] })
3064
- }
3065
- ) }, `${typeof option.value}-${option.value}`))
3066
- },
3067
- row.key
3068
- )) })
3069
- }
3070
- )
3071
- ] });
3072
- }
3073
-
3074
- // src/components/OverflowTags.tsx
3075
- var import_react16 = require("react");
3076
- var import_jsx_runtime16 = require("react/jsx-runtime");
3077
- function OverflowTags({ items, maxCount: maxCount2, className = "", tagClassName, restClassName = "" }) {
3078
- const rootRef = (0, import_react16.useRef)(null);
3079
- const measureRef = (0, import_react16.useRef)(null);
3080
- const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount2) || 0));
3081
- const [visibleCount, setVisibleCount] = (0, import_react16.useState)(0);
3082
- (0, import_react16.useLayoutEffect)(() => {
3083
- const root = rootRef.current;
3084
- const measure = measureRef.current;
3085
- if (!root || !measure) return;
3086
- const update = () => {
3087
- const gap = Number.parseFloat(getComputedStyle(root).columnGap) || 0;
3088
- const widths = Array.from(measure.children, (child) => child.getBoundingClientRect().width);
3089
- let used = 0;
3090
- let fitting = 0;
3091
- for (let count2 = 1; count2 <= limit; count2 += 1) {
3092
- used += widths[count2 - 1] + (count2 > 1 ? gap : 0);
3093
- const rest = count2 < items.length ? gap + widths[limit + count2] : 0;
3094
- if (used + rest <= root.clientWidth) fitting = count2;
3095
- }
3096
- setVisibleCount((previous) => previous === fitting ? previous : fitting);
3097
- };
3098
- update();
3099
- const observer = new ResizeObserver(update);
3100
- observer.observe(root);
3101
- for (const child of measure.children) observer.observe(child);
3102
- return () => observer.disconnect();
3103
- }, [items, limit]);
3104
- const count = Math.min(visibleCount, limit);
3105
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { ref: rootRef, className: `sia-overflow-tags ${className}`.trim(), children: [
3106
- items.slice(0, count).map((item) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
3107
- items.length > count ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: `${tagClassName} sia-overflow-tags__rest ${restClassName}`.trim(), children: [
3108
- "+",
3109
- items.length - count
3110
- ] }) : null,
3111
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { ref: measureRef, className: "sia-overflow-tags__measure", "aria-hidden": "true", children: [
3112
- items.slice(0, limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
3113
- Array.from({ length: limit + 1 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: `${tagClassName} ${restClassName}`.trim(), children: [
3114
- "+",
3115
- items.length - index
3116
- ] }, `rest-${index}`))
3117
- ] })
3118
- ] });
3119
- }
3120
-
3121
2884
  // src/components/FloatingScrollbarProvider.tsx
3122
- var import_react18 = require("react");
2885
+ var import_react16 = require("react");
3123
2886
 
3124
2887
  // src/components/useScrollbarProximity.ts
3125
- var import_react17 = require("react");
2888
+ var import_react15 = require("react");
3126
2889
  var users = 0;
3127
2890
  var cleanup;
3128
2891
  function useScrollbarProximity() {
3129
- (0, import_react17.useEffect)(() => {
2892
+ (0, import_react15.useEffect)(() => {
3130
2893
  if (users++ === 0) {
3131
2894
  let frame = 0;
3132
2895
  let x = -Infinity;
@@ -3247,7 +3010,7 @@ function createTrack(axis) {
3247
3010
  }
3248
3011
  function FloatingScrollbarProvider({ disabled = false, targetRef }) {
3249
3012
  useScrollbarProximity();
3250
- (0, import_react18.useEffect)(() => {
3013
+ (0, import_react16.useEffect)(() => {
3251
3014
  if (disabled) return;
3252
3015
  const layer = document.createElement("div");
3253
3016
  layer.className = "sia-floating-scrollbar-layer";
@@ -3493,6 +3256,244 @@ function FloatingScrollbarProvider({ disabled = false, targetRef }) {
3493
3256
  return null;
3494
3257
  }
3495
3258
 
3259
+ // src/components/SelectionPanel.tsx
3260
+ var import_jsx_runtime15 = require("react/jsx-runtime");
3261
+ function SelectionPanel({
3262
+ options,
3263
+ value,
3264
+ onChange,
3265
+ multiple = false,
3266
+ allowDeselect = false,
3267
+ disabled = false,
3268
+ loading = false,
3269
+ showSearch = true,
3270
+ showActions = true,
3271
+ includeUnknownValues = true,
3272
+ searchValue,
3273
+ onSearch,
3274
+ selectedOnly = false,
3275
+ showValue = false,
3276
+ displayField = "label",
3277
+ columns = 1,
3278
+ maxHeight = 250,
3279
+ autoFocusSearch = false
3280
+ }) {
3281
+ const [localSearch, setLocalSearch] = (0, import_react17.useState)("");
3282
+ const search = searchValue ?? localSearch;
3283
+ const [scrollTop, setScrollTop] = (0, import_react17.useState)(0);
3284
+ const [active, setActive] = (0, import_react17.useState)();
3285
+ const [keyboardActive, setKeyboardActive] = (0, import_react17.useState)(false);
3286
+ const [deselectedHover, setDeselectedHover] = (0, import_react17.useState)();
3287
+ const listRef = (0, import_react17.useRef)(null);
3288
+ const id = (0, import_react17.useId)();
3289
+ const selected = (0, import_react17.useMemo)(() => new Set(value), [value]);
3290
+ const count = Math.max(1, Math.floor(columns));
3291
+ const allOptions = (0, import_react17.useMemo)(() => {
3292
+ if (!includeUnknownValues) return [...options];
3293
+ const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
3294
+ return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
3295
+ }, [options, value, includeUnknownValues]);
3296
+ const filtered = (0, import_react17.useMemo)(
3297
+ () => allOptions.filter((option) => (!selectedOnly || selected.has(option.value)) && (!search || option.optionType !== "divider" && [option.label, option.value].some((text) => String(text ?? "").toLowerCase().includes(search.toLowerCase())))),
3298
+ [allOptions, selectedOnly, selected, search]
3299
+ );
3300
+ const rows = (0, import_react17.useMemo)(() => {
3301
+ const groups = /* @__PURE__ */ new Map();
3302
+ filtered.forEach((option) => {
3303
+ const items = groups.get(option.group) ?? [];
3304
+ items.push(option);
3305
+ groups.set(option.group, items);
3306
+ });
3307
+ const rows2 = [];
3308
+ let top = 0;
3309
+ for (const [group, items] of groups) {
3310
+ if (group) {
3311
+ rows2.push({ key: `group-${rows2.length}`, title: group, top, height: 30 });
3312
+ top += 30;
3313
+ }
3314
+ for (let index = 0; index < items.length; index += count) {
3315
+ const height = showValue ? 48 : 34;
3316
+ rows2.push({ key: `row-${rows2.length}`, items: items.slice(index, index + count), top, height });
3317
+ top += height;
3318
+ }
3319
+ }
3320
+ return rows2;
3321
+ }, [filtered, count, showValue]);
3322
+ const totalHeight = rows.length ? rows[rows.length - 1].top + rows[rows.length - 1].height : 0;
3323
+ const virtual = filtered.length > 100;
3324
+ const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
3325
+ const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
3326
+ (0, import_react17.useEffect)(() => {
3327
+ setScrollTop(0);
3328
+ if (listRef.current) listRef.current.scrollTop = 0;
3329
+ setActive(void 0);
3330
+ }, [search, selectedOnly, count]);
3331
+ function toggle(option, keyboard = false) {
3332
+ if (disabled || loading || option.disabled || option.optionType === "divider") return;
3333
+ setActive(option.value);
3334
+ setKeyboardActive(keyboard);
3335
+ setDeselectedHover(!keyboard && !multiple && allowDeselect && selected.has(option.value) ? option.value : void 0);
3336
+ onChange(multiple ? selected.has(option.value) ? value.filter((item) => item !== option.value) : [...value, option.value] : allowDeselect && selected.has(option.value) ? [] : [option.value]);
3337
+ }
3338
+ function batch(operation) {
3339
+ if (disabled || loading) return;
3340
+ if (operation === "clear") {
3341
+ onChange([]);
3342
+ return;
3343
+ }
3344
+ const editable = new Set(enabled.map((option) => option.value));
3345
+ const retained = value.filter((item) => !editable.has(item));
3346
+ const add = enabled.filter((option) => operation === "all" || !selected.has(option.value)).map((option) => option.value);
3347
+ onChange([...retained, ...add]);
3348
+ }
3349
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sia-selection-panel", children: [
3350
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FloatingScrollbarProvider, { targetRef: listRef }),
3351
+ showSearch && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3352
+ Input,
3353
+ {
3354
+ "aria-label": "\u641C\u7D22\u9009\u9879",
3355
+ placeholder: "\u641C\u7D22",
3356
+ autoFocus: autoFocusSearch,
3357
+ value: search,
3358
+ allowClear: true,
3359
+ onChange: (event) => {
3360
+ setLocalSearch(event.target.value);
3361
+ onSearch?.(event.target.value);
3362
+ }
3363
+ }
3364
+ ),
3365
+ multiple && showActions && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sia-selection-panel__actions", children: [
3366
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("all"), children: "\u5168\u9009" }),
3367
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("invert"), children: "\u53CD\u9009" }),
3368
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !value.length, onClick: () => batch("clear"), children: "\u6E05\u7A7A" }),
3369
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { children: [
3370
+ "\u5DF2\u9009 ",
3371
+ value.length,
3372
+ " \u9879"
3373
+ ] })
3374
+ ] }),
3375
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3376
+ "div",
3377
+ {
3378
+ ref: listRef,
3379
+ role: "listbox",
3380
+ "aria-label": "\u9009\u9879\u5217\u8868",
3381
+ "aria-multiselectable": multiple || void 0,
3382
+ tabIndex: disabled ? -1 : 0,
3383
+ className: "sia-selection-panel__list",
3384
+ style: { maxHeight },
3385
+ onScroll: (event) => setScrollTop(event.currentTarget.scrollTop),
3386
+ onPointerDown: () => setKeyboardActive(false),
3387
+ onBlur: (event) => {
3388
+ if (!event.currentTarget.contains(event.relatedTarget)) setKeyboardActive(false);
3389
+ },
3390
+ "aria-activedescendant": active !== void 0 ? `${id}-${typeof active}-${active}` : void 0,
3391
+ onKeyDown: (event) => {
3392
+ if (event.target instanceof HTMLInputElement) return;
3393
+ if (disabled || loading || !enabled.length) return;
3394
+ const index = enabled.findIndex((option) => option.value === active);
3395
+ if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
3396
+ event.preventDefault();
3397
+ setKeyboardActive(true);
3398
+ setDeselectedHover(void 0);
3399
+ 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)));
3400
+ const option = enabled[next];
3401
+ setActive(option.value);
3402
+ const row = rows.find((row2) => row2.items?.includes(option));
3403
+ if (row && listRef.current) {
3404
+ listRef.current.scrollTop = Math.max(0, row.top - maxHeight / 2);
3405
+ setScrollTop(listRef.current.scrollTop);
3406
+ }
3407
+ } else if ((event.key === "Enter" || event.key === " ") && index >= 0) {
3408
+ event.preventDefault();
3409
+ toggle(enabled[index], true);
3410
+ }
3411
+ },
3412
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { role: "status", children: "\u52A0\u8F7D\u4E2D\u2026" }) : !rows.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "sia-selection-panel__empty", children: "\u6682\u65E0\u5339\u914D\u9009\u9879" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { height: totalHeight, position: "relative" }, children: renderedRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3413
+ "div",
3414
+ {
3415
+ className: row.title !== void 0 ? "sia-selection-panel__group" : "sia-selection-panel__row",
3416
+ style: { position: "absolute", top: row.top, height: row.height, width: "100%", gridTemplateColumns: `repeat(${count}, minmax(0, 1fr))` },
3417
+ children: row.title ?? row.items?.map((option, index) => option.optionType === "divider" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { role: "separator", className: "sia-selection-panel__divider" }, `divider-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Tooltip, { title: option.disabled ? option.disabledTip : void 0, placement: "right", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3418
+ "div",
3419
+ {
3420
+ role: "option",
3421
+ id: `${id}-${typeof option.value}-${option.value}`,
3422
+ tabIndex: -1,
3423
+ "aria-selected": selected.has(option.value),
3424
+ "aria-disabled": disabled || option.disabled || void 0,
3425
+ className: `sia-selection-panel__option${keyboardActive && active === option.value ? " is-active" : ""}`,
3426
+ "data-deselected-hover": deselectedHover === option.value || void 0,
3427
+ onPointerLeave: () => {
3428
+ if (deselectedHover === option.value) setDeselectedHover(void 0);
3429
+ },
3430
+ onClick: (event) => {
3431
+ if (!event.target.closest(".sia-checkbox")) toggle(option);
3432
+ },
3433
+ children: multiple ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Checkbox2, { checked: selected.has(option.value), disabled: disabled || loading || option.disabled, tabIndex: -1, onChange: () => toggle(option), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "sia-selection-panel__text", children: [
3434
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
3435
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("small", { children: String(option.value) })
3436
+ ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "sia-selection-panel__text", children: [
3437
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
3438
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("small", { children: String(option.value) })
3439
+ ] })
3440
+ }
3441
+ ) }, `${typeof option.value}-${option.value}`))
3442
+ },
3443
+ row.key
3444
+ )) })
3445
+ }
3446
+ )
3447
+ ] });
3448
+ }
3449
+
3450
+ // src/components/OverflowTags.tsx
3451
+ var import_react18 = require("react");
3452
+ var import_jsx_runtime16 = require("react/jsx-runtime");
3453
+ function OverflowTags({ items, maxCount: maxCount2, className = "", tagClassName, restClassName = "" }) {
3454
+ const rootRef = (0, import_react18.useRef)(null);
3455
+ const measureRef = (0, import_react18.useRef)(null);
3456
+ const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount2) || 0));
3457
+ const [visibleCount, setVisibleCount] = (0, import_react18.useState)(0);
3458
+ (0, import_react18.useLayoutEffect)(() => {
3459
+ const root = rootRef.current;
3460
+ const measure = measureRef.current;
3461
+ if (!root || !measure) return;
3462
+ const update = () => {
3463
+ const gap = Number.parseFloat(getComputedStyle(root).columnGap) || 0;
3464
+ const widths = Array.from(measure.children, (child) => child.getBoundingClientRect().width);
3465
+ let used = 0;
3466
+ let fitting = 0;
3467
+ for (let count2 = 1; count2 <= limit; count2 += 1) {
3468
+ used += widths[count2 - 1] + (count2 > 1 ? gap : 0);
3469
+ const rest = count2 < items.length ? gap + widths[limit + count2] : 0;
3470
+ if (used + rest <= root.clientWidth) fitting = count2;
3471
+ }
3472
+ setVisibleCount((previous) => previous === fitting ? previous : fitting);
3473
+ };
3474
+ update();
3475
+ const observer = new ResizeObserver(update);
3476
+ observer.observe(root);
3477
+ for (const child of measure.children) observer.observe(child);
3478
+ return () => observer.disconnect();
3479
+ }, [items, limit]);
3480
+ const count = Math.min(visibleCount, limit);
3481
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { ref: rootRef, className: `sia-overflow-tags ${className}`.trim(), children: [
3482
+ items.slice(0, count).map((item) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
3483
+ items.length > count ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: `${tagClassName} sia-overflow-tags__rest ${restClassName}`.trim(), children: [
3484
+ "+",
3485
+ items.length - count
3486
+ ] }) : null,
3487
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { ref: measureRef, className: "sia-overflow-tags__measure", "aria-hidden": "true", children: [
3488
+ items.slice(0, limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
3489
+ Array.from({ length: limit + 1 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: `${tagClassName} ${restClassName}`.trim(), children: [
3490
+ "+",
3491
+ items.length - index
3492
+ ] }, `rest-${index}`))
3493
+ ] })
3494
+ ] });
3495
+ }
3496
+
3496
3497
  // src/components/Select.tsx
3497
3498
  var import_jsx_runtime17 = require("react/jsx-runtime");
3498
3499
  function defaultFilterOption(query, option) {
@@ -3555,6 +3556,8 @@ var Select = (0, import_react19.forwardRef)(function Select2({
3555
3556
  const [query, setQuery] = (0, import_react19.useState)("");
3556
3557
  const [activeIndex, setActiveIndex] = (0, import_react19.useState)(-1);
3557
3558
  const [scrollTop, setScrollTop] = (0, import_react19.useState)(0);
3559
+ const [dropdownFontSize, setDropdownFontSize] = (0, import_react19.useState)();
3560
+ const pendingSelectedScroll = (0, import_react19.useRef)(false);
3558
3561
  const deferredQuery = (0, import_react19.useDeferredValue)(query.trim());
3559
3562
  const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
3560
3563
  const [currentValue, setCurrentValue] = useControllableState({
@@ -3612,10 +3615,31 @@ var Select = (0, import_react19.forwardRef)(function Select2({
3612
3615
  (0, import_react19.useEffect)(() => {
3613
3616
  if (disabled || loading) closeDropdown();
3614
3617
  }, [disabled, loading]);
3618
+ (0, import_react19.useEffect)(() => {
3619
+ if (!open || popupMode !== "dropdown" || !pendingSelectedScroll.current || query) return;
3620
+ const index = filteredOptions.findIndex((option) => selectedValueSet.has(option.value));
3621
+ if (index < 0) return;
3622
+ const frame = requestAnimationFrame(() => {
3623
+ const list = listRef.current;
3624
+ if (!list) return;
3625
+ const item = virtualEnabled ? null : list.querySelectorAll('[role="option"]')[index];
3626
+ const top = virtualEnabled ? index * optionHeight : item ? item.getBoundingClientRect().top - list.getBoundingClientRect().top + list.scrollTop : 0;
3627
+ list.scrollTop = Math.max(0, top - (list.clientHeight - (item?.offsetHeight ?? optionHeight)) / 2);
3628
+ setScrollTop(list.scrollTop);
3629
+ pendingSelectedScroll.current = false;
3630
+ });
3631
+ return () => cancelAnimationFrame(frame);
3632
+ }, [open, popupMode, filteredOptions, selectedValueSet, virtualEnabled, optionHeight, query]);
3633
+ (0, import_react19.useLayoutEffect)(() => {
3634
+ if (!open || popupMode !== "dropdown") return;
3635
+ const trigger = rootRef.current?.querySelector(".sia-select__trigger");
3636
+ if (trigger) setDropdownFontSize(getComputedStyle(trigger).fontSize);
3637
+ }, [open, popupMode, size]);
3615
3638
  function firstEnabledIndex() {
3616
3639
  return filteredOptions.findIndex((option) => !option.disabled);
3617
3640
  }
3618
3641
  function closeDropdown() {
3642
+ pendingSelectedScroll.current = false;
3619
3643
  setOpen(false);
3620
3644
  setQuery("");
3621
3645
  setScrollTop(0);
@@ -3640,6 +3664,7 @@ var Select = (0, import_react19.forwardRef)(function Select2({
3640
3664
  }
3641
3665
  function openDropdown() {
3642
3666
  if (disabled || loading) return;
3667
+ pendingSelectedScroll.current = true;
3643
3668
  setOpenedMode(automaticMode);
3644
3669
  const selectedIndex = filteredOptions.findIndex((option) => selectedValueSet.has(option.value) && !option.disabled);
3645
3670
  setActiveIndex(selectedIndex >= 0 ? selectedIndex : firstEnabledIndex());
@@ -3814,7 +3839,7 @@ var Select = (0, import_react19.forwardRef)(function Select2({
3814
3839
  }
3815
3840
  ),
3816
3841
  allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
3817
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", className: `sia-select__dropdown${filteredOptions.length === 0 && !canSubmitInput ? " sia-select__dropdown--empty" : ""}`, children: [
3842
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", style: { fontSize: dropdownFontSize }, className: `sia-select__dropdown${filteredOptions.length === 0 && !canSubmitInput ? " sia-select__dropdown--empty" : ""}`, children: [
3818
3843
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FloatingScrollbarProvider, { targetRef: listRef }),
3819
3844
  showSearch || allowInput ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "sia-select__search", children: [
3820
3845
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "search", size: 15 }),
@@ -4015,6 +4040,7 @@ function Pagination({
4015
4040
  className: "sia-pagination__size-select",
4016
4041
  size: controlSize,
4017
4042
  "aria-label": "\u6BCF\u9875\u6761\u6570",
4043
+ allowClear: false,
4018
4044
  value: size,
4019
4045
  options: sizes.map((value) => ({ label: `${value} \u6761`, value })),
4020
4046
  disabled,
@@ -4099,7 +4125,7 @@ function Cascader({
4099
4125
  size: sizeProp,
4100
4126
  multiple = false,
4101
4127
  showSearch = false,
4102
- allowClear = false,
4128
+ allowClear = true,
4103
4129
  changeOnSelect = false,
4104
4130
  expandTrigger = "click",
4105
4131
  placeholder = "\u8BF7\u9009\u62E9",
@@ -6429,7 +6455,7 @@ function ColorPicker({
6429
6455
  defaultMode = "solid",
6430
6456
  modes = DEFAULT_MODES,
6431
6457
  disabled = false,
6432
- allowClear = false,
6458
+ allowClear = true,
6433
6459
  showText = false,
6434
6460
  showAlpha = false,
6435
6461
  presets,
@@ -6814,6 +6840,10 @@ function TimePanel({
6814
6840
  }) {
6815
6841
  const [hour = "00", minute = "00", second = "00"] = value.split(":");
6816
6842
  const columnsRef = (0, import_react33.useRef)(null);
6843
+ const hourRef = (0, import_react33.useRef)(null);
6844
+ const minuteRef = (0, import_react33.useRef)(null);
6845
+ const secondRef = (0, import_react33.useRef)(null);
6846
+ const columnRefs = [hourRef, minuteRef, secondRef];
6817
6847
  (0, import_react33.useLayoutEffect)(() => {
6818
6848
  for (const column of columnsRef.current?.children ?? []) {
6819
6849
  const selected = column.querySelector('[aria-selected="true"]');
@@ -6844,7 +6874,7 @@ function TimePanel({
6844
6874
  showSecond ? `:${second}` : "",
6845
6875
  use12Hours ? Number(hour) < 12 ? " AM" : " PM" : ""
6846
6876
  ] }),
6847
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: columnsRef, className: "sia-date-panel__time-columns", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { role: "listbox", "aria-label": `${ariaLabel}${column.label}`, children: Array.from({ length: column.count }, (_, index) => {
6877
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: columnsRef, className: "sia-date-panel__time-columns", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: columnRefs[column.index], role: "listbox", "aria-label": `${ariaLabel}${column.label}`, children: Array.from({ length: column.count }, (_, index) => {
6848
6878
  const next = pad2(index);
6849
6879
  const candidate = [hour, minute, second];
6850
6880
  candidate[column.index] = next;
@@ -6856,7 +6886,8 @@ function TimePanel({
6856
6886
  const target = event.key === "Home" ? 0 : event.key === "End" ? buttons.length - 1 : Math.max(0, Math.min(buttons.length - 1, position + (event.key === "ArrowDown" ? 1 : -1)));
6857
6887
  buttons[target]?.focus();
6858
6888
  }, onClick: () => update(column.index, next), children: use12Hours && column.index === 0 ? `${pad2(index % 12 || 12)} ${index < 12 ? "AM" : "PM"}` : next }, next);
6859
- }) }, column.label)) })
6889
+ }) }, column.label)) }),
6890
+ columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(FloatingScrollbarProvider, { targetRef: columnRefs[column.index] }, column.index))
6860
6891
  ] });
6861
6892
  }
6862
6893
  function DatePanelFooter({
@@ -7734,7 +7765,7 @@ function TreeSelect({
7734
7765
  multiple = false,
7735
7766
  treeCheckable = false,
7736
7767
  showSearch = false,
7737
- allowClear = false,
7768
+ allowClear = true,
7738
7769
  treeDefaultExpandAll = false,
7739
7770
  placeholder = "\u8BF7\u9009\u62E9",
7740
7771
  placeholderMode,