@sia.soul/sia-react-ui 0.1.24 → 0.1.26
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/{Select-O_yY51vc.d.ts → Select-CCrPqULn.d.ts} +1 -1
- package/dist/{Select-W_xpkpOW.d.cts → Select-YJbT-MF1.d.cts} +1 -1
- package/dist/chart.cjs +1 -1
- package/dist/chart.js +4 -4
- package/dist/{chunk-6R7JY7IY.js → chunk-5MW3NE2V.js} +227 -202
- package/dist/{chunk-T2QIW4OO.js → chunk-IQU4GGLM.js} +11 -5
- package/dist/{chunk-6WBABNAX.js → chunk-IYNS423D.js} +1 -1
- package/dist/{chunk-RGXVPS37.js → chunk-LK56NX5F.js} +3 -3
- package/dist/{chunk-LIYCU2GU.js → chunk-NAOV53NK.js} +5 -5
- package/dist/{chunk-LA7O3PN4.js → chunk-PXHBIRQW.js} +1 -1
- package/dist/{chunk-NSSPGXNM.js → chunk-RAO3JHDL.js} +1 -1
- package/dist/{chunk-GUXAWU63.js → chunk-TZROBD65.js} +3 -3
- package/dist/{chunk-LRPQ5FGE.js → chunk-YF2I6SDB.js} +3 -3
- package/dist/{chunk-OH6YILJW.js → chunk-YQDHCORW.js} +1 -1
- package/dist/{core-tbb9ZiBY.d.cts → core-BM-wnJRa.d.cts} +3 -3
- package/dist/{core-BOzLwiXG.d.ts → core-CLqv6btD.d.ts} +3 -3
- package/dist/core.cjs +270 -243
- package/dist/core.css +10 -5
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +6 -6
- package/dist/index.cjs +296 -252
- package/dist/index.css +10 -5
- package/dist/index.d.cts +20 -14
- package/dist/index.d.ts +20 -14
- package/dist/index.js +29 -15
- package/dist/markdown-editor.cjs +1 -1
- package/dist/markdown-editor.js +2 -2
- package/dist/rich-text-editor.cjs +2 -2
- package/dist/rich-text-editor.js +4 -4
- package/dist/{select-date-range-C9w8z3G8.d.cts → select-date-range-CtA-B8DB.d.cts} +1 -1
- package/dist/{select-date-range-BjqFUeU6.d.ts → select-date-range-D9W_mmMq.d.ts} +1 -1
- package/dist/select-date-range.cjs +706 -674
- package/dist/select-date-range.d.cts +2 -2
- package/dist/select-date-range.d.ts +2 -2
- package/dist/select-date-range.js +5 -5
- package/package.json +1 -1
|
@@ -301,7 +301,7 @@ interface SelectProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "def
|
|
|
301
301
|
*/
|
|
302
302
|
notFoundContent?: ReactNode;
|
|
303
303
|
}
|
|
304
|
-
/**
|
|
304
|
+
/** 选择器组件。下拉面板每次展开自动定位到列表顺序中的第一个已选项,支持普通和虚拟列表;未选中时从顶部显示。 */
|
|
305
305
|
declare const Select: react.ForwardRefExoticComponent<SelectProps & react.RefAttributes<HTMLButtonElement>>;
|
|
306
306
|
|
|
307
307
|
export { type ButtonProps as B, type ModalOpenConfig as M, type OverlayContainer as O, type SelectOption as S, type OverlayApiHandle as a, type SelectChangeValue as b, type SelectProps as c, type ModalActionResult as d, type ButtonSize as e, Button as f, type ButtonVariant as g, Modal as h, type ModalProps as i, type ModalType as j, Select as k, type SelectMode as l, type SelectValue as m };
|
|
@@ -301,7 +301,7 @@ interface SelectProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "def
|
|
|
301
301
|
*/
|
|
302
302
|
notFoundContent?: ReactNode;
|
|
303
303
|
}
|
|
304
|
-
/**
|
|
304
|
+
/** 选择器组件。下拉面板每次展开自动定位到列表顺序中的第一个已选项,支持普通和虚拟列表;未选中时从顶部显示。 */
|
|
305
305
|
declare const Select: react.ForwardRefExoticComponent<SelectProps & react.RefAttributes<HTMLButtonElement>>;
|
|
306
306
|
|
|
307
307
|
export { type ButtonProps as B, type ModalOpenConfig as M, type OverlayContainer as O, type SelectOption as S, type OverlayApiHandle as a, type SelectChangeValue as b, type SelectProps as c, type ModalActionResult as d, type ButtonSize as e, Button as f, type ButtonVariant as g, Modal as h, type ModalProps as i, type ModalType as j, Select as k, type SelectMode as l, type SelectValue as m };
|
package/dist/chart.cjs
CHANGED
|
@@ -317,7 +317,7 @@ function installTitleTooltips(doc) {
|
|
|
317
317
|
else if (active.getAttribute("data-sia-title") !== doc.getElementById(tooltipId)?.textContent) render();
|
|
318
318
|
});
|
|
319
319
|
observer.observe(doc.body, { childList: true, subtree: true, attributes: true, attributeFilter: ["data-sia-title"] });
|
|
320
|
-
},
|
|
320
|
+
}, 600);
|
|
321
321
|
};
|
|
322
322
|
doc.addEventListener("pointerover", (event) => {
|
|
323
323
|
if (event.pointerType === "touch") return;
|
package/dist/chart.js
CHANGED
|
@@ -56,10 +56,10 @@ import {
|
|
|
56
56
|
smoothSvgPath,
|
|
57
57
|
svgArcPath,
|
|
58
58
|
transferCompositeValue
|
|
59
|
-
} from "./chunk-
|
|
60
|
-
import "./chunk-
|
|
61
|
-
import "./chunk-
|
|
62
|
-
import "./chunk-
|
|
59
|
+
} from "./chunk-TZROBD65.js";
|
|
60
|
+
import "./chunk-YQDHCORW.js";
|
|
61
|
+
import "./chunk-IYNS423D.js";
|
|
62
|
+
import "./chunk-RAO3JHDL.js";
|
|
63
63
|
export {
|
|
64
64
|
BarChart,
|
|
65
65
|
CHART_VIEWBOX_HEIGHT,
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
Dropdown,
|
|
3
3
|
Icon,
|
|
4
4
|
Input
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YF2I6SDB.js";
|
|
6
6
|
import {
|
|
7
7
|
Button
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-IYNS423D.js";
|
|
9
9
|
import {
|
|
10
10
|
ControlSizeContext,
|
|
11
11
|
PopupPortal,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
useControllableState,
|
|
14
14
|
useFloatingPlaceholder,
|
|
15
15
|
withTitleTooltip
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-RAO3JHDL.js";
|
|
17
17
|
|
|
18
18
|
// src/components/Checkbox.tsx
|
|
19
19
|
import { createContext, forwardRef, useContext, useEffect, useId, useMemo, useRef } from "react";
|
|
@@ -852,206 +852,15 @@ var Modal2 = Object.assign(ModalRoot, {
|
|
|
852
852
|
}
|
|
853
853
|
});
|
|
854
854
|
|
|
855
|
-
// src/components/SelectionPanel.tsx
|
|
856
|
-
import { useEffect as useEffect5, useId as useId4, useMemo as useMemo3, useRef as useRef5, useState as useState3 } from "react";
|
|
857
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
858
|
-
function SelectionPanel({
|
|
859
|
-
options,
|
|
860
|
-
value,
|
|
861
|
-
onChange,
|
|
862
|
-
multiple = false,
|
|
863
|
-
allowDeselect = false,
|
|
864
|
-
disabled = false,
|
|
865
|
-
loading = false,
|
|
866
|
-
showSearch = true,
|
|
867
|
-
showActions = true,
|
|
868
|
-
includeUnknownValues = true,
|
|
869
|
-
searchValue,
|
|
870
|
-
onSearch,
|
|
871
|
-
selectedOnly = false,
|
|
872
|
-
showValue = false,
|
|
873
|
-
displayField = "label",
|
|
874
|
-
columns = 1,
|
|
875
|
-
maxHeight = 250,
|
|
876
|
-
autoFocusSearch = false
|
|
877
|
-
}) {
|
|
878
|
-
const [localSearch, setLocalSearch] = useState3("");
|
|
879
|
-
const search = searchValue ?? localSearch;
|
|
880
|
-
const [scrollTop, setScrollTop] = useState3(0);
|
|
881
|
-
const [active, setActive] = useState3();
|
|
882
|
-
const [keyboardActive, setKeyboardActive] = useState3(false);
|
|
883
|
-
const [deselectedHover, setDeselectedHover] = useState3();
|
|
884
|
-
const listRef = useRef5(null);
|
|
885
|
-
const id = useId4();
|
|
886
|
-
const selected = useMemo3(() => new Set(value), [value]);
|
|
887
|
-
const count = Math.max(1, Math.floor(columns));
|
|
888
|
-
const allOptions = useMemo3(() => {
|
|
889
|
-
if (!includeUnknownValues) return [...options];
|
|
890
|
-
const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
|
|
891
|
-
return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
|
|
892
|
-
}, [options, value, includeUnknownValues]);
|
|
893
|
-
const filtered = useMemo3(
|
|
894
|
-
() => allOptions.filter((option) => (!selectedOnly || selected.has(option.value)) && (!search || option.optionType !== "divider" && [option.label, option.value].some((text) => String(text ?? "").toLowerCase().includes(search.toLowerCase())))),
|
|
895
|
-
[allOptions, selectedOnly, selected, search]
|
|
896
|
-
);
|
|
897
|
-
const rows = useMemo3(() => {
|
|
898
|
-
const groups = /* @__PURE__ */ new Map();
|
|
899
|
-
filtered.forEach((option) => {
|
|
900
|
-
const items = groups.get(option.group) ?? [];
|
|
901
|
-
items.push(option);
|
|
902
|
-
groups.set(option.group, items);
|
|
903
|
-
});
|
|
904
|
-
const rows2 = [];
|
|
905
|
-
let top = 0;
|
|
906
|
-
for (const [group, items] of groups) {
|
|
907
|
-
if (group) {
|
|
908
|
-
rows2.push({ key: `group-${rows2.length}`, title: group, top, height: 30 });
|
|
909
|
-
top += 30;
|
|
910
|
-
}
|
|
911
|
-
for (let index = 0; index < items.length; index += count) {
|
|
912
|
-
const height = showValue ? 48 : 34;
|
|
913
|
-
rows2.push({ key: `row-${rows2.length}`, items: items.slice(index, index + count), top, height });
|
|
914
|
-
top += height;
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
return rows2;
|
|
918
|
-
}, [filtered, count, showValue]);
|
|
919
|
-
const totalHeight = rows.length ? rows[rows.length - 1].top + rows[rows.length - 1].height : 0;
|
|
920
|
-
const virtual = filtered.length > 100;
|
|
921
|
-
const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
|
|
922
|
-
const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
|
|
923
|
-
useEffect5(() => {
|
|
924
|
-
setScrollTop(0);
|
|
925
|
-
if (listRef.current) listRef.current.scrollTop = 0;
|
|
926
|
-
setActive(void 0);
|
|
927
|
-
}, [search, selectedOnly, count]);
|
|
928
|
-
function toggle(option, keyboard = false) {
|
|
929
|
-
if (disabled || loading || option.disabled || option.optionType === "divider") return;
|
|
930
|
-
setActive(option.value);
|
|
931
|
-
setKeyboardActive(keyboard);
|
|
932
|
-
setDeselectedHover(!keyboard && !multiple && allowDeselect && selected.has(option.value) ? option.value : void 0);
|
|
933
|
-
onChange(multiple ? selected.has(option.value) ? value.filter((item) => item !== option.value) : [...value, option.value] : allowDeselect && selected.has(option.value) ? [] : [option.value]);
|
|
934
|
-
}
|
|
935
|
-
function batch(operation) {
|
|
936
|
-
if (disabled || loading) return;
|
|
937
|
-
if (operation === "clear") {
|
|
938
|
-
onChange([]);
|
|
939
|
-
return;
|
|
940
|
-
}
|
|
941
|
-
const editable = new Set(enabled.map((option) => option.value));
|
|
942
|
-
const retained = value.filter((item) => !editable.has(item));
|
|
943
|
-
const add = enabled.filter((option) => operation === "all" || !selected.has(option.value)).map((option) => option.value);
|
|
944
|
-
onChange([...retained, ...add]);
|
|
945
|
-
}
|
|
946
|
-
return /* @__PURE__ */ jsxs4("div", { className: "sia-selection-panel", children: [
|
|
947
|
-
showSearch && /* @__PURE__ */ jsx4(
|
|
948
|
-
Input,
|
|
949
|
-
{
|
|
950
|
-
"aria-label": "\u641C\u7D22\u9009\u9879",
|
|
951
|
-
placeholder: "\u641C\u7D22",
|
|
952
|
-
autoFocus: autoFocusSearch,
|
|
953
|
-
value: search,
|
|
954
|
-
allowClear: true,
|
|
955
|
-
onChange: (event) => {
|
|
956
|
-
setLocalSearch(event.target.value);
|
|
957
|
-
onSearch?.(event.target.value);
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
),
|
|
961
|
-
multiple && showActions && /* @__PURE__ */ jsxs4("div", { className: "sia-selection-panel__actions", children: [
|
|
962
|
-
/* @__PURE__ */ jsx4(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("all"), children: "\u5168\u9009" }),
|
|
963
|
-
/* @__PURE__ */ jsx4(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("invert"), children: "\u53CD\u9009" }),
|
|
964
|
-
/* @__PURE__ */ jsx4(Button, { variant: "link", size: "small", disabled: disabled || loading || !value.length, onClick: () => batch("clear"), children: "\u6E05\u7A7A" }),
|
|
965
|
-
/* @__PURE__ */ jsxs4("span", { children: [
|
|
966
|
-
"\u5DF2\u9009 ",
|
|
967
|
-
value.length,
|
|
968
|
-
" \u9879"
|
|
969
|
-
] })
|
|
970
|
-
] }),
|
|
971
|
-
/* @__PURE__ */ jsx4(
|
|
972
|
-
"div",
|
|
973
|
-
{
|
|
974
|
-
ref: listRef,
|
|
975
|
-
role: "listbox",
|
|
976
|
-
"aria-label": "\u9009\u9879\u5217\u8868",
|
|
977
|
-
"aria-multiselectable": multiple || void 0,
|
|
978
|
-
tabIndex: disabled ? -1 : 0,
|
|
979
|
-
className: "sia-selection-panel__list",
|
|
980
|
-
style: { maxHeight },
|
|
981
|
-
onScroll: (event) => setScrollTop(event.currentTarget.scrollTop),
|
|
982
|
-
onPointerDown: () => setKeyboardActive(false),
|
|
983
|
-
onBlur: (event) => {
|
|
984
|
-
if (!event.currentTarget.contains(event.relatedTarget)) setKeyboardActive(false);
|
|
985
|
-
},
|
|
986
|
-
"aria-activedescendant": active !== void 0 ? `${id}-${typeof active}-${active}` : void 0,
|
|
987
|
-
onKeyDown: (event) => {
|
|
988
|
-
if (event.target instanceof HTMLInputElement) return;
|
|
989
|
-
if (disabled || loading || !enabled.length) return;
|
|
990
|
-
const index = enabled.findIndex((option) => option.value === active);
|
|
991
|
-
if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
|
|
992
|
-
event.preventDefault();
|
|
993
|
-
setKeyboardActive(true);
|
|
994
|
-
setDeselectedHover(void 0);
|
|
995
|
-
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)));
|
|
996
|
-
const option = enabled[next];
|
|
997
|
-
setActive(option.value);
|
|
998
|
-
const row = rows.find((row2) => row2.items?.includes(option));
|
|
999
|
-
if (row && listRef.current) {
|
|
1000
|
-
listRef.current.scrollTop = Math.max(0, row.top - maxHeight / 2);
|
|
1001
|
-
setScrollTop(listRef.current.scrollTop);
|
|
1002
|
-
}
|
|
1003
|
-
} else if ((event.key === "Enter" || event.key === " ") && index >= 0) {
|
|
1004
|
-
event.preventDefault();
|
|
1005
|
-
toggle(enabled[index], true);
|
|
1006
|
-
}
|
|
1007
|
-
},
|
|
1008
|
-
children: loading ? /* @__PURE__ */ jsx4("div", { role: "status", children: "\u52A0\u8F7D\u4E2D\u2026" }) : !rows.length ? /* @__PURE__ */ jsx4("div", { className: "sia-selection-panel__empty", children: "\u6682\u65E0\u5339\u914D\u9009\u9879" }) : /* @__PURE__ */ jsx4("div", { style: { height: totalHeight, position: "relative" }, children: renderedRows.map((row) => /* @__PURE__ */ jsx4(
|
|
1009
|
-
"div",
|
|
1010
|
-
{
|
|
1011
|
-
className: row.title !== void 0 ? "sia-selection-panel__group" : "sia-selection-panel__row",
|
|
1012
|
-
style: { position: "absolute", top: row.top, height: row.height, width: "100%", gridTemplateColumns: `repeat(${count}, minmax(0, 1fr))` },
|
|
1013
|
-
children: row.title ?? row.items?.map((option, index) => option.optionType === "divider" ? /* @__PURE__ */ jsx4("div", { role: "separator", className: "sia-selection-panel__divider" }, `divider-${index}`) : /* @__PURE__ */ jsx4(Tooltip, { title: option.disabled ? option.disabledTip : void 0, placement: "right", children: /* @__PURE__ */ jsx4(
|
|
1014
|
-
"div",
|
|
1015
|
-
{
|
|
1016
|
-
role: "option",
|
|
1017
|
-
id: `${id}-${typeof option.value}-${option.value}`,
|
|
1018
|
-
tabIndex: -1,
|
|
1019
|
-
"aria-selected": selected.has(option.value),
|
|
1020
|
-
"aria-disabled": disabled || option.disabled || void 0,
|
|
1021
|
-
className: `sia-selection-panel__option${keyboardActive && active === option.value ? " is-active" : ""}`,
|
|
1022
|
-
"data-deselected-hover": deselectedHover === option.value || void 0,
|
|
1023
|
-
onPointerLeave: () => {
|
|
1024
|
-
if (deselectedHover === option.value) setDeselectedHover(void 0);
|
|
1025
|
-
},
|
|
1026
|
-
onClick: (event) => {
|
|
1027
|
-
if (!event.target.closest(".sia-checkbox")) toggle(option);
|
|
1028
|
-
},
|
|
1029
|
-
children: multiple ? /* @__PURE__ */ jsx4(Checkbox2, { checked: selected.has(option.value), disabled: disabled || loading || option.disabled, tabIndex: -1, onChange: () => toggle(option), children: /* @__PURE__ */ jsxs4("span", { className: "sia-selection-panel__text", children: [
|
|
1030
|
-
/* @__PURE__ */ jsx4("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
|
|
1031
|
-
showValue && /* @__PURE__ */ jsx4("small", { children: String(option.value) })
|
|
1032
|
-
] }) }) : /* @__PURE__ */ jsxs4("span", { className: "sia-selection-panel__text", children: [
|
|
1033
|
-
/* @__PURE__ */ jsx4("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
|
|
1034
|
-
showValue && /* @__PURE__ */ jsx4("small", { children: String(option.value) })
|
|
1035
|
-
] })
|
|
1036
|
-
}
|
|
1037
|
-
) }, `${typeof option.value}-${option.value}`))
|
|
1038
|
-
},
|
|
1039
|
-
row.key
|
|
1040
|
-
)) })
|
|
1041
|
-
}
|
|
1042
|
-
)
|
|
1043
|
-
] });
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
855
|
// src/components/FloatingScrollbarProvider.tsx
|
|
1047
|
-
import { useEffect as
|
|
856
|
+
import { useEffect as useEffect6 } from "react";
|
|
1048
857
|
|
|
1049
858
|
// src/components/useScrollbarProximity.ts
|
|
1050
|
-
import { useEffect as
|
|
859
|
+
import { useEffect as useEffect5 } from "react";
|
|
1051
860
|
var users = 0;
|
|
1052
861
|
var cleanup;
|
|
1053
862
|
function useScrollbarProximity() {
|
|
1054
|
-
|
|
863
|
+
useEffect5(() => {
|
|
1055
864
|
if (users++ === 0) {
|
|
1056
865
|
let frame = 0;
|
|
1057
866
|
let x = -Infinity;
|
|
@@ -1172,7 +981,7 @@ function createTrack(axis) {
|
|
|
1172
981
|
}
|
|
1173
982
|
function FloatingScrollbarProvider({ disabled = false, targetRef }) {
|
|
1174
983
|
useScrollbarProximity();
|
|
1175
|
-
|
|
984
|
+
useEffect6(() => {
|
|
1176
985
|
if (disabled) return;
|
|
1177
986
|
const layer = document.createElement("div");
|
|
1178
987
|
layer.className = "sia-floating-scrollbar-layer";
|
|
@@ -1418,8 +1227,200 @@ function FloatingScrollbarProvider({ disabled = false, targetRef }) {
|
|
|
1418
1227
|
return null;
|
|
1419
1228
|
}
|
|
1420
1229
|
|
|
1230
|
+
// src/components/SelectionPanel.tsx
|
|
1231
|
+
import { useEffect as useEffect7, useId as useId4, useMemo as useMemo3, useRef as useRef5, useState as useState3 } from "react";
|
|
1232
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1233
|
+
function SelectionPanel({
|
|
1234
|
+
options,
|
|
1235
|
+
value,
|
|
1236
|
+
onChange,
|
|
1237
|
+
multiple = false,
|
|
1238
|
+
allowDeselect = false,
|
|
1239
|
+
disabled = false,
|
|
1240
|
+
loading = false,
|
|
1241
|
+
showSearch = true,
|
|
1242
|
+
showActions = true,
|
|
1243
|
+
includeUnknownValues = true,
|
|
1244
|
+
searchValue,
|
|
1245
|
+
onSearch,
|
|
1246
|
+
selectedOnly = false,
|
|
1247
|
+
showValue = false,
|
|
1248
|
+
displayField = "label",
|
|
1249
|
+
columns = 1,
|
|
1250
|
+
maxHeight = 250,
|
|
1251
|
+
autoFocusSearch = false
|
|
1252
|
+
}) {
|
|
1253
|
+
const [localSearch, setLocalSearch] = useState3("");
|
|
1254
|
+
const search = searchValue ?? localSearch;
|
|
1255
|
+
const [scrollTop, setScrollTop] = useState3(0);
|
|
1256
|
+
const [active, setActive] = useState3();
|
|
1257
|
+
const [keyboardActive, setKeyboardActive] = useState3(false);
|
|
1258
|
+
const [deselectedHover, setDeselectedHover] = useState3();
|
|
1259
|
+
const listRef = useRef5(null);
|
|
1260
|
+
const id = useId4();
|
|
1261
|
+
const selected = useMemo3(() => new Set(value), [value]);
|
|
1262
|
+
const count = Math.max(1, Math.floor(columns));
|
|
1263
|
+
const allOptions = useMemo3(() => {
|
|
1264
|
+
if (!includeUnknownValues) return [...options];
|
|
1265
|
+
const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
|
|
1266
|
+
return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
|
|
1267
|
+
}, [options, value, includeUnknownValues]);
|
|
1268
|
+
const filtered = useMemo3(
|
|
1269
|
+
() => allOptions.filter((option) => (!selectedOnly || selected.has(option.value)) && (!search || option.optionType !== "divider" && [option.label, option.value].some((text) => String(text ?? "").toLowerCase().includes(search.toLowerCase())))),
|
|
1270
|
+
[allOptions, selectedOnly, selected, search]
|
|
1271
|
+
);
|
|
1272
|
+
const rows = useMemo3(() => {
|
|
1273
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1274
|
+
filtered.forEach((option) => {
|
|
1275
|
+
const items = groups.get(option.group) ?? [];
|
|
1276
|
+
items.push(option);
|
|
1277
|
+
groups.set(option.group, items);
|
|
1278
|
+
});
|
|
1279
|
+
const rows2 = [];
|
|
1280
|
+
let top = 0;
|
|
1281
|
+
for (const [group, items] of groups) {
|
|
1282
|
+
if (group) {
|
|
1283
|
+
rows2.push({ key: `group-${rows2.length}`, title: group, top, height: 30 });
|
|
1284
|
+
top += 30;
|
|
1285
|
+
}
|
|
1286
|
+
for (let index = 0; index < items.length; index += count) {
|
|
1287
|
+
const height = showValue ? 48 : 34;
|
|
1288
|
+
rows2.push({ key: `row-${rows2.length}`, items: items.slice(index, index + count), top, height });
|
|
1289
|
+
top += height;
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
return rows2;
|
|
1293
|
+
}, [filtered, count, showValue]);
|
|
1294
|
+
const totalHeight = rows.length ? rows[rows.length - 1].top + rows[rows.length - 1].height : 0;
|
|
1295
|
+
const virtual = filtered.length > 100;
|
|
1296
|
+
const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
|
|
1297
|
+
const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
|
|
1298
|
+
useEffect7(() => {
|
|
1299
|
+
setScrollTop(0);
|
|
1300
|
+
if (listRef.current) listRef.current.scrollTop = 0;
|
|
1301
|
+
setActive(void 0);
|
|
1302
|
+
}, [search, selectedOnly, count]);
|
|
1303
|
+
function toggle(option, keyboard = false) {
|
|
1304
|
+
if (disabled || loading || option.disabled || option.optionType === "divider") return;
|
|
1305
|
+
setActive(option.value);
|
|
1306
|
+
setKeyboardActive(keyboard);
|
|
1307
|
+
setDeselectedHover(!keyboard && !multiple && allowDeselect && selected.has(option.value) ? option.value : void 0);
|
|
1308
|
+
onChange(multiple ? selected.has(option.value) ? value.filter((item) => item !== option.value) : [...value, option.value] : allowDeselect && selected.has(option.value) ? [] : [option.value]);
|
|
1309
|
+
}
|
|
1310
|
+
function batch(operation) {
|
|
1311
|
+
if (disabled || loading) return;
|
|
1312
|
+
if (operation === "clear") {
|
|
1313
|
+
onChange([]);
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
const editable = new Set(enabled.map((option) => option.value));
|
|
1317
|
+
const retained = value.filter((item) => !editable.has(item));
|
|
1318
|
+
const add = enabled.filter((option) => operation === "all" || !selected.has(option.value)).map((option) => option.value);
|
|
1319
|
+
onChange([...retained, ...add]);
|
|
1320
|
+
}
|
|
1321
|
+
return /* @__PURE__ */ jsxs4("div", { className: "sia-selection-panel", children: [
|
|
1322
|
+
/* @__PURE__ */ jsx4(FloatingScrollbarProvider, { targetRef: listRef }),
|
|
1323
|
+
showSearch && /* @__PURE__ */ jsx4(
|
|
1324
|
+
Input,
|
|
1325
|
+
{
|
|
1326
|
+
"aria-label": "\u641C\u7D22\u9009\u9879",
|
|
1327
|
+
placeholder: "\u641C\u7D22",
|
|
1328
|
+
autoFocus: autoFocusSearch,
|
|
1329
|
+
value: search,
|
|
1330
|
+
allowClear: true,
|
|
1331
|
+
onChange: (event) => {
|
|
1332
|
+
setLocalSearch(event.target.value);
|
|
1333
|
+
onSearch?.(event.target.value);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
),
|
|
1337
|
+
multiple && showActions && /* @__PURE__ */ jsxs4("div", { className: "sia-selection-panel__actions", children: [
|
|
1338
|
+
/* @__PURE__ */ jsx4(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("all"), children: "\u5168\u9009" }),
|
|
1339
|
+
/* @__PURE__ */ jsx4(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("invert"), children: "\u53CD\u9009" }),
|
|
1340
|
+
/* @__PURE__ */ jsx4(Button, { variant: "link", size: "small", disabled: disabled || loading || !value.length, onClick: () => batch("clear"), children: "\u6E05\u7A7A" }),
|
|
1341
|
+
/* @__PURE__ */ jsxs4("span", { children: [
|
|
1342
|
+
"\u5DF2\u9009 ",
|
|
1343
|
+
value.length,
|
|
1344
|
+
" \u9879"
|
|
1345
|
+
] })
|
|
1346
|
+
] }),
|
|
1347
|
+
/* @__PURE__ */ jsx4(
|
|
1348
|
+
"div",
|
|
1349
|
+
{
|
|
1350
|
+
ref: listRef,
|
|
1351
|
+
role: "listbox",
|
|
1352
|
+
"aria-label": "\u9009\u9879\u5217\u8868",
|
|
1353
|
+
"aria-multiselectable": multiple || void 0,
|
|
1354
|
+
tabIndex: disabled ? -1 : 0,
|
|
1355
|
+
className: "sia-selection-panel__list",
|
|
1356
|
+
style: { maxHeight },
|
|
1357
|
+
onScroll: (event) => setScrollTop(event.currentTarget.scrollTop),
|
|
1358
|
+
onPointerDown: () => setKeyboardActive(false),
|
|
1359
|
+
onBlur: (event) => {
|
|
1360
|
+
if (!event.currentTarget.contains(event.relatedTarget)) setKeyboardActive(false);
|
|
1361
|
+
},
|
|
1362
|
+
"aria-activedescendant": active !== void 0 ? `${id}-${typeof active}-${active}` : void 0,
|
|
1363
|
+
onKeyDown: (event) => {
|
|
1364
|
+
if (event.target instanceof HTMLInputElement) return;
|
|
1365
|
+
if (disabled || loading || !enabled.length) return;
|
|
1366
|
+
const index = enabled.findIndex((option) => option.value === active);
|
|
1367
|
+
if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
|
|
1368
|
+
event.preventDefault();
|
|
1369
|
+
setKeyboardActive(true);
|
|
1370
|
+
setDeselectedHover(void 0);
|
|
1371
|
+
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)));
|
|
1372
|
+
const option = enabled[next];
|
|
1373
|
+
setActive(option.value);
|
|
1374
|
+
const row = rows.find((row2) => row2.items?.includes(option));
|
|
1375
|
+
if (row && listRef.current) {
|
|
1376
|
+
listRef.current.scrollTop = Math.max(0, row.top - maxHeight / 2);
|
|
1377
|
+
setScrollTop(listRef.current.scrollTop);
|
|
1378
|
+
}
|
|
1379
|
+
} else if ((event.key === "Enter" || event.key === " ") && index >= 0) {
|
|
1380
|
+
event.preventDefault();
|
|
1381
|
+
toggle(enabled[index], true);
|
|
1382
|
+
}
|
|
1383
|
+
},
|
|
1384
|
+
children: loading ? /* @__PURE__ */ jsx4("div", { role: "status", children: "\u52A0\u8F7D\u4E2D\u2026" }) : !rows.length ? /* @__PURE__ */ jsx4("div", { className: "sia-selection-panel__empty", children: "\u6682\u65E0\u5339\u914D\u9009\u9879" }) : /* @__PURE__ */ jsx4("div", { style: { height: totalHeight, position: "relative" }, children: renderedRows.map((row) => /* @__PURE__ */ jsx4(
|
|
1385
|
+
"div",
|
|
1386
|
+
{
|
|
1387
|
+
className: row.title !== void 0 ? "sia-selection-panel__group" : "sia-selection-panel__row",
|
|
1388
|
+
style: { position: "absolute", top: row.top, height: row.height, width: "100%", gridTemplateColumns: `repeat(${count}, minmax(0, 1fr))` },
|
|
1389
|
+
children: row.title ?? row.items?.map((option, index) => option.optionType === "divider" ? /* @__PURE__ */ jsx4("div", { role: "separator", className: "sia-selection-panel__divider" }, `divider-${index}`) : /* @__PURE__ */ jsx4(Tooltip, { title: option.disabled ? option.disabledTip : void 0, placement: "right", children: /* @__PURE__ */ jsx4(
|
|
1390
|
+
"div",
|
|
1391
|
+
{
|
|
1392
|
+
role: "option",
|
|
1393
|
+
id: `${id}-${typeof option.value}-${option.value}`,
|
|
1394
|
+
tabIndex: -1,
|
|
1395
|
+
"aria-selected": selected.has(option.value),
|
|
1396
|
+
"aria-disabled": disabled || option.disabled || void 0,
|
|
1397
|
+
className: `sia-selection-panel__option${keyboardActive && active === option.value ? " is-active" : ""}`,
|
|
1398
|
+
"data-deselected-hover": deselectedHover === option.value || void 0,
|
|
1399
|
+
onPointerLeave: () => {
|
|
1400
|
+
if (deselectedHover === option.value) setDeselectedHover(void 0);
|
|
1401
|
+
},
|
|
1402
|
+
onClick: (event) => {
|
|
1403
|
+
if (!event.target.closest(".sia-checkbox")) toggle(option);
|
|
1404
|
+
},
|
|
1405
|
+
children: multiple ? /* @__PURE__ */ jsx4(Checkbox2, { checked: selected.has(option.value), disabled: disabled || loading || option.disabled, tabIndex: -1, onChange: () => toggle(option), children: /* @__PURE__ */ jsxs4("span", { className: "sia-selection-panel__text", children: [
|
|
1406
|
+
/* @__PURE__ */ jsx4("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
|
|
1407
|
+
showValue && /* @__PURE__ */ jsx4("small", { children: String(option.value) })
|
|
1408
|
+
] }) }) : /* @__PURE__ */ jsxs4("span", { className: "sia-selection-panel__text", children: [
|
|
1409
|
+
/* @__PURE__ */ jsx4("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
|
|
1410
|
+
showValue && /* @__PURE__ */ jsx4("small", { children: String(option.value) })
|
|
1411
|
+
] })
|
|
1412
|
+
}
|
|
1413
|
+
) }, `${typeof option.value}-${option.value}`))
|
|
1414
|
+
},
|
|
1415
|
+
row.key
|
|
1416
|
+
)) })
|
|
1417
|
+
}
|
|
1418
|
+
)
|
|
1419
|
+
] });
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1421
1422
|
// src/components/Select.tsx
|
|
1422
|
-
import { forwardRef as forwardRef3, useDeferredValue, useEffect as useEffect8, useId as useId5, useMemo as useMemo4, useRef as useRef7, useState as useState5 } from "react";
|
|
1423
|
+
import { forwardRef as forwardRef3, useDeferredValue, useEffect as useEffect8, useId as useId5, useLayoutEffect as useLayoutEffect3, useMemo as useMemo4, useRef as useRef7, useState as useState5 } from "react";
|
|
1423
1424
|
|
|
1424
1425
|
// src/components/OverflowTags.tsx
|
|
1425
1426
|
import { useLayoutEffect as useLayoutEffect2, useRef as useRef6, useState as useState4 } from "react";
|
|
@@ -1530,6 +1531,8 @@ var Select = forwardRef3(function Select2({
|
|
|
1530
1531
|
const [query, setQuery] = useState5("");
|
|
1531
1532
|
const [activeIndex, setActiveIndex] = useState5(-1);
|
|
1532
1533
|
const [scrollTop, setScrollTop] = useState5(0);
|
|
1534
|
+
const [dropdownFontSize, setDropdownFontSize] = useState5();
|
|
1535
|
+
const pendingSelectedScroll = useRef7(false);
|
|
1533
1536
|
const deferredQuery = useDeferredValue(query.trim());
|
|
1534
1537
|
const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
|
|
1535
1538
|
const [currentValue, setCurrentValue] = useControllableState({
|
|
@@ -1587,10 +1590,31 @@ var Select = forwardRef3(function Select2({
|
|
|
1587
1590
|
useEffect8(() => {
|
|
1588
1591
|
if (disabled || loading) closeDropdown();
|
|
1589
1592
|
}, [disabled, loading]);
|
|
1593
|
+
useEffect8(() => {
|
|
1594
|
+
if (!open || popupMode !== "dropdown" || !pendingSelectedScroll.current || query) return;
|
|
1595
|
+
const index = filteredOptions.findIndex((option) => selectedValueSet.has(option.value));
|
|
1596
|
+
if (index < 0) return;
|
|
1597
|
+
const frame = requestAnimationFrame(() => {
|
|
1598
|
+
const list = listRef.current;
|
|
1599
|
+
if (!list) return;
|
|
1600
|
+
const item = virtualEnabled ? null : list.querySelectorAll('[role="option"]')[index];
|
|
1601
|
+
const top = virtualEnabled ? index * optionHeight : item ? item.getBoundingClientRect().top - list.getBoundingClientRect().top + list.scrollTop : 0;
|
|
1602
|
+
list.scrollTop = Math.max(0, top - (list.clientHeight - (item?.offsetHeight ?? optionHeight)) / 2);
|
|
1603
|
+
setScrollTop(list.scrollTop);
|
|
1604
|
+
pendingSelectedScroll.current = false;
|
|
1605
|
+
});
|
|
1606
|
+
return () => cancelAnimationFrame(frame);
|
|
1607
|
+
}, [open, popupMode, filteredOptions, selectedValueSet, virtualEnabled, optionHeight, query]);
|
|
1608
|
+
useLayoutEffect3(() => {
|
|
1609
|
+
if (!open || popupMode !== "dropdown") return;
|
|
1610
|
+
const trigger = rootRef.current?.querySelector(".sia-select__trigger");
|
|
1611
|
+
if (trigger) setDropdownFontSize(getComputedStyle(trigger).fontSize);
|
|
1612
|
+
}, [open, popupMode, size]);
|
|
1590
1613
|
function firstEnabledIndex() {
|
|
1591
1614
|
return filteredOptions.findIndex((option) => !option.disabled);
|
|
1592
1615
|
}
|
|
1593
1616
|
function closeDropdown() {
|
|
1617
|
+
pendingSelectedScroll.current = false;
|
|
1594
1618
|
setOpen(false);
|
|
1595
1619
|
setQuery("");
|
|
1596
1620
|
setScrollTop(0);
|
|
@@ -1615,6 +1639,7 @@ var Select = forwardRef3(function Select2({
|
|
|
1615
1639
|
}
|
|
1616
1640
|
function openDropdown() {
|
|
1617
1641
|
if (disabled || loading) return;
|
|
1642
|
+
pendingSelectedScroll.current = true;
|
|
1618
1643
|
setOpenedMode(automaticMode);
|
|
1619
1644
|
const selectedIndex = filteredOptions.findIndex((option) => selectedValueSet.has(option.value) && !option.disabled);
|
|
1620
1645
|
setActiveIndex(selectedIndex >= 0 ? selectedIndex : firstEnabledIndex());
|
|
@@ -1789,7 +1814,7 @@ var Select = forwardRef3(function Select2({
|
|
|
1789
1814
|
}
|
|
1790
1815
|
),
|
|
1791
1816
|
allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ jsx6("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ jsx6(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
|
|
1792
|
-
/* @__PURE__ */ jsxs6(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", className: `sia-select__dropdown${filteredOptions.length === 0 && !canSubmitInput ? " sia-select__dropdown--empty" : ""}`, children: [
|
|
1817
|
+
/* @__PURE__ */ jsxs6(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: [
|
|
1793
1818
|
/* @__PURE__ */ jsx6(FloatingScrollbarProvider, { targetRef: listRef }),
|
|
1794
1819
|
showSearch || allowInput ? /* @__PURE__ */ jsxs6("label", { className: "sia-select__search", children: [
|
|
1795
1820
|
/* @__PURE__ */ jsx6(Icon, { name: "search", size: 15 }),
|
|
@@ -1929,9 +1954,9 @@ export {
|
|
|
1929
1954
|
useOverlayLifecycle,
|
|
1930
1955
|
OverlayPortal,
|
|
1931
1956
|
Modal2 as Modal,
|
|
1932
|
-
SelectionPanel,
|
|
1933
|
-
OverflowTags,
|
|
1934
1957
|
useScrollbarProximity,
|
|
1935
1958
|
FloatingScrollbarProvider,
|
|
1959
|
+
SelectionPanel,
|
|
1960
|
+
OverflowTags,
|
|
1936
1961
|
Select
|
|
1937
1962
|
};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
+
FloatingScrollbarProvider,
|
|
2
3
|
Select
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-5MW3NE2V.js";
|
|
4
5
|
import {
|
|
5
6
|
Icon
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-YF2I6SDB.js";
|
|
7
8
|
import {
|
|
8
9
|
PopupPortal,
|
|
9
10
|
useControlSize,
|
|
10
11
|
useControllableState,
|
|
11
12
|
useFloatingPlaceholder,
|
|
12
13
|
withTitleTooltip
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-RAO3JHDL.js";
|
|
14
15
|
|
|
15
16
|
// src/components/DatePicker.tsx
|
|
16
17
|
import { useEffect, useId, useMemo, useRef as useRef2, useState } from "react";
|
|
@@ -161,6 +162,10 @@ function TimePanel({
|
|
|
161
162
|
}) {
|
|
162
163
|
const [hour = "00", minute = "00", second = "00"] = value.split(":");
|
|
163
164
|
const columnsRef = useRef(null);
|
|
165
|
+
const hourRef = useRef(null);
|
|
166
|
+
const minuteRef = useRef(null);
|
|
167
|
+
const secondRef = useRef(null);
|
|
168
|
+
const columnRefs = [hourRef, minuteRef, secondRef];
|
|
164
169
|
useLayoutEffect(() => {
|
|
165
170
|
for (const column of columnsRef.current?.children ?? []) {
|
|
166
171
|
const selected = column.querySelector('[aria-selected="true"]');
|
|
@@ -191,7 +196,7 @@ function TimePanel({
|
|
|
191
196
|
showSecond ? `:${second}` : "",
|
|
192
197
|
use12Hours ? Number(hour) < 12 ? " AM" : " PM" : ""
|
|
193
198
|
] }),
|
|
194
|
-
/* @__PURE__ */ jsx("div", { ref: columnsRef, className: "sia-date-panel__time-columns", children: columns.map((column) => /* @__PURE__ */ jsx("div", { role: "listbox", "aria-label": `${ariaLabel}${column.label}`, children: Array.from({ length: column.count }, (_, index) => {
|
|
199
|
+
/* @__PURE__ */ jsx("div", { ref: columnsRef, className: "sia-date-panel__time-columns", children: columns.map((column) => /* @__PURE__ */ jsx("div", { ref: columnRefs[column.index], role: "listbox", "aria-label": `${ariaLabel}${column.label}`, children: Array.from({ length: column.count }, (_, index) => {
|
|
195
200
|
const next = pad(index);
|
|
196
201
|
const candidate = [hour, minute, second];
|
|
197
202
|
candidate[column.index] = next;
|
|
@@ -203,7 +208,8 @@ function TimePanel({
|
|
|
203
208
|
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)));
|
|
204
209
|
buttons[target]?.focus();
|
|
205
210
|
}, onClick: () => update(column.index, next), children: use12Hours && column.index === 0 ? `${pad(index % 12 || 12)} ${index < 12 ? "AM" : "PM"}` : next }, next);
|
|
206
|
-
}) }, column.label)) })
|
|
211
|
+
}) }, column.label)) }),
|
|
212
|
+
columns.map((column) => /* @__PURE__ */ jsx(FloatingScrollbarProvider, { targetRef: columnRefs[column.index] }, column.index))
|
|
207
213
|
] });
|
|
208
214
|
}
|
|
209
215
|
function DatePanelFooter({
|
|
@@ -2,14 +2,14 @@ import {
|
|
|
2
2
|
Dropdown,
|
|
3
3
|
Icon,
|
|
4
4
|
Input
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YF2I6SDB.js";
|
|
6
6
|
import {
|
|
7
7
|
Button
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-IYNS423D.js";
|
|
9
9
|
import {
|
|
10
10
|
useFloatingPlaceholder,
|
|
11
11
|
withTitleTooltip
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-RAO3JHDL.js";
|
|
13
13
|
|
|
14
14
|
// src/components/RichTextEditor.tsx
|
|
15
15
|
import { useEffect, useMemo, useRef, useState } from "react";
|