@sia.soul/sia-react-ui 0.1.6 → 0.1.8
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-GiTHMScg.d.cts → Select-CVvF4mcy.d.cts} +14 -0
- package/dist/{Select-rtDktLYY.d.ts → Select-Ce2Irbpt.d.ts} +14 -0
- package/dist/{chunk-PX6BOFTW.js → chunk-F3VH6LJH.js} +2 -4
- package/dist/chunk-FVQON65A.js +1331 -0
- package/dist/{chunk-EJ23MVR6.js → chunk-JJVD2ITI.js} +592 -1
- package/dist/chunk-JMVCKK34.js +1494 -0
- package/dist/{chunk-MJUTLEEE.js → chunk-PXQUIG6V.js} +2 -2
- package/dist/{core-D8BSMfHD.d.ts → core-ByQQ3hq2.d.ts} +1 -1
- package/dist/{core-CBtbeAms.d.cts → core-Dwc_30PN.d.cts} +1 -1
- package/dist/core.cjs +1094 -715
- package/dist/core.css +142 -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 +4123 -3971
- package/dist/index.css +142 -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-CQ1vmze_.d.ts → select-date-range-D-JMfpwD.d.ts} +1 -1
- package/dist/{select-date-range-DRmGaEzP.d.cts → select-date-range-l-xgB959.d.cts} +1 -1
- package/dist/select-date-range.cjs +1092 -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,655 @@ 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
|
+
showActions = mode === "multiple",
|
|
2809
|
+
maxTagCount = 2,
|
|
2810
|
+
virtual = true,
|
|
2811
|
+
virtualThreshold = 100,
|
|
2812
|
+
listHeight = 256,
|
|
2813
|
+
optionHeight = showValue ? 54 : 34,
|
|
2814
|
+
disabled,
|
|
2815
|
+
className = "",
|
|
2816
|
+
id,
|
|
2817
|
+
notFoundContent = "\u6682\u65E0\u6570\u636E",
|
|
2818
|
+
onKeyDown,
|
|
2819
|
+
...props
|
|
2820
|
+
}, forwardedRef) {
|
|
2821
|
+
const fallbackId = (0, import_react18.useId)();
|
|
2822
|
+
const selectId = id ?? fallbackId;
|
|
2823
|
+
const listboxId = `${selectId}-listbox`;
|
|
2824
|
+
const rootRef = (0, import_react18.useRef)(null);
|
|
2825
|
+
const popupRef = (0, import_react18.useRef)(null);
|
|
2826
|
+
const searchRef = (0, import_react18.useRef)(null);
|
|
2827
|
+
const listRef = (0, import_react18.useRef)(null);
|
|
2828
|
+
const [open, setOpen] = (0, import_react18.useState)(false);
|
|
2829
|
+
const [modalValues, setModalValues] = (0, import_react18.useState)([]);
|
|
2830
|
+
const [selectedOnly, setSelectedOnly] = (0, import_react18.useState)(false);
|
|
2831
|
+
const [query, setQuery] = (0, import_react18.useState)("");
|
|
2832
|
+
const [activeIndex, setActiveIndex] = (0, import_react18.useState)(-1);
|
|
2833
|
+
const [scrollTop, setScrollTop] = (0, import_react18.useState)(0);
|
|
2834
|
+
const deferredQuery = (0, import_react18.useDeferredValue)(query.trim());
|
|
2835
|
+
const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
|
|
2836
|
+
const [currentValue, setCurrentValue] = useControllableState({
|
|
2837
|
+
value,
|
|
2838
|
+
defaultValue: initialValue,
|
|
2839
|
+
onChange: (nextValue) => {
|
|
2840
|
+
if (Array.isArray(nextValue)) {
|
|
2841
|
+
const selectedOptions2 = nextValue.map((selectedValue) => options.find((option) => option.value === selectedValue) ?? (allowInput ? { label: String(selectedValue), value: selectedValue } : void 0)).filter((option) => option !== void 0);
|
|
2842
|
+
onChange?.(nextValue, selectedOptions2);
|
|
2843
|
+
} else {
|
|
2844
|
+
const selectedOption = nextValue === null ? null : options.find((option) => option.value === nextValue) ?? (allowInput ? { label: String(nextValue), value: nextValue } : null);
|
|
2845
|
+
onChange?.(nextValue, selectedOption);
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2848
|
+
});
|
|
2849
|
+
const selectedValues = (0, import_react18.useMemo)(() => {
|
|
2850
|
+
if (mode === "multiple") return Array.isArray(currentValue) ? currentValue : currentValue === null ? [] : [currentValue];
|
|
2851
|
+
return Array.isArray(currentValue) ? currentValue.slice(0, 1) : currentValue === null ? [] : [currentValue];
|
|
2852
|
+
}, [currentValue, mode]);
|
|
2853
|
+
const selectedValueSet = (0, import_react18.useMemo)(() => new Set(selectedValues), [selectedValues]);
|
|
2854
|
+
const availableOptions = (0, import_react18.useMemo)(() => {
|
|
2855
|
+
if (!allowInput) return options;
|
|
2856
|
+
const optionValueSet = new Set(options.map((option) => option.value));
|
|
2857
|
+
const selectedCustomOptions = selectedValues.filter((selectedValue) => !optionValueSet.has(selectedValue)).map((selectedValue) => ({ label: String(selectedValue), value: selectedValue }));
|
|
2858
|
+
return selectedCustomOptions.length ? [...selectedCustomOptions, ...options] : options;
|
|
2859
|
+
}, [allowInput, options, selectedValues]);
|
|
2860
|
+
const selectedOptions = (0, import_react18.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
|
|
2861
|
+
const filteredOptions = (0, import_react18.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
|
|
2862
|
+
const inputValue = query.trim();
|
|
2863
|
+
const exactInputOption = inputValue ? availableOptions.find((option) => String(option.value).toLowerCase() === inputValue.toLowerCase() || typeof option.label === "string" && option.label.toLowerCase() === inputValue.toLowerCase()) : void 0;
|
|
2864
|
+
const canSubmitInput = allowInput && Boolean(inputValue) && !exactInputOption;
|
|
2865
|
+
const multiple = mode === "multiple";
|
|
2866
|
+
const hasValue = selectedOptions.length > 0;
|
|
2867
|
+
const virtualEnabled = virtual && filteredOptions.length >= virtualThreshold;
|
|
2868
|
+
const overscan = 3;
|
|
2869
|
+
const visibleCount = Math.ceil(listHeight / optionHeight) + overscan * 2;
|
|
2870
|
+
const virtualStart = virtualEnabled ? Math.max(0, Math.floor(scrollTop / optionHeight) - overscan) : 0;
|
|
2871
|
+
const virtualEnd = virtualEnabled ? Math.min(filteredOptions.length, virtualStart + visibleCount) : filteredOptions.length;
|
|
2872
|
+
const renderedOptions = virtualEnabled ? filteredOptions.slice(virtualStart, virtualEnd) : filteredOptions;
|
|
2873
|
+
const enabledFilteredOptions = filteredOptions.filter((option) => !option.disabled);
|
|
2874
|
+
const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((option) => selectedValueSet.has(option.value));
|
|
2875
|
+
(0, import_react18.useEffect)(() => {
|
|
2876
|
+
if (!open || popupMode === "modal") return void 0;
|
|
2877
|
+
function closeFromOutside(event) {
|
|
2878
|
+
const target = event.target;
|
|
2879
|
+
if (!rootRef.current?.contains(target) && !popupRef.current?.contains(target)) closeDropdown();
|
|
2880
|
+
}
|
|
2881
|
+
document.addEventListener("mousedown", closeFromOutside);
|
|
2882
|
+
return () => document.removeEventListener("mousedown", closeFromOutside);
|
|
2883
|
+
}, [open, popupMode]);
|
|
2884
|
+
(0, import_react18.useEffect)(() => {
|
|
2885
|
+
if (open && (showSearch || allowInput)) searchRef.current?.focus();
|
|
2886
|
+
}, [allowInput, open, showSearch]);
|
|
2887
|
+
(0, import_react18.useEffect)(() => {
|
|
2888
|
+
if (disabled || loading) closeDropdown();
|
|
2889
|
+
}, [disabled, loading]);
|
|
2890
|
+
function firstEnabledIndex() {
|
|
2891
|
+
return filteredOptions.findIndex((option) => !option.disabled);
|
|
2892
|
+
}
|
|
2893
|
+
function closeDropdown() {
|
|
2894
|
+
setOpen(false);
|
|
2895
|
+
setQuery("");
|
|
2896
|
+
setScrollTop(0);
|
|
2897
|
+
}
|
|
2898
|
+
function openDropdown() {
|
|
2899
|
+
if (disabled || loading) return;
|
|
2900
|
+
const selectedIndex = filteredOptions.findIndex((option) => selectedValueSet.has(option.value) && !option.disabled);
|
|
2901
|
+
setActiveIndex(selectedIndex >= 0 ? selectedIndex : firstEnabledIndex());
|
|
2902
|
+
if (popupMode === "modal") {
|
|
2903
|
+
setModalValues([...selectedValues]);
|
|
2904
|
+
setSelectedOnly(false);
|
|
2905
|
+
}
|
|
2906
|
+
setOpen(true);
|
|
2907
|
+
}
|
|
2908
|
+
function keepActiveVisible(index) {
|
|
2909
|
+
if (!virtualEnabled || !listRef.current) return;
|
|
2910
|
+
const optionTop = index * optionHeight;
|
|
2911
|
+
const optionBottom = optionTop + optionHeight;
|
|
2912
|
+
const viewportTop = listRef.current.scrollTop;
|
|
2913
|
+
const viewportBottom = viewportTop + listHeight;
|
|
2914
|
+
const nextScrollTop = optionTop < viewportTop ? optionTop : optionBottom > viewportBottom ? optionBottom - listHeight : viewportTop;
|
|
2915
|
+
if (nextScrollTop !== viewportTop) {
|
|
2916
|
+
listRef.current.scrollTop = nextScrollTop;
|
|
2917
|
+
setScrollTop(nextScrollTop);
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
function moveActive(direction) {
|
|
2921
|
+
if (filteredOptions.length === 0) return;
|
|
2922
|
+
let nextIndex = activeIndex;
|
|
2923
|
+
for (let index = 0; index < filteredOptions.length; index += 1) {
|
|
2924
|
+
nextIndex = (nextIndex + direction + filteredOptions.length) % filteredOptions.length;
|
|
2925
|
+
if (!filteredOptions[nextIndex]?.disabled) {
|
|
2926
|
+
setActiveIndex(nextIndex);
|
|
2927
|
+
keepActiveVisible(nextIndex);
|
|
2928
|
+
return;
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
function selectOption(option) {
|
|
2933
|
+
if (option.disabled) return;
|
|
2934
|
+
if (multiple) {
|
|
2935
|
+
const nextValues = selectedValueSet.has(option.value) ? selectedValues.filter((item) => item !== option.value) : [...selectedValues, option.value];
|
|
2936
|
+
setCurrentValue(nextValues);
|
|
2937
|
+
return;
|
|
2938
|
+
}
|
|
2939
|
+
setCurrentValue(option.value);
|
|
2940
|
+
closeDropdown();
|
|
2941
|
+
}
|
|
2942
|
+
function selectAllFiltered() {
|
|
2943
|
+
if (allFilteredSelected) return;
|
|
2944
|
+
const nextValues = [...selectedValues];
|
|
2945
|
+
const nextValueSet = new Set(nextValues);
|
|
2946
|
+
enabledFilteredOptions.forEach((option) => {
|
|
2947
|
+
if (!nextValueSet.has(option.value)) nextValues.push(option.value);
|
|
2948
|
+
});
|
|
2949
|
+
setCurrentValue(nextValues);
|
|
2950
|
+
}
|
|
2951
|
+
function submitInputValue() {
|
|
2952
|
+
if (!allowInput || !inputValue) return;
|
|
2953
|
+
selectOption(exactInputOption ?? { label: inputValue, value: inputValue });
|
|
2954
|
+
if (multiple) {
|
|
2955
|
+
setQuery("");
|
|
2956
|
+
setActiveIndex(-1);
|
|
2957
|
+
setScrollTop(0);
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2960
|
+
function invertFiltered() {
|
|
2961
|
+
const enabled = new Set(enabledFilteredOptions.map((option) => option.value));
|
|
2962
|
+
setCurrentValue([...selectedValues.filter((value2) => !enabled.has(value2)), ...enabledFilteredOptions.filter((option) => !selectedValueSet.has(option.value)).map((option) => option.value)]);
|
|
2963
|
+
}
|
|
2964
|
+
function clearSelection() {
|
|
2965
|
+
setCurrentValue(multiple ? [] : null);
|
|
2966
|
+
}
|
|
2967
|
+
function handleInteractionKeyDown(event, fromSearch = false) {
|
|
2968
|
+
if (popupMode === "modal" && open) return;
|
|
2969
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
2970
|
+
event.preventDefault();
|
|
2971
|
+
if (!open) openDropdown();
|
|
2972
|
+
else moveActive(event.key === "ArrowDown" ? 1 : -1);
|
|
2973
|
+
} else if (event.key === "Enter" || event.key === " " && !fromSearch) {
|
|
2974
|
+
event.preventDefault();
|
|
2975
|
+
if (!open) openDropdown();
|
|
2976
|
+
else if (activeIndex >= 0 && filteredOptions[activeIndex]) selectOption(filteredOptions[activeIndex]);
|
|
2977
|
+
else if (fromSearch && allowInput) submitInputValue();
|
|
2978
|
+
} else if (event.key === "Escape") {
|
|
2979
|
+
closeDropdown();
|
|
2980
|
+
} else if (event.key === "Home" && open && !fromSearch) {
|
|
2981
|
+
event.preventDefault();
|
|
2982
|
+
const firstIndex = firstEnabledIndex();
|
|
2983
|
+
setActiveIndex(firstIndex);
|
|
2984
|
+
keepActiveVisible(firstIndex);
|
|
2985
|
+
} else if (event.key === "End" && open && !fromSearch) {
|
|
2986
|
+
event.preventDefault();
|
|
2987
|
+
const reversedIndex = [...filteredOptions].reverse().findIndex((option) => !option.disabled);
|
|
2988
|
+
const lastIndex = reversedIndex < 0 ? -1 : filteredOptions.length - 1 - reversedIndex;
|
|
2989
|
+
setActiveIndex(lastIndex);
|
|
2990
|
+
keepActiveVisible(lastIndex);
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
function handleTriggerKeyDown(event) {
|
|
2994
|
+
handleInteractionKeyDown(event);
|
|
2995
|
+
onKeyDown?.(event);
|
|
2996
|
+
}
|
|
2997
|
+
function handleSearchChange(event) {
|
|
2998
|
+
const nextQuery = event.target.value;
|
|
2999
|
+
setQuery(nextQuery);
|
|
3000
|
+
setActiveIndex(-1);
|
|
3001
|
+
setScrollTop(0);
|
|
3002
|
+
if (listRef.current) listRef.current.scrollTop = 0;
|
|
3003
|
+
onSearch?.(nextQuery);
|
|
3004
|
+
}
|
|
3005
|
+
function clearValue(event) {
|
|
3006
|
+
event.stopPropagation();
|
|
3007
|
+
clearSelection();
|
|
3008
|
+
}
|
|
3009
|
+
function handleListScroll(event) {
|
|
3010
|
+
if (virtualEnabled) setScrollTop(event.currentTarget.scrollTop);
|
|
3011
|
+
}
|
|
3012
|
+
function renderOption(option, renderedIndex) {
|
|
3013
|
+
const optionIndex = virtualEnabled ? virtualStart + renderedIndex : renderedIndex;
|
|
3014
|
+
const selected = selectedValueSet.has(option.value);
|
|
3015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3016
|
+
"div",
|
|
3017
|
+
{
|
|
3018
|
+
id: `${listboxId}-${optionIndex}`,
|
|
3019
|
+
className: `sia-select__option${selected ? " is-selected" : ""}${optionIndex === activeIndex ? " is-active" : ""}${option.disabled ? " is-disabled" : ""}`,
|
|
3020
|
+
role: "option",
|
|
3021
|
+
"aria-selected": selected,
|
|
3022
|
+
"aria-disabled": option.disabled || void 0,
|
|
3023
|
+
style: virtualEnabled ? { position: "absolute", top: optionIndex * optionHeight, right: 0, left: 0, height: optionHeight } : void 0,
|
|
3024
|
+
onMouseEnter: () => !option.disabled && setActiveIndex(optionIndex),
|
|
3025
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
3026
|
+
onClick: () => selectOption(option),
|
|
3027
|
+
children: [
|
|
3028
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "sia-select__option-content", children: [
|
|
3029
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sia-select__option-label", children: option.label }),
|
|
3030
|
+
showValue ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("small", { className: "sia-select__option-value", children: String(option.value) }) : null
|
|
3031
|
+
] }),
|
|
3032
|
+
selected ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "check", size: 15 }) : null
|
|
3033
|
+
]
|
|
3034
|
+
},
|
|
3035
|
+
`${typeof option.value}-${option.value}`
|
|
3036
|
+
);
|
|
3037
|
+
}
|
|
3038
|
+
const modalAvailable = [...availableOptions, ...modalValues.filter((value2) => !availableOptions.some((option) => option.value === value2)).map((value2) => ({ value: value2, label: String(value2) }))];
|
|
3039
|
+
const modalFiltered = deferredQuery ? modalAvailable.filter((option) => filterOption(deferredQuery, option)) : modalAvailable;
|
|
3040
|
+
const modalEnabled = modalFiltered.filter((option) => !option.disabled && (!selectedOnly || modalValues.includes(option.value)));
|
|
3041
|
+
function modalBatch(operation) {
|
|
3042
|
+
const editable = new Set(modalEnabled.map((option) => option.value));
|
|
3043
|
+
setModalValues([...modalValues.filter((value2) => !editable.has(value2)), ...modalEnabled.filter((option) => operation === "all" || operation === "invert" && !modalValues.includes(option.value)).map((option) => option.value)]);
|
|
3044
|
+
}
|
|
3045
|
+
const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: hasValue, active: open });
|
|
3046
|
+
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: [
|
|
3047
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3048
|
+
"button",
|
|
3049
|
+
{
|
|
3050
|
+
...props,
|
|
3051
|
+
ref: forwardedRef,
|
|
3052
|
+
className: `sia-select__trigger${floating.className}`,
|
|
3053
|
+
id: selectId,
|
|
3054
|
+
type: "button",
|
|
3055
|
+
role: "combobox",
|
|
3056
|
+
"aria-controls": popupMode === "modal" ? void 0 : listboxId,
|
|
3057
|
+
"aria-expanded": open,
|
|
3058
|
+
"aria-haspopup": popupMode === "modal" ? "dialog" : "listbox",
|
|
3059
|
+
"aria-activedescendant": popupMode === "dropdown" && open && activeIndex >= 0 ? `${listboxId}-${activeIndex}` : void 0,
|
|
3060
|
+
"aria-invalid": status === "error" || void 0,
|
|
3061
|
+
disabled,
|
|
3062
|
+
onClick: () => open ? closeDropdown() : openDropdown(),
|
|
3063
|
+
onKeyDown: handleTriggerKeyDown,
|
|
3064
|
+
children: [
|
|
3065
|
+
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 }),
|
|
3066
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sia-select__spinner", "aria-hidden": "true" }) : null,
|
|
3067
|
+
floating.label,
|
|
3068
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { className: "sia-select__arrow", name: "chevron-down", size: 15 })
|
|
3069
|
+
]
|
|
3070
|
+
}
|
|
3071
|
+
),
|
|
3072
|
+
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,
|
|
3073
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", className: "sia-select__dropdown", children: [
|
|
3074
|
+
showSearch || allowInput ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "sia-select__search", children: [
|
|
3075
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "search", size: 15 }),
|
|
3076
|
+
/* @__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 })
|
|
3077
|
+
] }) : null,
|
|
3078
|
+
canSubmitInput ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", className: "sia-select__input-option", onMouseDown: (event) => event.preventDefault(), onClick: submitInputValue, children: [
|
|
3079
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "plus", size: 14 }),
|
|
3080
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { children: [
|
|
3081
|
+
"\u4F7F\u7528\u201C",
|
|
3082
|
+
inputValue,
|
|
3083
|
+
"\u201D"
|
|
3084
|
+
] })
|
|
3085
|
+
] }) : null,
|
|
3086
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3087
|
+
"div",
|
|
3088
|
+
{
|
|
3089
|
+
ref: listRef,
|
|
3090
|
+
id: listboxId,
|
|
3091
|
+
className: "sia-select__list",
|
|
3092
|
+
role: "listbox",
|
|
3093
|
+
"aria-labelledby": selectId,
|
|
3094
|
+
"aria-multiselectable": multiple || void 0,
|
|
3095
|
+
style: { maxHeight: listHeight },
|
|
3096
|
+
onScroll: handleListScroll,
|
|
3097
|
+
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 })
|
|
3098
|
+
}
|
|
3099
|
+
),
|
|
3100
|
+
showActions ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select__actions", children: [
|
|
3101
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { children: [
|
|
3102
|
+
"\u5171 ",
|
|
3103
|
+
filteredOptions.length,
|
|
3104
|
+
" \u6761"
|
|
3105
|
+
] }),
|
|
3106
|
+
multiple && showSelectAll ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
3107
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", disabled: allFilteredSelected || !enabledFilteredOptions.length, onClick: selectAllFiltered, children: "\u5168\u9009" }),
|
|
3108
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", disabled: !enabledFilteredOptions.length, onClick: invertFiltered, children: "\u53CD\u9009" })
|
|
3109
|
+
] }) : null,
|
|
3110
|
+
multiple || allowClear ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", danger: true, disabled: !hasValue, onClick: clearSelection, children: "\u6E05\u7A7A" }) : null
|
|
3111
|
+
] }) : null
|
|
3112
|
+
] }),
|
|
3113
|
+
popupMode === "modal" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3114
|
+
Modal2,
|
|
3115
|
+
{
|
|
3116
|
+
className: "sia-select-modal",
|
|
3117
|
+
open,
|
|
3118
|
+
title: modalConfig?.title ?? placeholder,
|
|
3119
|
+
width: modalConfig?.width ?? 900,
|
|
3120
|
+
onOpenChange: (next) => {
|
|
3121
|
+
if (!next) closeDropdown();
|
|
3122
|
+
},
|
|
3123
|
+
onCancel: closeDropdown,
|
|
3124
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select-modal__footer", children: [
|
|
3125
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { children: modalConfig?.footerExtra }),
|
|
3126
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
|
|
3127
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { onClick: closeDropdown, children: "\u53D6\u6D88" }),
|
|
3128
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "primary", disabled: disabled || loading, onClick: () => {
|
|
3129
|
+
setCurrentValue(multiple ? modalValues : modalValues[0] ?? null);
|
|
3130
|
+
closeDropdown();
|
|
3131
|
+
}, children: "\u786E\u5B9A" })
|
|
3132
|
+
] })
|
|
3133
|
+
] }),
|
|
3134
|
+
children: open ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
3135
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select-modal__heading", children: [
|
|
3136
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { role: "tablist", "aria-label": "\u9009\u9879\u8303\u56F4", children: [
|
|
3137
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { role: "tab", "aria-selected": !selectedOnly, variant: "link", onClick: () => setSelectedOnly(false), children: "\u5168\u90E8" }),
|
|
3138
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Button, { role: "tab", "aria-selected": selectedOnly, variant: "link", onClick: () => setSelectedOnly(true), children: [
|
|
3139
|
+
"\u5DF2\u9009\u9879(",
|
|
3140
|
+
modalValues.length,
|
|
3141
|
+
")"
|
|
3142
|
+
] })
|
|
3143
|
+
] }),
|
|
3144
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3145
|
+
Input,
|
|
3146
|
+
{
|
|
3147
|
+
"aria-label": searchPlaceholder,
|
|
3148
|
+
placeholder: searchPlaceholder,
|
|
3149
|
+
prefix: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "search", size: 14 }),
|
|
3150
|
+
value: query,
|
|
3151
|
+
allowClear: true,
|
|
3152
|
+
onChange: (event) => {
|
|
3153
|
+
setQuery(event.target.value);
|
|
3154
|
+
onSearch?.(event.target.value);
|
|
3155
|
+
}
|
|
3156
|
+
}
|
|
3157
|
+
)
|
|
3158
|
+
] }),
|
|
3159
|
+
multiple && showSelectAll ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select-modal__actions", children: [
|
|
3160
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3161
|
+
Checkbox2,
|
|
3162
|
+
{
|
|
3163
|
+
checked: modalEnabled.length > 0 && modalEnabled.every((option) => modalValues.includes(option.value)),
|
|
3164
|
+
indeterminate: modalEnabled.some((option) => modalValues.includes(option.value)) && !modalEnabled.every((option) => modalValues.includes(option.value)),
|
|
3165
|
+
disabled: !modalEnabled.length,
|
|
3166
|
+
onChange: (checked) => modalBatch(checked ? "all" : "remove"),
|
|
3167
|
+
children: "\u5168\u9009"
|
|
3168
|
+
}
|
|
3169
|
+
),
|
|
3170
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", disabled: !modalEnabled.length, onClick: () => modalBatch("invert"), children: "\u53CD\u9009" }),
|
|
3171
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", danger: true, disabled: !modalValues.length, onClick: () => setModalValues([]), children: "\u6E05\u7A7A" })
|
|
3172
|
+
] }) : null,
|
|
3173
|
+
allowInput && canSubmitInput ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Button, { variant: "link", onClick: () => {
|
|
3174
|
+
setModalValues(multiple ? [.../* @__PURE__ */ new Set([...modalValues, inputValue])] : [inputValue]);
|
|
3175
|
+
setQuery("");
|
|
3176
|
+
}, children: [
|
|
3177
|
+
"\u4F7F\u7528\u201C",
|
|
3178
|
+
inputValue,
|
|
3179
|
+
"\u201D"
|
|
3180
|
+
] }) : null,
|
|
3181
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3182
|
+
SelectionPanel,
|
|
3183
|
+
{
|
|
3184
|
+
options: modalFiltered,
|
|
3185
|
+
value: modalValues,
|
|
3186
|
+
onChange: setModalValues,
|
|
3187
|
+
multiple,
|
|
3188
|
+
selectedOnly,
|
|
3189
|
+
showValue,
|
|
3190
|
+
showSearch: false,
|
|
3191
|
+
showActions: false,
|
|
3192
|
+
includeUnknownValues: false,
|
|
3193
|
+
columns: modalConfig?.columns ?? 3,
|
|
3194
|
+
maxHeight: modalConfig?.maxHeight ?? 360
|
|
3195
|
+
}
|
|
3196
|
+
)
|
|
3197
|
+
] }) : null
|
|
3198
|
+
}
|
|
3199
|
+
) : null
|
|
3200
|
+
] });
|
|
3201
|
+
});
|
|
3202
|
+
|
|
2608
3203
|
// src/components/Upload.tsx
|
|
2609
|
-
var
|
|
2610
|
-
var
|
|
3204
|
+
var import_react19 = require("react");
|
|
3205
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2611
3206
|
var LIST_IGNORE = /* @__PURE__ */ Symbol("SIA_UPLOAD_LIST_IGNORE");
|
|
2612
3207
|
function UploadRoot({
|
|
2613
3208
|
accept,
|
|
@@ -2629,9 +3224,9 @@ function UploadRoot({
|
|
|
2629
3224
|
onDrop,
|
|
2630
3225
|
...props
|
|
2631
3226
|
}) {
|
|
2632
|
-
const inputRef = (0,
|
|
2633
|
-
const filesRef = (0,
|
|
2634
|
-
const id = (0,
|
|
3227
|
+
const inputRef = (0, import_react19.useRef)(null);
|
|
3228
|
+
const filesRef = (0, import_react19.useRef)(fileList ?? defaultFileList);
|
|
3229
|
+
const id = (0, import_react19.useId)();
|
|
2635
3230
|
const [files, setFiles] = useControllableState({ value: fileList, defaultValue: defaultFileList });
|
|
2636
3231
|
filesRef.current = files;
|
|
2637
3232
|
function emit(file, nextList) {
|
|
@@ -2690,7 +3285,7 @@ function UploadRoot({
|
|
|
2690
3285
|
const next = files.filter((item) => item.uid !== file.uid);
|
|
2691
3286
|
emit({ ...file, status: "ready" }, next);
|
|
2692
3287
|
}
|
|
2693
|
-
return /* @__PURE__ */ (0,
|
|
3288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
2694
3289
|
"div",
|
|
2695
3290
|
{
|
|
2696
3291
|
className: `sia-upload sia-upload--${listType} ${className}`.trim(),
|
|
@@ -2701,7 +3296,7 @@ function UploadRoot({
|
|
|
2701
3296
|
onDrop: handleDrop,
|
|
2702
3297
|
...props,
|
|
2703
3298
|
children: [
|
|
2704
|
-
/* @__PURE__ */ (0,
|
|
3299
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2705
3300
|
"input",
|
|
2706
3301
|
{
|
|
2707
3302
|
ref: inputRef,
|
|
@@ -2715,245 +3310,29 @@ function UploadRoot({
|
|
|
2715
3310
|
onChange: handleFiles
|
|
2716
3311
|
}
|
|
2717
3312
|
),
|
|
2718
|
-
/* @__PURE__ */ (0,
|
|
2719
|
-
showUploadList && files.length ? /* @__PURE__ */ (0,
|
|
2720
|
-
/* @__PURE__ */ (0,
|
|
2721
|
-
/* @__PURE__ */ (0,
|
|
2722
|
-
file.status === "uploading" ? /* @__PURE__ */ (0,
|
|
2723
|
-
/* @__PURE__ */ (0,
|
|
3313
|
+
/* @__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" }) }),
|
|
3314
|
+
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: [
|
|
3315
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: file.status === "done" ? "circle-check" : "file", size: 16 }),
|
|
3316
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-upload__name", title: file.name, children: file.name }),
|
|
3317
|
+
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,
|
|
3318
|
+
/* @__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
3319
|
] }, file.uid)) }) : null
|
|
2725
3320
|
]
|
|
2726
3321
|
}
|
|
2727
3322
|
);
|
|
2728
3323
|
}
|
|
2729
3324
|
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,
|
|
3325
|
+
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: [
|
|
3326
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "upload", size: 28 }),
|
|
3327
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("strong", { children: "\u70B9\u51FB\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u6B64\u533A\u57DF\u4E0A\u4F20" }),
|
|
3328
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: hint })
|
|
2734
3329
|
] }) });
|
|
2735
3330
|
}
|
|
2736
3331
|
var Upload = Object.assign(UploadRoot, { Dragger: UploadDragger, LIST_IGNORE });
|
|
2737
3332
|
|
|
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
3333
|
// src/components/Message.tsx
|
|
2955
3334
|
var import_client3 = require("react-dom/client");
|
|
2956
|
-
var
|
|
3335
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2957
3336
|
var messageSeed = 0;
|
|
2958
3337
|
var messageRoot = null;
|
|
2959
3338
|
var messageContainer = null;
|
|
@@ -2962,11 +3341,11 @@ var defaultDuration = 3;
|
|
|
2962
3341
|
var maxCount = 5;
|
|
2963
3342
|
var messageTimers = /* @__PURE__ */ new Map();
|
|
2964
3343
|
var messageIcons = {
|
|
2965
|
-
info: /* @__PURE__ */ (0,
|
|
2966
|
-
success: /* @__PURE__ */ (0,
|
|
2967
|
-
warning: /* @__PURE__ */ (0,
|
|
2968
|
-
error: /* @__PURE__ */ (0,
|
|
2969
|
-
loading: /* @__PURE__ */ (0,
|
|
3344
|
+
info: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "info", size: 18 }),
|
|
3345
|
+
success: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "circle-check", size: 18 }),
|
|
3346
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "warning", size: 18 }),
|
|
3347
|
+
error: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "circle-close", size: 18 }),
|
|
3348
|
+
loading: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "loader", size: 18, spin: true })
|
|
2970
3349
|
};
|
|
2971
3350
|
function ensureMessageRoot() {
|
|
2972
3351
|
if (typeof document === "undefined") return false;
|
|
@@ -2980,10 +3359,10 @@ function ensureMessageRoot() {
|
|
|
2980
3359
|
}
|
|
2981
3360
|
function renderMessages() {
|
|
2982
3361
|
if (!ensureMessageRoot()) return;
|
|
2983
|
-
messageRoot.render(/* @__PURE__ */ (0,
|
|
2984
|
-
/* @__PURE__ */ (0,
|
|
2985
|
-
/* @__PURE__ */ (0,
|
|
2986
|
-
item.closable ? /* @__PURE__ */ (0,
|
|
3362
|
+
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: [
|
|
3363
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sia-message__icon", "aria-hidden": "true", children: messageIcons[item.type] }),
|
|
3364
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sia-message__content", children: item.content }),
|
|
3365
|
+
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
3366
|
] }, item.key)) }));
|
|
2988
3367
|
}
|
|
2989
3368
|
function closeMessage(key) {
|
|
@@ -3049,33 +3428,33 @@ var message = {
|
|
|
3049
3428
|
};
|
|
3050
3429
|
|
|
3051
3430
|
// src/components/Breadcrumb.tsx
|
|
3052
|
-
var
|
|
3431
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3053
3432
|
function Breadcrumb({ items, separator = "/", itemRender, className = "", ...props }) {
|
|
3054
|
-
return /* @__PURE__ */ (0,
|
|
3433
|
+
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
3434
|
const current = index === items.length - 1;
|
|
3056
|
-
const content = /* @__PURE__ */ (0,
|
|
3057
|
-
item.icon ? /* @__PURE__ */ (0,
|
|
3058
|
-
/* @__PURE__ */ (0,
|
|
3435
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
3436
|
+
item.icon ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__icon", "aria-hidden": "true", children: item.icon }) : null,
|
|
3437
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__title", children: item.title })
|
|
3059
3438
|
] });
|
|
3060
3439
|
const custom = itemRender?.(item, index, items);
|
|
3061
|
-
const label = item.disabled ? /* @__PURE__ */ (0,
|
|
3062
|
-
return /* @__PURE__ */ (0,
|
|
3063
|
-
/* @__PURE__ */ (0,
|
|
3440
|
+
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 });
|
|
3441
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("li", { className: `sia-breadcrumb__item${current ? " is-current" : ""}${item.disabled ? " is-disabled" : ""}`, children: [
|
|
3442
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "sia-breadcrumb__entry", "aria-current": current ? "page" : void 0, children: [
|
|
3064
3443
|
label,
|
|
3065
|
-
item.menu?.items.length ? /* @__PURE__ */ (0,
|
|
3444
|
+
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
3445
|
] }),
|
|
3067
|
-
!current ? /* @__PURE__ */ (0,
|
|
3446
|
+
!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
3447
|
] }, item.key ?? index);
|
|
3069
3448
|
}) }) });
|
|
3070
3449
|
}
|
|
3071
3450
|
|
|
3072
3451
|
// src/components/Typography.tsx
|
|
3073
|
-
var
|
|
3452
|
+
var import_react21 = require("react");
|
|
3074
3453
|
|
|
3075
3454
|
// src/components/TextArea.tsx
|
|
3076
|
-
var
|
|
3077
|
-
var
|
|
3078
|
-
var TextArea = (0,
|
|
3455
|
+
var import_react20 = require("react");
|
|
3456
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3457
|
+
var TextArea = (0, import_react20.forwardRef)(function TextArea2({
|
|
3079
3458
|
label,
|
|
3080
3459
|
hint,
|
|
3081
3460
|
status = "default",
|
|
@@ -3091,9 +3470,9 @@ var TextArea = (0, import_react18.forwardRef)(function TextArea2({
|
|
|
3091
3470
|
onChange,
|
|
3092
3471
|
...props
|
|
3093
3472
|
}, ref) {
|
|
3094
|
-
const fallbackId = (0,
|
|
3473
|
+
const fallbackId = (0, import_react20.useId)();
|
|
3095
3474
|
const textAreaId = id ?? fallbackId;
|
|
3096
|
-
const [uncontrolledValue, setUncontrolledValue] = (0,
|
|
3475
|
+
const [uncontrolledValue, setUncontrolledValue] = (0, import_react20.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
|
|
3097
3476
|
const currentText = value !== void 0 ? String(value) : uncontrolledValue;
|
|
3098
3477
|
const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: currentText.length > 0 });
|
|
3099
3478
|
const hintId = `${textAreaId}-hint`;
|
|
@@ -3102,8 +3481,8 @@ var TextArea = (0, import_react18.forwardRef)(function TextArea2({
|
|
|
3102
3481
|
setUncontrolledValue(event.target.value);
|
|
3103
3482
|
onChange?.(event);
|
|
3104
3483
|
}
|
|
3105
|
-
const control = /* @__PURE__ */ (0,
|
|
3106
|
-
/* @__PURE__ */ (0,
|
|
3484
|
+
const control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: `sia-textarea-control sia-textarea-control--${status}${floating.className}${disabled ? " is-disabled" : ""}`, children: [
|
|
3485
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3107
3486
|
"textarea",
|
|
3108
3487
|
{
|
|
3109
3488
|
...props,
|
|
@@ -3121,21 +3500,21 @@ var TextArea = (0, import_react18.forwardRef)(function TextArea2({
|
|
|
3121
3500
|
}
|
|
3122
3501
|
),
|
|
3123
3502
|
floating.label,
|
|
3124
|
-
showCount ? /* @__PURE__ */ (0,
|
|
3503
|
+
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
3504
|
currentText.length,
|
|
3126
3505
|
maxLength !== void 0 ? `/${maxLength}` : null
|
|
3127
3506
|
] }) : null
|
|
3128
3507
|
] });
|
|
3129
|
-
if (!label && !hint) return /* @__PURE__ */ (0,
|
|
3130
|
-
return /* @__PURE__ */ (0,
|
|
3131
|
-
label ? /* @__PURE__ */ (0,
|
|
3508
|
+
if (!label && !hint) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `sia-field ${className}`.trim(), children: control });
|
|
3509
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: `sia-field ${className}`.trim(), children: [
|
|
3510
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { className: "sia-field__label", htmlFor: textAreaId, children: label }) : null,
|
|
3132
3511
|
control,
|
|
3133
|
-
hint ? /* @__PURE__ */ (0,
|
|
3512
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
|
|
3134
3513
|
] });
|
|
3135
3514
|
});
|
|
3136
3515
|
|
|
3137
3516
|
// src/components/Typography.tsx
|
|
3138
|
-
var
|
|
3517
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
3139
3518
|
function TypographyContent({
|
|
3140
3519
|
as: Tag2 = "span",
|
|
3141
3520
|
type,
|
|
@@ -3154,26 +3533,26 @@ function TypographyContent({
|
|
|
3154
3533
|
className = "",
|
|
3155
3534
|
...props
|
|
3156
3535
|
}) {
|
|
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,
|
|
3536
|
+
const contentRef = (0, import_react21.useRef)(null);
|
|
3537
|
+
const editRef = (0, import_react21.useRef)(null);
|
|
3538
|
+
const timer = (0, import_react21.useRef)();
|
|
3539
|
+
const [localText, setLocalText] = (0, import_react21.useState)();
|
|
3540
|
+
const [draft, setDraft] = (0, import_react21.useState)("");
|
|
3541
|
+
const [editing, setEditing] = (0, import_react21.useState)(false);
|
|
3542
|
+
const [copied, setCopied] = (0, import_react21.useState)(false);
|
|
3543
|
+
const [copyError, setCopyError] = (0, import_react21.useState)(false);
|
|
3544
|
+
const [expanded, setExpanded] = (0, import_react21.useState)(false);
|
|
3545
|
+
const [overflow, setOverflow] = (0, import_react21.useState)(false);
|
|
3167
3546
|
const editConfig = typeof editable === "object" ? editable : void 0;
|
|
3168
3547
|
const content = editConfig?.text ?? localText ?? children;
|
|
3169
3548
|
const requestedRows = typeof ellipsis === "object" ? ellipsis.rows ?? 1 : 1;
|
|
3170
3549
|
const rows = Number.isFinite(requestedRows) ? Math.max(1, Math.floor(requestedRows)) : 1;
|
|
3171
3550
|
const expandable = typeof ellipsis === "object" && ellipsis.expandable;
|
|
3172
|
-
(0,
|
|
3551
|
+
(0, import_react21.useEffect)(() => {
|
|
3173
3552
|
setLocalText(void 0);
|
|
3174
3553
|
}, [children]);
|
|
3175
|
-
(0,
|
|
3176
|
-
(0,
|
|
3554
|
+
(0, import_react21.useEffect)(() => () => clearTimeout(timer.current), []);
|
|
3555
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
3177
3556
|
const element = contentRef.current;
|
|
3178
3557
|
if (!element || !ellipsis || editing || expanded) return;
|
|
3179
3558
|
const measure = () => setOverflow(element.scrollHeight > element.clientHeight + 1 || element.scrollWidth > element.clientWidth + 1);
|
|
@@ -3204,15 +3583,15 @@ function TypographyContent({
|
|
|
3204
3583
|
requestAnimationFrame(() => editRef.current?.focus());
|
|
3205
3584
|
}
|
|
3206
3585
|
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,
|
|
3586
|
+
if (strong) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("strong", { children: formatted });
|
|
3587
|
+
if (italic) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("em", { children: formatted });
|
|
3588
|
+
if (underline) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("u", { children: formatted });
|
|
3589
|
+
if (deleted) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("del", { children: formatted });
|
|
3590
|
+
if (mark) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("mark", { children: formatted });
|
|
3591
|
+
if (code) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("code", { children: formatted });
|
|
3592
|
+
if (keyboard) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("kbd", { children: formatted });
|
|
3593
|
+
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: [
|
|
3594
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3216
3595
|
TextArea,
|
|
3217
3596
|
{
|
|
3218
3597
|
autoFocus: true,
|
|
@@ -3234,32 +3613,32 @@ function TypographyContent({
|
|
|
3234
3613
|
}
|
|
3235
3614
|
}
|
|
3236
3615
|
),
|
|
3237
|
-
/* @__PURE__ */ (0,
|
|
3238
|
-
/* @__PURE__ */ (0,
|
|
3239
|
-
/* @__PURE__ */ (0,
|
|
3616
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "sia-typography__edit-actions", children: [
|
|
3617
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { size: "small", onClick: () => finish(false), children: "\u53D6\u6D88" }),
|
|
3618
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { size: "small", variant: "primary", onClick: () => finish(true), children: "\u4FDD\u5B58" })
|
|
3240
3619
|
] })
|
|
3241
|
-
] }) : /* @__PURE__ */ (0,
|
|
3242
|
-
/* @__PURE__ */ (0,
|
|
3243
|
-
expandable && (overflow || expanded) ? /* @__PURE__ */ (0,
|
|
3244
|
-
editable ? /* @__PURE__ */ (0,
|
|
3620
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
3621
|
+
/* @__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 }),
|
|
3622
|
+
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,
|
|
3623
|
+
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
3624
|
setDraft(contentRef.current?.textContent ?? "");
|
|
3246
3625
|
setEditing(true);
|
|
3247
3626
|
} }) : null,
|
|
3248
|
-
copyable ? /* @__PURE__ */ (0,
|
|
3249
|
-
copyError ? /* @__PURE__ */ (0,
|
|
3627
|
+
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,
|
|
3628
|
+
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
3629
|
] }) });
|
|
3251
3630
|
}
|
|
3252
3631
|
function Title({ level = 1, ...props }) {
|
|
3253
|
-
return /* @__PURE__ */ (0,
|
|
3632
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props, as: `h${level}` });
|
|
3254
3633
|
}
|
|
3255
3634
|
function Text(props) {
|
|
3256
|
-
return /* @__PURE__ */ (0,
|
|
3635
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props });
|
|
3257
3636
|
}
|
|
3258
3637
|
function Paragraph(props) {
|
|
3259
|
-
return /* @__PURE__ */ (0,
|
|
3638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props, as: "p" });
|
|
3260
3639
|
}
|
|
3261
3640
|
function Link({ disabled, className = "", onClick, href, target, rel, ...props }) {
|
|
3262
|
-
return /* @__PURE__ */ (0,
|
|
3641
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3263
3642
|
"a",
|
|
3264
3643
|
{
|
|
3265
3644
|
...props,
|
|
@@ -3277,15 +3656,15 @@ function Link({ disabled, className = "", onClick, href, target, rel, ...props }
|
|
|
3277
3656
|
);
|
|
3278
3657
|
}
|
|
3279
3658
|
function TypographyRoot({ className = "", ...props }) {
|
|
3280
|
-
return /* @__PURE__ */ (0,
|
|
3659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ...props, className: `sia-typography ${className}`.trim() });
|
|
3281
3660
|
}
|
|
3282
3661
|
var Typography = Object.assign(TypographyRoot, { Title, Text, Paragraph, Link });
|
|
3283
3662
|
|
|
3284
3663
|
// src/components/FloatButton.tsx
|
|
3285
|
-
var
|
|
3286
|
-
var
|
|
3287
|
-
var GroupShape = (0,
|
|
3288
|
-
var FloatButtonRoot = (0,
|
|
3664
|
+
var import_react22 = require("react");
|
|
3665
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
3666
|
+
var GroupShape = (0, import_react22.createContext)(void 0);
|
|
3667
|
+
var FloatButtonRoot = (0, import_react22.forwardRef)(function FloatButton({
|
|
3289
3668
|
icon,
|
|
3290
3669
|
description,
|
|
3291
3670
|
tooltip,
|
|
@@ -3298,9 +3677,9 @@ var FloatButtonRoot = (0, import_react20.forwardRef)(function FloatButton({
|
|
|
3298
3677
|
children,
|
|
3299
3678
|
...props
|
|
3300
3679
|
}, ref) {
|
|
3301
|
-
const groupShape = (0,
|
|
3680
|
+
const groupShape = (0, import_react22.useContext)(GroupShape);
|
|
3302
3681
|
const label = props["aria-label"] ?? (typeof tooltip === "string" ? tooltip : typeof description === "string" ? description : "\u60AC\u6D6E\u64CD\u4F5C");
|
|
3303
|
-
const button = /* @__PURE__ */ (0,
|
|
3682
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3304
3683
|
"button",
|
|
3305
3684
|
{
|
|
3306
3685
|
...props,
|
|
@@ -3308,13 +3687,13 @@ var FloatButtonRoot = (0, import_react20.forwardRef)(function FloatButton({
|
|
|
3308
3687
|
type: htmlType,
|
|
3309
3688
|
"aria-label": label,
|
|
3310
3689
|
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,
|
|
3690
|
+
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: [
|
|
3691
|
+
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,
|
|
3692
|
+
description != null || children != null ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sia-float-button__description", children: description ?? children }) : null
|
|
3314
3693
|
] }) })
|
|
3315
3694
|
}
|
|
3316
3695
|
);
|
|
3317
|
-
return /* @__PURE__ */ (0,
|
|
3696
|
+
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
3697
|
});
|
|
3319
3698
|
function FloatButtonGroup({
|
|
3320
3699
|
shape = "circle",
|
|
@@ -3336,10 +3715,10 @@ function FloatButtonGroup({
|
|
|
3336
3715
|
...props
|
|
3337
3716
|
}) {
|
|
3338
3717
|
const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
|
|
3339
|
-
const rootRef = (0,
|
|
3340
|
-
const triggerRef = (0,
|
|
3341
|
-
const id = (0,
|
|
3342
|
-
(0,
|
|
3718
|
+
const rootRef = (0, import_react22.useRef)(null);
|
|
3719
|
+
const triggerRef = (0, import_react22.useRef)(null);
|
|
3720
|
+
const id = (0, import_react22.useId)();
|
|
3721
|
+
(0, import_react22.useEffect)(() => {
|
|
3343
3722
|
if (!trigger || !visible) return;
|
|
3344
3723
|
const close = (event) => {
|
|
3345
3724
|
if (!rootRef.current?.contains(event.target)) setVisible(false);
|
|
@@ -3347,7 +3726,7 @@ function FloatButtonGroup({
|
|
|
3347
3726
|
document.addEventListener("pointerdown", close);
|
|
3348
3727
|
return () => document.removeEventListener("pointerdown", close);
|
|
3349
3728
|
}, [trigger, visible, setVisible]);
|
|
3350
|
-
return /* @__PURE__ */ (0,
|
|
3729
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GroupShape.Provider, { value: shape, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
3351
3730
|
"div",
|
|
3352
3731
|
{
|
|
3353
3732
|
...props,
|
|
@@ -3374,13 +3753,13 @@ function FloatButtonGroup({
|
|
|
3374
3753
|
}
|
|
3375
3754
|
},
|
|
3376
3755
|
children: [
|
|
3377
|
-
!trigger || visible ? /* @__PURE__ */ (0,
|
|
3378
|
-
trigger ? /* @__PURE__ */ (0,
|
|
3756
|
+
!trigger || visible ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { id, className: "sia-float-button-group__list", children }) : null,
|
|
3757
|
+
trigger ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3379
3758
|
FloatButtonRoot,
|
|
3380
3759
|
{
|
|
3381
3760
|
ref: triggerRef,
|
|
3382
3761
|
type,
|
|
3383
|
-
icon: visible ? closeIcon ?? /* @__PURE__ */ (0,
|
|
3762
|
+
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
3763
|
tooltip,
|
|
3385
3764
|
"aria-label": visible ? "\u6536\u8D77\u60AC\u6D6E\u83DC\u5355" : "\u5C55\u5F00\u60AC\u6D6E\u83DC\u5355",
|
|
3386
3765
|
"aria-expanded": visible,
|
|
@@ -3393,8 +3772,8 @@ function FloatButtonGroup({
|
|
|
3393
3772
|
) });
|
|
3394
3773
|
}
|
|
3395
3774
|
function FloatButtonBackTop({ target, visibilityHeight = 400, behavior = "smooth", onClick, icon, tooltip = "\u8FD4\u56DE\u9876\u90E8", ...props }) {
|
|
3396
|
-
const [visible, setVisible] = (0,
|
|
3397
|
-
(0,
|
|
3775
|
+
const [visible, setVisible] = (0, import_react22.useState)(false);
|
|
3776
|
+
(0, import_react22.useEffect)(() => {
|
|
3398
3777
|
const element = target ? target() : window;
|
|
3399
3778
|
if (!element) return;
|
|
3400
3779
|
const update = () => setVisible((element === window ? window.scrollY : element.scrollTop) >= visibilityHeight);
|
|
@@ -3403,7 +3782,7 @@ function FloatButtonBackTop({ target, visibilityHeight = 400, behavior = "smooth
|
|
|
3403
3782
|
return () => element.removeEventListener("scroll", update);
|
|
3404
3783
|
}, [target, visibilityHeight]);
|
|
3405
3784
|
if (!visible) return null;
|
|
3406
|
-
return /* @__PURE__ */ (0,
|
|
3785
|
+
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
3786
|
onClick?.(event);
|
|
3408
3787
|
if (event.defaultPrevented) return;
|
|
3409
3788
|
const element = target ? target() : window;
|