@sia.soul/sia-react-ui 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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,654 @@ var Input = (0, import_react15.forwardRef)(function Input2({
2605
2554
  ] });
2606
2555
  });
2607
2556
 
2557
+ // src/components/SelectionPanel.tsx
2558
+ var import_react16 = require("react");
2559
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2560
+ function SelectionPanel({
2561
+ options,
2562
+ value,
2563
+ onChange,
2564
+ multiple = false,
2565
+ disabled = false,
2566
+ loading = false,
2567
+ showSearch = true,
2568
+ showActions = true,
2569
+ includeUnknownValues = true,
2570
+ searchValue,
2571
+ onSearch,
2572
+ selectedOnly = false,
2573
+ showValue = false,
2574
+ displayField = "label",
2575
+ columns = 1,
2576
+ maxHeight = 250,
2577
+ autoFocusSearch = false
2578
+ }) {
2579
+ const [localSearch, setLocalSearch] = (0, import_react16.useState)("");
2580
+ const search = searchValue ?? localSearch;
2581
+ const [scrollTop, setScrollTop] = (0, import_react16.useState)(0);
2582
+ const [active, setActive] = (0, import_react16.useState)();
2583
+ const listRef = (0, import_react16.useRef)(null);
2584
+ const id = (0, import_react16.useId)();
2585
+ const selected = (0, import_react16.useMemo)(() => new Set(value), [value]);
2586
+ const count = Math.max(1, Math.floor(columns));
2587
+ const allOptions = (0, import_react16.useMemo)(() => {
2588
+ if (!includeUnknownValues) return [...options];
2589
+ const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
2590
+ return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
2591
+ }, [options, value, includeUnknownValues]);
2592
+ const filtered = (0, import_react16.useMemo)(
2593
+ () => allOptions.filter((option) => (!selectedOnly || selected.has(option.value)) && (!search || option.optionType !== "divider" && [option.label, option.value].some((text) => String(text ?? "").toLowerCase().includes(search.toLowerCase())))),
2594
+ [allOptions, selectedOnly, selected, search]
2595
+ );
2596
+ const rows = (0, import_react16.useMemo)(() => {
2597
+ const groups = /* @__PURE__ */ new Map();
2598
+ filtered.forEach((option) => {
2599
+ const items = groups.get(option.group) ?? [];
2600
+ items.push(option);
2601
+ groups.set(option.group, items);
2602
+ });
2603
+ const rows2 = [];
2604
+ let top = 0;
2605
+ for (const [group, items] of groups) {
2606
+ if (group) {
2607
+ rows2.push({ key: `group-${rows2.length}`, title: group, top, height: 30 });
2608
+ top += 30;
2609
+ }
2610
+ for (let index = 0; index < items.length; index += count) {
2611
+ const height = showValue ? 48 : 34;
2612
+ rows2.push({ key: `row-${rows2.length}`, items: items.slice(index, index + count), top, height });
2613
+ top += height;
2614
+ }
2615
+ }
2616
+ return rows2;
2617
+ }, [filtered, count, showValue]);
2618
+ const totalHeight = rows.length ? rows[rows.length - 1].top + rows[rows.length - 1].height : 0;
2619
+ const virtual = filtered.length > 100;
2620
+ const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
2621
+ const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
2622
+ (0, import_react16.useEffect)(() => {
2623
+ setScrollTop(0);
2624
+ if (listRef.current) listRef.current.scrollTop = 0;
2625
+ setActive(void 0);
2626
+ }, [search, selectedOnly, count]);
2627
+ function toggle(option) {
2628
+ if (disabled || loading || option.disabled || option.optionType === "divider") return;
2629
+ setActive(option.value);
2630
+ onChange(multiple ? selected.has(option.value) ? value.filter((item) => item !== option.value) : [...value, option.value] : [option.value]);
2631
+ }
2632
+ function batch(operation) {
2633
+ if (disabled || loading) return;
2634
+ if (operation === "clear") {
2635
+ onChange([]);
2636
+ return;
2637
+ }
2638
+ const editable = new Set(enabled.map((option) => option.value));
2639
+ const retained = value.filter((item) => !editable.has(item));
2640
+ const add = enabled.filter((option) => operation === "all" || !selected.has(option.value)).map((option) => option.value);
2641
+ onChange([...retained, ...add]);
2642
+ }
2643
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-selection-panel", children: [
2644
+ showSearch && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2645
+ Input,
2646
+ {
2647
+ "aria-label": "\u641C\u7D22\u9009\u9879",
2648
+ placeholder: "\u641C\u7D22",
2649
+ autoFocus: autoFocusSearch,
2650
+ value: search,
2651
+ allowClear: true,
2652
+ onChange: (event) => {
2653
+ setLocalSearch(event.target.value);
2654
+ onSearch?.(event.target.value);
2655
+ }
2656
+ }
2657
+ ),
2658
+ multiple && showActions && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-selection-panel__actions", children: [
2659
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("all"), children: "\u5168\u9009" }),
2660
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("invert"), children: "\u53CD\u9009" }),
2661
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !value.length, onClick: () => batch("clear"), children: "\u6E05\u7A7A" }),
2662
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { children: [
2663
+ "\u5DF2\u9009 ",
2664
+ value.length,
2665
+ " \u9879"
2666
+ ] })
2667
+ ] }),
2668
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2669
+ "div",
2670
+ {
2671
+ ref: listRef,
2672
+ role: "listbox",
2673
+ "aria-label": "\u9009\u9879\u5217\u8868",
2674
+ "aria-multiselectable": multiple || void 0,
2675
+ tabIndex: disabled ? -1 : 0,
2676
+ className: "sia-selection-panel__list",
2677
+ style: { maxHeight },
2678
+ onScroll: (event) => setScrollTop(event.currentTarget.scrollTop),
2679
+ "aria-activedescendant": active !== void 0 ? `${id}-${typeof active}-${active}` : void 0,
2680
+ onKeyDown: (event) => {
2681
+ if (event.target instanceof HTMLInputElement) return;
2682
+ if (disabled || loading || !enabled.length) return;
2683
+ const index = enabled.findIndex((option) => option.value === active);
2684
+ if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
2685
+ event.preventDefault();
2686
+ const next = event.key === "Home" ? 0 : event.key === "End" ? enabled.length - 1 : Math.max(0, Math.min(enabled.length - 1, index + (event.key === "ArrowDown" ? 1 : -1)));
2687
+ const option = enabled[next];
2688
+ setActive(option.value);
2689
+ const row = rows.find((row2) => row2.items?.includes(option));
2690
+ if (row && listRef.current) {
2691
+ listRef.current.scrollTop = Math.max(0, row.top - maxHeight / 2);
2692
+ setScrollTop(listRef.current.scrollTop);
2693
+ }
2694
+ } else if ((event.key === "Enter" || event.key === " ") && index >= 0) {
2695
+ event.preventDefault();
2696
+ toggle(enabled[index]);
2697
+ }
2698
+ },
2699
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { role: "status", children: "\u52A0\u8F7D\u4E2D\u2026" }) : !rows.length ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "sia-selection-panel__empty", children: "\u6682\u65E0\u5339\u914D\u9009\u9879" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { height: totalHeight, position: "relative" }, children: renderedRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2700
+ "div",
2701
+ {
2702
+ className: row.title !== void 0 ? "sia-selection-panel__group" : "sia-selection-panel__row",
2703
+ style: { position: "absolute", top: row.top, height: row.height, width: "100%", gridTemplateColumns: `repeat(${count}, minmax(0, 1fr))` },
2704
+ children: row.title ?? row.items?.map((option, index) => option.optionType === "divider" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { role: "separator", className: "sia-selection-panel__divider" }, `divider-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Tooltip, { title: option.disabled ? option.disabledTip : void 0, placement: "right", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2705
+ "div",
2706
+ {
2707
+ role: "option",
2708
+ id: `${id}-${typeof option.value}-${option.value}`,
2709
+ tabIndex: -1,
2710
+ "aria-selected": selected.has(option.value),
2711
+ "aria-disabled": disabled || option.disabled || void 0,
2712
+ className: `sia-selection-panel__option${active === option.value ? " is-active" : ""}`,
2713
+ onClick: (event) => {
2714
+ if (!event.target.closest(".sia-checkbox")) toggle(option);
2715
+ },
2716
+ children: multiple ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Checkbox2, { checked: selected.has(option.value), disabled: disabled || loading || option.disabled, tabIndex: -1, onChange: () => toggle(option), children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "sia-selection-panel__text", children: [
2717
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
2718
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("small", { children: String(option.value) })
2719
+ ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "sia-selection-panel__text", children: [
2720
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
2721
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("small", { children: String(option.value) })
2722
+ ] })
2723
+ }
2724
+ ) }, `${typeof option.value}-${option.value}`))
2725
+ },
2726
+ row.key
2727
+ )) })
2728
+ }
2729
+ )
2730
+ ] });
2731
+ }
2732
+
2733
+ // src/components/OverflowTags.tsx
2734
+ var import_react17 = require("react");
2735
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2736
+ function OverflowTags({ items, maxCount: maxCount2, className = "", tagClassName, restClassName = "" }) {
2737
+ const rootRef = (0, import_react17.useRef)(null);
2738
+ const measureRef = (0, import_react17.useRef)(null);
2739
+ const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount2) || 0));
2740
+ const [visibleCount, setVisibleCount] = (0, import_react17.useState)(0);
2741
+ (0, import_react17.useLayoutEffect)(() => {
2742
+ const root = rootRef.current;
2743
+ const measure = measureRef.current;
2744
+ if (!root || !measure) return;
2745
+ const update = () => {
2746
+ const gap = Number.parseFloat(getComputedStyle(root).columnGap) || 0;
2747
+ const widths = Array.from(measure.children, (child) => child.getBoundingClientRect().width);
2748
+ let used = 0;
2749
+ let fitting = 0;
2750
+ for (let count2 = 1; count2 <= limit; count2 += 1) {
2751
+ used += widths[count2 - 1] + (count2 > 1 ? gap : 0);
2752
+ const rest = count2 < items.length ? gap + widths[limit + count2] : 0;
2753
+ if (used + rest <= root.clientWidth) fitting = count2;
2754
+ }
2755
+ setVisibleCount((previous) => previous === fitting ? previous : fitting);
2756
+ };
2757
+ update();
2758
+ const observer = new ResizeObserver(update);
2759
+ observer.observe(root);
2760
+ for (const child of measure.children) observer.observe(child);
2761
+ return () => observer.disconnect();
2762
+ }, [items, limit]);
2763
+ const count = Math.min(visibleCount, limit);
2764
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { ref: rootRef, className: `sia-overflow-tags ${className}`.trim(), children: [
2765
+ items.slice(0, count).map((item) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
2766
+ items.length > count ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: `${tagClassName} sia-overflow-tags__rest ${restClassName}`.trim(), children: [
2767
+ "+",
2768
+ items.length - count
2769
+ ] }) : null,
2770
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { ref: measureRef, className: "sia-overflow-tags__measure", "aria-hidden": "true", children: [
2771
+ items.slice(0, limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
2772
+ Array.from({ length: limit + 1 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: `${tagClassName} ${restClassName}`.trim(), children: [
2773
+ "+",
2774
+ items.length - index
2775
+ ] }, `rest-${index}`))
2776
+ ] })
2777
+ ] });
2778
+ }
2779
+
2780
+ // src/components/Select.tsx
2781
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2782
+ function defaultFilterOption(query, option) {
2783
+ const keyword = query.toLowerCase();
2784
+ return [option.label, option.value].some((value) => String(value).toLowerCase().includes(keyword));
2785
+ }
2786
+ var Select = (0, import_react18.forwardRef)(function Select2({
2787
+ options,
2788
+ mode = "single",
2789
+ popupMode = "dropdown",
2790
+ modalConfig,
2791
+ value,
2792
+ defaultValue,
2793
+ onChange,
2794
+ placeholder = "\u8BF7\u9009\u62E9",
2795
+ placeholderMode,
2796
+ size = "medium",
2797
+ status = "default",
2798
+ allowClear = false,
2799
+ loading = false,
2800
+ showSearch = false,
2801
+ showValue = false,
2802
+ allowInput = false,
2803
+ inputMaxLength,
2804
+ searchPlaceholder = "\u641C\u7D22\u9009\u9879",
2805
+ onSearch,
2806
+ filterOption = defaultFilterOption,
2807
+ showSelectAll = true,
2808
+ maxTagCount = 2,
2809
+ virtual = true,
2810
+ virtualThreshold = 100,
2811
+ listHeight = 256,
2812
+ optionHeight = showValue ? 54 : 34,
2813
+ disabled,
2814
+ className = "",
2815
+ id,
2816
+ notFoundContent = "\u6682\u65E0\u6570\u636E",
2817
+ onKeyDown,
2818
+ ...props
2819
+ }, forwardedRef) {
2820
+ const fallbackId = (0, import_react18.useId)();
2821
+ const selectId = id ?? fallbackId;
2822
+ const listboxId = `${selectId}-listbox`;
2823
+ const rootRef = (0, import_react18.useRef)(null);
2824
+ const popupRef = (0, import_react18.useRef)(null);
2825
+ const searchRef = (0, import_react18.useRef)(null);
2826
+ const listRef = (0, import_react18.useRef)(null);
2827
+ const [open, setOpen] = (0, import_react18.useState)(false);
2828
+ const [modalValues, setModalValues] = (0, import_react18.useState)([]);
2829
+ const [selectedOnly, setSelectedOnly] = (0, import_react18.useState)(false);
2830
+ const [query, setQuery] = (0, import_react18.useState)("");
2831
+ const [activeIndex, setActiveIndex] = (0, import_react18.useState)(-1);
2832
+ const [scrollTop, setScrollTop] = (0, import_react18.useState)(0);
2833
+ const deferredQuery = (0, import_react18.useDeferredValue)(query.trim());
2834
+ const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
2835
+ const [currentValue, setCurrentValue] = useControllableState({
2836
+ value,
2837
+ defaultValue: initialValue,
2838
+ onChange: (nextValue) => {
2839
+ if (Array.isArray(nextValue)) {
2840
+ const selectedOptions2 = nextValue.map((selectedValue) => options.find((option) => option.value === selectedValue) ?? (allowInput ? { label: String(selectedValue), value: selectedValue } : void 0)).filter((option) => option !== void 0);
2841
+ onChange?.(nextValue, selectedOptions2);
2842
+ } else {
2843
+ const selectedOption = nextValue === null ? null : options.find((option) => option.value === nextValue) ?? (allowInput ? { label: String(nextValue), value: nextValue } : null);
2844
+ onChange?.(nextValue, selectedOption);
2845
+ }
2846
+ }
2847
+ });
2848
+ const selectedValues = (0, import_react18.useMemo)(() => {
2849
+ if (mode === "multiple") return Array.isArray(currentValue) ? currentValue : currentValue === null ? [] : [currentValue];
2850
+ return Array.isArray(currentValue) ? currentValue.slice(0, 1) : currentValue === null ? [] : [currentValue];
2851
+ }, [currentValue, mode]);
2852
+ const selectedValueSet = (0, import_react18.useMemo)(() => new Set(selectedValues), [selectedValues]);
2853
+ const availableOptions = (0, import_react18.useMemo)(() => {
2854
+ if (!allowInput) return options;
2855
+ const optionValueSet = new Set(options.map((option) => option.value));
2856
+ const selectedCustomOptions = selectedValues.filter((selectedValue) => !optionValueSet.has(selectedValue)).map((selectedValue) => ({ label: String(selectedValue), value: selectedValue }));
2857
+ return selectedCustomOptions.length ? [...selectedCustomOptions, ...options] : options;
2858
+ }, [allowInput, options, selectedValues]);
2859
+ const selectedOptions = (0, import_react18.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
2860
+ const filteredOptions = (0, import_react18.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
2861
+ const inputValue = query.trim();
2862
+ const exactInputOption = inputValue ? availableOptions.find((option) => String(option.value).toLowerCase() === inputValue.toLowerCase() || typeof option.label === "string" && option.label.toLowerCase() === inputValue.toLowerCase()) : void 0;
2863
+ const canSubmitInput = allowInput && Boolean(inputValue) && !exactInputOption;
2864
+ const multiple = mode === "multiple";
2865
+ const hasValue = selectedOptions.length > 0;
2866
+ const virtualEnabled = virtual && filteredOptions.length >= virtualThreshold;
2867
+ const overscan = 3;
2868
+ const visibleCount = Math.ceil(listHeight / optionHeight) + overscan * 2;
2869
+ const virtualStart = virtualEnabled ? Math.max(0, Math.floor(scrollTop / optionHeight) - overscan) : 0;
2870
+ const virtualEnd = virtualEnabled ? Math.min(filteredOptions.length, virtualStart + visibleCount) : filteredOptions.length;
2871
+ const renderedOptions = virtualEnabled ? filteredOptions.slice(virtualStart, virtualEnd) : filteredOptions;
2872
+ const enabledFilteredOptions = filteredOptions.filter((option) => !option.disabled);
2873
+ const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((option) => selectedValueSet.has(option.value));
2874
+ (0, import_react18.useEffect)(() => {
2875
+ if (!open || popupMode === "modal") return void 0;
2876
+ function closeFromOutside(event) {
2877
+ const target = event.target;
2878
+ if (!rootRef.current?.contains(target) && !popupRef.current?.contains(target)) closeDropdown();
2879
+ }
2880
+ document.addEventListener("mousedown", closeFromOutside);
2881
+ return () => document.removeEventListener("mousedown", closeFromOutside);
2882
+ }, [open, popupMode]);
2883
+ (0, import_react18.useEffect)(() => {
2884
+ if (open && (showSearch || allowInput)) searchRef.current?.focus();
2885
+ }, [allowInput, open, showSearch]);
2886
+ (0, import_react18.useEffect)(() => {
2887
+ if (disabled || loading) closeDropdown();
2888
+ }, [disabled, loading]);
2889
+ function firstEnabledIndex() {
2890
+ return filteredOptions.findIndex((option) => !option.disabled);
2891
+ }
2892
+ function closeDropdown() {
2893
+ setOpen(false);
2894
+ setQuery("");
2895
+ setScrollTop(0);
2896
+ }
2897
+ function openDropdown() {
2898
+ if (disabled || loading) return;
2899
+ const selectedIndex = filteredOptions.findIndex((option) => selectedValueSet.has(option.value) && !option.disabled);
2900
+ setActiveIndex(selectedIndex >= 0 ? selectedIndex : firstEnabledIndex());
2901
+ if (popupMode === "modal") {
2902
+ setModalValues([...selectedValues]);
2903
+ setSelectedOnly(false);
2904
+ }
2905
+ setOpen(true);
2906
+ }
2907
+ function keepActiveVisible(index) {
2908
+ if (!virtualEnabled || !listRef.current) return;
2909
+ const optionTop = index * optionHeight;
2910
+ const optionBottom = optionTop + optionHeight;
2911
+ const viewportTop = listRef.current.scrollTop;
2912
+ const viewportBottom = viewportTop + listHeight;
2913
+ const nextScrollTop = optionTop < viewportTop ? optionTop : optionBottom > viewportBottom ? optionBottom - listHeight : viewportTop;
2914
+ if (nextScrollTop !== viewportTop) {
2915
+ listRef.current.scrollTop = nextScrollTop;
2916
+ setScrollTop(nextScrollTop);
2917
+ }
2918
+ }
2919
+ function moveActive(direction) {
2920
+ if (filteredOptions.length === 0) return;
2921
+ let nextIndex = activeIndex;
2922
+ for (let index = 0; index < filteredOptions.length; index += 1) {
2923
+ nextIndex = (nextIndex + direction + filteredOptions.length) % filteredOptions.length;
2924
+ if (!filteredOptions[nextIndex]?.disabled) {
2925
+ setActiveIndex(nextIndex);
2926
+ keepActiveVisible(nextIndex);
2927
+ return;
2928
+ }
2929
+ }
2930
+ }
2931
+ function selectOption(option) {
2932
+ if (option.disabled) return;
2933
+ if (multiple) {
2934
+ const nextValues = selectedValueSet.has(option.value) ? selectedValues.filter((item) => item !== option.value) : [...selectedValues, option.value];
2935
+ setCurrentValue(nextValues);
2936
+ return;
2937
+ }
2938
+ setCurrentValue(option.value);
2939
+ closeDropdown();
2940
+ }
2941
+ function selectAllFiltered() {
2942
+ if (allFilteredSelected) return;
2943
+ const nextValues = [...selectedValues];
2944
+ const nextValueSet = new Set(nextValues);
2945
+ enabledFilteredOptions.forEach((option) => {
2946
+ if (!nextValueSet.has(option.value)) nextValues.push(option.value);
2947
+ });
2948
+ setCurrentValue(nextValues);
2949
+ }
2950
+ function submitInputValue() {
2951
+ if (!allowInput || !inputValue) return;
2952
+ selectOption(exactInputOption ?? { label: inputValue, value: inputValue });
2953
+ if (multiple) {
2954
+ setQuery("");
2955
+ setActiveIndex(-1);
2956
+ setScrollTop(0);
2957
+ }
2958
+ }
2959
+ function invertFiltered() {
2960
+ const enabled = new Set(enabledFilteredOptions.map((option) => option.value));
2961
+ setCurrentValue([...selectedValues.filter((value2) => !enabled.has(value2)), ...enabledFilteredOptions.filter((option) => !selectedValueSet.has(option.value)).map((option) => option.value)]);
2962
+ }
2963
+ function clearSelection() {
2964
+ setCurrentValue(multiple ? [] : null);
2965
+ }
2966
+ function handleInteractionKeyDown(event, fromSearch = false) {
2967
+ if (popupMode === "modal" && open) return;
2968
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
2969
+ event.preventDefault();
2970
+ if (!open) openDropdown();
2971
+ else moveActive(event.key === "ArrowDown" ? 1 : -1);
2972
+ } else if (event.key === "Enter" || event.key === " " && !fromSearch) {
2973
+ event.preventDefault();
2974
+ if (!open) openDropdown();
2975
+ else if (activeIndex >= 0 && filteredOptions[activeIndex]) selectOption(filteredOptions[activeIndex]);
2976
+ else if (fromSearch && allowInput) submitInputValue();
2977
+ } else if (event.key === "Escape") {
2978
+ closeDropdown();
2979
+ } else if (event.key === "Home" && open && !fromSearch) {
2980
+ event.preventDefault();
2981
+ const firstIndex = firstEnabledIndex();
2982
+ setActiveIndex(firstIndex);
2983
+ keepActiveVisible(firstIndex);
2984
+ } else if (event.key === "End" && open && !fromSearch) {
2985
+ event.preventDefault();
2986
+ const reversedIndex = [...filteredOptions].reverse().findIndex((option) => !option.disabled);
2987
+ const lastIndex = reversedIndex < 0 ? -1 : filteredOptions.length - 1 - reversedIndex;
2988
+ setActiveIndex(lastIndex);
2989
+ keepActiveVisible(lastIndex);
2990
+ }
2991
+ }
2992
+ function handleTriggerKeyDown(event) {
2993
+ handleInteractionKeyDown(event);
2994
+ onKeyDown?.(event);
2995
+ }
2996
+ function handleSearchChange(event) {
2997
+ const nextQuery = event.target.value;
2998
+ setQuery(nextQuery);
2999
+ setActiveIndex(-1);
3000
+ setScrollTop(0);
3001
+ if (listRef.current) listRef.current.scrollTop = 0;
3002
+ onSearch?.(nextQuery);
3003
+ }
3004
+ function clearValue(event) {
3005
+ event.stopPropagation();
3006
+ clearSelection();
3007
+ }
3008
+ function handleListScroll(event) {
3009
+ if (virtualEnabled) setScrollTop(event.currentTarget.scrollTop);
3010
+ }
3011
+ function renderOption(option, renderedIndex) {
3012
+ const optionIndex = virtualEnabled ? virtualStart + renderedIndex : renderedIndex;
3013
+ const selected = selectedValueSet.has(option.value);
3014
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3015
+ "div",
3016
+ {
3017
+ id: `${listboxId}-${optionIndex}`,
3018
+ className: `sia-select__option${selected ? " is-selected" : ""}${optionIndex === activeIndex ? " is-active" : ""}${option.disabled ? " is-disabled" : ""}`,
3019
+ role: "option",
3020
+ "aria-selected": selected,
3021
+ "aria-disabled": option.disabled || void 0,
3022
+ style: virtualEnabled ? { position: "absolute", top: optionIndex * optionHeight, right: 0, left: 0, height: optionHeight } : void 0,
3023
+ onMouseEnter: () => !option.disabled && setActiveIndex(optionIndex),
3024
+ onMouseDown: (event) => event.preventDefault(),
3025
+ onClick: () => selectOption(option),
3026
+ children: [
3027
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "sia-select__option-content", children: [
3028
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sia-select__option-label", children: option.label }),
3029
+ showValue ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("small", { className: "sia-select__option-value", children: String(option.value) }) : null
3030
+ ] }),
3031
+ selected ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "check", size: 15 }) : null
3032
+ ]
3033
+ },
3034
+ `${typeof option.value}-${option.value}`
3035
+ );
3036
+ }
3037
+ const modalAvailable = [...availableOptions, ...modalValues.filter((value2) => !availableOptions.some((option) => option.value === value2)).map((value2) => ({ value: value2, label: String(value2) }))];
3038
+ const modalFiltered = deferredQuery ? modalAvailable.filter((option) => filterOption(deferredQuery, option)) : modalAvailable;
3039
+ const modalEnabled = modalFiltered.filter((option) => !option.disabled && (!selectedOnly || modalValues.includes(option.value)));
3040
+ function modalBatch(operation) {
3041
+ const editable = new Set(modalEnabled.map((option) => option.value));
3042
+ setModalValues([...modalValues.filter((value2) => !editable.has(value2)), ...modalEnabled.filter((option) => operation === "all" || operation === "invert" && !modalValues.includes(option.value)).map((option) => option.value)]);
3043
+ }
3044
+ const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: hasValue, active: open });
3045
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { ref: rootRef, className: `sia-select sia-select--${size} sia-select--${status}${open ? " is-open" : ""}${disabled ? " is-disabled" : ""}${multiple ? " sia-select--multiple" : ""} ${className}`.trim(), children: [
3046
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3047
+ "button",
3048
+ {
3049
+ ...props,
3050
+ ref: forwardedRef,
3051
+ className: `sia-select__trigger${floating.className}`,
3052
+ id: selectId,
3053
+ type: "button",
3054
+ role: "combobox",
3055
+ "aria-controls": popupMode === "modal" ? void 0 : listboxId,
3056
+ "aria-expanded": open,
3057
+ "aria-haspopup": popupMode === "modal" ? "dialog" : "listbox",
3058
+ "aria-activedescendant": popupMode === "dropdown" && open && activeIndex >= 0 ? `${listboxId}-${activeIndex}` : void 0,
3059
+ "aria-invalid": status === "error" || void 0,
3060
+ disabled,
3061
+ onClick: () => open ? closeDropdown() : openDropdown(),
3062
+ onKeyDown: handleTriggerKeyDown,
3063
+ children: [
3064
+ multiple && hasValue ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(OverflowTags, { className: "sia-select__tags", tagClassName: "sia-select__tag", restClassName: "sia-select__tag--rest", maxCount: maxTagCount, items: selectedOptions.map((option) => ({ key: `${typeof option.value}-${option.value}`, label: option.label })) }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: `sia-select__value${hasValue ? "" : " is-placeholder"}`, children: selectedOptions[0]?.label ?? placeholder }),
3065
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sia-select__spinner", "aria-hidden": "true" }) : null,
3066
+ floating.label,
3067
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { className: "sia-select__arrow", name: "chevron-down", size: 15 })
3068
+ ]
3069
+ }
3070
+ ),
3071
+ allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
3072
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", className: "sia-select__dropdown", children: [
3073
+ showSearch || allowInput ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "sia-select__search", children: [
3074
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "search", size: 15 }),
3075
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("input", { ref: searchRef, value: query, maxLength: inputMaxLength, onChange: handleSearchChange, onKeyDown: (event) => handleInteractionKeyDown(event, true), placeholder: searchPlaceholder, "aria-label": searchPlaceholder })
3076
+ ] }) : null,
3077
+ canSubmitInput ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { type: "button", className: "sia-select__input-option", onMouseDown: (event) => event.preventDefault(), onClick: submitInputValue, children: [
3078
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "plus", size: 14 }),
3079
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { children: [
3080
+ "\u4F7F\u7528\u201C",
3081
+ inputValue,
3082
+ "\u201D"
3083
+ ] })
3084
+ ] }) : null,
3085
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3086
+ "div",
3087
+ {
3088
+ ref: listRef,
3089
+ id: listboxId,
3090
+ className: "sia-select__list",
3091
+ role: "listbox",
3092
+ "aria-labelledby": selectId,
3093
+ "aria-multiselectable": multiple || void 0,
3094
+ style: { maxHeight: listHeight },
3095
+ onScroll: handleListScroll,
3096
+ children: filteredOptions.length > 0 ? virtualEnabled ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "sia-select__virtual-space", style: { height: filteredOptions.length * optionHeight }, children: renderedOptions.map(renderOption) }) : renderedOptions.map(renderOption) : canSubmitInput ? null : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "sia-select__empty", children: notFoundContent })
3097
+ }
3098
+ ),
3099
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select__actions", children: [
3100
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { children: [
3101
+ "\u5171 ",
3102
+ filteredOptions.length,
3103
+ " \u6761"
3104
+ ] }),
3105
+ multiple && showSelectAll ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
3106
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", disabled: allFilteredSelected || !enabledFilteredOptions.length, onClick: selectAllFiltered, children: "\u5168\u9009" }),
3107
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", disabled: !enabledFilteredOptions.length, onClick: invertFiltered, children: "\u53CD\u9009" })
3108
+ ] }) : null,
3109
+ multiple || allowClear ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", danger: true, disabled: !hasValue, onClick: clearSelection, children: "\u6E05\u7A7A" }) : null
3110
+ ] })
3111
+ ] }),
3112
+ popupMode === "modal" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3113
+ Modal2,
3114
+ {
3115
+ className: "sia-select-modal",
3116
+ open,
3117
+ title: modalConfig?.title ?? placeholder,
3118
+ width: modalConfig?.width ?? 900,
3119
+ onOpenChange: (next) => {
3120
+ if (!next) closeDropdown();
3121
+ },
3122
+ onCancel: closeDropdown,
3123
+ footer: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select-modal__footer", children: [
3124
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { children: modalConfig?.footerExtra }),
3125
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
3126
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { onClick: closeDropdown, children: "\u53D6\u6D88" }),
3127
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "primary", disabled: disabled || loading, onClick: () => {
3128
+ setCurrentValue(multiple ? modalValues : modalValues[0] ?? null);
3129
+ closeDropdown();
3130
+ }, children: "\u786E\u5B9A" })
3131
+ ] })
3132
+ ] }),
3133
+ children: open ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
3134
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select-modal__heading", children: [
3135
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { role: "tablist", "aria-label": "\u9009\u9879\u8303\u56F4", children: [
3136
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { role: "tab", "aria-selected": !selectedOnly, variant: "link", onClick: () => setSelectedOnly(false), children: "\u5168\u90E8" }),
3137
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Button, { role: "tab", "aria-selected": selectedOnly, variant: "link", onClick: () => setSelectedOnly(true), children: [
3138
+ "\u5DF2\u9009\u9879(",
3139
+ modalValues.length,
3140
+ ")"
3141
+ ] })
3142
+ ] }),
3143
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3144
+ Input,
3145
+ {
3146
+ "aria-label": searchPlaceholder,
3147
+ placeholder: searchPlaceholder,
3148
+ prefix: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Icon, { name: "search", size: 14 }),
3149
+ value: query,
3150
+ allowClear: true,
3151
+ onChange: (event) => {
3152
+ setQuery(event.target.value);
3153
+ onSearch?.(event.target.value);
3154
+ }
3155
+ }
3156
+ )
3157
+ ] }),
3158
+ multiple && showSelectAll ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sia-select-modal__actions", children: [
3159
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3160
+ Checkbox2,
3161
+ {
3162
+ checked: modalEnabled.length > 0 && modalEnabled.every((option) => modalValues.includes(option.value)),
3163
+ indeterminate: modalEnabled.some((option) => modalValues.includes(option.value)) && !modalEnabled.every((option) => modalValues.includes(option.value)),
3164
+ disabled: !modalEnabled.length,
3165
+ onChange: (checked) => modalBatch(checked ? "all" : "remove"),
3166
+ children: "\u5168\u9009"
3167
+ }
3168
+ ),
3169
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", disabled: !modalEnabled.length, onClick: () => modalBatch("invert"), children: "\u53CD\u9009" }),
3170
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { variant: "link", size: "small", danger: true, disabled: !modalValues.length, onClick: () => setModalValues([]), children: "\u6E05\u7A7A" })
3171
+ ] }) : null,
3172
+ allowInput && canSubmitInput ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Button, { variant: "link", onClick: () => {
3173
+ setModalValues(multiple ? [.../* @__PURE__ */ new Set([...modalValues, inputValue])] : [inputValue]);
3174
+ setQuery("");
3175
+ }, children: [
3176
+ "\u4F7F\u7528\u201C",
3177
+ inputValue,
3178
+ "\u201D"
3179
+ ] }) : null,
3180
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3181
+ SelectionPanel,
3182
+ {
3183
+ options: modalFiltered,
3184
+ value: modalValues,
3185
+ onChange: setModalValues,
3186
+ multiple,
3187
+ selectedOnly,
3188
+ showValue,
3189
+ showSearch: false,
3190
+ showActions: false,
3191
+ includeUnknownValues: false,
3192
+ columns: modalConfig?.columns ?? 3,
3193
+ maxHeight: modalConfig?.maxHeight ?? 360
3194
+ }
3195
+ )
3196
+ ] }) : null
3197
+ }
3198
+ ) : null
3199
+ ] });
3200
+ });
3201
+
2608
3202
  // src/components/Upload.tsx
2609
- var import_react16 = require("react");
2610
- var import_jsx_runtime17 = require("react/jsx-runtime");
3203
+ var import_react19 = require("react");
3204
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2611
3205
  var LIST_IGNORE = /* @__PURE__ */ Symbol("SIA_UPLOAD_LIST_IGNORE");
2612
3206
  function UploadRoot({
2613
3207
  accept,
@@ -2629,9 +3223,9 @@ function UploadRoot({
2629
3223
  onDrop,
2630
3224
  ...props
2631
3225
  }) {
2632
- const inputRef = (0, import_react16.useRef)(null);
2633
- const filesRef = (0, import_react16.useRef)(fileList ?? defaultFileList);
2634
- const id = (0, import_react16.useId)();
3226
+ const inputRef = (0, import_react19.useRef)(null);
3227
+ const filesRef = (0, import_react19.useRef)(fileList ?? defaultFileList);
3228
+ const id = (0, import_react19.useId)();
2635
3229
  const [files, setFiles] = useControllableState({ value: fileList, defaultValue: defaultFileList });
2636
3230
  filesRef.current = files;
2637
3231
  function emit(file, nextList) {
@@ -2690,7 +3284,7 @@ function UploadRoot({
2690
3284
  const next = files.filter((item) => item.uid !== file.uid);
2691
3285
  emit({ ...file, status: "ready" }, next);
2692
3286
  }
2693
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3287
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
2694
3288
  "div",
2695
3289
  {
2696
3290
  className: `sia-upload sia-upload--${listType} ${className}`.trim(),
@@ -2701,7 +3295,7 @@ function UploadRoot({
2701
3295
  onDrop: handleDrop,
2702
3296
  ...props,
2703
3297
  children: [
2704
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3298
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2705
3299
  "input",
2706
3300
  {
2707
3301
  ref: inputRef,
@@ -2715,245 +3309,29 @@ function UploadRoot({
2715
3309
  onChange: handleFiles
2716
3310
  }
2717
3311
  ),
2718
- /* @__PURE__ */ (0, 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 }) })
3312
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "sia-upload__trigger", onClick: () => !disabled && inputRef.current?.click(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "upload", size: 16 }), disabled, children: "\u9009\u62E9\u6587\u4EF6" }) }),
3313
+ showUploadList && files.length ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "sia-upload__list", children: files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: `sia-upload__item sia-upload__item--${file.status ?? "ready"}`, children: [
3314
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: file.status === "done" ? "circle-check" : "file", size: 16 }),
3315
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-upload__name", title: file.name, children: file.name }),
3316
+ file.status === "uploading" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-upload__progress", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { width: `${file.percent ?? 0}%` } }) }) : null,
3317
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", "aria-label": `\u79FB\u9664 ${file.name}`, onClick: () => void remove(file), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "close", size: 14 }) })
2724
3318
  ] }, file.uid)) }) : null
2725
3319
  ]
2726
3320
  }
2727
3321
  );
2728
3322
  }
2729
3323
  function UploadDragger({ hint = "\u652F\u6301\u5355\u4E2A\u6216\u6279\u91CF\u4E0A\u4F20", children, className = "", ...props }) {
2730
- return /* @__PURE__ */ (0, 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 })
3324
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(UploadRoot, { ...props, className: `sia-upload-dragger ${className}`.trim(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "sia-upload-dragger__content", children: [
3325
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, { name: "upload", size: 28 }),
3326
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("strong", { children: "\u70B9\u51FB\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u6B64\u533A\u57DF\u4E0A\u4F20" }),
3327
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: hint })
2734
3328
  ] }) });
2735
3329
  }
2736
3330
  var Upload = Object.assign(UploadRoot, { Dragger: UploadDragger, LIST_IGNORE });
2737
3331
 
2738
- // src/components/Modal.tsx
2739
- var import_react17 = require("react");
2740
- var import_client2 = require("react-dom/client");
2741
- var import_jsx_runtime18 = require("react/jsx-runtime");
2742
- var modalHandles = /* @__PURE__ */ new Set();
2743
- var MODAL_MOTION_DURATION = 220;
2744
- var typeIcons = {
2745
- info: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "info", size: 23 }),
2746
- success: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "circle-check", size: 23 }),
2747
- warning: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "warning", size: 23 }),
2748
- error: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "circle-close", size: 23 }),
2749
- confirm: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "question", size: 23 })
2750
- };
2751
- var ModalRoot = (0, import_react17.forwardRef)(function Modal({
2752
- open,
2753
- title,
2754
- children,
2755
- footer,
2756
- type = "default",
2757
- okText = "\u786E\u5B9A",
2758
- cancelText = "\u53D6\u6D88",
2759
- showCancel = type === "default" || type === "confirm",
2760
- confirmLoading = false,
2761
- okButtonProps,
2762
- cancelButtonProps,
2763
- closable = true,
2764
- maskClosable = true,
2765
- keyboard = true,
2766
- centered = false,
2767
- width = 520,
2768
- zIndex = 1e3,
2769
- getContainer,
2770
- onOk,
2771
- onCancel,
2772
- onOpenChange,
2773
- afterOpenChange,
2774
- className = "",
2775
- style,
2776
- ...props
2777
- }, forwardedRef) {
2778
- const localRef = (0, import_react17.useRef)(null);
2779
- const titleId = (0, import_react17.useId)();
2780
- const [submitting, setSubmitting] = (0, import_react17.useState)(false);
2781
- const [rendered, setRendered] = (0, import_react17.useState)(open);
2782
- const [closing, setClosing] = (0, import_react17.useState)(false);
2783
- const afterOpenChangeRef = (0, import_react17.useRef)(afterOpenChange);
2784
- afterOpenChangeRef.current = afterOpenChange;
2785
- const submitLock = (0, import_react17.useRef)(false);
2786
- (0, import_react17.useEffect)(() => {
2787
- if (!open || !rendered) return void 0;
2788
- const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
2789
- return () => window.clearTimeout(timer);
2790
- }, [open, rendered]);
2791
- (0, import_react17.useEffect)(() => {
2792
- if (open) {
2793
- setRendered(true);
2794
- setClosing(false);
2795
- return void 0;
2796
- }
2797
- if (!rendered) return void 0;
2798
- setClosing(true);
2799
- const timer = window.setTimeout(() => {
2800
- setRendered(false);
2801
- setClosing(false);
2802
- afterOpenChangeRef.current?.(false);
2803
- }, MODAL_MOTION_DURATION);
2804
- return () => window.clearTimeout(timer);
2805
- }, [open, rendered]);
2806
- function setRef(node) {
2807
- localRef.current = node;
2808
- if (typeof forwardedRef === "function") forwardedRef(node);
2809
- else if (forwardedRef) forwardedRef.current = node;
2810
- }
2811
- function requestClose() {
2812
- if (submitting || confirmLoading) return;
2813
- onCancel?.();
2814
- onOpenChange?.(false);
2815
- }
2816
- async function handleOk() {
2817
- if (submitLock.current || confirmLoading) return;
2818
- submitLock.current = true;
2819
- if (!onOk) {
2820
- onOpenChange?.(false);
2821
- submitLock.current = false;
2822
- return;
2823
- }
2824
- try {
2825
- const result = onOk();
2826
- if (result instanceof Promise) {
2827
- setSubmitting(true);
2828
- const resolved = await result;
2829
- if (resolved !== false) onOpenChange?.(false);
2830
- } else if (result !== false) {
2831
- onOpenChange?.(false);
2832
- }
2833
- } catch {
2834
- return;
2835
- } finally {
2836
- submitLock.current = false;
2837
- setSubmitting(false);
2838
- }
2839
- }
2840
- useOverlayLifecycle(rendered, localRef, requestClose, keyboard);
2841
- if (!rendered) return null;
2842
- const mergedStyle = {
2843
- ...style,
2844
- "--sia-modal-width": typeof width === "number" ? `${width}px` : width
2845
- };
2846
- const loading = submitting || confirmLoading;
2847
- const defaultFooter = /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
2848
- showCancel ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { ...cancelButtonProps, onClick: requestClose, disabled: loading || cancelButtonProps?.disabled, children: cancelText }) : null,
2849
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { variant: "primary", ...okButtonProps, onClick: handleOk, loading, children: okText })
2850
- ] });
2851
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(OverlayPortal, { container: getContainer, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2852
- "div",
2853
- {
2854
- className: `sia-modal-root${centered ? " sia-modal-root--centered" : ""}`,
2855
- "data-state": closing ? "closing" : "open",
2856
- style: { zIndex },
2857
- onMouseDown: (event) => {
2858
- if (event.target === event.currentTarget && maskClosable) requestClose();
2859
- },
2860
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2861
- "div",
2862
- {
2863
- ref: setRef,
2864
- className: `sia-modal sia-modal--${type} ${className}`.trim(),
2865
- style: mergedStyle,
2866
- role: "dialog",
2867
- "aria-modal": "true",
2868
- "aria-labelledby": title ? titleId : void 0,
2869
- tabIndex: -1,
2870
- ...props,
2871
- children: [
2872
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sia-modal__header", children: [
2873
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sia-modal__heading", children: [
2874
- typeIcons[type] ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-modal__type-icon", "aria-hidden": "true", children: typeIcons[type] }) : null,
2875
- title ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("strong", { id: titleId, children: title }) : null
2876
- ] }),
2877
- closable ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "button", className: "sia-modal__close", "aria-label": "\u5173\u95ED\u5BF9\u8BDD\u6846", onClick: requestClose, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "close", size: 17 }) }) : null
2878
- ] }),
2879
- children !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "sia-modal__body", children }) : null,
2880
- footer !== null ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "sia-modal__footer", children: footer ?? defaultFooter }) : null
2881
- ]
2882
- }
2883
- )
2884
- }
2885
- ) });
2886
- });
2887
- function openModal(config) {
2888
- if (typeof document === "undefined") return { destroy() {
2889
- }, update() {
2890
- } };
2891
- const container = document.createElement("div");
2892
- container.className = "sia-modal-api-host";
2893
- document.body.appendChild(container);
2894
- const root = (0, import_client2.createRoot)(container);
2895
- let currentConfig = config;
2896
- let currentOpen = true;
2897
- let destroyed = false;
2898
- let cleanupTimer;
2899
- function cleanup() {
2900
- if (destroyed) return;
2901
- destroyed = true;
2902
- if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
2903
- root.unmount();
2904
- container.remove();
2905
- modalHandles.delete(handle);
2906
- }
2907
- function closeWithMotion() {
2908
- if (destroyed || !currentOpen) return;
2909
- currentOpen = false;
2910
- render();
2911
- cleanupTimer = window.setTimeout(cleanup, MODAL_MOTION_DURATION);
2912
- }
2913
- function render() {
2914
- root.render(/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
2915
- currentConfig.onOpenChange?.(nextOpen);
2916
- if (!nextOpen) closeWithMotion();
2917
- } }));
2918
- }
2919
- const handle = {
2920
- destroy: closeWithMotion,
2921
- update(next) {
2922
- if (destroyed) return;
2923
- currentConfig = { ...currentConfig, ...next };
2924
- render();
2925
- }
2926
- };
2927
- modalHandles.add(handle);
2928
- render();
2929
- return handle;
2930
- }
2931
- function preset(type, defaults = {}) {
2932
- return (config) => openModal({
2933
- okText: type === "confirm" ? "\u786E\u5B9A" : "\u77E5\u9053\u4E86",
2934
- showCancel: type === "confirm",
2935
- closable: type !== "confirm",
2936
- maskClosable: type !== "confirm",
2937
- ...defaults,
2938
- ...config,
2939
- type
2940
- });
2941
- }
2942
- var Modal2 = Object.assign(ModalRoot, {
2943
- open: openModal,
2944
- info: preset("info", { title: "\u63D0\u793A" }),
2945
- success: preset("success", { title: "\u64CD\u4F5C\u6210\u529F" }),
2946
- warning: preset("warning", { title: "\u8BF7\u6CE8\u610F" }),
2947
- error: preset("error", { title: "\u64CD\u4F5C\u5931\u8D25" }),
2948
- confirm: preset("confirm", { title: "\u786E\u8BA4\u64CD\u4F5C" }),
2949
- destroyAll() {
2950
- [...modalHandles].forEach((handle) => handle.destroy());
2951
- }
2952
- });
2953
-
2954
3332
  // src/components/Message.tsx
2955
3333
  var import_client3 = require("react-dom/client");
2956
- var import_jsx_runtime19 = require("react/jsx-runtime");
3334
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2957
3335
  var messageSeed = 0;
2958
3336
  var messageRoot = null;
2959
3337
  var messageContainer = null;
@@ -2962,11 +3340,11 @@ var defaultDuration = 3;
2962
3340
  var maxCount = 5;
2963
3341
  var messageTimers = /* @__PURE__ */ new Map();
2964
3342
  var messageIcons = {
2965
- info: /* @__PURE__ */ (0, 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 })
3343
+ info: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "info", size: 18 }),
3344
+ success: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "circle-check", size: 18 }),
3345
+ warning: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "warning", size: 18 }),
3346
+ error: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "circle-close", size: 18 }),
3347
+ loading: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "loader", size: 18, spin: true })
2970
3348
  };
2971
3349
  function ensureMessageRoot() {
2972
3350
  if (typeof document === "undefined") return false;
@@ -2980,10 +3358,10 @@ function ensureMessageRoot() {
2980
3358
  }
2981
3359
  function renderMessages() {
2982
3360
  if (!ensureMessageRoot()) return;
2983
- messageRoot.render(/* @__PURE__ */ (0, 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
3361
+ messageRoot.render(/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "sia-message-list", "aria-live": "polite", children: messageItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `sia-message sia-message--${item.type}`, role: item.type === "loading" ? "status" : "alert", children: [
3362
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sia-message__icon", "aria-hidden": "true", children: messageIcons[item.type] }),
3363
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sia-message__content", children: item.content }),
3364
+ item.closable ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", className: "sia-message__close", "aria-label": "\u5173\u95ED\u63D0\u793A", onClick: () => closeMessage(item.key), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "close", size: 14 }) }) : null
2987
3365
  ] }, item.key)) }));
2988
3366
  }
2989
3367
  function closeMessage(key) {
@@ -3049,33 +3427,33 @@ var message = {
3049
3427
  };
3050
3428
 
3051
3429
  // src/components/Breadcrumb.tsx
3052
- var import_jsx_runtime20 = require("react/jsx-runtime");
3430
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3053
3431
  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) => {
3432
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("nav", { "aria-label": "\u9762\u5305\u5C51\u5BFC\u822A", ...props, className: `sia-breadcrumb ${className}`.trim(), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ol", { className: "sia-breadcrumb__list", children: items.map((item, index) => {
3055
3433
  const current = index === items.length - 1;
3056
- const content = /* @__PURE__ */ (0, 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 })
3434
+ const content = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3435
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__icon", "aria-hidden": "true", children: item.icon }) : null,
3436
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__title", children: item.title })
3059
3437
  ] });
3060
3438
  const custom = itemRender?.(item, index, items);
3061
- const label = item.disabled ? /* @__PURE__ */ (0, 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: [
3439
+ const label = item.disabled ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__label", "aria-disabled": "true", children: content }) : custom !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__label", children: custom }) : item.href ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "sia-breadcrumb__label", href: item.href, target: item.target, rel: item.target === "_blank" ? "noopener noreferrer" : void 0, onClick: item.onClick, children: content }) : item.onClick ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { className: "sia-breadcrumb__label", variant: "text", onClick: item.onClick, children: content }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__label", children: content });
3440
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("li", { className: `sia-breadcrumb__item${current ? " is-current" : ""}${item.disabled ? " is-disabled" : ""}`, children: [
3441
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "sia-breadcrumb__entry", "aria-current": current ? "page" : void 0, children: [
3064
3442
  label,
3065
- item.menu?.items.length ? /* @__PURE__ */ (0, 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
3443
+ item.menu?.items.length ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Dropdown, { menu: item.menu, trigger: ["click"], disabled: item.disabled, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { className: "sia-breadcrumb__menu-trigger", variant: "text", size: "small", disabled: item.disabled, "aria-label": `\u5C55\u5F00${typeof item.title === "string" ? item.title : "\u5C42\u7EA7"}\u83DC\u5355`, icon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Icon, { name: "chevron-down", size: 12 }) }) }) : null
3066
3444
  ] }),
3067
- !current ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sia-breadcrumb__separator", "aria-hidden": "true", children: item.separator === void 0 ? separator : item.separator }) : null
3445
+ !current ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sia-breadcrumb__separator", "aria-hidden": "true", children: item.separator === void 0 ? separator : item.separator }) : null
3068
3446
  ] }, item.key ?? index);
3069
3447
  }) }) });
3070
3448
  }
3071
3449
 
3072
3450
  // src/components/Typography.tsx
3073
- var import_react19 = require("react");
3451
+ var import_react21 = require("react");
3074
3452
 
3075
3453
  // 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({
3454
+ var import_react20 = require("react");
3455
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3456
+ var TextArea = (0, import_react20.forwardRef)(function TextArea2({
3079
3457
  label,
3080
3458
  hint,
3081
3459
  status = "default",
@@ -3091,9 +3469,9 @@ var TextArea = (0, import_react18.forwardRef)(function TextArea2({
3091
3469
  onChange,
3092
3470
  ...props
3093
3471
  }, ref) {
3094
- const fallbackId = (0, import_react18.useId)();
3472
+ const fallbackId = (0, import_react20.useId)();
3095
3473
  const textAreaId = id ?? fallbackId;
3096
- const [uncontrolledValue, setUncontrolledValue] = (0, import_react18.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
3474
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react20.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
3097
3475
  const currentText = value !== void 0 ? String(value) : uncontrolledValue;
3098
3476
  const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: currentText.length > 0 });
3099
3477
  const hintId = `${textAreaId}-hint`;
@@ -3102,8 +3480,8 @@ var TextArea = (0, import_react18.forwardRef)(function TextArea2({
3102
3480
  setUncontrolledValue(event.target.value);
3103
3481
  onChange?.(event);
3104
3482
  }
3105
- const control = /* @__PURE__ */ (0, 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)(
3483
+ const control = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: `sia-textarea-control sia-textarea-control--${status}${floating.className}${disabled ? " is-disabled" : ""}`, children: [
3484
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3107
3485
  "textarea",
3108
3486
  {
3109
3487
  ...props,
@@ -3121,21 +3499,21 @@ var TextArea = (0, import_react18.forwardRef)(function TextArea2({
3121
3499
  }
3122
3500
  ),
3123
3501
  floating.label,
3124
- showCount ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: `sia-textarea-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
3502
+ showCount ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: `sia-textarea-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
3125
3503
  currentText.length,
3126
3504
  maxLength !== void 0 ? `/${maxLength}` : null
3127
3505
  ] }) : null
3128
3506
  ] });
3129
- if (!label && !hint) return /* @__PURE__ */ (0, 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,
3507
+ if (!label && !hint) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `sia-field ${className}`.trim(), children: control });
3508
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: `sia-field ${className}`.trim(), children: [
3509
+ label ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { className: "sia-field__label", htmlFor: textAreaId, children: label }) : null,
3132
3510
  control,
3133
- hint ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
3511
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
3134
3512
  ] });
3135
3513
  });
3136
3514
 
3137
3515
  // src/components/Typography.tsx
3138
- var import_jsx_runtime22 = require("react/jsx-runtime");
3516
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3139
3517
  function TypographyContent({
3140
3518
  as: Tag2 = "span",
3141
3519
  type,
@@ -3154,26 +3532,26 @@ function TypographyContent({
3154
3532
  className = "",
3155
3533
  ...props
3156
3534
  }) {
3157
- const contentRef = (0, 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);
3535
+ const contentRef = (0, import_react21.useRef)(null);
3536
+ const editRef = (0, import_react21.useRef)(null);
3537
+ const timer = (0, import_react21.useRef)();
3538
+ const [localText, setLocalText] = (0, import_react21.useState)();
3539
+ const [draft, setDraft] = (0, import_react21.useState)("");
3540
+ const [editing, setEditing] = (0, import_react21.useState)(false);
3541
+ const [copied, setCopied] = (0, import_react21.useState)(false);
3542
+ const [copyError, setCopyError] = (0, import_react21.useState)(false);
3543
+ const [expanded, setExpanded] = (0, import_react21.useState)(false);
3544
+ const [overflow, setOverflow] = (0, import_react21.useState)(false);
3167
3545
  const editConfig = typeof editable === "object" ? editable : void 0;
3168
3546
  const content = editConfig?.text ?? localText ?? children;
3169
3547
  const requestedRows = typeof ellipsis === "object" ? ellipsis.rows ?? 1 : 1;
3170
3548
  const rows = Number.isFinite(requestedRows) ? Math.max(1, Math.floor(requestedRows)) : 1;
3171
3549
  const expandable = typeof ellipsis === "object" && ellipsis.expandable;
3172
- (0, import_react19.useEffect)(() => {
3550
+ (0, import_react21.useEffect)(() => {
3173
3551
  setLocalText(void 0);
3174
3552
  }, [children]);
3175
- (0, import_react19.useEffect)(() => () => clearTimeout(timer.current), []);
3176
- (0, import_react19.useLayoutEffect)(() => {
3553
+ (0, import_react21.useEffect)(() => () => clearTimeout(timer.current), []);
3554
+ (0, import_react21.useLayoutEffect)(() => {
3177
3555
  const element = contentRef.current;
3178
3556
  if (!element || !ellipsis || editing || expanded) return;
3179
3557
  const measure = () => setOverflow(element.scrollHeight > element.clientHeight + 1 || element.scrollWidth > element.clientWidth + 1);
@@ -3204,15 +3582,15 @@ function TypographyContent({
3204
3582
  requestAnimationFrame(() => editRef.current?.focus());
3205
3583
  }
3206
3584
  let formatted = content;
3207
- if (strong) formatted = /* @__PURE__ */ (0, 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)(
3585
+ if (strong) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("strong", { children: formatted });
3586
+ if (italic) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("em", { children: formatted });
3587
+ if (underline) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("u", { children: formatted });
3588
+ if (deleted) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("del", { children: formatted });
3589
+ if (mark) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("mark", { children: formatted });
3590
+ if (code) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("code", { children: formatted });
3591
+ if (keyboard) formatted = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("kbd", { children: formatted });
3592
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Tag2, { ...props, "aria-disabled": disabled || void 0, className: `sia-typography sia-typography--${Tag2}${type ? ` sia-typography--${type}` : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), children: editing ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "sia-typography__editor", children: [
3593
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3216
3594
  TextArea,
3217
3595
  {
3218
3596
  autoFocus: true,
@@ -3234,32 +3612,32 @@ function TypographyContent({
3234
3612
  }
3235
3613
  }
3236
3614
  ),
3237
- /* @__PURE__ */ (0, 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" })
3615
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "sia-typography__edit-actions", children: [
3616
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { size: "small", onClick: () => finish(false), children: "\u53D6\u6D88" }),
3617
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { size: "small", variant: "primary", onClick: () => finish(true), children: "\u4FDD\u5B58" })
3240
3618
  ] })
3241
- ] }) : /* @__PURE__ */ (0, 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: () => {
3619
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
3620
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { ref: contentRef, className: ellipsis && !expanded ? "sia-typography__ellipsis" : void 0, style: ellipsis && !expanded ? { "--sia-typography-rows": rows } : void 0, children: formatted }),
3621
+ expandable && (overflow || expanded) ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { variant: "link", size: "small", className: "sia-typography__action", "aria-expanded": expanded, disabled, onClick: () => setExpanded(!expanded), children: expanded ? "\u6536\u8D77" : "\u5C55\u5F00" }) : null,
3622
+ editable ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { ref: editRef, variant: "text", size: "small", className: "sia-typography__action", "aria-label": "\u7F16\u8F91\u6587\u672C", title: "\u7F16\u8F91", disabled, icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Icon, { name: "edit", size: 14 }), onClick: () => {
3245
3623
  setDraft(contentRef.current?.textContent ?? "");
3246
3624
  setEditing(true);
3247
3625
  } }) : null,
3248
- copyable ? /* @__PURE__ */ (0, 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
3626
+ copyable ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { variant: "text", size: "small", className: "sia-typography__action", "aria-label": copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236\u6587\u672C", title: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236", disabled, icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Icon, { name: copied ? "check" : "copy", size: 14 }), onClick: () => void copy() }) : null,
3627
+ copyError ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { role: "status", className: "sia-typography--danger", children: "\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u6587\u672C\u590D\u5236\u3002" }) : null
3250
3628
  ] }) });
3251
3629
  }
3252
3630
  function Title({ level = 1, ...props }) {
3253
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TypographyContent, { ...props, as: `h${level}` });
3631
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props, as: `h${level}` });
3254
3632
  }
3255
3633
  function Text(props) {
3256
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TypographyContent, { ...props });
3634
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props });
3257
3635
  }
3258
3636
  function Paragraph(props) {
3259
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TypographyContent, { ...props, as: "p" });
3637
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TypographyContent, { ...props, as: "p" });
3260
3638
  }
3261
3639
  function Link({ disabled, className = "", onClick, href, target, rel, ...props }) {
3262
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3640
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3263
3641
  "a",
3264
3642
  {
3265
3643
  ...props,
@@ -3277,15 +3655,15 @@ function Link({ disabled, className = "", onClick, href, target, rel, ...props }
3277
3655
  );
3278
3656
  }
3279
3657
  function TypographyRoot({ className = "", ...props }) {
3280
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { ...props, className: `sia-typography ${className}`.trim() });
3658
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ...props, className: `sia-typography ${className}`.trim() });
3281
3659
  }
3282
3660
  var Typography = Object.assign(TypographyRoot, { Title, Text, Paragraph, Link });
3283
3661
 
3284
3662
  // src/components/FloatButton.tsx
3285
- var 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({
3663
+ var import_react22 = require("react");
3664
+ var import_jsx_runtime25 = require("react/jsx-runtime");
3665
+ var GroupShape = (0, import_react22.createContext)(void 0);
3666
+ var FloatButtonRoot = (0, import_react22.forwardRef)(function FloatButton({
3289
3667
  icon,
3290
3668
  description,
3291
3669
  tooltip,
@@ -3298,9 +3676,9 @@ var FloatButtonRoot = (0, import_react20.forwardRef)(function FloatButton({
3298
3676
  children,
3299
3677
  ...props
3300
3678
  }, ref) {
3301
- const groupShape = (0, import_react20.useContext)(GroupShape);
3679
+ const groupShape = (0, import_react22.useContext)(GroupShape);
3302
3680
  const label = props["aria-label"] ?? (typeof tooltip === "string" ? tooltip : typeof description === "string" ? description : "\u60AC\u6D6E\u64CD\u4F5C");
3303
- const button = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3681
+ const button = /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3304
3682
  "button",
3305
3683
  {
3306
3684
  ...props,
@@ -3308,13 +3686,13 @@ var FloatButtonRoot = (0, import_react20.forwardRef)(function FloatButton({
3308
3686
  type: htmlType,
3309
3687
  "aria-label": label,
3310
3688
  className: `sia-float-button sia-float-button--${groupShape ?? shape} sia-float-button--${type} ${className}`.trim(),
3311
- children: /* @__PURE__ */ (0, 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
3689
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Badge, { ...badge, className: "sia-float-button__badge", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "sia-float-button__body", children: [
3690
+ icon !== null ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sia-float-button__icon", children: icon ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { name: "question", size: 20 }) }) : null,
3691
+ description != null || children != null ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sia-float-button__description", children: description ?? children }) : null
3314
3692
  ] }) })
3315
3693
  }
3316
3694
  );
3317
- return /* @__PURE__ */ (0, 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 });
3695
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sia-float-button-root", style, children: tooltip ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Tooltip, { title: tooltip, placement: "left", children: button }) : button });
3318
3696
  });
3319
3697
  function FloatButtonGroup({
3320
3698
  shape = "circle",
@@ -3336,10 +3714,10 @@ function FloatButtonGroup({
3336
3714
  ...props
3337
3715
  }) {
3338
3716
  const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
3339
- const rootRef = (0, import_react20.useRef)(null);
3340
- const triggerRef = (0, import_react20.useRef)(null);
3341
- const id = (0, import_react20.useId)();
3342
- (0, import_react20.useEffect)(() => {
3717
+ const rootRef = (0, import_react22.useRef)(null);
3718
+ const triggerRef = (0, import_react22.useRef)(null);
3719
+ const id = (0, import_react22.useId)();
3720
+ (0, import_react22.useEffect)(() => {
3343
3721
  if (!trigger || !visible) return;
3344
3722
  const close = (event) => {
3345
3723
  if (!rootRef.current?.contains(event.target)) setVisible(false);
@@ -3347,7 +3725,7 @@ function FloatButtonGroup({
3347
3725
  document.addEventListener("pointerdown", close);
3348
3726
  return () => document.removeEventListener("pointerdown", close);
3349
3727
  }, [trigger, visible, setVisible]);
3350
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(GroupShape.Provider, { value: shape, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
3728
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GroupShape.Provider, { value: shape, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3351
3729
  "div",
3352
3730
  {
3353
3731
  ...props,
@@ -3374,13 +3752,13 @@ function FloatButtonGroup({
3374
3752
  }
3375
3753
  },
3376
3754
  children: [
3377
- !trigger || visible ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { id, className: "sia-float-button-group__list", children }) : null,
3378
- trigger ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3755
+ !trigger || visible ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { id, className: "sia-float-button-group__list", children }) : null,
3756
+ trigger ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3379
3757
  FloatButtonRoot,
3380
3758
  {
3381
3759
  ref: triggerRef,
3382
3760
  type,
3383
- icon: visible ? closeIcon ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { name: "close", size: 20 }) : icon ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { name: "plus", size: 20 }),
3761
+ icon: visible ? closeIcon ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { name: "close", size: 20 }) : icon ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { name: "plus", size: 20 }),
3384
3762
  tooltip,
3385
3763
  "aria-label": visible ? "\u6536\u8D77\u60AC\u6D6E\u83DC\u5355" : "\u5C55\u5F00\u60AC\u6D6E\u83DC\u5355",
3386
3764
  "aria-expanded": visible,
@@ -3393,8 +3771,8 @@ function FloatButtonGroup({
3393
3771
  ) });
3394
3772
  }
3395
3773
  function FloatButtonBackTop({ target, visibilityHeight = 400, behavior = "smooth", onClick, icon, tooltip = "\u8FD4\u56DE\u9876\u90E8", ...props }) {
3396
- const [visible, setVisible] = (0, import_react20.useState)(false);
3397
- (0, import_react20.useEffect)(() => {
3774
+ const [visible, setVisible] = (0, import_react22.useState)(false);
3775
+ (0, import_react22.useEffect)(() => {
3398
3776
  const element = target ? target() : window;
3399
3777
  if (!element) return;
3400
3778
  const update = () => setVisible((element === window ? window.scrollY : element.scrollTop) >= visibilityHeight);
@@ -3403,7 +3781,7 @@ function FloatButtonBackTop({ target, visibilityHeight = 400, behavior = "smooth
3403
3781
  return () => element.removeEventListener("scroll", update);
3404
3782
  }, [target, visibilityHeight]);
3405
3783
  if (!visible) return null;
3406
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(FloatButtonRoot, { ...props, tooltip, icon: icon ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { name: "arrow-up", size: 20 }), onClick: (event) => {
3784
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FloatButtonRoot, { ...props, tooltip, icon: icon ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { name: "arrow-up", size: 20 }), onClick: (event) => {
3407
3785
  onClick?.(event);
3408
3786
  if (event.defaultPrevented) return;
3409
3787
  const element = target ? target() : window;