@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/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: collapsed ? void 0 : 12 + level * props.inlineIndent },
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 import_react10 = require("react");
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 import_react9 = require("react");
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, import_react9.useRef)(null);
1817
- const overlayRef = (0, import_react9.useRef)(null);
1818
- const enterTimer = (0, import_react9.useRef)();
1819
- const leaveTimer = (0, import_react9.useRef)();
1820
- const contentId = (0, import_react9.useId)();
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, import_react9.useState)();
1824
- const setVisibleRef = (0, import_react9.useRef)(setVisible);
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, import_react9.useRef)();
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, import_react9.useEffect)(() => {
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, import_react9.useLayoutEffect)(() => {
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, import_react9.useEffect)(() => () => {
1958
+ (0, import_react10.useEffect)(() => () => {
1885
1959
  clearTimers();
1886
1960
  if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
1887
1961
  }, []);
1888
- const child = (0, import_react9.cloneElement)(children, {
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, import_jsx_runtime10.jsxs)(
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, import_jsx_runtime10.jsx)("span", { className: "sia-floating__arrow" }) : null
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, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1938
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { ref: rootRef, className: `sia-floating ${className}`.trim(), children: child }),
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, import_jsx_runtime10.jsx)(Floating, { ...props, content: props.title });
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 import_jsx_runtime11 = require("react/jsx-runtime");
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, import_jsx_runtime11.jsx)(Icon, { name: "close" }) : resolved === "success" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "check" }) : `${safe}%`);
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, import_jsx_runtime11.jsxs)("div", { className: `sia-progress sia-progress--${type} sia-progress--${resolved} ${className}`.trim(), style: { width, height: width, ...style }, ...props, children: [
1975
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { viewBox: "0 0 100 100", role: "progressbar", "aria-valuenow": safe, children: [
1976
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { className: "sia-progress__trail", cx: "50", cy: "50", r: radius, style: { stroke: trailColor } }),
1977
- /* @__PURE__ */ (0, import_jsx_runtime11.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 } })
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, import_jsx_runtime11.jsx)("span", { className: "sia-progress__text", children: label }) : null
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, import_jsx_runtime11.jsxs)("div", { className: `sia-progress sia-progress--line sia-progress--${resolved} ${className}`.trim(), style, ...props, children: [
1984
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "sia-progress__outer", style: { height, backgroundColor: trailColor }, children: steps ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "sia-progress__steps", children: Array.from({ length: steps }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1985
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sia-progress__bar", style: { width: `${safe}%`, background } }),
1986
- success?.percent ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sia-progress__success", style: { width: `${success.percent}%`, background: success.strokeColor } }) : null
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, import_jsx_runtime11.jsx)("span", { className: "sia-progress__info", children: label }) : null
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 import_react12 = require("react");
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 import_react11 = require("react");
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, import_react11.useRef)(/* @__PURE__ */ Symbol("sia-overlay"));
2020
- const closeRef = (0, import_react11.useRef)(onRequestClose);
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, import_react11.useEffect)(() => {
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 import_jsx_runtime12 = require("react/jsx-runtime");
2150
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2077
2151
  function BadgeRibbon({ text, color, placement = "end", className = "", children, ...props }) {
2078
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `sia-ribbon-wrap ${className}`.trim(), ...props, children: [
2152
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `sia-ribbon-wrap ${className}`.trim(), ...props, children: [
2079
2153
  children,
2080
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `sia-ribbon sia-ribbon--${placement}`, style: { backgroundColor: color }, children: text })
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, import_jsx_runtime12.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;
2088
- if (status && !children) return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: `sia-badge sia-badge--status ${className}`.trim(), style, ...props, children: [
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, import_jsx_runtime12.jsx)("span", { className: "sia-badge__text", children: text }) : null
2164
+ text ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sia-badge__text", children: text }) : null
2091
2165
  ] });
2092
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: `sia-badge ${className}`.trim(), style, ...props, children: [
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, import_jsx_runtime12.jsx)("span", { className: "sia-badge__text", children: text }) : null
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, import_react12.useState)(open || forceRender || !destroyInactivePanel);
2106
- (0, import_react12.useEffect)(() => {
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, import_jsx_runtime12.jsx)("div", { className: "sia-collapse__panel", "aria-hidden": !open, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "sia-collapse__panel-motion", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "sia-collapse__panel-body", children: renderChildren ? children : null }) }) });
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, import_react12.useState)(normalize(defaultActiveKey));
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, import_jsx_runtime12.jsx)("div", { className: `sia-collapse ${borderClassName}${ghost ? " sia-collapse--ghost" : ""} sia-collapse--icon-${expandIconPosition} ${className}`.trim(), ...props, children: items.map((item) => {
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, import_jsx_runtime12.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_runtime12.jsx)(Icon, { name: "chevron-right", size: 14 }) });
2133
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("section", { className: `sia-collapse__item${open ? " is-open" : ""}${item.disabled ? " is-disabled" : ""} ${item.className ?? ""}`.trim(), children: [
2134
- /* @__PURE__ */ (0, import_jsx_runtime12.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) => {
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, import_jsx_runtime12.jsx)("span", { className: "sia-collapse__label", children: item.label }),
2142
- item.extra ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sia-collapse__extra", onClick: (event) => event.stopPropagation(), children: item.extra }) : null,
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, import_jsx_runtime12.jsx)(CollapsePanel, { open, forceRender: item.forceRender, destroyInactivePanel, children: item.children })
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 import_jsx_runtime13 = require("react/jsx-runtime");
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, import_jsx_runtime13.jsx)("span", { className: "sia-floating-placeholder", "aria-hidden": "true", children: placeholder }) : null
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 import_react14 = require("react");
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/Select.tsx
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
- function defaultFilterOption(query, option) {
2214
- return String(option.label).toLowerCase().includes(query.toLowerCase());
2215
- }
2216
- var Select = (0, import_react14.forwardRef)(function Select2({
2217
- options,
2218
- mode = "single",
2219
- value,
2220
- defaultValue,
2221
- onChange,
2222
- placeholder = "\u8BF7\u9009\u62E9",
2223
- placeholderMode,
2224
- size = "medium",
2225
- status = "default",
2226
- allowClear = false,
2227
- loading = false,
2228
- showSearch = false,
2229
- allowInput = false,
2230
- inputMaxLength,
2231
- searchPlaceholder = "\u641C\u7D22\u9009\u9879",
2232
- onSearch,
2233
- filterOption = defaultFilterOption,
2234
- showSelectAll = false,
2235
- maxTagCount = 2,
2236
- virtual = true,
2237
- virtualThreshold = 100,
2238
- listHeight = 256,
2239
- optionHeight = 34,
2240
- disabled,
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
- id,
2243
- notFoundContent = "\u6682\u65E0\u6570\u636E",
2244
- onKeyDown,
2275
+ style,
2245
2276
  ...props
2246
2277
  }, forwardedRef) {
2247
- const fallbackId = (0, import_react14.useId)();
2248
- const selectId = id ?? fallbackId;
2249
- const listboxId = `${selectId}-listbox`;
2250
- const rootRef = (0, import_react14.useRef)(null);
2251
- const popupRef = (0, import_react14.useRef)(null);
2252
- const searchRef = (0, import_react14.useRef)(null);
2253
- const listRef = (0, import_react14.useRef)(null);
2254
- const [open, setOpen] = (0, import_react14.useState)(false);
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
- function closeFromOutside(event) {
2302
- const target = event.target;
2303
- if (!rootRef.current?.contains(target) && !popupRef.current?.contains(target)) closeDropdown();
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 && (showSearch || allowInput)) searchRef.current?.focus();
2310
- }, [allowInput, open, showSearch]);
2311
- function firstEnabledIndex() {
2312
- return filteredOptions.findIndex((option) => !option.disabled);
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 moveActive(direction) {
2338
- if (filteredOptions.length === 0) return;
2339
- let nextIndex = activeIndex;
2340
- for (let index = 0; index < filteredOptions.length; index += 1) {
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 selectOption(option) {
2350
- if (option.disabled) return;
2351
- if (multiple) {
2352
- const nextValues = selectedValueSet.has(option.value) ? selectedValues.filter((item) => item !== option.value) : [...selectedValues, option.value];
2353
- setCurrentValue(nextValues);
2354
- return;
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
- function clearSelection() {
2378
- setCurrentValue(multiple ? [] : null);
2379
- }
2380
- function handleInteractionKeyDown(event, fromSearch = false) {
2381
- if (event.key === "ArrowDown" || event.key === "ArrowUp") {
2382
- event.preventDefault();
2383
- if (!open) openDropdown();
2384
- else moveActive(event.key === "ArrowDown" ? 1 : -1);
2385
- } else if (event.key === "Enter" || event.key === " " && !fromSearch) {
2386
- event.preventDefault();
2387
- if (!open) openDropdown();
2388
- else if (activeIndex >= 0 && filteredOptions[activeIndex]) selectOption(filteredOptions[activeIndex]);
2389
- else if (fromSearch && allowInput) submitInputValue();
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
- function handleTriggerKeyDown(event) {
2406
- handleInteractionKeyDown(event);
2407
- onKeyDown?.(event);
2408
- }
2409
- function handleSearchChange(event) {
2410
- const nextQuery = event.target.value;
2411
- setQuery(nextQuery);
2412
- setActiveIndex(-1);
2413
- setScrollTop(0);
2414
- if (listRef.current) listRef.current.scrollTop = 0;
2415
- onSearch?.(nextQuery);
2416
- }
2417
- function clearValue(event) {
2418
- event.stopPropagation();
2419
- clearSelection();
2420
- }
2421
- function handleListScroll(event) {
2422
- if (virtualEnabled) setScrollTop(event.currentTarget.scrollTop);
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
- `${typeof option.value}-${option.value}`
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: listRef,
2500
- id: listboxId,
2501
- className: "sia-select__list",
2502
- role: "listbox",
2503
- "aria-labelledby": selectId,
2504
- "aria-multiselectable": multiple || void 0,
2505
- style: { maxHeight: listHeight },
2506
- onScroll: handleListScroll,
2507
- children: filteredOptions.length > 0 ? virtualEnabled ? /* @__PURE__ */ (0, import_jsx_runtime15.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_runtime15.jsx)("div", { className: "sia-select__empty", children: notFoundContent })
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 import_react16 = require("react");
2610
- var import_jsx_runtime17 = require("react/jsx-runtime");
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, import_react16.useRef)(null);
2633
- const filesRef = (0, import_react16.useRef)(fileList ?? defaultFileList);
2634
- const id = (0, import_react16.useId)();
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, import_jsx_runtime17.jsxs)(
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, import_jsx_runtime17.jsx)(
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, import_jsx_runtime17.jsx)("div", { className: "sia-upload__trigger", onClick: () => !disabled && inputRef.current?.click(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "upload", size: 16 }), disabled, children: "\u9009\u62E9\u6587\u4EF6" }) }),
2719
- showUploadList && files.length ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "sia-upload__list", children: files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: `sia-upload__item sia-upload__item--${file.status ?? "ready"}`, children: [
2720
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: file.status === "done" ? "circle-check" : "file", size: 16 }),
2721
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "sia-upload__name", title: file.name, children: file.name }),
2722
- file.status === "uploading" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "sia-upload__progress", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { width: `${file.percent ?? 0}%` } }) }) : null,
2723
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", "aria-label": `\u79FB\u9664 ${file.name}`, onClick: () => void remove(file), children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "close", size: 14 }) })
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, import_jsx_runtime17.jsx)(UploadRoot, { ...props, className: `sia-upload-dragger ${className}`.trim(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-upload-dragger__content", children: [
2731
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "upload", size: 28 }),
2732
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("strong", { children: "\u70B9\u51FB\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u6B64\u533A\u57DF\u4E0A\u4F20" }),
2733
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: hint })
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 import_jsx_runtime19 = require("react/jsx-runtime");
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, import_jsx_runtime19.jsx)(Icon, { name: "info", size: 18 }),
2966
- success: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "circle-check", size: 18 }),
2967
- warning: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "warning", size: 18 }),
2968
- error: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "circle-close", size: 18 }),
2969
- loading: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "loader", size: 18, spin: true })
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, import_jsx_runtime19.jsx)("div", { className: "sia-message-list", "aria-live": "polite", children: messageItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: `sia-message sia-message--${item.type}`, role: item.type === "loading" ? "status" : "alert", children: [
2984
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sia-message__icon", "aria-hidden": "true", children: messageIcons[item.type] }),
2985
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sia-message__content", children: item.content }),
2986
- item.closable ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "sia-message__close", "aria-label": "\u5173\u95ED\u63D0\u793A", onClick: () => closeMessage(item.key), children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "close", size: 14 }) }) : null
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 import_jsx_runtime20 = require("react/jsx-runtime");
3431
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3053
3432
  function Breadcrumb({ items, separator = "/", itemRender, className = "", ...props }) {
3054
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("nav", { "aria-label": "\u9762\u5305\u5C51\u5BFC\u822A", ...props, className: `sia-breadcrumb ${className}`.trim(), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("ol", { className: "sia-breadcrumb__list", children: items.map((item, index) => {
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, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3057
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-breadcrumb__icon", "aria-hidden": "true", children: item.icon }) : null,
3058
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-breadcrumb__title", children: item.title })
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, import_jsx_runtime20.jsx)("span", { className: "sia-breadcrumb__label", "aria-disabled": "true", children: content }) : custom !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-breadcrumb__label", children: custom }) : item.href ? /* @__PURE__ */ (0, import_jsx_runtime20.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_runtime20.jsx)(Button, { className: "sia-breadcrumb__label", variant: "text", onClick: item.onClick, children: content }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-breadcrumb__label", children: content });
3062
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("li", { className: `sia-breadcrumb__item${current ? " is-current" : ""}${item.disabled ? " is-disabled" : ""}`, children: [
3063
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "sia-breadcrumb__entry", "aria-current": current ? "page" : void 0, children: [
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, import_jsx_runtime20.jsx)(Dropdown, { menu: item.menu, trigger: ["click"], disabled: item.disabled, children: /* @__PURE__ */ (0, import_jsx_runtime20.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_runtime20.jsx)(Icon, { name: "chevron-down", size: 12 }) }) }) : null
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, import_jsx_runtime20.jsx)("span", { className: "sia-breadcrumb__separator", "aria-hidden": "true", children: item.separator === void 0 ? separator : item.separator }) : null
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 import_react19 = require("react");
3452
+ var import_react21 = require("react");
3074
3453
 
3075
3454
  // src/components/TextArea.tsx
3076
- var import_react18 = require("react");
3077
- var import_jsx_runtime21 = require("react/jsx-runtime");
3078
- var TextArea = (0, import_react18.forwardRef)(function TextArea2({
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, import_react18.useId)();
3473
+ const fallbackId = (0, import_react20.useId)();
3095
3474
  const textAreaId = id ?? fallbackId;
3096
- const [uncontrolledValue, setUncontrolledValue] = (0, import_react18.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
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, import_jsx_runtime21.jsxs)("span", { className: `sia-textarea-control sia-textarea-control--${status}${floating.className}${disabled ? " is-disabled" : ""}`, children: [
3106
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
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, import_jsx_runtime21.jsxs)("span", { className: `sia-textarea-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
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, import_jsx_runtime21.jsx)("span", { className: `sia-field ${className}`.trim(), children: control });
3130
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: `sia-field ${className}`.trim(), children: [
3131
- label ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "sia-field__label", htmlFor: textAreaId, children: label }) : null,
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, import_jsx_runtime21.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
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 import_jsx_runtime22 = require("react/jsx-runtime");
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, import_react19.useRef)(null);
3158
- const editRef = (0, import_react19.useRef)(null);
3159
- const timer = (0, import_react19.useRef)();
3160
- const [localText, setLocalText] = (0, import_react19.useState)();
3161
- const [draft, setDraft] = (0, import_react19.useState)("");
3162
- const [editing, setEditing] = (0, import_react19.useState)(false);
3163
- const [copied, setCopied] = (0, import_react19.useState)(false);
3164
- const [copyError, setCopyError] = (0, import_react19.useState)(false);
3165
- const [expanded, setExpanded] = (0, import_react19.useState)(false);
3166
- const [overflow, setOverflow] = (0, import_react19.useState)(false);
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, import_react19.useEffect)(() => {
3551
+ (0, import_react21.useEffect)(() => {
3173
3552
  setLocalText(void 0);
3174
3553
  }, [children]);
3175
- (0, import_react19.useEffect)(() => () => clearTimeout(timer.current), []);
3176
- (0, import_react19.useLayoutEffect)(() => {
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, import_jsx_runtime22.jsx)("strong", { children: formatted });
3208
- if (italic) formatted = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("em", { children: formatted });
3209
- if (underline) formatted = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("u", { children: formatted });
3210
- if (deleted) formatted = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("del", { children: formatted });
3211
- if (mark) formatted = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("mark", { children: formatted });
3212
- if (code) formatted = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("code", { children: formatted });
3213
- if (keyboard) formatted = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("kbd", { children: formatted });
3214
- return /* @__PURE__ */ (0, import_jsx_runtime22.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_runtime22.jsxs)("span", { className: "sia-typography__editor", children: [
3215
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
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, import_jsx_runtime22.jsxs)("span", { className: "sia-typography__edit-actions", children: [
3238
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { size: "small", onClick: () => finish(false), children: "\u53D6\u6D88" }),
3239
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { size: "small", variant: "primary", onClick: () => finish(true), children: "\u4FDD\u5B58" })
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, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3242
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { ref: contentRef, className: ellipsis && !expanded ? "sia-typography__ellipsis" : void 0, style: ellipsis && !expanded ? { "--sia-typography-rows": rows } : void 0, children: formatted }),
3243
- expandable && (overflow || expanded) ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { variant: "link", size: "small", className: "sia-typography__action", "aria-expanded": expanded, disabled, onClick: () => setExpanded(!expanded), children: expanded ? "\u6536\u8D77" : "\u5C55\u5F00" }) : null,
3244
- editable ? /* @__PURE__ */ (0, import_jsx_runtime22.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_runtime22.jsx)(Icon, { name: "edit", size: 14 }), onClick: () => {
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, import_jsx_runtime22.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_runtime22.jsx)(Icon, { name: copied ? "check" : "copy", size: 14 }), onClick: () => void copy() }) : null,
3249
- copyError ? /* @__PURE__ */ (0, import_jsx_runtime22.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
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, import_jsx_runtime22.jsx)(TypographyContent, { ...props, as: `h${level}` });
3632
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props, as: `h${level}` });
3254
3633
  }
3255
3634
  function Text(props) {
3256
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TypographyContent, { ...props });
3635
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props });
3257
3636
  }
3258
3637
  function Paragraph(props) {
3259
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TypographyContent, { ...props, as: "p" });
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, import_jsx_runtime22.jsx)(
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, import_jsx_runtime22.jsx)("div", { ...props, className: `sia-typography ${className}`.trim() });
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 import_react20 = require("react");
3286
- var import_jsx_runtime23 = require("react/jsx-runtime");
3287
- var GroupShape = (0, import_react20.createContext)(void 0);
3288
- var FloatButtonRoot = (0, import_react20.forwardRef)(function FloatButton({
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, import_react20.useContext)(GroupShape);
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, import_jsx_runtime23.jsx)(
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, import_jsx_runtime23.jsx)(Badge, { ...badge, className: "sia-float-button__badge", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "sia-float-button__body", children: [
3312
- icon !== null ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "sia-float-button__icon", children: icon ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { name: "question", size: 20 }) }) : null,
3313
- description != null || children != null ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "sia-float-button__description", children: description ?? children }) : null
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, import_jsx_runtime23.jsx)("span", { className: "sia-float-button-root", style, children: tooltip ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Tooltip, { title: tooltip, placement: "left", children: button }) : button });
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, import_react20.useRef)(null);
3340
- const triggerRef = (0, import_react20.useRef)(null);
3341
- const id = (0, import_react20.useId)();
3342
- (0, import_react20.useEffect)(() => {
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, import_jsx_runtime23.jsx)(GroupShape.Provider, { value: shape, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
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, import_jsx_runtime23.jsx)("div", { id, className: "sia-float-button-group__list", children }) : null,
3378
- trigger ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
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, import_jsx_runtime23.jsx)(Icon, { name: "close", size: 20 }) : icon ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { name: "plus", size: 20 }),
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, import_react20.useState)(false);
3397
- (0, import_react20.useEffect)(() => {
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, import_jsx_runtime23.jsx)(FloatButtonRoot, { ...props, tooltip, icon: icon ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { name: "arrow-up", size: 20 }), onClick: (event) => {
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;