@sia.soul/sia-react-ui 0.1.6 → 0.1.7
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-rtDktLYY.d.ts → Select-Cl6UXsN5.d.ts} +12 -0
- package/dist/{Select-GiTHMScg.d.cts → Select-IjA4yqLh.d.cts} +12 -0
- package/dist/chunk-6QQRMGW4.js +1331 -0
- package/dist/{chunk-PX6BOFTW.js → chunk-F3VH6LJH.js} +2 -4
- package/dist/{chunk-EJ23MVR6.js → chunk-JJVD2ITI.js} +592 -1
- package/dist/chunk-SMNSQDXN.js +1493 -0
- package/dist/{chunk-MJUTLEEE.js → chunk-X6ZPBBDF.js} +2 -2
- package/dist/{core-D8BSMfHD.d.ts → core-CcB8n8uv.d.ts} +1 -1
- package/dist/{core-CBtbeAms.d.cts → core-DrpbQni9.d.cts} +1 -1
- package/dist/core.cjs +1093 -715
- package/dist/core.css +137 -11
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +7 -9
- package/dist/index.cjs +4122 -3971
- package/dist/index.css +137 -11
- package/dist/index.d.cts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +76 -230
- package/dist/rich-text-editor.cjs +11 -2
- package/dist/rich-text-editor.js +2 -3
- package/dist/{select-date-range-DRmGaEzP.d.cts → select-date-range-BzEXIsqZ.d.cts} +1 -1
- package/dist/{select-date-range-CQ1vmze_.d.ts → select-date-range-CU2ou9sD.d.ts} +1 -1
- package/dist/select-date-range.cjs +1091 -77
- package/dist/select-date-range.d.cts +2 -2
- package/dist/select-date-range.d.ts +2 -2
- package/dist/select-date-range.js +4 -3
- package/package.json +1 -1
- package/dist/chunk-IHTODT53.js +0 -586
- package/dist/chunk-R7BVDN3Q.js +0 -366
- package/dist/chunk-S2JAJCLN.js +0 -2154
package/dist/core.cjs
CHANGED
|
@@ -1223,7 +1223,7 @@ function MenuEntry({
|
|
|
1223
1223
|
ref: anchorRef,
|
|
1224
1224
|
type: "button",
|
|
1225
1225
|
className: "sia-menu__item",
|
|
1226
|
-
style: { paddingInlineStart:
|
|
1226
|
+
style: { paddingInlineStart: props.mode === "inline" && !props.inlineCollapsed ? 12 + level * props.inlineIndent : void 0 },
|
|
1227
1227
|
title: collapsed ? item.title ?? (typeof item.label === "string" ? item.label : void 0) : item.title,
|
|
1228
1228
|
disabled: item.disabled,
|
|
1229
1229
|
"aria-current": isSelected ? "page" : void 0,
|
|
@@ -1750,14 +1750,88 @@ function Tabs({
|
|
|
1750
1750
|
}
|
|
1751
1751
|
|
|
1752
1752
|
// src/components/Feedback.tsx
|
|
1753
|
-
var
|
|
1753
|
+
var import_react11 = require("react");
|
|
1754
1754
|
var import_react_dom3 = require("react-dom");
|
|
1755
1755
|
var import_client = require("react-dom/client");
|
|
1756
1756
|
|
|
1757
1757
|
// src/components/FloatingDisplay.tsx
|
|
1758
|
-
var
|
|
1758
|
+
var import_react10 = require("react");
|
|
1759
1759
|
var import_react_dom2 = require("react-dom");
|
|
1760
|
+
|
|
1761
|
+
// src/components/Checkbox.tsx
|
|
1762
|
+
var import_react9 = require("react");
|
|
1760
1763
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1764
|
+
var CheckboxGroupContext = (0, import_react9.createContext)(null);
|
|
1765
|
+
var CheckboxRoot = (0, import_react9.forwardRef)(function Checkbox({ value, indeterminate = false, children, disabled, checked, defaultChecked, className = "", onChange, ...props }, forwardedRef) {
|
|
1766
|
+
const group = (0, import_react9.useContext)(CheckboxGroupContext);
|
|
1767
|
+
const localRef = (0, import_react9.useRef)(null);
|
|
1768
|
+
const fallbackId = (0, import_react9.useId)();
|
|
1769
|
+
const grouped = group !== null && value !== void 0;
|
|
1770
|
+
const currentChecked = grouped ? group.values.includes(value) : checked;
|
|
1771
|
+
(0, import_react9.useEffect)(() => {
|
|
1772
|
+
if (localRef.current) localRef.current.indeterminate = indeterminate;
|
|
1773
|
+
}, [indeterminate]);
|
|
1774
|
+
function setRef(node) {
|
|
1775
|
+
localRef.current = node;
|
|
1776
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
1777
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
1778
|
+
}
|
|
1779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: `sia-checkbox${disabled || group?.disabled ? " is-disabled" : ""} ${className}`.trim(), children: [
|
|
1780
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1781
|
+
"input",
|
|
1782
|
+
{
|
|
1783
|
+
...props,
|
|
1784
|
+
ref: setRef,
|
|
1785
|
+
id: props.id ?? fallbackId,
|
|
1786
|
+
className: "sia-checkbox__input",
|
|
1787
|
+
type: "checkbox",
|
|
1788
|
+
name: group?.name ?? props.name,
|
|
1789
|
+
disabled: disabled || group?.disabled,
|
|
1790
|
+
checked: currentChecked,
|
|
1791
|
+
defaultChecked: grouped ? void 0 : defaultChecked,
|
|
1792
|
+
"aria-checked": indeterminate ? "mixed" : currentChecked,
|
|
1793
|
+
onChange: (event) => {
|
|
1794
|
+
if (grouped) group.toggle(value, event.currentTarget.checked);
|
|
1795
|
+
onChange?.(event.currentTarget.checked, event);
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
),
|
|
1799
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "sia-checkbox__control", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", {}) }),
|
|
1800
|
+
children !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "sia-checkbox__label", children }) : null
|
|
1801
|
+
] });
|
|
1802
|
+
});
|
|
1803
|
+
function CheckboxGroup({
|
|
1804
|
+
value,
|
|
1805
|
+
defaultValue = [],
|
|
1806
|
+
options,
|
|
1807
|
+
disabled,
|
|
1808
|
+
name,
|
|
1809
|
+
className = "",
|
|
1810
|
+
children,
|
|
1811
|
+
onChange
|
|
1812
|
+
}) {
|
|
1813
|
+
const [values, setValues] = useControllableState({ value, defaultValue, onChange });
|
|
1814
|
+
const context = (0, import_react9.useMemo)(() => ({
|
|
1815
|
+
values,
|
|
1816
|
+
disabled,
|
|
1817
|
+
name,
|
|
1818
|
+
toggle(optionValue, checked) {
|
|
1819
|
+
const next = checked ? values.includes(optionValue) ? values : [...values, optionValue] : values.filter((item) => item !== optionValue);
|
|
1820
|
+
setValues(next);
|
|
1821
|
+
}
|
|
1822
|
+
}), [disabled, name, setValues, values]);
|
|
1823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CheckboxGroupContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `sia-checkbox-group ${className}`.trim(), role: "group", children: [
|
|
1824
|
+
options?.map((option) => {
|
|
1825
|
+
const normalized = typeof option === "object" ? option : { label: String(option), value: option };
|
|
1826
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CheckboxRoot, { value: normalized.value, disabled: normalized.disabled, children: normalized.label }, normalized.value);
|
|
1827
|
+
}),
|
|
1828
|
+
children
|
|
1829
|
+
] }) });
|
|
1830
|
+
}
|
|
1831
|
+
var Checkbox2 = Object.assign(CheckboxRoot, { Group: CheckboxGroup });
|
|
1832
|
+
|
|
1833
|
+
// src/components/FloatingDisplay.tsx
|
|
1834
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1761
1835
|
var FLOATING_GAP = 9;
|
|
1762
1836
|
var FLOATING_VIEWPORT_PADDING = 8;
|
|
1763
1837
|
var FLOATING_ARROW_EDGE_OFFSET = 16;
|
|
@@ -1813,17 +1887,17 @@ function Floating({
|
|
|
1813
1887
|
role = "tooltip",
|
|
1814
1888
|
onOpenChange
|
|
1815
1889
|
}) {
|
|
1816
|
-
const rootRef = (0,
|
|
1817
|
-
const overlayRef = (0,
|
|
1818
|
-
const enterTimer = (0,
|
|
1819
|
-
const leaveTimer = (0,
|
|
1820
|
-
const contentId = (0,
|
|
1890
|
+
const rootRef = (0, import_react10.useRef)(null);
|
|
1891
|
+
const overlayRef = (0, import_react10.useRef)(null);
|
|
1892
|
+
const enterTimer = (0, import_react10.useRef)();
|
|
1893
|
+
const leaveTimer = (0, import_react10.useRef)();
|
|
1894
|
+
const contentId = (0, import_react10.useId)();
|
|
1821
1895
|
const triggers = Array.isArray(trigger) ? trigger : [trigger];
|
|
1822
1896
|
const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
|
|
1823
|
-
const [position, setPosition] = (0,
|
|
1824
|
-
const setVisibleRef = (0,
|
|
1897
|
+
const [position, setPosition] = (0, import_react10.useState)();
|
|
1898
|
+
const setVisibleRef = (0, import_react10.useRef)(setVisible);
|
|
1825
1899
|
setVisibleRef.current = setVisible;
|
|
1826
|
-
const closeSelfRef = (0,
|
|
1900
|
+
const closeSelfRef = (0, import_react10.useRef)();
|
|
1827
1901
|
if (!closeSelfRef.current) closeSelfRef.current = () => setVisibleRef.current(false);
|
|
1828
1902
|
const exclusiveTooltip = role === "tooltip" && triggers.includes("hover");
|
|
1829
1903
|
function openNow() {
|
|
@@ -1851,7 +1925,7 @@ function Floating({
|
|
|
1851
1925
|
if (delay <= 0) closeNow();
|
|
1852
1926
|
else leaveTimer.current = window.setTimeout(closeNow, delay * 1e3);
|
|
1853
1927
|
}
|
|
1854
|
-
(0,
|
|
1928
|
+
(0, import_react10.useEffect)(() => {
|
|
1855
1929
|
if (!visible || !triggers.includes("click")) return;
|
|
1856
1930
|
const close = (event) => {
|
|
1857
1931
|
const target = event.target;
|
|
@@ -1860,7 +1934,7 @@ function Floating({
|
|
|
1860
1934
|
document.addEventListener("pointerdown", close);
|
|
1861
1935
|
return () => document.removeEventListener("pointerdown", close);
|
|
1862
1936
|
}, [triggers.join("|"), visible]);
|
|
1863
|
-
(0,
|
|
1937
|
+
(0, import_react10.useLayoutEffect)(() => {
|
|
1864
1938
|
if (!visible) {
|
|
1865
1939
|
setPosition(void 0);
|
|
1866
1940
|
return;
|
|
@@ -1881,11 +1955,11 @@ function Floating({
|
|
|
1881
1955
|
observer.disconnect();
|
|
1882
1956
|
};
|
|
1883
1957
|
}, [children, content, placement, visible]);
|
|
1884
|
-
(0,
|
|
1958
|
+
(0, import_react10.useEffect)(() => () => {
|
|
1885
1959
|
clearTimers();
|
|
1886
1960
|
if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
|
|
1887
1961
|
}, []);
|
|
1888
|
-
const child = (0,
|
|
1962
|
+
const child = (0, import_react10.cloneElement)(children, {
|
|
1889
1963
|
...triggers.includes("hover") ? { onMouseEnter: (event) => {
|
|
1890
1964
|
children.props.onMouseEnter?.(event);
|
|
1891
1965
|
show(mouseEnterDelay);
|
|
@@ -1908,7 +1982,7 @@ function Floating({
|
|
|
1908
1982
|
"aria-describedby": visible ? contentId : void 0
|
|
1909
1983
|
});
|
|
1910
1984
|
const overlay = visible && content !== null && content !== void 0 && typeof document !== "undefined" ? (0, import_react_dom2.createPortal)(
|
|
1911
|
-
/* @__PURE__ */ (0,
|
|
1985
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1912
1986
|
"span",
|
|
1913
1987
|
{
|
|
1914
1988
|
ref: overlayRef,
|
|
@@ -1928,23 +2002,23 @@ function Floating({
|
|
|
1928
2002
|
onMouseLeave: triggers.includes("hover") ? () => hide(mouseLeaveDelay) : void 0,
|
|
1929
2003
|
children: [
|
|
1930
2004
|
content,
|
|
1931
|
-
arrow ? /* @__PURE__ */ (0,
|
|
2005
|
+
arrow ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sia-floating__arrow" }) : null
|
|
1932
2006
|
]
|
|
1933
2007
|
}
|
|
1934
2008
|
),
|
|
1935
2009
|
document.body
|
|
1936
2010
|
) : null;
|
|
1937
|
-
return /* @__PURE__ */ (0,
|
|
1938
|
-
/* @__PURE__ */ (0,
|
|
2011
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2012
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { ref: rootRef, className: `sia-floating ${className}`.trim(), children: child }),
|
|
1939
2013
|
overlay
|
|
1940
2014
|
] });
|
|
1941
2015
|
}
|
|
1942
2016
|
function Tooltip(props) {
|
|
1943
|
-
return /* @__PURE__ */ (0,
|
|
2017
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Floating, { ...props, content: props.title });
|
|
1944
2018
|
}
|
|
1945
2019
|
|
|
1946
2020
|
// src/components/Feedback.tsx
|
|
1947
|
-
var
|
|
2021
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1948
2022
|
function Progress({
|
|
1949
2023
|
percent = 0,
|
|
1950
2024
|
type = "line",
|
|
@@ -1966,35 +2040,35 @@ function Progress({
|
|
|
1966
2040
|
const resolved = status ?? (safe >= 100 ? "success" : "normal");
|
|
1967
2041
|
const color = typeof strokeColor === "string" ? strokeColor : void 0;
|
|
1968
2042
|
const background = typeof strokeColor === "object" ? `linear-gradient(90deg, ${strokeColor.from}, ${strokeColor.to})` : color;
|
|
1969
|
-
const label = format?.(safe, success?.percent) ?? (resolved === "exception" ? /* @__PURE__ */ (0,
|
|
2043
|
+
const label = format?.(safe, success?.percent) ?? (resolved === "exception" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: "close" }) : resolved === "success" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { name: "check" }) : `${safe}%`);
|
|
1970
2044
|
if (type !== "line") {
|
|
1971
2045
|
const radius = 46;
|
|
1972
2046
|
const circumference = 2 * Math.PI * radius;
|
|
1973
2047
|
const dash = circumference * (safe / 100);
|
|
1974
|
-
return /* @__PURE__ */ (0,
|
|
1975
|
-
/* @__PURE__ */ (0,
|
|
1976
|
-
/* @__PURE__ */ (0,
|
|
1977
|
-
/* @__PURE__ */ (0,
|
|
2048
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `sia-progress sia-progress--${type} sia-progress--${resolved} ${className}`.trim(), style: { width, height: width, ...style }, ...props, children: [
|
|
2049
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { viewBox: "0 0 100 100", role: "progressbar", "aria-valuenow": safe, children: [
|
|
2050
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { className: "sia-progress__trail", cx: "50", cy: "50", r: radius, style: { stroke: trailColor } }),
|
|
2051
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { className: "sia-progress__circle", cx: "50", cy: "50", r: radius, style: { stroke: color, strokeDasharray: type === "dashboard" ? `${circumference * 0.75} ${circumference * 0.25}` : circumference, strokeDashoffset: (type === "dashboard" ? circumference * 0.75 : circumference) - dash * (type === "dashboard" ? 0.75 : 1), strokeWidth } })
|
|
1978
2052
|
] }),
|
|
1979
|
-
showInfo ? /* @__PURE__ */ (0,
|
|
2053
|
+
showInfo ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sia-progress__text", children: label }) : null
|
|
1980
2054
|
] });
|
|
1981
2055
|
}
|
|
1982
2056
|
const height = Array.isArray(size) ? size[1] : typeof size === "number" ? size : size === "small" ? 6 : strokeWidth;
|
|
1983
|
-
return /* @__PURE__ */ (0,
|
|
1984
|
-
/* @__PURE__ */ (0,
|
|
1985
|
-
/* @__PURE__ */ (0,
|
|
1986
|
-
success?.percent ? /* @__PURE__ */ (0,
|
|
2057
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `sia-progress sia-progress--line sia-progress--${resolved} ${className}`.trim(), style, ...props, children: [
|
|
2058
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "sia-progress__outer", style: { height, backgroundColor: trailColor }, children: steps ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "sia-progress__steps", children: Array.from({ length: steps }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: index < Math.round(steps * safe / 100) ? "is-active" : "", style: { background: index < Math.round(steps * safe / 100) ? background : trailColor } }, index)) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
2059
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sia-progress__bar", style: { width: `${safe}%`, background } }),
|
|
2060
|
+
success?.percent ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sia-progress__success", style: { width: `${success.percent}%`, background: success.strokeColor } }) : null
|
|
1987
2061
|
] }) }),
|
|
1988
|
-
showInfo ? /* @__PURE__ */ (0,
|
|
2062
|
+
showInfo ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sia-progress__info", children: label }) : null
|
|
1989
2063
|
] });
|
|
1990
2064
|
}
|
|
1991
2065
|
|
|
1992
2066
|
// src/components/DataDisplay.tsx
|
|
1993
|
-
var
|
|
2067
|
+
var import_react13 = require("react");
|
|
1994
2068
|
var import_react_dom5 = require("react-dom");
|
|
1995
2069
|
|
|
1996
2070
|
// src/components/Overlay.tsx
|
|
1997
|
-
var
|
|
2071
|
+
var import_react12 = require("react");
|
|
1998
2072
|
var import_react_dom4 = require("react-dom");
|
|
1999
2073
|
var bodyLockCount = 0;
|
|
2000
2074
|
var previousBodyOverflow = "";
|
|
@@ -2016,10 +2090,10 @@ function focusableElements(container) {
|
|
|
2016
2090
|
)].filter((element) => !element.hidden && element.getAttribute("aria-hidden") !== "true");
|
|
2017
2091
|
}
|
|
2018
2092
|
function useOverlayLifecycle(open, panelRef, onRequestClose, keyboard = true) {
|
|
2019
|
-
const overlayIdRef = (0,
|
|
2020
|
-
const closeRef = (0,
|
|
2093
|
+
const overlayIdRef = (0, import_react12.useRef)(/* @__PURE__ */ Symbol("sia-overlay"));
|
|
2094
|
+
const closeRef = (0, import_react12.useRef)(onRequestClose);
|
|
2021
2095
|
closeRef.current = onRequestClose;
|
|
2022
|
-
(0,
|
|
2096
|
+
(0, import_react12.useEffect)(() => {
|
|
2023
2097
|
if (!open || typeof document === "undefined") return void 0;
|
|
2024
2098
|
const overlayId = overlayIdRef.current;
|
|
2025
2099
|
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -2073,26 +2147,26 @@ function OverlayPortal({ children, container }) {
|
|
|
2073
2147
|
}
|
|
2074
2148
|
|
|
2075
2149
|
// src/components/DataDisplay.tsx
|
|
2076
|
-
var
|
|
2150
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2077
2151
|
function BadgeRibbon({ text, color, placement = "end", className = "", children, ...props }) {
|
|
2078
|
-
return /* @__PURE__ */ (0,
|
|
2152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `sia-ribbon-wrap ${className}`.trim(), ...props, children: [
|
|
2079
2153
|
children,
|
|
2080
|
-
/* @__PURE__ */ (0,
|
|
2154
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: `sia-ribbon sia-ribbon--${placement}`, style: { backgroundColor: color }, children: text })
|
|
2081
2155
|
] });
|
|
2082
2156
|
}
|
|
2083
2157
|
function Badge({ count, showZero = false, overflowCount = 99, dot = false, status, text, color, offset = [0, 0], size = "default", className = "", children, style, ...props }) {
|
|
2084
2158
|
const numeric = typeof count === "number";
|
|
2085
2159
|
const hidden = !dot && !status && (count === void 0 || count === null || count === 0 && !showZero);
|
|
2086
2160
|
const display = numeric && count > overflowCount ? `${overflowCount}+` : count;
|
|
2087
|
-
const badge = !hidden ? /* @__PURE__ */ (0,
|
|
2088
|
-
if (status && !children) return /* @__PURE__ */ (0,
|
|
2161
|
+
const badge = !hidden ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("sup", { className: `sia-badge__count${dot || status ? " sia-badge__dot" : ""}${status ? ` sia-badge__dot--${status}` : ""} sia-badge__count--${size}`, style: { backgroundColor: color, transform: `translate(calc(50% + ${offset[0]}px), calc(-50% + ${offset[1]}px))` }, children: dot || status ? null : display }) : null;
|
|
2162
|
+
if (status && !children) return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: `sia-badge sia-badge--status ${className}`.trim(), style, ...props, children: [
|
|
2089
2163
|
badge,
|
|
2090
|
-
text ? /* @__PURE__ */ (0,
|
|
2164
|
+
text ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sia-badge__text", children: text }) : null
|
|
2091
2165
|
] });
|
|
2092
|
-
return /* @__PURE__ */ (0,
|
|
2166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: `sia-badge ${className}`.trim(), style, ...props, children: [
|
|
2093
2167
|
children,
|
|
2094
2168
|
badge,
|
|
2095
|
-
text && !status ? /* @__PURE__ */ (0,
|
|
2169
|
+
text && !status ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sia-badge__text", children: text }) : null
|
|
2096
2170
|
] });
|
|
2097
2171
|
}
|
|
2098
2172
|
Badge.Ribbon = BadgeRibbon;
|
|
@@ -2102,8 +2176,8 @@ function CollapsePanel({
|
|
|
2102
2176
|
destroyInactivePanel = false,
|
|
2103
2177
|
children
|
|
2104
2178
|
}) {
|
|
2105
|
-
const [keepChildren, setKeepChildren] = (0,
|
|
2106
|
-
(0,
|
|
2179
|
+
const [keepChildren, setKeepChildren] = (0, import_react13.useState)(open || forceRender || !destroyInactivePanel);
|
|
2180
|
+
(0, import_react13.useEffect)(() => {
|
|
2107
2181
|
if (open || forceRender || !destroyInactivePanel) {
|
|
2108
2182
|
setKeepChildren(true);
|
|
2109
2183
|
return void 0;
|
|
@@ -2112,12 +2186,12 @@ function CollapsePanel({
|
|
|
2112
2186
|
return () => window.clearTimeout(timer);
|
|
2113
2187
|
}, [destroyInactivePanel, forceRender, open]);
|
|
2114
2188
|
const renderChildren = open || forceRender || !destroyInactivePanel || keepChildren;
|
|
2115
|
-
return /* @__PURE__ */ (0,
|
|
2189
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "sia-collapse__panel", "aria-hidden": !open, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "sia-collapse__panel-motion", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "sia-collapse__panel-body", children: renderChildren ? children : null }) }) });
|
|
2116
2190
|
}
|
|
2117
2191
|
function Collapse({ items, activeKey, defaultActiveKey = [], accordion = false, bordered = true, ghost = false, destroyInactivePanel = false, expandIconPosition = "start", onChange, className = "", ...props }) {
|
|
2118
2192
|
const normalize = (key) => Array.isArray(key) ? [...key] : key === void 0 ? [] : [key];
|
|
2119
2193
|
const controlled = activeKey !== void 0;
|
|
2120
|
-
const [internal, setInternal] = (0,
|
|
2194
|
+
const [internal, setInternal] = (0, import_react13.useState)(normalize(defaultActiveKey));
|
|
2121
2195
|
const openKeys = controlled ? normalize(activeKey) : internal;
|
|
2122
2196
|
function toggle(item) {
|
|
2123
2197
|
if (item.disabled || item.collapsible === "disabled") return;
|
|
@@ -2127,388 +2201,254 @@ function Collapse({ items, activeKey, defaultActiveKey = [], accordion = false,
|
|
|
2127
2201
|
onChange?.(accordion ? next[0] ?? "" : next);
|
|
2128
2202
|
}
|
|
2129
2203
|
const borderClassName = !bordered || ghost ? "sia-collapse--borderless" : "sia-collapse--bordered";
|
|
2130
|
-
return /* @__PURE__ */ (0,
|
|
2204
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: `sia-collapse ${borderClassName}${ghost ? " sia-collapse--ghost" : ""} sia-collapse--icon-${expandIconPosition} ${className}`.trim(), ...props, children: items.map((item) => {
|
|
2131
2205
|
const open = openKeys.includes(item.key);
|
|
2132
|
-
const arrow = item.showArrow === false ? null : /* @__PURE__ */ (0,
|
|
2133
|
-
return /* @__PURE__ */ (0,
|
|
2134
|
-
/* @__PURE__ */ (0,
|
|
2206
|
+
const arrow = item.showArrow === false ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "sia-collapse__arrow", "aria-label": open ? "\u6536\u8D77" : "\u5C55\u5F00", onClick: item.collapsible === "icon" ? () => toggle(item) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "chevron-right", size: 14 }) });
|
|
2207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("section", { className: `sia-collapse__item${open ? " is-open" : ""}${item.disabled ? " is-disabled" : ""} ${item.className ?? ""}`.trim(), children: [
|
|
2208
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("header", { className: "sia-collapse__header", role: "button", tabIndex: item.disabled ? -1 : 0, "aria-expanded": open, onClick: item.collapsible === "icon" ? void 0 : () => toggle(item), onKeyDown: (event) => {
|
|
2135
2209
|
if (event.key === "Enter" || event.key === " ") {
|
|
2136
2210
|
event.preventDefault();
|
|
2137
2211
|
toggle(item);
|
|
2138
2212
|
}
|
|
2139
2213
|
}, children: [
|
|
2140
2214
|
expandIconPosition === "start" ? arrow : null,
|
|
2141
|
-
/* @__PURE__ */ (0,
|
|
2142
|
-
item.extra ? /* @__PURE__ */ (0,
|
|
2215
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sia-collapse__label", children: item.label }),
|
|
2216
|
+
item.extra ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sia-collapse__extra", onClick: (event) => event.stopPropagation(), children: item.extra }) : null,
|
|
2143
2217
|
expandIconPosition === "end" ? arrow : null
|
|
2144
2218
|
] }),
|
|
2145
|
-
/* @__PURE__ */ (0,
|
|
2219
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CollapsePanel, { open, forceRender: item.forceRender, destroyInactivePanel, children: item.children })
|
|
2146
2220
|
] }, item.key);
|
|
2147
2221
|
}) });
|
|
2148
2222
|
}
|
|
2149
2223
|
|
|
2150
2224
|
// src/components/FloatingPlaceholder.tsx
|
|
2151
|
-
var
|
|
2225
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2152
2226
|
function useFloatingPlaceholder({ mode, placeholder, filled, active = false }) {
|
|
2153
2227
|
const enabled = usePlaceholderMode(mode) === "floating" && Boolean(placeholder);
|
|
2154
2228
|
return {
|
|
2155
2229
|
enabled,
|
|
2156
2230
|
className: enabled ? ` sia-placeholder-floating${filled ? " sia-placeholder-floating--filled" : ""}${active ? " sia-placeholder-floating--active" : ""}` : "",
|
|
2157
|
-
label: enabled ? /* @__PURE__ */ (0,
|
|
2231
|
+
label: enabled ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "sia-floating-placeholder", "aria-hidden": "true", children: placeholder }) : null
|
|
2158
2232
|
};
|
|
2159
2233
|
}
|
|
2160
2234
|
|
|
2161
2235
|
// src/components/Select.tsx
|
|
2162
|
-
var
|
|
2163
|
-
|
|
2164
|
-
// src/components/OverflowTags.tsx
|
|
2165
|
-
var import_react13 = require("react");
|
|
2166
|
-
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2167
|
-
function OverflowTags({ items, maxCount: maxCount2, className = "", tagClassName, restClassName = "" }) {
|
|
2168
|
-
const rootRef = (0, import_react13.useRef)(null);
|
|
2169
|
-
const measureRef = (0, import_react13.useRef)(null);
|
|
2170
|
-
const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount2) || 0));
|
|
2171
|
-
const [visibleCount, setVisibleCount] = (0, import_react13.useState)(0);
|
|
2172
|
-
(0, import_react13.useLayoutEffect)(() => {
|
|
2173
|
-
const root = rootRef.current;
|
|
2174
|
-
const measure = measureRef.current;
|
|
2175
|
-
if (!root || !measure) return;
|
|
2176
|
-
const update = () => {
|
|
2177
|
-
const gap = Number.parseFloat(getComputedStyle(root).columnGap) || 0;
|
|
2178
|
-
const widths = Array.from(measure.children, (child) => child.getBoundingClientRect().width);
|
|
2179
|
-
let used = 0;
|
|
2180
|
-
let fitting = 0;
|
|
2181
|
-
for (let count2 = 1; count2 <= limit; count2 += 1) {
|
|
2182
|
-
used += widths[count2 - 1] + (count2 > 1 ? gap : 0);
|
|
2183
|
-
const rest = count2 < items.length ? gap + widths[limit + count2] : 0;
|
|
2184
|
-
if (used + rest <= root.clientWidth) fitting = count2;
|
|
2185
|
-
}
|
|
2186
|
-
setVisibleCount((previous) => previous === fitting ? previous : fitting);
|
|
2187
|
-
};
|
|
2188
|
-
update();
|
|
2189
|
-
const observer = new ResizeObserver(update);
|
|
2190
|
-
observer.observe(root);
|
|
2191
|
-
for (const child of measure.children) observer.observe(child);
|
|
2192
|
-
return () => observer.disconnect();
|
|
2193
|
-
}, [items, limit]);
|
|
2194
|
-
const count = Math.min(visibleCount, limit);
|
|
2195
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { ref: rootRef, className: `sia-overflow-tags ${className}`.trim(), children: [
|
|
2196
|
-
items.slice(0, count).map((item) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
|
|
2197
|
-
items.length > count ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: `${tagClassName} sia-overflow-tags__rest ${restClassName}`.trim(), children: [
|
|
2198
|
-
"+",
|
|
2199
|
-
items.length - count
|
|
2200
|
-
] }) : null,
|
|
2201
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { ref: measureRef, className: "sia-overflow-tags__measure", "aria-hidden": "true", children: [
|
|
2202
|
-
items.slice(0, limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
|
|
2203
|
-
Array.from({ length: limit + 1 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: `${tagClassName} ${restClassName}`.trim(), children: [
|
|
2204
|
-
"+",
|
|
2205
|
-
items.length - index
|
|
2206
|
-
] }, `rest-${index}`))
|
|
2207
|
-
] })
|
|
2208
|
-
] });
|
|
2209
|
-
}
|
|
2236
|
+
var import_react18 = require("react");
|
|
2210
2237
|
|
|
2211
|
-
// src/components/
|
|
2238
|
+
// src/components/Modal.tsx
|
|
2239
|
+
var import_react14 = require("react");
|
|
2240
|
+
var import_client2 = require("react-dom/client");
|
|
2212
2241
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2242
|
+
var modalHandles = /* @__PURE__ */ new Set();
|
|
2243
|
+
var MODAL_MOTION_DURATION = 220;
|
|
2244
|
+
var typeIcons = {
|
|
2245
|
+
info: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "info", size: 23 }),
|
|
2246
|
+
success: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "circle-check", size: 23 }),
|
|
2247
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "warning", size: 23 }),
|
|
2248
|
+
error: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "circle-close", size: 23 }),
|
|
2249
|
+
confirm: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "question", size: 23 })
|
|
2250
|
+
};
|
|
2251
|
+
var ModalRoot = (0, import_react14.forwardRef)(function Modal({
|
|
2252
|
+
open,
|
|
2253
|
+
title,
|
|
2254
|
+
children,
|
|
2255
|
+
footer,
|
|
2256
|
+
type = "default",
|
|
2257
|
+
okText = "\u786E\u5B9A",
|
|
2258
|
+
cancelText = "\u53D6\u6D88",
|
|
2259
|
+
showCancel = type === "default" || type === "confirm",
|
|
2260
|
+
confirmLoading = false,
|
|
2261
|
+
okButtonProps,
|
|
2262
|
+
cancelButtonProps,
|
|
2263
|
+
closable = true,
|
|
2264
|
+
maskClosable = true,
|
|
2265
|
+
keyboard = true,
|
|
2266
|
+
centered = false,
|
|
2267
|
+
width = 520,
|
|
2268
|
+
zIndex = 1e3,
|
|
2269
|
+
getContainer,
|
|
2270
|
+
onOk,
|
|
2271
|
+
onCancel,
|
|
2272
|
+
onOpenChange,
|
|
2273
|
+
afterOpenChange,
|
|
2241
2274
|
className = "",
|
|
2242
|
-
|
|
2243
|
-
notFoundContent = "\u6682\u65E0\u6570\u636E",
|
|
2244
|
-
onKeyDown,
|
|
2275
|
+
style,
|
|
2245
2276
|
...props
|
|
2246
2277
|
}, forwardedRef) {
|
|
2247
|
-
const
|
|
2248
|
-
const
|
|
2249
|
-
const
|
|
2250
|
-
const
|
|
2251
|
-
const
|
|
2252
|
-
const
|
|
2253
|
-
|
|
2254
|
-
const
|
|
2255
|
-
const [query, setQuery] = (0, import_react14.useState)("");
|
|
2256
|
-
const [activeIndex, setActiveIndex] = (0, import_react14.useState)(-1);
|
|
2257
|
-
const [scrollTop, setScrollTop] = (0, import_react14.useState)(0);
|
|
2258
|
-
const deferredQuery = (0, import_react14.useDeferredValue)(query.trim());
|
|
2259
|
-
const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
|
|
2260
|
-
const [currentValue, setCurrentValue] = useControllableState({
|
|
2261
|
-
value,
|
|
2262
|
-
defaultValue: initialValue,
|
|
2263
|
-
onChange: (nextValue) => {
|
|
2264
|
-
if (Array.isArray(nextValue)) {
|
|
2265
|
-
const selectedOptions2 = nextValue.map((selectedValue) => options.find((option) => option.value === selectedValue) ?? (allowInput ? { label: String(selectedValue), value: selectedValue } : void 0)).filter((option) => option !== void 0);
|
|
2266
|
-
onChange?.(nextValue, selectedOptions2);
|
|
2267
|
-
} else {
|
|
2268
|
-
const selectedOption = nextValue === null ? null : options.find((option) => option.value === nextValue) ?? (allowInput ? { label: String(nextValue), value: nextValue } : null);
|
|
2269
|
-
onChange?.(nextValue, selectedOption);
|
|
2270
|
-
}
|
|
2271
|
-
}
|
|
2272
|
-
});
|
|
2273
|
-
const selectedValues = (0, import_react14.useMemo)(() => {
|
|
2274
|
-
if (mode === "multiple") return Array.isArray(currentValue) ? currentValue : currentValue === null ? [] : [currentValue];
|
|
2275
|
-
return Array.isArray(currentValue) ? currentValue.slice(0, 1) : currentValue === null ? [] : [currentValue];
|
|
2276
|
-
}, [currentValue, mode]);
|
|
2277
|
-
const selectedValueSet = (0, import_react14.useMemo)(() => new Set(selectedValues), [selectedValues]);
|
|
2278
|
-
const availableOptions = (0, import_react14.useMemo)(() => {
|
|
2279
|
-
if (!allowInput) return options;
|
|
2280
|
-
const optionValueSet = new Set(options.map((option) => option.value));
|
|
2281
|
-
const selectedCustomOptions = selectedValues.filter((selectedValue) => !optionValueSet.has(selectedValue)).map((selectedValue) => ({ label: String(selectedValue), value: selectedValue }));
|
|
2282
|
-
return selectedCustomOptions.length ? [...selectedCustomOptions, ...options] : options;
|
|
2283
|
-
}, [allowInput, options, selectedValues]);
|
|
2284
|
-
const selectedOptions = (0, import_react14.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
|
|
2285
|
-
const filteredOptions = (0, import_react14.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
|
|
2286
|
-
const inputValue = query.trim();
|
|
2287
|
-
const exactInputOption = inputValue ? availableOptions.find((option) => String(option.value).toLowerCase() === inputValue.toLowerCase() || typeof option.label === "string" && option.label.toLowerCase() === inputValue.toLowerCase()) : void 0;
|
|
2288
|
-
const canSubmitInput = allowInput && Boolean(inputValue) && !exactInputOption;
|
|
2289
|
-
const multiple = mode === "multiple";
|
|
2290
|
-
const hasValue = selectedOptions.length > 0;
|
|
2291
|
-
const virtualEnabled = virtual && filteredOptions.length >= virtualThreshold;
|
|
2292
|
-
const overscan = 3;
|
|
2293
|
-
const visibleCount = Math.ceil(listHeight / optionHeight) + overscan * 2;
|
|
2294
|
-
const virtualStart = virtualEnabled ? Math.max(0, Math.floor(scrollTop / optionHeight) - overscan) : 0;
|
|
2295
|
-
const virtualEnd = virtualEnabled ? Math.min(filteredOptions.length, virtualStart + visibleCount) : filteredOptions.length;
|
|
2296
|
-
const renderedOptions = virtualEnabled ? filteredOptions.slice(virtualStart, virtualEnd) : filteredOptions;
|
|
2297
|
-
const enabledFilteredOptions = filteredOptions.filter((option) => !option.disabled);
|
|
2298
|
-
const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((option) => selectedValueSet.has(option.value));
|
|
2278
|
+
const localRef = (0, import_react14.useRef)(null);
|
|
2279
|
+
const titleId = (0, import_react14.useId)();
|
|
2280
|
+
const [submitting, setSubmitting] = (0, import_react14.useState)(false);
|
|
2281
|
+
const [rendered, setRendered] = (0, import_react14.useState)(open);
|
|
2282
|
+
const [closing, setClosing] = (0, import_react14.useState)(false);
|
|
2283
|
+
const afterOpenChangeRef = (0, import_react14.useRef)(afterOpenChange);
|
|
2284
|
+
afterOpenChangeRef.current = afterOpenChange;
|
|
2285
|
+
const submitLock = (0, import_react14.useRef)(false);
|
|
2299
2286
|
(0, import_react14.useEffect)(() => {
|
|
2300
|
-
if (!open) return void 0;
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
}
|
|
2305
|
-
document.addEventListener("mousedown", closeFromOutside);
|
|
2306
|
-
return () => document.removeEventListener("mousedown", closeFromOutside);
|
|
2307
|
-
}, [open]);
|
|
2287
|
+
if (!open || !rendered) return void 0;
|
|
2288
|
+
const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
|
|
2289
|
+
return () => window.clearTimeout(timer);
|
|
2290
|
+
}, [open, rendered]);
|
|
2308
2291
|
(0, import_react14.useEffect)(() => {
|
|
2309
|
-
if (open
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
}
|
|
2314
|
-
function closeDropdown() {
|
|
2315
|
-
setOpen(false);
|
|
2316
|
-
setQuery("");
|
|
2317
|
-
setScrollTop(0);
|
|
2318
|
-
}
|
|
2319
|
-
function openDropdown() {
|
|
2320
|
-
if (disabled || loading) return;
|
|
2321
|
-
const selectedIndex = filteredOptions.findIndex((option) => selectedValueSet.has(option.value) && !option.disabled);
|
|
2322
|
-
setActiveIndex(selectedIndex >= 0 ? selectedIndex : firstEnabledIndex());
|
|
2323
|
-
setOpen(true);
|
|
2324
|
-
}
|
|
2325
|
-
function keepActiveVisible(index) {
|
|
2326
|
-
if (!virtualEnabled || !listRef.current) return;
|
|
2327
|
-
const optionTop = index * optionHeight;
|
|
2328
|
-
const optionBottom = optionTop + optionHeight;
|
|
2329
|
-
const viewportTop = listRef.current.scrollTop;
|
|
2330
|
-
const viewportBottom = viewportTop + listHeight;
|
|
2331
|
-
const nextScrollTop = optionTop < viewportTop ? optionTop : optionBottom > viewportBottom ? optionBottom - listHeight : viewportTop;
|
|
2332
|
-
if (nextScrollTop !== viewportTop) {
|
|
2333
|
-
listRef.current.scrollTop = nextScrollTop;
|
|
2334
|
-
setScrollTop(nextScrollTop);
|
|
2292
|
+
if (open) {
|
|
2293
|
+
setRendered(true);
|
|
2294
|
+
setClosing(false);
|
|
2295
|
+
return void 0;
|
|
2335
2296
|
}
|
|
2297
|
+
if (!rendered) return void 0;
|
|
2298
|
+
setClosing(true);
|
|
2299
|
+
const timer = window.setTimeout(() => {
|
|
2300
|
+
setRendered(false);
|
|
2301
|
+
setClosing(false);
|
|
2302
|
+
afterOpenChangeRef.current?.(false);
|
|
2303
|
+
}, MODAL_MOTION_DURATION);
|
|
2304
|
+
return () => window.clearTimeout(timer);
|
|
2305
|
+
}, [open, rendered]);
|
|
2306
|
+
function setRef(node) {
|
|
2307
|
+
localRef.current = node;
|
|
2308
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
2309
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
2336
2310
|
}
|
|
2337
|
-
function
|
|
2338
|
-
if (
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
nextIndex = (nextIndex + direction + filteredOptions.length) % filteredOptions.length;
|
|
2342
|
-
if (!filteredOptions[nextIndex]?.disabled) {
|
|
2343
|
-
setActiveIndex(nextIndex);
|
|
2344
|
-
keepActiveVisible(nextIndex);
|
|
2345
|
-
return;
|
|
2346
|
-
}
|
|
2347
|
-
}
|
|
2311
|
+
function requestClose() {
|
|
2312
|
+
if (submitting || confirmLoading) return;
|
|
2313
|
+
onCancel?.();
|
|
2314
|
+
onOpenChange?.(false);
|
|
2348
2315
|
}
|
|
2349
|
-
function
|
|
2350
|
-
if (
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
setCurrentValue(option.value);
|
|
2357
|
-
closeDropdown();
|
|
2358
|
-
}
|
|
2359
|
-
function selectAllFiltered() {
|
|
2360
|
-
if (allFilteredSelected) return;
|
|
2361
|
-
const nextValues = [...selectedValues];
|
|
2362
|
-
const nextValueSet = new Set(nextValues);
|
|
2363
|
-
enabledFilteredOptions.forEach((option) => {
|
|
2364
|
-
if (!nextValueSet.has(option.value)) nextValues.push(option.value);
|
|
2365
|
-
});
|
|
2366
|
-
setCurrentValue(nextValues);
|
|
2367
|
-
}
|
|
2368
|
-
function submitInputValue() {
|
|
2369
|
-
if (!allowInput || !inputValue) return;
|
|
2370
|
-
selectOption(exactInputOption ?? { label: inputValue, value: inputValue });
|
|
2371
|
-
if (multiple) {
|
|
2372
|
-
setQuery("");
|
|
2373
|
-
setActiveIndex(-1);
|
|
2374
|
-
setScrollTop(0);
|
|
2316
|
+
async function handleOk() {
|
|
2317
|
+
if (submitLock.current || confirmLoading) return;
|
|
2318
|
+
submitLock.current = true;
|
|
2319
|
+
if (!onOk) {
|
|
2320
|
+
onOpenChange?.(false);
|
|
2321
|
+
submitLock.current = false;
|
|
2322
|
+
return;
|
|
2375
2323
|
}
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
}
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
} else if (event.key === "Escape") {
|
|
2391
|
-
closeDropdown();
|
|
2392
|
-
} else if (event.key === "Home" && open && !fromSearch) {
|
|
2393
|
-
event.preventDefault();
|
|
2394
|
-
const firstIndex = firstEnabledIndex();
|
|
2395
|
-
setActiveIndex(firstIndex);
|
|
2396
|
-
keepActiveVisible(firstIndex);
|
|
2397
|
-
} else if (event.key === "End" && open && !fromSearch) {
|
|
2398
|
-
event.preventDefault();
|
|
2399
|
-
const reversedIndex = [...filteredOptions].reverse().findIndex((option) => !option.disabled);
|
|
2400
|
-
const lastIndex = reversedIndex < 0 ? -1 : filteredOptions.length - 1 - reversedIndex;
|
|
2401
|
-
setActiveIndex(lastIndex);
|
|
2402
|
-
keepActiveVisible(lastIndex);
|
|
2324
|
+
try {
|
|
2325
|
+
const result = onOk();
|
|
2326
|
+
if (result instanceof Promise) {
|
|
2327
|
+
setSubmitting(true);
|
|
2328
|
+
const resolved = await result;
|
|
2329
|
+
if (resolved !== false) onOpenChange?.(false);
|
|
2330
|
+
} else if (result !== false) {
|
|
2331
|
+
onOpenChange?.(false);
|
|
2332
|
+
}
|
|
2333
|
+
} catch {
|
|
2334
|
+
return;
|
|
2335
|
+
} finally {
|
|
2336
|
+
submitLock.current = false;
|
|
2337
|
+
setSubmitting(false);
|
|
2403
2338
|
}
|
|
2404
2339
|
}
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
function renderOption(option, renderedIndex) {
|
|
2425
|
-
const optionIndex = virtualEnabled ? virtualStart + renderedIndex : renderedIndex;
|
|
2426
|
-
const selected = selectedValueSet.has(option.value);
|
|
2427
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2428
|
-
"div",
|
|
2429
|
-
{
|
|
2430
|
-
id: `${listboxId}-${optionIndex}`,
|
|
2431
|
-
className: `sia-select__option${selected ? " is-selected" : ""}${optionIndex === activeIndex ? " is-active" : ""}${option.disabled ? " is-disabled" : ""}`,
|
|
2432
|
-
role: "option",
|
|
2433
|
-
"aria-selected": selected,
|
|
2434
|
-
"aria-disabled": option.disabled || void 0,
|
|
2435
|
-
style: virtualEnabled ? { position: "absolute", top: optionIndex * optionHeight, right: 0, left: 0, height: optionHeight } : void 0,
|
|
2436
|
-
onMouseEnter: () => !option.disabled && setActiveIndex(optionIndex),
|
|
2437
|
-
onMouseDown: (event) => event.preventDefault(),
|
|
2438
|
-
onClick: () => selectOption(option),
|
|
2439
|
-
children: [
|
|
2440
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: option.label }),
|
|
2441
|
-
selected ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "check", size: 15 }) : null
|
|
2442
|
-
]
|
|
2340
|
+
useOverlayLifecycle(rendered, localRef, requestClose, keyboard);
|
|
2341
|
+
if (!rendered) return null;
|
|
2342
|
+
const mergedStyle = {
|
|
2343
|
+
...style,
|
|
2344
|
+
"--sia-modal-width": typeof width === "number" ? `${width}px` : width
|
|
2345
|
+
};
|
|
2346
|
+
const loading = submitting || confirmLoading;
|
|
2347
|
+
const defaultFooter = /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
2348
|
+
showCancel ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { ...cancelButtonProps, onClick: requestClose, disabled: loading || cancelButtonProps?.disabled, children: cancelText }) : null,
|
|
2349
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "primary", ...okButtonProps, onClick: handleOk, loading, children: okText })
|
|
2350
|
+
] });
|
|
2351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(OverlayPortal, { container: getContainer, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2352
|
+
"div",
|
|
2353
|
+
{
|
|
2354
|
+
className: `sia-modal-root${centered ? " sia-modal-root--centered" : ""}`,
|
|
2355
|
+
"data-state": closing ? "closing" : "open",
|
|
2356
|
+
style: { zIndex },
|
|
2357
|
+
onMouseDown: (event) => {
|
|
2358
|
+
if (event.target === event.currentTarget && maskClosable) requestClose();
|
|
2443
2359
|
},
|
|
2444
|
-
|
|
2445
|
-
);
|
|
2446
|
-
}
|
|
2447
|
-
const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: hasValue, active: open });
|
|
2448
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { ref: rootRef, className: `sia-select sia-select--${size} sia-select--${status}${open ? " is-open" : ""}${disabled ? " is-disabled" : ""}${multiple ? " sia-select--multiple" : ""} ${className}`.trim(), children: [
|
|
2449
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2450
|
-
"button",
|
|
2451
|
-
{
|
|
2452
|
-
...props,
|
|
2453
|
-
ref: forwardedRef,
|
|
2454
|
-
className: `sia-select__trigger${floating.className}`,
|
|
2455
|
-
id: selectId,
|
|
2456
|
-
type: "button",
|
|
2457
|
-
role: "combobox",
|
|
2458
|
-
"aria-controls": listboxId,
|
|
2459
|
-
"aria-expanded": open,
|
|
2460
|
-
"aria-haspopup": "listbox",
|
|
2461
|
-
"aria-activedescendant": open && activeIndex >= 0 ? `${listboxId}-${activeIndex}` : void 0,
|
|
2462
|
-
"aria-invalid": status === "error" || void 0,
|
|
2463
|
-
disabled,
|
|
2464
|
-
onClick: () => open ? closeDropdown() : openDropdown(),
|
|
2465
|
-
onKeyDown: handleTriggerKeyDown,
|
|
2466
|
-
children: [
|
|
2467
|
-
multiple && hasValue ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(OverflowTags, { className: "sia-select__tags", tagClassName: "sia-select__tag", restClassName: "sia-select__tag--rest", maxCount: maxTagCount, items: selectedOptions.map((option) => ({ key: `${typeof option.value}-${option.value}`, label: option.label })) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: `sia-select__value${hasValue ? "" : " is-placeholder"}`, children: selectedOptions[0]?.label ?? placeholder }),
|
|
2468
|
-
loading ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sia-select__spinner", "aria-hidden": "true" }) : null,
|
|
2469
|
-
floating.label,
|
|
2470
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { className: "sia-select__arrow", name: "chevron-down", size: 15 })
|
|
2471
|
-
]
|
|
2472
|
-
}
|
|
2473
|
-
),
|
|
2474
|
-
allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
|
|
2475
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open, className: "sia-select__dropdown", children: [
|
|
2476
|
-
showSearch || allowInput ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "sia-select__search", children: [
|
|
2477
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "search", size: 15 }),
|
|
2478
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("input", { ref: searchRef, value: query, maxLength: inputMaxLength, onChange: handleSearchChange, onKeyDown: (event) => handleInteractionKeyDown(event, true), placeholder: searchPlaceholder, "aria-label": searchPlaceholder })
|
|
2479
|
-
] }) : null,
|
|
2480
|
-
canSubmitInput ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("button", { type: "button", className: "sia-select__input-option", onMouseDown: (event) => event.preventDefault(), onClick: submitInputValue, children: [
|
|
2481
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "plus", size: 14 }),
|
|
2482
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { children: [
|
|
2483
|
-
"\u4F7F\u7528\u201C",
|
|
2484
|
-
inputValue,
|
|
2485
|
-
"\u201D"
|
|
2486
|
-
] })
|
|
2487
|
-
] }) : null,
|
|
2488
|
-
multiple && showSelectAll ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sia-select__actions", children: [
|
|
2489
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", disabled: allFilteredSelected || enabledFilteredOptions.length === 0, onClick: selectAllFiltered, children: "\u5168\u9009" }),
|
|
2490
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", disabled: !hasValue, onClick: clearSelection, children: "\u6E05\u9664" }),
|
|
2491
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { children: [
|
|
2492
|
-
selectedValues.length,
|
|
2493
|
-
" \u9879\u5DF2\u9009"
|
|
2494
|
-
] })
|
|
2495
|
-
] }) : null,
|
|
2496
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2360
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2497
2361
|
"div",
|
|
2498
2362
|
{
|
|
2499
|
-
ref:
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
role: "
|
|
2503
|
-
"aria-
|
|
2504
|
-
"aria-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
children:
|
|
2363
|
+
ref: setRef,
|
|
2364
|
+
className: `sia-modal sia-modal--${type} ${className}`.trim(),
|
|
2365
|
+
style: mergedStyle,
|
|
2366
|
+
role: "dialog",
|
|
2367
|
+
"aria-modal": "true",
|
|
2368
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
2369
|
+
tabIndex: -1,
|
|
2370
|
+
...props,
|
|
2371
|
+
children: [
|
|
2372
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sia-modal__header", children: [
|
|
2373
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sia-modal__heading", children: [
|
|
2374
|
+
typeIcons[type] ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sia-modal__type-icon", "aria-hidden": "true", children: typeIcons[type] }) : null,
|
|
2375
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { id: titleId, children: title }) : null
|
|
2376
|
+
] }),
|
|
2377
|
+
closable ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: "sia-modal__close", "aria-label": "\u5173\u95ED\u5BF9\u8BDD\u6846", onClick: requestClose, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: "close", size: 17 }) }) : null
|
|
2378
|
+
] }),
|
|
2379
|
+
children !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "sia-modal__body", children }) : null,
|
|
2380
|
+
footer !== null ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "sia-modal__footer", children: footer ?? defaultFooter }) : null
|
|
2381
|
+
]
|
|
2508
2382
|
}
|
|
2509
2383
|
)
|
|
2510
|
-
|
|
2511
|
-
|
|
2384
|
+
}
|
|
2385
|
+
) });
|
|
2386
|
+
});
|
|
2387
|
+
function openModal(config) {
|
|
2388
|
+
if (typeof document === "undefined") return { destroy() {
|
|
2389
|
+
}, update() {
|
|
2390
|
+
} };
|
|
2391
|
+
const container = document.createElement("div");
|
|
2392
|
+
container.className = "sia-modal-api-host";
|
|
2393
|
+
document.body.appendChild(container);
|
|
2394
|
+
const root = (0, import_client2.createRoot)(container);
|
|
2395
|
+
let currentConfig = config;
|
|
2396
|
+
let currentOpen = true;
|
|
2397
|
+
let destroyed = false;
|
|
2398
|
+
let cleanupTimer;
|
|
2399
|
+
function cleanup() {
|
|
2400
|
+
if (destroyed) return;
|
|
2401
|
+
destroyed = true;
|
|
2402
|
+
if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
|
|
2403
|
+
root.unmount();
|
|
2404
|
+
container.remove();
|
|
2405
|
+
modalHandles.delete(handle);
|
|
2406
|
+
}
|
|
2407
|
+
function closeWithMotion() {
|
|
2408
|
+
if (destroyed || !currentOpen) return;
|
|
2409
|
+
currentOpen = false;
|
|
2410
|
+
render();
|
|
2411
|
+
cleanupTimer = window.setTimeout(cleanup, MODAL_MOTION_DURATION);
|
|
2412
|
+
}
|
|
2413
|
+
function render() {
|
|
2414
|
+
root.render(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
|
|
2415
|
+
currentConfig.onOpenChange?.(nextOpen);
|
|
2416
|
+
if (!nextOpen) closeWithMotion();
|
|
2417
|
+
} }));
|
|
2418
|
+
}
|
|
2419
|
+
const handle = {
|
|
2420
|
+
destroy: closeWithMotion,
|
|
2421
|
+
update(next) {
|
|
2422
|
+
if (destroyed) return;
|
|
2423
|
+
currentConfig = { ...currentConfig, ...next };
|
|
2424
|
+
render();
|
|
2425
|
+
}
|
|
2426
|
+
};
|
|
2427
|
+
modalHandles.add(handle);
|
|
2428
|
+
render();
|
|
2429
|
+
return handle;
|
|
2430
|
+
}
|
|
2431
|
+
function preset(type, defaults = {}) {
|
|
2432
|
+
return (config) => openModal({
|
|
2433
|
+
okText: type === "confirm" ? "\u786E\u5B9A" : "\u77E5\u9053\u4E86",
|
|
2434
|
+
showCancel: type === "confirm",
|
|
2435
|
+
closable: type !== "confirm",
|
|
2436
|
+
maskClosable: type !== "confirm",
|
|
2437
|
+
...defaults,
|
|
2438
|
+
...config,
|
|
2439
|
+
type
|
|
2440
|
+
});
|
|
2441
|
+
}
|
|
2442
|
+
var Modal2 = Object.assign(ModalRoot, {
|
|
2443
|
+
open: openModal,
|
|
2444
|
+
info: preset("info", { title: "\u63D0\u793A" }),
|
|
2445
|
+
success: preset("success", { title: "\u64CD\u4F5C\u6210\u529F" }),
|
|
2446
|
+
warning: preset("warning", { title: "\u8BF7\u6CE8\u610F" }),
|
|
2447
|
+
error: preset("error", { title: "\u64CD\u4F5C\u5931\u8D25" }),
|
|
2448
|
+
confirm: preset("confirm", { title: "\u786E\u8BA4\u64CD\u4F5C" }),
|
|
2449
|
+
destroyAll() {
|
|
2450
|
+
[...modalHandles].forEach((handle) => handle.destroy());
|
|
2451
|
+
}
|
|
2512
2452
|
});
|
|
2513
2453
|
|
|
2514
2454
|
// src/components/Input.tsx
|
|
@@ -2567,6 +2507,15 @@ var Input = (0, import_react15.forwardRef)(function Input2({
|
|
|
2567
2507
|
input2.focus();
|
|
2568
2508
|
onClear?.();
|
|
2569
2509
|
}
|
|
2510
|
+
function handleControlMouseDown(event) {
|
|
2511
|
+
if (disabled || event.defaultPrevented || event.button !== 0) return;
|
|
2512
|
+
const target = event.target;
|
|
2513
|
+
if (!(target instanceof Element)) return;
|
|
2514
|
+
const interactive = target.closest("input, textarea, select, button, a[href], [tabindex], [contenteditable]:not([contenteditable='false']), [role='button'], [role='link']");
|
|
2515
|
+
if (interactive && event.currentTarget.contains(interactive) && !interactive.classList.contains("sia-input-control__clear")) return;
|
|
2516
|
+
event.preventDefault();
|
|
2517
|
+
localRef.current?.focus({ preventScroll: true });
|
|
2518
|
+
}
|
|
2570
2519
|
const input = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2571
2520
|
"input",
|
|
2572
2521
|
{
|
|
@@ -2584,7 +2533,7 @@ var Input = (0, import_react15.forwardRef)(function Input2({
|
|
|
2584
2533
|
onChange: handleChange
|
|
2585
2534
|
}
|
|
2586
2535
|
);
|
|
2587
|
-
const control = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: `sia-input-control sia-input-control--${size} sia-input-control--${status}${floatingPlaceholder ? " sia-input-control--floating" : ""}${floatingPlaceholder && hasValue ? " is-filled" : ""}${disabled ? " is-disabled" : ""}`, children: [
|
|
2536
|
+
const control = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { onMouseDown: handleControlMouseDown, className: `sia-input-control sia-input-control--${size} sia-input-control--${status}${floatingPlaceholder ? " sia-input-control--floating" : ""}${floatingPlaceholder && hasValue ? " is-filled" : ""}${disabled ? " is-disabled" : ""}`, children: [
|
|
2588
2537
|
prefix ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "sia-input-control__affix", children: prefix }) : null,
|
|
2589
2538
|
floatingPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "sia-input-control__input-wrap", children: [
|
|
2590
2539
|
input,
|
|
@@ -2605,9 +2554,654 @@ var Input = (0, import_react15.forwardRef)(function Input2({
|
|
|
2605
2554
|
] });
|
|
2606
2555
|
});
|
|
2607
2556
|
|
|
2557
|
+
// src/components/SelectionPanel.tsx
|
|
2558
|
+
var import_react16 = require("react");
|
|
2559
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2560
|
+
function SelectionPanel({
|
|
2561
|
+
options,
|
|
2562
|
+
value,
|
|
2563
|
+
onChange,
|
|
2564
|
+
multiple = false,
|
|
2565
|
+
disabled = false,
|
|
2566
|
+
loading = false,
|
|
2567
|
+
showSearch = true,
|
|
2568
|
+
showActions = true,
|
|
2569
|
+
includeUnknownValues = true,
|
|
2570
|
+
searchValue,
|
|
2571
|
+
onSearch,
|
|
2572
|
+
selectedOnly = false,
|
|
2573
|
+
showValue = false,
|
|
2574
|
+
displayField = "label",
|
|
2575
|
+
columns = 1,
|
|
2576
|
+
maxHeight = 250,
|
|
2577
|
+
autoFocusSearch = false
|
|
2578
|
+
}) {
|
|
2579
|
+
const [localSearch, setLocalSearch] = (0, import_react16.useState)("");
|
|
2580
|
+
const search = searchValue ?? localSearch;
|
|
2581
|
+
const [scrollTop, setScrollTop] = (0, import_react16.useState)(0);
|
|
2582
|
+
const [active, setActive] = (0, import_react16.useState)();
|
|
2583
|
+
const listRef = (0, import_react16.useRef)(null);
|
|
2584
|
+
const id = (0, import_react16.useId)();
|
|
2585
|
+
const selected = (0, import_react16.useMemo)(() => new Set(value), [value]);
|
|
2586
|
+
const count = Math.max(1, Math.floor(columns));
|
|
2587
|
+
const allOptions = (0, import_react16.useMemo)(() => {
|
|
2588
|
+
if (!includeUnknownValues) return [...options];
|
|
2589
|
+
const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
|
|
2590
|
+
return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
|
|
2591
|
+
}, [options, value, includeUnknownValues]);
|
|
2592
|
+
const filtered = (0, import_react16.useMemo)(
|
|
2593
|
+
() => allOptions.filter((option) => (!selectedOnly || selected.has(option.value)) && (!search || option.optionType !== "divider" && [option.label, option.value].some((text) => String(text ?? "").toLowerCase().includes(search.toLowerCase())))),
|
|
2594
|
+
[allOptions, selectedOnly, selected, search]
|
|
2595
|
+
);
|
|
2596
|
+
const rows = (0, import_react16.useMemo)(() => {
|
|
2597
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2598
|
+
filtered.forEach((option) => {
|
|
2599
|
+
const items = groups.get(option.group) ?? [];
|
|
2600
|
+
items.push(option);
|
|
2601
|
+
groups.set(option.group, items);
|
|
2602
|
+
});
|
|
2603
|
+
const rows2 = [];
|
|
2604
|
+
let top = 0;
|
|
2605
|
+
for (const [group, items] of groups) {
|
|
2606
|
+
if (group) {
|
|
2607
|
+
rows2.push({ key: `group-${rows2.length}`, title: group, top, height: 30 });
|
|
2608
|
+
top += 30;
|
|
2609
|
+
}
|
|
2610
|
+
for (let index = 0; index < items.length; index += count) {
|
|
2611
|
+
const height = showValue ? 48 : 34;
|
|
2612
|
+
rows2.push({ key: `row-${rows2.length}`, items: items.slice(index, index + count), top, height });
|
|
2613
|
+
top += height;
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
return rows2;
|
|
2617
|
+
}, [filtered, count, showValue]);
|
|
2618
|
+
const totalHeight = rows.length ? rows[rows.length - 1].top + rows[rows.length - 1].height : 0;
|
|
2619
|
+
const virtual = filtered.length > 100;
|
|
2620
|
+
const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
|
|
2621
|
+
const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
|
|
2622
|
+
(0, import_react16.useEffect)(() => {
|
|
2623
|
+
setScrollTop(0);
|
|
2624
|
+
if (listRef.current) listRef.current.scrollTop = 0;
|
|
2625
|
+
setActive(void 0);
|
|
2626
|
+
}, [search, selectedOnly, count]);
|
|
2627
|
+
function toggle(option) {
|
|
2628
|
+
if (disabled || loading || option.disabled || option.optionType === "divider") return;
|
|
2629
|
+
setActive(option.value);
|
|
2630
|
+
onChange(multiple ? selected.has(option.value) ? value.filter((item) => item !== option.value) : [...value, option.value] : [option.value]);
|
|
2631
|
+
}
|
|
2632
|
+
function batch(operation) {
|
|
2633
|
+
if (disabled || loading) return;
|
|
2634
|
+
if (operation === "clear") {
|
|
2635
|
+
onChange([]);
|
|
2636
|
+
return;
|
|
2637
|
+
}
|
|
2638
|
+
const editable = new Set(enabled.map((option) => option.value));
|
|
2639
|
+
const retained = value.filter((item) => !editable.has(item));
|
|
2640
|
+
const add = enabled.filter((option) => operation === "all" || !selected.has(option.value)).map((option) => option.value);
|
|
2641
|
+
onChange([...retained, ...add]);
|
|
2642
|
+
}
|
|
2643
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-selection-panel", children: [
|
|
2644
|
+
showSearch && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2645
|
+
Input,
|
|
2646
|
+
{
|
|
2647
|
+
"aria-label": "\u641C\u7D22\u9009\u9879",
|
|
2648
|
+
placeholder: "\u641C\u7D22",
|
|
2649
|
+
autoFocus: autoFocusSearch,
|
|
2650
|
+
value: search,
|
|
2651
|
+
allowClear: true,
|
|
2652
|
+
onChange: (event) => {
|
|
2653
|
+
setLocalSearch(event.target.value);
|
|
2654
|
+
onSearch?.(event.target.value);
|
|
2655
|
+
}
|
|
2656
|
+
}
|
|
2657
|
+
),
|
|
2658
|
+
multiple && showActions && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-selection-panel__actions", children: [
|
|
2659
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("all"), children: "\u5168\u9009" }),
|
|
2660
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("invert"), children: "\u53CD\u9009" }),
|
|
2661
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !value.length, onClick: () => batch("clear"), children: "\u6E05\u7A7A" }),
|
|
2662
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { children: [
|
|
2663
|
+
"\u5DF2\u9009 ",
|
|
2664
|
+
value.length,
|
|
2665
|
+
" \u9879"
|
|
2666
|
+
] })
|
|
2667
|
+
] }),
|
|
2668
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2669
|
+
"div",
|
|
2670
|
+
{
|
|
2671
|
+
ref: listRef,
|
|
2672
|
+
role: "listbox",
|
|
2673
|
+
"aria-label": "\u9009\u9879\u5217\u8868",
|
|
2674
|
+
"aria-multiselectable": multiple || void 0,
|
|
2675
|
+
tabIndex: disabled ? -1 : 0,
|
|
2676
|
+
className: "sia-selection-panel__list",
|
|
2677
|
+
style: { maxHeight },
|
|
2678
|
+
onScroll: (event) => setScrollTop(event.currentTarget.scrollTop),
|
|
2679
|
+
"aria-activedescendant": active !== void 0 ? `${id}-${typeof active}-${active}` : void 0,
|
|
2680
|
+
onKeyDown: (event) => {
|
|
2681
|
+
if (event.target instanceof HTMLInputElement) return;
|
|
2682
|
+
if (disabled || loading || !enabled.length) return;
|
|
2683
|
+
const index = enabled.findIndex((option) => option.value === active);
|
|
2684
|
+
if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
|
|
2685
|
+
event.preventDefault();
|
|
2686
|
+
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)));
|
|
2687
|
+
const option = enabled[next];
|
|
2688
|
+
setActive(option.value);
|
|
2689
|
+
const row = rows.find((row2) => row2.items?.includes(option));
|
|
2690
|
+
if (row && listRef.current) {
|
|
2691
|
+
listRef.current.scrollTop = Math.max(0, row.top - maxHeight / 2);
|
|
2692
|
+
setScrollTop(listRef.current.scrollTop);
|
|
2693
|
+
}
|
|
2694
|
+
} else if ((event.key === "Enter" || event.key === " ") && index >= 0) {
|
|
2695
|
+
event.preventDefault();
|
|
2696
|
+
toggle(enabled[index]);
|
|
2697
|
+
}
|
|
2698
|
+
},
|
|
2699
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { role: "status", children: "\u52A0\u8F7D\u4E2D\u2026" }) : !rows.length ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "sia-selection-panel__empty", children: "\u6682\u65E0\u5339\u914D\u9009\u9879" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { height: totalHeight, position: "relative" }, children: renderedRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2700
|
+
"div",
|
|
2701
|
+
{
|
|
2702
|
+
className: row.title !== void 0 ? "sia-selection-panel__group" : "sia-selection-panel__row",
|
|
2703
|
+
style: { position: "absolute", top: row.top, height: row.height, width: "100%", gridTemplateColumns: `repeat(${count}, minmax(0, 1fr))` },
|
|
2704
|
+
children: row.title ?? row.items?.map((option, index) => option.optionType === "divider" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { role: "separator", className: "sia-selection-panel__divider" }, `divider-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Tooltip, { title: option.disabled ? option.disabledTip : void 0, placement: "right", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2705
|
+
"div",
|
|
2706
|
+
{
|
|
2707
|
+
role: "option",
|
|
2708
|
+
id: `${id}-${typeof option.value}-${option.value}`,
|
|
2709
|
+
tabIndex: -1,
|
|
2710
|
+
"aria-selected": selected.has(option.value),
|
|
2711
|
+
"aria-disabled": disabled || option.disabled || void 0,
|
|
2712
|
+
className: `sia-selection-panel__option${active === option.value ? " is-active" : ""}`,
|
|
2713
|
+
onClick: (event) => {
|
|
2714
|
+
if (!event.target.closest(".sia-checkbox")) toggle(option);
|
|
2715
|
+
},
|
|
2716
|
+
children: multiple ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Checkbox2, { checked: selected.has(option.value), disabled: disabled || loading || option.disabled, tabIndex: -1, onChange: () => toggle(option), children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "sia-selection-panel__text", children: [
|
|
2717
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
|
|
2718
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("small", { children: String(option.value) })
|
|
2719
|
+
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "sia-selection-panel__text", children: [
|
|
2720
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
|
|
2721
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("small", { children: String(option.value) })
|
|
2722
|
+
] })
|
|
2723
|
+
}
|
|
2724
|
+
) }, `${typeof option.value}-${option.value}`))
|
|
2725
|
+
},
|
|
2726
|
+
row.key
|
|
2727
|
+
)) })
|
|
2728
|
+
}
|
|
2729
|
+
)
|
|
2730
|
+
] });
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
// src/components/OverflowTags.tsx
|
|
2734
|
+
var import_react17 = require("react");
|
|
2735
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2736
|
+
function OverflowTags({ items, maxCount: maxCount2, className = "", tagClassName, restClassName = "" }) {
|
|
2737
|
+
const rootRef = (0, import_react17.useRef)(null);
|
|
2738
|
+
const measureRef = (0, import_react17.useRef)(null);
|
|
2739
|
+
const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount2) || 0));
|
|
2740
|
+
const [visibleCount, setVisibleCount] = (0, import_react17.useState)(0);
|
|
2741
|
+
(0, import_react17.useLayoutEffect)(() => {
|
|
2742
|
+
const root = rootRef.current;
|
|
2743
|
+
const measure = measureRef.current;
|
|
2744
|
+
if (!root || !measure) return;
|
|
2745
|
+
const update = () => {
|
|
2746
|
+
const gap = Number.parseFloat(getComputedStyle(root).columnGap) || 0;
|
|
2747
|
+
const widths = Array.from(measure.children, (child) => child.getBoundingClientRect().width);
|
|
2748
|
+
let used = 0;
|
|
2749
|
+
let fitting = 0;
|
|
2750
|
+
for (let count2 = 1; count2 <= limit; count2 += 1) {
|
|
2751
|
+
used += widths[count2 - 1] + (count2 > 1 ? gap : 0);
|
|
2752
|
+
const rest = count2 < items.length ? gap + widths[limit + count2] : 0;
|
|
2753
|
+
if (used + rest <= root.clientWidth) fitting = count2;
|
|
2754
|
+
}
|
|
2755
|
+
setVisibleCount((previous) => previous === fitting ? previous : fitting);
|
|
2756
|
+
};
|
|
2757
|
+
update();
|
|
2758
|
+
const observer = new ResizeObserver(update);
|
|
2759
|
+
observer.observe(root);
|
|
2760
|
+
for (const child of measure.children) observer.observe(child);
|
|
2761
|
+
return () => observer.disconnect();
|
|
2762
|
+
}, [items, limit]);
|
|
2763
|
+
const count = Math.min(visibleCount, limit);
|
|
2764
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { ref: rootRef, className: `sia-overflow-tags ${className}`.trim(), children: [
|
|
2765
|
+
items.slice(0, count).map((item) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
|
|
2766
|
+
items.length > count ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: `${tagClassName} sia-overflow-tags__rest ${restClassName}`.trim(), children: [
|
|
2767
|
+
"+",
|
|
2768
|
+
items.length - count
|
|
2769
|
+
] }) : null,
|
|
2770
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { ref: measureRef, className: "sia-overflow-tags__measure", "aria-hidden": "true", children: [
|
|
2771
|
+
items.slice(0, limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
|
|
2772
|
+
Array.from({ length: limit + 1 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: `${tagClassName} ${restClassName}`.trim(), children: [
|
|
2773
|
+
"+",
|
|
2774
|
+
items.length - index
|
|
2775
|
+
] }, `rest-${index}`))
|
|
2776
|
+
] })
|
|
2777
|
+
] });
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
// src/components/Select.tsx
|
|
2781
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2782
|
+
function defaultFilterOption(query, option) {
|
|
2783
|
+
const keyword = query.toLowerCase();
|
|
2784
|
+
return [option.label, option.value].some((value) => String(value).toLowerCase().includes(keyword));
|
|
2785
|
+
}
|
|
2786
|
+
var Select = (0, import_react18.forwardRef)(function Select2({
|
|
2787
|
+
options,
|
|
2788
|
+
mode = "single",
|
|
2789
|
+
popupMode = "dropdown",
|
|
2790
|
+
modalConfig,
|
|
2791
|
+
value,
|
|
2792
|
+
defaultValue,
|
|
2793
|
+
onChange,
|
|
2794
|
+
placeholder = "\u8BF7\u9009\u62E9",
|
|
2795
|
+
placeholderMode,
|
|
2796
|
+
size = "medium",
|
|
2797
|
+
status = "default",
|
|
2798
|
+
allowClear = false,
|
|
2799
|
+
loading = false,
|
|
2800
|
+
showSearch = false,
|
|
2801
|
+
showValue = false,
|
|
2802
|
+
allowInput = false,
|
|
2803
|
+
inputMaxLength,
|
|
2804
|
+
searchPlaceholder = "\u641C\u7D22\u9009\u9879",
|
|
2805
|
+
onSearch,
|
|
2806
|
+
filterOption = defaultFilterOption,
|
|
2807
|
+
showSelectAll = true,
|
|
2808
|
+
maxTagCount = 2,
|
|
2809
|
+
virtual = true,
|
|
2810
|
+
virtualThreshold = 100,
|
|
2811
|
+
listHeight = 256,
|
|
2812
|
+
optionHeight = showValue ? 54 : 34,
|
|
2813
|
+
disabled,
|
|
2814
|
+
className = "",
|
|
2815
|
+
id,
|
|
2816
|
+
notFoundContent = "\u6682\u65E0\u6570\u636E",
|
|
2817
|
+
onKeyDown,
|
|
2818
|
+
...props
|
|
2819
|
+
}, forwardedRef) {
|
|
2820
|
+
const fallbackId = (0, import_react18.useId)();
|
|
2821
|
+
const selectId = id ?? fallbackId;
|
|
2822
|
+
const listboxId = `${selectId}-listbox`;
|
|
2823
|
+
const rootRef = (0, import_react18.useRef)(null);
|
|
2824
|
+
const popupRef = (0, import_react18.useRef)(null);
|
|
2825
|
+
const searchRef = (0, import_react18.useRef)(null);
|
|
2826
|
+
const listRef = (0, import_react18.useRef)(null);
|
|
2827
|
+
const [open, setOpen] = (0, import_react18.useState)(false);
|
|
2828
|
+
const [modalValues, setModalValues] = (0, import_react18.useState)([]);
|
|
2829
|
+
const [selectedOnly, setSelectedOnly] = (0, import_react18.useState)(false);
|
|
2830
|
+
const [query, setQuery] = (0, import_react18.useState)("");
|
|
2831
|
+
const [activeIndex, setActiveIndex] = (0, import_react18.useState)(-1);
|
|
2832
|
+
const [scrollTop, setScrollTop] = (0, import_react18.useState)(0);
|
|
2833
|
+
const deferredQuery = (0, import_react18.useDeferredValue)(query.trim());
|
|
2834
|
+
const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
|
|
2835
|
+
const [currentValue, setCurrentValue] = useControllableState({
|
|
2836
|
+
value,
|
|
2837
|
+
defaultValue: initialValue,
|
|
2838
|
+
onChange: (nextValue) => {
|
|
2839
|
+
if (Array.isArray(nextValue)) {
|
|
2840
|
+
const selectedOptions2 = nextValue.map((selectedValue) => options.find((option) => option.value === selectedValue) ?? (allowInput ? { label: String(selectedValue), value: selectedValue } : void 0)).filter((option) => option !== void 0);
|
|
2841
|
+
onChange?.(nextValue, selectedOptions2);
|
|
2842
|
+
} else {
|
|
2843
|
+
const selectedOption = nextValue === null ? null : options.find((option) => option.value === nextValue) ?? (allowInput ? { label: String(nextValue), value: nextValue } : null);
|
|
2844
|
+
onChange?.(nextValue, selectedOption);
|
|
2845
|
+
}
|
|
2846
|
+
}
|
|
2847
|
+
});
|
|
2848
|
+
const selectedValues = (0, import_react18.useMemo)(() => {
|
|
2849
|
+
if (mode === "multiple") return Array.isArray(currentValue) ? currentValue : currentValue === null ? [] : [currentValue];
|
|
2850
|
+
return Array.isArray(currentValue) ? currentValue.slice(0, 1) : currentValue === null ? [] : [currentValue];
|
|
2851
|
+
}, [currentValue, mode]);
|
|
2852
|
+
const selectedValueSet = (0, import_react18.useMemo)(() => new Set(selectedValues), [selectedValues]);
|
|
2853
|
+
const availableOptions = (0, import_react18.useMemo)(() => {
|
|
2854
|
+
if (!allowInput) return options;
|
|
2855
|
+
const optionValueSet = new Set(options.map((option) => option.value));
|
|
2856
|
+
const selectedCustomOptions = selectedValues.filter((selectedValue) => !optionValueSet.has(selectedValue)).map((selectedValue) => ({ label: String(selectedValue), value: selectedValue }));
|
|
2857
|
+
return selectedCustomOptions.length ? [...selectedCustomOptions, ...options] : options;
|
|
2858
|
+
}, [allowInput, options, selectedValues]);
|
|
2859
|
+
const selectedOptions = (0, import_react18.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
|
|
2860
|
+
const filteredOptions = (0, import_react18.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
|
|
2861
|
+
const inputValue = query.trim();
|
|
2862
|
+
const exactInputOption = inputValue ? availableOptions.find((option) => String(option.value).toLowerCase() === inputValue.toLowerCase() || typeof option.label === "string" && option.label.toLowerCase() === inputValue.toLowerCase()) : void 0;
|
|
2863
|
+
const canSubmitInput = allowInput && Boolean(inputValue) && !exactInputOption;
|
|
2864
|
+
const multiple = mode === "multiple";
|
|
2865
|
+
const hasValue = selectedOptions.length > 0;
|
|
2866
|
+
const virtualEnabled = virtual && filteredOptions.length >= virtualThreshold;
|
|
2867
|
+
const overscan = 3;
|
|
2868
|
+
const visibleCount = Math.ceil(listHeight / optionHeight) + overscan * 2;
|
|
2869
|
+
const virtualStart = virtualEnabled ? Math.max(0, Math.floor(scrollTop / optionHeight) - overscan) : 0;
|
|
2870
|
+
const virtualEnd = virtualEnabled ? Math.min(filteredOptions.length, virtualStart + visibleCount) : filteredOptions.length;
|
|
2871
|
+
const renderedOptions = virtualEnabled ? filteredOptions.slice(virtualStart, virtualEnd) : filteredOptions;
|
|
2872
|
+
const enabledFilteredOptions = filteredOptions.filter((option) => !option.disabled);
|
|
2873
|
+
const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((option) => selectedValueSet.has(option.value));
|
|
2874
|
+
(0, import_react18.useEffect)(() => {
|
|
2875
|
+
if (!open || popupMode === "modal") return void 0;
|
|
2876
|
+
function closeFromOutside(event) {
|
|
2877
|
+
const target = event.target;
|
|
2878
|
+
if (!rootRef.current?.contains(target) && !popupRef.current?.contains(target)) closeDropdown();
|
|
2879
|
+
}
|
|
2880
|
+
document.addEventListener("mousedown", closeFromOutside);
|
|
2881
|
+
return () => document.removeEventListener("mousedown", closeFromOutside);
|
|
2882
|
+
}, [open, popupMode]);
|
|
2883
|
+
(0, import_react18.useEffect)(() => {
|
|
2884
|
+
if (open && (showSearch || allowInput)) searchRef.current?.focus();
|
|
2885
|
+
}, [allowInput, open, showSearch]);
|
|
2886
|
+
(0, import_react18.useEffect)(() => {
|
|
2887
|
+
if (disabled || loading) closeDropdown();
|
|
2888
|
+
}, [disabled, loading]);
|
|
2889
|
+
function firstEnabledIndex() {
|
|
2890
|
+
return filteredOptions.findIndex((option) => !option.disabled);
|
|
2891
|
+
}
|
|
2892
|
+
function closeDropdown() {
|
|
2893
|
+
setOpen(false);
|
|
2894
|
+
setQuery("");
|
|
2895
|
+
setScrollTop(0);
|
|
2896
|
+
}
|
|
2897
|
+
function openDropdown() {
|
|
2898
|
+
if (disabled || loading) return;
|
|
2899
|
+
const selectedIndex = filteredOptions.findIndex((option) => selectedValueSet.has(option.value) && !option.disabled);
|
|
2900
|
+
setActiveIndex(selectedIndex >= 0 ? selectedIndex : firstEnabledIndex());
|
|
2901
|
+
if (popupMode === "modal") {
|
|
2902
|
+
setModalValues([...selectedValues]);
|
|
2903
|
+
setSelectedOnly(false);
|
|
2904
|
+
}
|
|
2905
|
+
setOpen(true);
|
|
2906
|
+
}
|
|
2907
|
+
function keepActiveVisible(index) {
|
|
2908
|
+
if (!virtualEnabled || !listRef.current) return;
|
|
2909
|
+
const optionTop = index * optionHeight;
|
|
2910
|
+
const optionBottom = optionTop + optionHeight;
|
|
2911
|
+
const viewportTop = listRef.current.scrollTop;
|
|
2912
|
+
const viewportBottom = viewportTop + listHeight;
|
|
2913
|
+
const nextScrollTop = optionTop < viewportTop ? optionTop : optionBottom > viewportBottom ? optionBottom - listHeight : viewportTop;
|
|
2914
|
+
if (nextScrollTop !== viewportTop) {
|
|
2915
|
+
listRef.current.scrollTop = nextScrollTop;
|
|
2916
|
+
setScrollTop(nextScrollTop);
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
function moveActive(direction) {
|
|
2920
|
+
if (filteredOptions.length === 0) return;
|
|
2921
|
+
let nextIndex = activeIndex;
|
|
2922
|
+
for (let index = 0; index < filteredOptions.length; index += 1) {
|
|
2923
|
+
nextIndex = (nextIndex + direction + filteredOptions.length) % filteredOptions.length;
|
|
2924
|
+
if (!filteredOptions[nextIndex]?.disabled) {
|
|
2925
|
+
setActiveIndex(nextIndex);
|
|
2926
|
+
keepActiveVisible(nextIndex);
|
|
2927
|
+
return;
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
function selectOption(option) {
|
|
2932
|
+
if (option.disabled) return;
|
|
2933
|
+
if (multiple) {
|
|
2934
|
+
const nextValues = selectedValueSet.has(option.value) ? selectedValues.filter((item) => item !== option.value) : [...selectedValues, option.value];
|
|
2935
|
+
setCurrentValue(nextValues);
|
|
2936
|
+
return;
|
|
2937
|
+
}
|
|
2938
|
+
setCurrentValue(option.value);
|
|
2939
|
+
closeDropdown();
|
|
2940
|
+
}
|
|
2941
|
+
function selectAllFiltered() {
|
|
2942
|
+
if (allFilteredSelected) return;
|
|
2943
|
+
const nextValues = [...selectedValues];
|
|
2944
|
+
const nextValueSet = new Set(nextValues);
|
|
2945
|
+
enabledFilteredOptions.forEach((option) => {
|
|
2946
|
+
if (!nextValueSet.has(option.value)) nextValues.push(option.value);
|
|
2947
|
+
});
|
|
2948
|
+
setCurrentValue(nextValues);
|
|
2949
|
+
}
|
|
2950
|
+
function submitInputValue() {
|
|
2951
|
+
if (!allowInput || !inputValue) return;
|
|
2952
|
+
selectOption(exactInputOption ?? { label: inputValue, value: inputValue });
|
|
2953
|
+
if (multiple) {
|
|
2954
|
+
setQuery("");
|
|
2955
|
+
setActiveIndex(-1);
|
|
2956
|
+
setScrollTop(0);
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2959
|
+
function invertFiltered() {
|
|
2960
|
+
const enabled = new Set(enabledFilteredOptions.map((option) => option.value));
|
|
2961
|
+
setCurrentValue([...selectedValues.filter((value2) => !enabled.has(value2)), ...enabledFilteredOptions.filter((option) => !selectedValueSet.has(option.value)).map((option) => option.value)]);
|
|
2962
|
+
}
|
|
2963
|
+
function clearSelection() {
|
|
2964
|
+
setCurrentValue(multiple ? [] : null);
|
|
2965
|
+
}
|
|
2966
|
+
function handleInteractionKeyDown(event, fromSearch = false) {
|
|
2967
|
+
if (popupMode === "modal" && open) return;
|
|
2968
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
2969
|
+
event.preventDefault();
|
|
2970
|
+
if (!open) openDropdown();
|
|
2971
|
+
else moveActive(event.key === "ArrowDown" ? 1 : -1);
|
|
2972
|
+
} else if (event.key === "Enter" || event.key === " " && !fromSearch) {
|
|
2973
|
+
event.preventDefault();
|
|
2974
|
+
if (!open) openDropdown();
|
|
2975
|
+
else if (activeIndex >= 0 && filteredOptions[activeIndex]) selectOption(filteredOptions[activeIndex]);
|
|
2976
|
+
else if (fromSearch && allowInput) submitInputValue();
|
|
2977
|
+
} else if (event.key === "Escape") {
|
|
2978
|
+
closeDropdown();
|
|
2979
|
+
} else if (event.key === "Home" && open && !fromSearch) {
|
|
2980
|
+
event.preventDefault();
|
|
2981
|
+
const firstIndex = firstEnabledIndex();
|
|
2982
|
+
setActiveIndex(firstIndex);
|
|
2983
|
+
keepActiveVisible(firstIndex);
|
|
2984
|
+
} else if (event.key === "End" && open && !fromSearch) {
|
|
2985
|
+
event.preventDefault();
|
|
2986
|
+
const reversedIndex = [...filteredOptions].reverse().findIndex((option) => !option.disabled);
|
|
2987
|
+
const lastIndex = reversedIndex < 0 ? -1 : filteredOptions.length - 1 - reversedIndex;
|
|
2988
|
+
setActiveIndex(lastIndex);
|
|
2989
|
+
keepActiveVisible(lastIndex);
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
function handleTriggerKeyDown(event) {
|
|
2993
|
+
handleInteractionKeyDown(event);
|
|
2994
|
+
onKeyDown?.(event);
|
|
2995
|
+
}
|
|
2996
|
+
function handleSearchChange(event) {
|
|
2997
|
+
const nextQuery = event.target.value;
|
|
2998
|
+
setQuery(nextQuery);
|
|
2999
|
+
setActiveIndex(-1);
|
|
3000
|
+
setScrollTop(0);
|
|
3001
|
+
if (listRef.current) listRef.current.scrollTop = 0;
|
|
3002
|
+
onSearch?.(nextQuery);
|
|
3003
|
+
}
|
|
3004
|
+
function clearValue(event) {
|
|
3005
|
+
event.stopPropagation();
|
|
3006
|
+
clearSelection();
|
|
3007
|
+
}
|
|
3008
|
+
function handleListScroll(event) {
|
|
3009
|
+
if (virtualEnabled) setScrollTop(event.currentTarget.scrollTop);
|
|
3010
|
+
}
|
|
3011
|
+
function renderOption(option, renderedIndex) {
|
|
3012
|
+
const optionIndex = virtualEnabled ? virtualStart + renderedIndex : renderedIndex;
|
|
3013
|
+
const selected = selectedValueSet.has(option.value);
|
|
3014
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3015
|
+
"div",
|
|
3016
|
+
{
|
|
3017
|
+
id: `${listboxId}-${optionIndex}`,
|
|
3018
|
+
className: `sia-select__option${selected ? " is-selected" : ""}${optionIndex === activeIndex ? " is-active" : ""}${option.disabled ? " is-disabled" : ""}`,
|
|
3019
|
+
role: "option",
|
|
3020
|
+
"aria-selected": selected,
|
|
3021
|
+
"aria-disabled": option.disabled || void 0,
|
|
3022
|
+
style: virtualEnabled ? { position: "absolute", top: optionIndex * optionHeight, right: 0, left: 0, height: optionHeight } : void 0,
|
|
3023
|
+
onMouseEnter: () => !option.disabled && setActiveIndex(optionIndex),
|
|
3024
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
3025
|
+
onClick: () => selectOption(option),
|
|
3026
|
+
children: [
|
|
3027
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "sia-select__option-content", children: [
|
|
3028
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sia-select__option-label", children: option.label }),
|
|
3029
|
+
showValue ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("small", { className: "sia-select__option-value", children: String(option.value) }) : null
|
|
3030
|
+
] }),
|
|
3031
|
+
selected ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "check", size: 15 }) : null
|
|
3032
|
+
]
|
|
3033
|
+
},
|
|
3034
|
+
`${typeof option.value}-${option.value}`
|
|
3035
|
+
);
|
|
3036
|
+
}
|
|
3037
|
+
const modalAvailable = [...availableOptions, ...modalValues.filter((value2) => !availableOptions.some((option) => option.value === value2)).map((value2) => ({ value: value2, label: String(value2) }))];
|
|
3038
|
+
const modalFiltered = deferredQuery ? modalAvailable.filter((option) => filterOption(deferredQuery, option)) : modalAvailable;
|
|
3039
|
+
const modalEnabled = modalFiltered.filter((option) => !option.disabled && (!selectedOnly || modalValues.includes(option.value)));
|
|
3040
|
+
function modalBatch(operation) {
|
|
3041
|
+
const editable = new Set(modalEnabled.map((option) => option.value));
|
|
3042
|
+
setModalValues([...modalValues.filter((value2) => !editable.has(value2)), ...modalEnabled.filter((option) => operation === "all" || operation === "invert" && !modalValues.includes(option.value)).map((option) => option.value)]);
|
|
3043
|
+
}
|
|
3044
|
+
const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: hasValue, active: open });
|
|
3045
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { ref: rootRef, className: `sia-select sia-select--${size} sia-select--${status}${open ? " is-open" : ""}${disabled ? " is-disabled" : ""}${multiple ? " sia-select--multiple" : ""} ${className}`.trim(), children: [
|
|
3046
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3047
|
+
"button",
|
|
3048
|
+
{
|
|
3049
|
+
...props,
|
|
3050
|
+
ref: forwardedRef,
|
|
3051
|
+
className: `sia-select__trigger${floating.className}`,
|
|
3052
|
+
id: selectId,
|
|
3053
|
+
type: "button",
|
|
3054
|
+
role: "combobox",
|
|
3055
|
+
"aria-controls": popupMode === "modal" ? void 0 : listboxId,
|
|
3056
|
+
"aria-expanded": open,
|
|
3057
|
+
"aria-haspopup": popupMode === "modal" ? "dialog" : "listbox",
|
|
3058
|
+
"aria-activedescendant": popupMode === "dropdown" && open && activeIndex >= 0 ? `${listboxId}-${activeIndex}` : void 0,
|
|
3059
|
+
"aria-invalid": status === "error" || void 0,
|
|
3060
|
+
disabled,
|
|
3061
|
+
onClick: () => open ? closeDropdown() : openDropdown(),
|
|
3062
|
+
onKeyDown: handleTriggerKeyDown,
|
|
3063
|
+
children: [
|
|
3064
|
+
multiple && hasValue ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(OverflowTags, { className: "sia-select__tags", tagClassName: "sia-select__tag", restClassName: "sia-select__tag--rest", maxCount: maxTagCount, items: selectedOptions.map((option) => ({ key: `${typeof option.value}-${option.value}`, label: option.label })) }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: `sia-select__value${hasValue ? "" : " is-placeholder"}`, children: selectedOptions[0]?.label ?? placeholder }),
|
|
3065
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sia-select__spinner", "aria-hidden": "true" }) : null,
|
|
3066
|
+
floating.label,
|
|
3067
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { className: "sia-select__arrow", name: "chevron-down", size: 15 })
|
|
3068
|
+
]
|
|
3069
|
+
}
|
|
3070
|
+
),
|
|
3071
|
+
allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
|
|
3072
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", className: "sia-select__dropdown", children: [
|
|
3073
|
+
showSearch || allowInput ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "sia-select__search", children: [
|
|
3074
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "search", size: 15 }),
|
|
3075
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("input", { ref: searchRef, value: query, maxLength: inputMaxLength, onChange: handleSearchChange, onKeyDown: (event) => handleInteractionKeyDown(event, true), placeholder: searchPlaceholder, "aria-label": searchPlaceholder })
|
|
3076
|
+
] }) : null,
|
|
3077
|
+
canSubmitInput ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", className: "sia-select__input-option", onMouseDown: (event) => event.preventDefault(), onClick: submitInputValue, children: [
|
|
3078
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "plus", size: 14 }),
|
|
3079
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { children: [
|
|
3080
|
+
"\u4F7F\u7528\u201C",
|
|
3081
|
+
inputValue,
|
|
3082
|
+
"\u201D"
|
|
3083
|
+
] })
|
|
3084
|
+
] }) : null,
|
|
3085
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3086
|
+
"div",
|
|
3087
|
+
{
|
|
3088
|
+
ref: listRef,
|
|
3089
|
+
id: listboxId,
|
|
3090
|
+
className: "sia-select__list",
|
|
3091
|
+
role: "listbox",
|
|
3092
|
+
"aria-labelledby": selectId,
|
|
3093
|
+
"aria-multiselectable": multiple || void 0,
|
|
3094
|
+
style: { maxHeight: listHeight },
|
|
3095
|
+
onScroll: handleListScroll,
|
|
3096
|
+
children: filteredOptions.length > 0 ? virtualEnabled ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "sia-select__virtual-space", style: { height: filteredOptions.length * optionHeight }, children: renderedOptions.map(renderOption) }) : renderedOptions.map(renderOption) : canSubmitInput ? null : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "sia-select__empty", children: notFoundContent })
|
|
3097
|
+
}
|
|
3098
|
+
),
|
|
3099
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select__actions", children: [
|
|
3100
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { children: [
|
|
3101
|
+
"\u5171 ",
|
|
3102
|
+
filteredOptions.length,
|
|
3103
|
+
" \u6761"
|
|
3104
|
+
] }),
|
|
3105
|
+
multiple && showSelectAll ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
3106
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", disabled: allFilteredSelected || !enabledFilteredOptions.length, onClick: selectAllFiltered, children: "\u5168\u9009" }),
|
|
3107
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", disabled: !enabledFilteredOptions.length, onClick: invertFiltered, children: "\u53CD\u9009" })
|
|
3108
|
+
] }) : null,
|
|
3109
|
+
multiple || allowClear ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", danger: true, disabled: !hasValue, onClick: clearSelection, children: "\u6E05\u7A7A" }) : null
|
|
3110
|
+
] })
|
|
3111
|
+
] }),
|
|
3112
|
+
popupMode === "modal" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3113
|
+
Modal2,
|
|
3114
|
+
{
|
|
3115
|
+
className: "sia-select-modal",
|
|
3116
|
+
open,
|
|
3117
|
+
title: modalConfig?.title ?? placeholder,
|
|
3118
|
+
width: modalConfig?.width ?? 900,
|
|
3119
|
+
onOpenChange: (next) => {
|
|
3120
|
+
if (!next) closeDropdown();
|
|
3121
|
+
},
|
|
3122
|
+
onCancel: closeDropdown,
|
|
3123
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select-modal__footer", children: [
|
|
3124
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { children: modalConfig?.footerExtra }),
|
|
3125
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
|
|
3126
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { onClick: closeDropdown, children: "\u53D6\u6D88" }),
|
|
3127
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "primary", disabled: disabled || loading, onClick: () => {
|
|
3128
|
+
setCurrentValue(multiple ? modalValues : modalValues[0] ?? null);
|
|
3129
|
+
closeDropdown();
|
|
3130
|
+
}, children: "\u786E\u5B9A" })
|
|
3131
|
+
] })
|
|
3132
|
+
] }),
|
|
3133
|
+
children: open ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
3134
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select-modal__heading", children: [
|
|
3135
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { role: "tablist", "aria-label": "\u9009\u9879\u8303\u56F4", children: [
|
|
3136
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { role: "tab", "aria-selected": !selectedOnly, variant: "link", onClick: () => setSelectedOnly(false), children: "\u5168\u90E8" }),
|
|
3137
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Button, { role: "tab", "aria-selected": selectedOnly, variant: "link", onClick: () => setSelectedOnly(true), children: [
|
|
3138
|
+
"\u5DF2\u9009\u9879(",
|
|
3139
|
+
modalValues.length,
|
|
3140
|
+
")"
|
|
3141
|
+
] })
|
|
3142
|
+
] }),
|
|
3143
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3144
|
+
Input,
|
|
3145
|
+
{
|
|
3146
|
+
"aria-label": searchPlaceholder,
|
|
3147
|
+
placeholder: searchPlaceholder,
|
|
3148
|
+
prefix: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "search", size: 14 }),
|
|
3149
|
+
value: query,
|
|
3150
|
+
allowClear: true,
|
|
3151
|
+
onChange: (event) => {
|
|
3152
|
+
setQuery(event.target.value);
|
|
3153
|
+
onSearch?.(event.target.value);
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
)
|
|
3157
|
+
] }),
|
|
3158
|
+
multiple && showSelectAll ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select-modal__actions", children: [
|
|
3159
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3160
|
+
Checkbox2,
|
|
3161
|
+
{
|
|
3162
|
+
checked: modalEnabled.length > 0 && modalEnabled.every((option) => modalValues.includes(option.value)),
|
|
3163
|
+
indeterminate: modalEnabled.some((option) => modalValues.includes(option.value)) && !modalEnabled.every((option) => modalValues.includes(option.value)),
|
|
3164
|
+
disabled: !modalEnabled.length,
|
|
3165
|
+
onChange: (checked) => modalBatch(checked ? "all" : "remove"),
|
|
3166
|
+
children: "\u5168\u9009"
|
|
3167
|
+
}
|
|
3168
|
+
),
|
|
3169
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", disabled: !modalEnabled.length, onClick: () => modalBatch("invert"), children: "\u53CD\u9009" }),
|
|
3170
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", danger: true, disabled: !modalValues.length, onClick: () => setModalValues([]), children: "\u6E05\u7A7A" })
|
|
3171
|
+
] }) : null,
|
|
3172
|
+
allowInput && canSubmitInput ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Button, { variant: "link", onClick: () => {
|
|
3173
|
+
setModalValues(multiple ? [.../* @__PURE__ */ new Set([...modalValues, inputValue])] : [inputValue]);
|
|
3174
|
+
setQuery("");
|
|
3175
|
+
}, children: [
|
|
3176
|
+
"\u4F7F\u7528\u201C",
|
|
3177
|
+
inputValue,
|
|
3178
|
+
"\u201D"
|
|
3179
|
+
] }) : null,
|
|
3180
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3181
|
+
SelectionPanel,
|
|
3182
|
+
{
|
|
3183
|
+
options: modalFiltered,
|
|
3184
|
+
value: modalValues,
|
|
3185
|
+
onChange: setModalValues,
|
|
3186
|
+
multiple,
|
|
3187
|
+
selectedOnly,
|
|
3188
|
+
showValue,
|
|
3189
|
+
showSearch: false,
|
|
3190
|
+
showActions: false,
|
|
3191
|
+
includeUnknownValues: false,
|
|
3192
|
+
columns: modalConfig?.columns ?? 3,
|
|
3193
|
+
maxHeight: modalConfig?.maxHeight ?? 360
|
|
3194
|
+
}
|
|
3195
|
+
)
|
|
3196
|
+
] }) : null
|
|
3197
|
+
}
|
|
3198
|
+
) : null
|
|
3199
|
+
] });
|
|
3200
|
+
});
|
|
3201
|
+
|
|
2608
3202
|
// src/components/Upload.tsx
|
|
2609
|
-
var
|
|
2610
|
-
var
|
|
3203
|
+
var import_react19 = require("react");
|
|
3204
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2611
3205
|
var LIST_IGNORE = /* @__PURE__ */ Symbol("SIA_UPLOAD_LIST_IGNORE");
|
|
2612
3206
|
function UploadRoot({
|
|
2613
3207
|
accept,
|
|
@@ -2629,9 +3223,9 @@ function UploadRoot({
|
|
|
2629
3223
|
onDrop,
|
|
2630
3224
|
...props
|
|
2631
3225
|
}) {
|
|
2632
|
-
const inputRef = (0,
|
|
2633
|
-
const filesRef = (0,
|
|
2634
|
-
const id = (0,
|
|
3226
|
+
const inputRef = (0, import_react19.useRef)(null);
|
|
3227
|
+
const filesRef = (0, import_react19.useRef)(fileList ?? defaultFileList);
|
|
3228
|
+
const id = (0, import_react19.useId)();
|
|
2635
3229
|
const [files, setFiles] = useControllableState({ value: fileList, defaultValue: defaultFileList });
|
|
2636
3230
|
filesRef.current = files;
|
|
2637
3231
|
function emit(file, nextList) {
|
|
@@ -2690,7 +3284,7 @@ function UploadRoot({
|
|
|
2690
3284
|
const next = files.filter((item) => item.uid !== file.uid);
|
|
2691
3285
|
emit({ ...file, status: "ready" }, next);
|
|
2692
3286
|
}
|
|
2693
|
-
return /* @__PURE__ */ (0,
|
|
3287
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
2694
3288
|
"div",
|
|
2695
3289
|
{
|
|
2696
3290
|
className: `sia-upload sia-upload--${listType} ${className}`.trim(),
|
|
@@ -2701,7 +3295,7 @@ function UploadRoot({
|
|
|
2701
3295
|
onDrop: handleDrop,
|
|
2702
3296
|
...props,
|
|
2703
3297
|
children: [
|
|
2704
|
-
/* @__PURE__ */ (0,
|
|
3298
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2705
3299
|
"input",
|
|
2706
3300
|
{
|
|
2707
3301
|
ref: inputRef,
|
|
@@ -2715,245 +3309,29 @@ function UploadRoot({
|
|
|
2715
3309
|
onChange: handleFiles
|
|
2716
3310
|
}
|
|
2717
3311
|
),
|
|
2718
|
-
/* @__PURE__ */ (0,
|
|
2719
|
-
showUploadList && files.length ? /* @__PURE__ */ (0,
|
|
2720
|
-
/* @__PURE__ */ (0,
|
|
2721
|
-
/* @__PURE__ */ (0,
|
|
2722
|
-
file.status === "uploading" ? /* @__PURE__ */ (0,
|
|
2723
|
-
/* @__PURE__ */ (0,
|
|
3312
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "sia-upload__trigger", onClick: () => !disabled && inputRef.current?.click(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "upload", size: 16 }), disabled, children: "\u9009\u62E9\u6587\u4EF6" }) }),
|
|
3313
|
+
showUploadList && files.length ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "sia-upload__list", children: files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: `sia-upload__item sia-upload__item--${file.status ?? "ready"}`, children: [
|
|
3314
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: file.status === "done" ? "circle-check" : "file", size: 16 }),
|
|
3315
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-upload__name", title: file.name, children: file.name }),
|
|
3316
|
+
file.status === "uploading" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-upload__progress", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { width: `${file.percent ?? 0}%` } }) }) : null,
|
|
3317
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", "aria-label": `\u79FB\u9664 ${file.name}`, onClick: () => void remove(file), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "close", size: 14 }) })
|
|
2724
3318
|
] }, file.uid)) }) : null
|
|
2725
3319
|
]
|
|
2726
3320
|
}
|
|
2727
3321
|
);
|
|
2728
3322
|
}
|
|
2729
3323
|
function UploadDragger({ hint = "\u652F\u6301\u5355\u4E2A\u6216\u6279\u91CF\u4E0A\u4F20", children, className = "", ...props }) {
|
|
2730
|
-
return /* @__PURE__ */ (0,
|
|
2731
|
-
/* @__PURE__ */ (0,
|
|
2732
|
-
/* @__PURE__ */ (0,
|
|
2733
|
-
/* @__PURE__ */ (0,
|
|
3324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(UploadRoot, { ...props, className: `sia-upload-dragger ${className}`.trim(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "sia-upload-dragger__content", children: [
|
|
3325
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "upload", size: 28 }),
|
|
3326
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("strong", { children: "\u70B9\u51FB\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u6B64\u533A\u57DF\u4E0A\u4F20" }),
|
|
3327
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: hint })
|
|
2734
3328
|
] }) });
|
|
2735
3329
|
}
|
|
2736
3330
|
var Upload = Object.assign(UploadRoot, { Dragger: UploadDragger, LIST_IGNORE });
|
|
2737
3331
|
|
|
2738
|
-
// src/components/Modal.tsx
|
|
2739
|
-
var import_react17 = require("react");
|
|
2740
|
-
var import_client2 = require("react-dom/client");
|
|
2741
|
-
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2742
|
-
var modalHandles = /* @__PURE__ */ new Set();
|
|
2743
|
-
var MODAL_MOTION_DURATION = 220;
|
|
2744
|
-
var typeIcons = {
|
|
2745
|
-
info: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "info", size: 23 }),
|
|
2746
|
-
success: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "circle-check", size: 23 }),
|
|
2747
|
-
warning: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "warning", size: 23 }),
|
|
2748
|
-
error: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "circle-close", size: 23 }),
|
|
2749
|
-
confirm: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "question", size: 23 })
|
|
2750
|
-
};
|
|
2751
|
-
var ModalRoot = (0, import_react17.forwardRef)(function Modal({
|
|
2752
|
-
open,
|
|
2753
|
-
title,
|
|
2754
|
-
children,
|
|
2755
|
-
footer,
|
|
2756
|
-
type = "default",
|
|
2757
|
-
okText = "\u786E\u5B9A",
|
|
2758
|
-
cancelText = "\u53D6\u6D88",
|
|
2759
|
-
showCancel = type === "default" || type === "confirm",
|
|
2760
|
-
confirmLoading = false,
|
|
2761
|
-
okButtonProps,
|
|
2762
|
-
cancelButtonProps,
|
|
2763
|
-
closable = true,
|
|
2764
|
-
maskClosable = true,
|
|
2765
|
-
keyboard = true,
|
|
2766
|
-
centered = false,
|
|
2767
|
-
width = 520,
|
|
2768
|
-
zIndex = 1e3,
|
|
2769
|
-
getContainer,
|
|
2770
|
-
onOk,
|
|
2771
|
-
onCancel,
|
|
2772
|
-
onOpenChange,
|
|
2773
|
-
afterOpenChange,
|
|
2774
|
-
className = "",
|
|
2775
|
-
style,
|
|
2776
|
-
...props
|
|
2777
|
-
}, forwardedRef) {
|
|
2778
|
-
const localRef = (0, import_react17.useRef)(null);
|
|
2779
|
-
const titleId = (0, import_react17.useId)();
|
|
2780
|
-
const [submitting, setSubmitting] = (0, import_react17.useState)(false);
|
|
2781
|
-
const [rendered, setRendered] = (0, import_react17.useState)(open);
|
|
2782
|
-
const [closing, setClosing] = (0, import_react17.useState)(false);
|
|
2783
|
-
const afterOpenChangeRef = (0, import_react17.useRef)(afterOpenChange);
|
|
2784
|
-
afterOpenChangeRef.current = afterOpenChange;
|
|
2785
|
-
const submitLock = (0, import_react17.useRef)(false);
|
|
2786
|
-
(0, import_react17.useEffect)(() => {
|
|
2787
|
-
if (!open || !rendered) return void 0;
|
|
2788
|
-
const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
|
|
2789
|
-
return () => window.clearTimeout(timer);
|
|
2790
|
-
}, [open, rendered]);
|
|
2791
|
-
(0, import_react17.useEffect)(() => {
|
|
2792
|
-
if (open) {
|
|
2793
|
-
setRendered(true);
|
|
2794
|
-
setClosing(false);
|
|
2795
|
-
return void 0;
|
|
2796
|
-
}
|
|
2797
|
-
if (!rendered) return void 0;
|
|
2798
|
-
setClosing(true);
|
|
2799
|
-
const timer = window.setTimeout(() => {
|
|
2800
|
-
setRendered(false);
|
|
2801
|
-
setClosing(false);
|
|
2802
|
-
afterOpenChangeRef.current?.(false);
|
|
2803
|
-
}, MODAL_MOTION_DURATION);
|
|
2804
|
-
return () => window.clearTimeout(timer);
|
|
2805
|
-
}, [open, rendered]);
|
|
2806
|
-
function setRef(node) {
|
|
2807
|
-
localRef.current = node;
|
|
2808
|
-
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
2809
|
-
else if (forwardedRef) forwardedRef.current = node;
|
|
2810
|
-
}
|
|
2811
|
-
function requestClose() {
|
|
2812
|
-
if (submitting || confirmLoading) return;
|
|
2813
|
-
onCancel?.();
|
|
2814
|
-
onOpenChange?.(false);
|
|
2815
|
-
}
|
|
2816
|
-
async function handleOk() {
|
|
2817
|
-
if (submitLock.current || confirmLoading) return;
|
|
2818
|
-
submitLock.current = true;
|
|
2819
|
-
if (!onOk) {
|
|
2820
|
-
onOpenChange?.(false);
|
|
2821
|
-
submitLock.current = false;
|
|
2822
|
-
return;
|
|
2823
|
-
}
|
|
2824
|
-
try {
|
|
2825
|
-
const result = onOk();
|
|
2826
|
-
if (result instanceof Promise) {
|
|
2827
|
-
setSubmitting(true);
|
|
2828
|
-
const resolved = await result;
|
|
2829
|
-
if (resolved !== false) onOpenChange?.(false);
|
|
2830
|
-
} else if (result !== false) {
|
|
2831
|
-
onOpenChange?.(false);
|
|
2832
|
-
}
|
|
2833
|
-
} catch {
|
|
2834
|
-
return;
|
|
2835
|
-
} finally {
|
|
2836
|
-
submitLock.current = false;
|
|
2837
|
-
setSubmitting(false);
|
|
2838
|
-
}
|
|
2839
|
-
}
|
|
2840
|
-
useOverlayLifecycle(rendered, localRef, requestClose, keyboard);
|
|
2841
|
-
if (!rendered) return null;
|
|
2842
|
-
const mergedStyle = {
|
|
2843
|
-
...style,
|
|
2844
|
-
"--sia-modal-width": typeof width === "number" ? `${width}px` : width
|
|
2845
|
-
};
|
|
2846
|
-
const loading = submitting || confirmLoading;
|
|
2847
|
-
const defaultFooter = /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
2848
|
-
showCancel ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { ...cancelButtonProps, onClick: requestClose, disabled: loading || cancelButtonProps?.disabled, children: cancelText }) : null,
|
|
2849
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { variant: "primary", ...okButtonProps, onClick: handleOk, loading, children: okText })
|
|
2850
|
-
] });
|
|
2851
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(OverlayPortal, { container: getContainer, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2852
|
-
"div",
|
|
2853
|
-
{
|
|
2854
|
-
className: `sia-modal-root${centered ? " sia-modal-root--centered" : ""}`,
|
|
2855
|
-
"data-state": closing ? "closing" : "open",
|
|
2856
|
-
style: { zIndex },
|
|
2857
|
-
onMouseDown: (event) => {
|
|
2858
|
-
if (event.target === event.currentTarget && maskClosable) requestClose();
|
|
2859
|
-
},
|
|
2860
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2861
|
-
"div",
|
|
2862
|
-
{
|
|
2863
|
-
ref: setRef,
|
|
2864
|
-
className: `sia-modal sia-modal--${type} ${className}`.trim(),
|
|
2865
|
-
style: mergedStyle,
|
|
2866
|
-
role: "dialog",
|
|
2867
|
-
"aria-modal": "true",
|
|
2868
|
-
"aria-labelledby": title ? titleId : void 0,
|
|
2869
|
-
tabIndex: -1,
|
|
2870
|
-
...props,
|
|
2871
|
-
children: [
|
|
2872
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sia-modal__header", children: [
|
|
2873
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sia-modal__heading", children: [
|
|
2874
|
-
typeIcons[type] ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-modal__type-icon", "aria-hidden": "true", children: typeIcons[type] }) : null,
|
|
2875
|
-
title ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("strong", { id: titleId, children: title }) : null
|
|
2876
|
-
] }),
|
|
2877
|
-
closable ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "button", className: "sia-modal__close", "aria-label": "\u5173\u95ED\u5BF9\u8BDD\u6846", onClick: requestClose, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "close", size: 17 }) }) : null
|
|
2878
|
-
] }),
|
|
2879
|
-
children !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "sia-modal__body", children }) : null,
|
|
2880
|
-
footer !== null ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "sia-modal__footer", children: footer ?? defaultFooter }) : null
|
|
2881
|
-
]
|
|
2882
|
-
}
|
|
2883
|
-
)
|
|
2884
|
-
}
|
|
2885
|
-
) });
|
|
2886
|
-
});
|
|
2887
|
-
function openModal(config) {
|
|
2888
|
-
if (typeof document === "undefined") return { destroy() {
|
|
2889
|
-
}, update() {
|
|
2890
|
-
} };
|
|
2891
|
-
const container = document.createElement("div");
|
|
2892
|
-
container.className = "sia-modal-api-host";
|
|
2893
|
-
document.body.appendChild(container);
|
|
2894
|
-
const root = (0, import_client2.createRoot)(container);
|
|
2895
|
-
let currentConfig = config;
|
|
2896
|
-
let currentOpen = true;
|
|
2897
|
-
let destroyed = false;
|
|
2898
|
-
let cleanupTimer;
|
|
2899
|
-
function cleanup() {
|
|
2900
|
-
if (destroyed) return;
|
|
2901
|
-
destroyed = true;
|
|
2902
|
-
if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
|
|
2903
|
-
root.unmount();
|
|
2904
|
-
container.remove();
|
|
2905
|
-
modalHandles.delete(handle);
|
|
2906
|
-
}
|
|
2907
|
-
function closeWithMotion() {
|
|
2908
|
-
if (destroyed || !currentOpen) return;
|
|
2909
|
-
currentOpen = false;
|
|
2910
|
-
render();
|
|
2911
|
-
cleanupTimer = window.setTimeout(cleanup, MODAL_MOTION_DURATION);
|
|
2912
|
-
}
|
|
2913
|
-
function render() {
|
|
2914
|
-
root.render(/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
|
|
2915
|
-
currentConfig.onOpenChange?.(nextOpen);
|
|
2916
|
-
if (!nextOpen) closeWithMotion();
|
|
2917
|
-
} }));
|
|
2918
|
-
}
|
|
2919
|
-
const handle = {
|
|
2920
|
-
destroy: closeWithMotion,
|
|
2921
|
-
update(next) {
|
|
2922
|
-
if (destroyed) return;
|
|
2923
|
-
currentConfig = { ...currentConfig, ...next };
|
|
2924
|
-
render();
|
|
2925
|
-
}
|
|
2926
|
-
};
|
|
2927
|
-
modalHandles.add(handle);
|
|
2928
|
-
render();
|
|
2929
|
-
return handle;
|
|
2930
|
-
}
|
|
2931
|
-
function preset(type, defaults = {}) {
|
|
2932
|
-
return (config) => openModal({
|
|
2933
|
-
okText: type === "confirm" ? "\u786E\u5B9A" : "\u77E5\u9053\u4E86",
|
|
2934
|
-
showCancel: type === "confirm",
|
|
2935
|
-
closable: type !== "confirm",
|
|
2936
|
-
maskClosable: type !== "confirm",
|
|
2937
|
-
...defaults,
|
|
2938
|
-
...config,
|
|
2939
|
-
type
|
|
2940
|
-
});
|
|
2941
|
-
}
|
|
2942
|
-
var Modal2 = Object.assign(ModalRoot, {
|
|
2943
|
-
open: openModal,
|
|
2944
|
-
info: preset("info", { title: "\u63D0\u793A" }),
|
|
2945
|
-
success: preset("success", { title: "\u64CD\u4F5C\u6210\u529F" }),
|
|
2946
|
-
warning: preset("warning", { title: "\u8BF7\u6CE8\u610F" }),
|
|
2947
|
-
error: preset("error", { title: "\u64CD\u4F5C\u5931\u8D25" }),
|
|
2948
|
-
confirm: preset("confirm", { title: "\u786E\u8BA4\u64CD\u4F5C" }),
|
|
2949
|
-
destroyAll() {
|
|
2950
|
-
[...modalHandles].forEach((handle) => handle.destroy());
|
|
2951
|
-
}
|
|
2952
|
-
});
|
|
2953
|
-
|
|
2954
3332
|
// src/components/Message.tsx
|
|
2955
3333
|
var import_client3 = require("react-dom/client");
|
|
2956
|
-
var
|
|
3334
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2957
3335
|
var messageSeed = 0;
|
|
2958
3336
|
var messageRoot = null;
|
|
2959
3337
|
var messageContainer = null;
|
|
@@ -2962,11 +3340,11 @@ var defaultDuration = 3;
|
|
|
2962
3340
|
var maxCount = 5;
|
|
2963
3341
|
var messageTimers = /* @__PURE__ */ new Map();
|
|
2964
3342
|
var messageIcons = {
|
|
2965
|
-
info: /* @__PURE__ */ (0,
|
|
2966
|
-
success: /* @__PURE__ */ (0,
|
|
2967
|
-
warning: /* @__PURE__ */ (0,
|
|
2968
|
-
error: /* @__PURE__ */ (0,
|
|
2969
|
-
loading: /* @__PURE__ */ (0,
|
|
3343
|
+
info: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "info", size: 18 }),
|
|
3344
|
+
success: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "circle-check", size: 18 }),
|
|
3345
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "warning", size: 18 }),
|
|
3346
|
+
error: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "circle-close", size: 18 }),
|
|
3347
|
+
loading: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "loader", size: 18, spin: true })
|
|
2970
3348
|
};
|
|
2971
3349
|
function ensureMessageRoot() {
|
|
2972
3350
|
if (typeof document === "undefined") return false;
|
|
@@ -2980,10 +3358,10 @@ function ensureMessageRoot() {
|
|
|
2980
3358
|
}
|
|
2981
3359
|
function renderMessages() {
|
|
2982
3360
|
if (!ensureMessageRoot()) return;
|
|
2983
|
-
messageRoot.render(/* @__PURE__ */ (0,
|
|
2984
|
-
/* @__PURE__ */ (0,
|
|
2985
|
-
/* @__PURE__ */ (0,
|
|
2986
|
-
item.closable ? /* @__PURE__ */ (0,
|
|
3361
|
+
messageRoot.render(/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "sia-message-list", "aria-live": "polite", children: messageItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `sia-message sia-message--${item.type}`, role: item.type === "loading" ? "status" : "alert", children: [
|
|
3362
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sia-message__icon", "aria-hidden": "true", children: messageIcons[item.type] }),
|
|
3363
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sia-message__content", children: item.content }),
|
|
3364
|
+
item.closable ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", className: "sia-message__close", "aria-label": "\u5173\u95ED\u63D0\u793A", onClick: () => closeMessage(item.key), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "close", size: 14 }) }) : null
|
|
2987
3365
|
] }, item.key)) }));
|
|
2988
3366
|
}
|
|
2989
3367
|
function closeMessage(key) {
|
|
@@ -3049,33 +3427,33 @@ var message = {
|
|
|
3049
3427
|
};
|
|
3050
3428
|
|
|
3051
3429
|
// src/components/Breadcrumb.tsx
|
|
3052
|
-
var
|
|
3430
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3053
3431
|
function Breadcrumb({ items, separator = "/", itemRender, className = "", ...props }) {
|
|
3054
|
-
return /* @__PURE__ */ (0,
|
|
3432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("nav", { "aria-label": "\u9762\u5305\u5C51\u5BFC\u822A", ...props, className: `sia-breadcrumb ${className}`.trim(), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ol", { className: "sia-breadcrumb__list", children: items.map((item, index) => {
|
|
3055
3433
|
const current = index === items.length - 1;
|
|
3056
|
-
const content = /* @__PURE__ */ (0,
|
|
3057
|
-
item.icon ? /* @__PURE__ */ (0,
|
|
3058
|
-
/* @__PURE__ */ (0,
|
|
3434
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
3435
|
+
item.icon ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__icon", "aria-hidden": "true", children: item.icon }) : null,
|
|
3436
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__title", children: item.title })
|
|
3059
3437
|
] });
|
|
3060
3438
|
const custom = itemRender?.(item, index, items);
|
|
3061
|
-
const label = item.disabled ? /* @__PURE__ */ (0,
|
|
3062
|
-
return /* @__PURE__ */ (0,
|
|
3063
|
-
/* @__PURE__ */ (0,
|
|
3439
|
+
const label = item.disabled ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__label", "aria-disabled": "true", children: content }) : custom !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__label", children: custom }) : item.href ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "sia-breadcrumb__label", href: item.href, target: item.target, rel: item.target === "_blank" ? "noopener noreferrer" : void 0, onClick: item.onClick, children: content }) : item.onClick ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { className: "sia-breadcrumb__label", variant: "text", onClick: item.onClick, children: content }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__label", children: content });
|
|
3440
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("li", { className: `sia-breadcrumb__item${current ? " is-current" : ""}${item.disabled ? " is-disabled" : ""}`, children: [
|
|
3441
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "sia-breadcrumb__entry", "aria-current": current ? "page" : void 0, children: [
|
|
3064
3442
|
label,
|
|
3065
|
-
item.menu?.items.length ? /* @__PURE__ */ (0,
|
|
3443
|
+
item.menu?.items.length ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Dropdown, { menu: item.menu, trigger: ["click"], disabled: item.disabled, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { className: "sia-breadcrumb__menu-trigger", variant: "text", size: "small", disabled: item.disabled, "aria-label": `\u5C55\u5F00${typeof item.title === "string" ? item.title : "\u5C42\u7EA7"}\u83DC\u5355`, icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Icon, { name: "chevron-down", size: 12 }) }) }) : null
|
|
3066
3444
|
] }),
|
|
3067
|
-
!current ? /* @__PURE__ */ (0,
|
|
3445
|
+
!current ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__separator", "aria-hidden": "true", children: item.separator === void 0 ? separator : item.separator }) : null
|
|
3068
3446
|
] }, item.key ?? index);
|
|
3069
3447
|
}) }) });
|
|
3070
3448
|
}
|
|
3071
3449
|
|
|
3072
3450
|
// src/components/Typography.tsx
|
|
3073
|
-
var
|
|
3451
|
+
var import_react21 = require("react");
|
|
3074
3452
|
|
|
3075
3453
|
// src/components/TextArea.tsx
|
|
3076
|
-
var
|
|
3077
|
-
var
|
|
3078
|
-
var TextArea = (0,
|
|
3454
|
+
var import_react20 = require("react");
|
|
3455
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3456
|
+
var TextArea = (0, import_react20.forwardRef)(function TextArea2({
|
|
3079
3457
|
label,
|
|
3080
3458
|
hint,
|
|
3081
3459
|
status = "default",
|
|
@@ -3091,9 +3469,9 @@ var TextArea = (0, import_react18.forwardRef)(function TextArea2({
|
|
|
3091
3469
|
onChange,
|
|
3092
3470
|
...props
|
|
3093
3471
|
}, ref) {
|
|
3094
|
-
const fallbackId = (0,
|
|
3472
|
+
const fallbackId = (0, import_react20.useId)();
|
|
3095
3473
|
const textAreaId = id ?? fallbackId;
|
|
3096
|
-
const [uncontrolledValue, setUncontrolledValue] = (0,
|
|
3474
|
+
const [uncontrolledValue, setUncontrolledValue] = (0, import_react20.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
|
|
3097
3475
|
const currentText = value !== void 0 ? String(value) : uncontrolledValue;
|
|
3098
3476
|
const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: currentText.length > 0 });
|
|
3099
3477
|
const hintId = `${textAreaId}-hint`;
|
|
@@ -3102,8 +3480,8 @@ var TextArea = (0, import_react18.forwardRef)(function TextArea2({
|
|
|
3102
3480
|
setUncontrolledValue(event.target.value);
|
|
3103
3481
|
onChange?.(event);
|
|
3104
3482
|
}
|
|
3105
|
-
const control = /* @__PURE__ */ (0,
|
|
3106
|
-
/* @__PURE__ */ (0,
|
|
3483
|
+
const control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: `sia-textarea-control sia-textarea-control--${status}${floating.className}${disabled ? " is-disabled" : ""}`, children: [
|
|
3484
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3107
3485
|
"textarea",
|
|
3108
3486
|
{
|
|
3109
3487
|
...props,
|
|
@@ -3121,21 +3499,21 @@ var TextArea = (0, import_react18.forwardRef)(function TextArea2({
|
|
|
3121
3499
|
}
|
|
3122
3500
|
),
|
|
3123
3501
|
floating.label,
|
|
3124
|
-
showCount ? /* @__PURE__ */ (0,
|
|
3502
|
+
showCount ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: `sia-textarea-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
|
|
3125
3503
|
currentText.length,
|
|
3126
3504
|
maxLength !== void 0 ? `/${maxLength}` : null
|
|
3127
3505
|
] }) : null
|
|
3128
3506
|
] });
|
|
3129
|
-
if (!label && !hint) return /* @__PURE__ */ (0,
|
|
3130
|
-
return /* @__PURE__ */ (0,
|
|
3131
|
-
label ? /* @__PURE__ */ (0,
|
|
3507
|
+
if (!label && !hint) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `sia-field ${className}`.trim(), children: control });
|
|
3508
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: `sia-field ${className}`.trim(), children: [
|
|
3509
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { className: "sia-field__label", htmlFor: textAreaId, children: label }) : null,
|
|
3132
3510
|
control,
|
|
3133
|
-
hint ? /* @__PURE__ */ (0,
|
|
3511
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
|
|
3134
3512
|
] });
|
|
3135
3513
|
});
|
|
3136
3514
|
|
|
3137
3515
|
// src/components/Typography.tsx
|
|
3138
|
-
var
|
|
3516
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
3139
3517
|
function TypographyContent({
|
|
3140
3518
|
as: Tag2 = "span",
|
|
3141
3519
|
type,
|
|
@@ -3154,26 +3532,26 @@ function TypographyContent({
|
|
|
3154
3532
|
className = "",
|
|
3155
3533
|
...props
|
|
3156
3534
|
}) {
|
|
3157
|
-
const contentRef = (0,
|
|
3158
|
-
const editRef = (0,
|
|
3159
|
-
const timer = (0,
|
|
3160
|
-
const [localText, setLocalText] = (0,
|
|
3161
|
-
const [draft, setDraft] = (0,
|
|
3162
|
-
const [editing, setEditing] = (0,
|
|
3163
|
-
const [copied, setCopied] = (0,
|
|
3164
|
-
const [copyError, setCopyError] = (0,
|
|
3165
|
-
const [expanded, setExpanded] = (0,
|
|
3166
|
-
const [overflow, setOverflow] = (0,
|
|
3535
|
+
const contentRef = (0, import_react21.useRef)(null);
|
|
3536
|
+
const editRef = (0, import_react21.useRef)(null);
|
|
3537
|
+
const timer = (0, import_react21.useRef)();
|
|
3538
|
+
const [localText, setLocalText] = (0, import_react21.useState)();
|
|
3539
|
+
const [draft, setDraft] = (0, import_react21.useState)("");
|
|
3540
|
+
const [editing, setEditing] = (0, import_react21.useState)(false);
|
|
3541
|
+
const [copied, setCopied] = (0, import_react21.useState)(false);
|
|
3542
|
+
const [copyError, setCopyError] = (0, import_react21.useState)(false);
|
|
3543
|
+
const [expanded, setExpanded] = (0, import_react21.useState)(false);
|
|
3544
|
+
const [overflow, setOverflow] = (0, import_react21.useState)(false);
|
|
3167
3545
|
const editConfig = typeof editable === "object" ? editable : void 0;
|
|
3168
3546
|
const content = editConfig?.text ?? localText ?? children;
|
|
3169
3547
|
const requestedRows = typeof ellipsis === "object" ? ellipsis.rows ?? 1 : 1;
|
|
3170
3548
|
const rows = Number.isFinite(requestedRows) ? Math.max(1, Math.floor(requestedRows)) : 1;
|
|
3171
3549
|
const expandable = typeof ellipsis === "object" && ellipsis.expandable;
|
|
3172
|
-
(0,
|
|
3550
|
+
(0, import_react21.useEffect)(() => {
|
|
3173
3551
|
setLocalText(void 0);
|
|
3174
3552
|
}, [children]);
|
|
3175
|
-
(0,
|
|
3176
|
-
(0,
|
|
3553
|
+
(0, import_react21.useEffect)(() => () => clearTimeout(timer.current), []);
|
|
3554
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
3177
3555
|
const element = contentRef.current;
|
|
3178
3556
|
if (!element || !ellipsis || editing || expanded) return;
|
|
3179
3557
|
const measure = () => setOverflow(element.scrollHeight > element.clientHeight + 1 || element.scrollWidth > element.clientWidth + 1);
|
|
@@ -3204,15 +3582,15 @@ function TypographyContent({
|
|
|
3204
3582
|
requestAnimationFrame(() => editRef.current?.focus());
|
|
3205
3583
|
}
|
|
3206
3584
|
let formatted = content;
|
|
3207
|
-
if (strong) formatted = /* @__PURE__ */ (0,
|
|
3208
|
-
if (italic) formatted = /* @__PURE__ */ (0,
|
|
3209
|
-
if (underline) formatted = /* @__PURE__ */ (0,
|
|
3210
|
-
if (deleted) formatted = /* @__PURE__ */ (0,
|
|
3211
|
-
if (mark) formatted = /* @__PURE__ */ (0,
|
|
3212
|
-
if (code) formatted = /* @__PURE__ */ (0,
|
|
3213
|
-
if (keyboard) formatted = /* @__PURE__ */ (0,
|
|
3214
|
-
return /* @__PURE__ */ (0,
|
|
3215
|
-
/* @__PURE__ */ (0,
|
|
3585
|
+
if (strong) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("strong", { children: formatted });
|
|
3586
|
+
if (italic) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("em", { children: formatted });
|
|
3587
|
+
if (underline) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("u", { children: formatted });
|
|
3588
|
+
if (deleted) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("del", { children: formatted });
|
|
3589
|
+
if (mark) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("mark", { children: formatted });
|
|
3590
|
+
if (code) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("code", { children: formatted });
|
|
3591
|
+
if (keyboard) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("kbd", { children: formatted });
|
|
3592
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Tag2, { ...props, "aria-disabled": disabled || void 0, className: `sia-typography sia-typography--${Tag2}${type ? ` sia-typography--${type}` : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), children: editing ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "sia-typography__editor", children: [
|
|
3593
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3216
3594
|
TextArea,
|
|
3217
3595
|
{
|
|
3218
3596
|
autoFocus: true,
|
|
@@ -3234,32 +3612,32 @@ function TypographyContent({
|
|
|
3234
3612
|
}
|
|
3235
3613
|
}
|
|
3236
3614
|
),
|
|
3237
|
-
/* @__PURE__ */ (0,
|
|
3238
|
-
/* @__PURE__ */ (0,
|
|
3239
|
-
/* @__PURE__ */ (0,
|
|
3615
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "sia-typography__edit-actions", children: [
|
|
3616
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { size: "small", onClick: () => finish(false), children: "\u53D6\u6D88" }),
|
|
3617
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { size: "small", variant: "primary", onClick: () => finish(true), children: "\u4FDD\u5B58" })
|
|
3240
3618
|
] })
|
|
3241
|
-
] }) : /* @__PURE__ */ (0,
|
|
3242
|
-
/* @__PURE__ */ (0,
|
|
3243
|
-
expandable && (overflow || expanded) ? /* @__PURE__ */ (0,
|
|
3244
|
-
editable ? /* @__PURE__ */ (0,
|
|
3619
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
3620
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { ref: contentRef, className: ellipsis && !expanded ? "sia-typography__ellipsis" : void 0, style: ellipsis && !expanded ? { "--sia-typography-rows": rows } : void 0, children: formatted }),
|
|
3621
|
+
expandable && (overflow || expanded) ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { variant: "link", size: "small", className: "sia-typography__action", "aria-expanded": expanded, disabled, onClick: () => setExpanded(!expanded), children: expanded ? "\u6536\u8D77" : "\u5C55\u5F00" }) : null,
|
|
3622
|
+
editable ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { ref: editRef, variant: "text", size: "small", className: "sia-typography__action", "aria-label": "\u7F16\u8F91\u6587\u672C", title: "\u7F16\u8F91", disabled, icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Icon, { name: "edit", size: 14 }), onClick: () => {
|
|
3245
3623
|
setDraft(contentRef.current?.textContent ?? "");
|
|
3246
3624
|
setEditing(true);
|
|
3247
3625
|
} }) : null,
|
|
3248
|
-
copyable ? /* @__PURE__ */ (0,
|
|
3249
|
-
copyError ? /* @__PURE__ */ (0,
|
|
3626
|
+
copyable ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { variant: "text", size: "small", className: "sia-typography__action", "aria-label": copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236\u6587\u672C", title: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236", disabled, icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Icon, { name: copied ? "check" : "copy", size: 14 }), onClick: () => void copy() }) : null,
|
|
3627
|
+
copyError ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { role: "status", className: "sia-typography--danger", children: "\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u6587\u672C\u590D\u5236\u3002" }) : null
|
|
3250
3628
|
] }) });
|
|
3251
3629
|
}
|
|
3252
3630
|
function Title({ level = 1, ...props }) {
|
|
3253
|
-
return /* @__PURE__ */ (0,
|
|
3631
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props, as: `h${level}` });
|
|
3254
3632
|
}
|
|
3255
3633
|
function Text(props) {
|
|
3256
|
-
return /* @__PURE__ */ (0,
|
|
3634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props });
|
|
3257
3635
|
}
|
|
3258
3636
|
function Paragraph(props) {
|
|
3259
|
-
return /* @__PURE__ */ (0,
|
|
3637
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props, as: "p" });
|
|
3260
3638
|
}
|
|
3261
3639
|
function Link({ disabled, className = "", onClick, href, target, rel, ...props }) {
|
|
3262
|
-
return /* @__PURE__ */ (0,
|
|
3640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3263
3641
|
"a",
|
|
3264
3642
|
{
|
|
3265
3643
|
...props,
|
|
@@ -3277,15 +3655,15 @@ function Link({ disabled, className = "", onClick, href, target, rel, ...props }
|
|
|
3277
3655
|
);
|
|
3278
3656
|
}
|
|
3279
3657
|
function TypographyRoot({ className = "", ...props }) {
|
|
3280
|
-
return /* @__PURE__ */ (0,
|
|
3658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ...props, className: `sia-typography ${className}`.trim() });
|
|
3281
3659
|
}
|
|
3282
3660
|
var Typography = Object.assign(TypographyRoot, { Title, Text, Paragraph, Link });
|
|
3283
3661
|
|
|
3284
3662
|
// src/components/FloatButton.tsx
|
|
3285
|
-
var
|
|
3286
|
-
var
|
|
3287
|
-
var GroupShape = (0,
|
|
3288
|
-
var FloatButtonRoot = (0,
|
|
3663
|
+
var import_react22 = require("react");
|
|
3664
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
3665
|
+
var GroupShape = (0, import_react22.createContext)(void 0);
|
|
3666
|
+
var FloatButtonRoot = (0, import_react22.forwardRef)(function FloatButton({
|
|
3289
3667
|
icon,
|
|
3290
3668
|
description,
|
|
3291
3669
|
tooltip,
|
|
@@ -3298,9 +3676,9 @@ var FloatButtonRoot = (0, import_react20.forwardRef)(function FloatButton({
|
|
|
3298
3676
|
children,
|
|
3299
3677
|
...props
|
|
3300
3678
|
}, ref) {
|
|
3301
|
-
const groupShape = (0,
|
|
3679
|
+
const groupShape = (0, import_react22.useContext)(GroupShape);
|
|
3302
3680
|
const label = props["aria-label"] ?? (typeof tooltip === "string" ? tooltip : typeof description === "string" ? description : "\u60AC\u6D6E\u64CD\u4F5C");
|
|
3303
|
-
const button = /* @__PURE__ */ (0,
|
|
3681
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3304
3682
|
"button",
|
|
3305
3683
|
{
|
|
3306
3684
|
...props,
|
|
@@ -3308,13 +3686,13 @@ var FloatButtonRoot = (0, import_react20.forwardRef)(function FloatButton({
|
|
|
3308
3686
|
type: htmlType,
|
|
3309
3687
|
"aria-label": label,
|
|
3310
3688
|
className: `sia-float-button sia-float-button--${groupShape ?? shape} sia-float-button--${type} ${className}`.trim(),
|
|
3311
|
-
children: /* @__PURE__ */ (0,
|
|
3312
|
-
icon !== null ? /* @__PURE__ */ (0,
|
|
3313
|
-
description != null || children != null ? /* @__PURE__ */ (0,
|
|
3689
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Badge, { ...badge, className: "sia-float-button__badge", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "sia-float-button__body", children: [
|
|
3690
|
+
icon !== null ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sia-float-button__icon", children: icon ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { name: "question", size: 20 }) }) : null,
|
|
3691
|
+
description != null || children != null ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sia-float-button__description", children: description ?? children }) : null
|
|
3314
3692
|
] }) })
|
|
3315
3693
|
}
|
|
3316
3694
|
);
|
|
3317
|
-
return /* @__PURE__ */ (0,
|
|
3695
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sia-float-button-root", style, children: tooltip ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Tooltip, { title: tooltip, placement: "left", children: button }) : button });
|
|
3318
3696
|
});
|
|
3319
3697
|
function FloatButtonGroup({
|
|
3320
3698
|
shape = "circle",
|
|
@@ -3336,10 +3714,10 @@ function FloatButtonGroup({
|
|
|
3336
3714
|
...props
|
|
3337
3715
|
}) {
|
|
3338
3716
|
const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
|
|
3339
|
-
const rootRef = (0,
|
|
3340
|
-
const triggerRef = (0,
|
|
3341
|
-
const id = (0,
|
|
3342
|
-
(0,
|
|
3717
|
+
const rootRef = (0, import_react22.useRef)(null);
|
|
3718
|
+
const triggerRef = (0, import_react22.useRef)(null);
|
|
3719
|
+
const id = (0, import_react22.useId)();
|
|
3720
|
+
(0, import_react22.useEffect)(() => {
|
|
3343
3721
|
if (!trigger || !visible) return;
|
|
3344
3722
|
const close = (event) => {
|
|
3345
3723
|
if (!rootRef.current?.contains(event.target)) setVisible(false);
|
|
@@ -3347,7 +3725,7 @@ function FloatButtonGroup({
|
|
|
3347
3725
|
document.addEventListener("pointerdown", close);
|
|
3348
3726
|
return () => document.removeEventListener("pointerdown", close);
|
|
3349
3727
|
}, [trigger, visible, setVisible]);
|
|
3350
|
-
return /* @__PURE__ */ (0,
|
|
3728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GroupShape.Provider, { value: shape, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
3351
3729
|
"div",
|
|
3352
3730
|
{
|
|
3353
3731
|
...props,
|
|
@@ -3374,13 +3752,13 @@ function FloatButtonGroup({
|
|
|
3374
3752
|
}
|
|
3375
3753
|
},
|
|
3376
3754
|
children: [
|
|
3377
|
-
!trigger || visible ? /* @__PURE__ */ (0,
|
|
3378
|
-
trigger ? /* @__PURE__ */ (0,
|
|
3755
|
+
!trigger || visible ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { id, className: "sia-float-button-group__list", children }) : null,
|
|
3756
|
+
trigger ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3379
3757
|
FloatButtonRoot,
|
|
3380
3758
|
{
|
|
3381
3759
|
ref: triggerRef,
|
|
3382
3760
|
type,
|
|
3383
|
-
icon: visible ? closeIcon ?? /* @__PURE__ */ (0,
|
|
3761
|
+
icon: visible ? closeIcon ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { name: "close", size: 20 }) : icon ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { name: "plus", size: 20 }),
|
|
3384
3762
|
tooltip,
|
|
3385
3763
|
"aria-label": visible ? "\u6536\u8D77\u60AC\u6D6E\u83DC\u5355" : "\u5C55\u5F00\u60AC\u6D6E\u83DC\u5355",
|
|
3386
3764
|
"aria-expanded": visible,
|
|
@@ -3393,8 +3771,8 @@ function FloatButtonGroup({
|
|
|
3393
3771
|
) });
|
|
3394
3772
|
}
|
|
3395
3773
|
function FloatButtonBackTop({ target, visibilityHeight = 400, behavior = "smooth", onClick, icon, tooltip = "\u8FD4\u56DE\u9876\u90E8", ...props }) {
|
|
3396
|
-
const [visible, setVisible] = (0,
|
|
3397
|
-
(0,
|
|
3774
|
+
const [visible, setVisible] = (0, import_react22.useState)(false);
|
|
3775
|
+
(0, import_react22.useEffect)(() => {
|
|
3398
3776
|
const element = target ? target() : window;
|
|
3399
3777
|
if (!element) return;
|
|
3400
3778
|
const update = () => setVisible((element === window ? window.scrollY : element.scrollTop) >= visibilityHeight);
|
|
@@ -3403,7 +3781,7 @@ function FloatButtonBackTop({ target, visibilityHeight = 400, behavior = "smooth
|
|
|
3403
3781
|
return () => element.removeEventListener("scroll", update);
|
|
3404
3782
|
}, [target, visibilityHeight]);
|
|
3405
3783
|
if (!visible) return null;
|
|
3406
|
-
return /* @__PURE__ */ (0,
|
|
3784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FloatButtonRoot, { ...props, tooltip, icon: icon ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { name: "arrow-up", size: 20 }), onClick: (event) => {
|
|
3407
3785
|
onClick?.(event);
|
|
3408
3786
|
if (event.defaultPrevented) return;
|
|
3409
3787
|
const element = target ? target() : window;
|