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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1375,15 +1375,15 @@ function DatePicker({
1375
1375
  allowClear && display && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "sia-picker__clear", "aria-label": "\u6E05\u9664\u65E5\u671F", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
1376
1376
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: visible, className: `sia-date-panel${showTime ? " sia-date-panel--with-time" : ""}${presets?.length ? " sia-date-panel--with-presets" : ""}`, role: "dialog", "aria-label": "\u65E5\u671F\u9009\u62E9\u9762\u677F", children: [
1377
1377
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sia-date-panel__body", children: [
1378
- presets?.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("aside", { className: "sia-date-panel__presets", children: presets.map((preset, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => {
1379
- const next = resolvePreset(preset.value);
1378
+ presets?.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("aside", { className: "sia-date-panel__presets", children: presets.map((preset2, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => {
1379
+ const next = resolvePreset(preset2.value);
1380
1380
  if (!next || isDisabled(dayFromValue(next))) return;
1381
1381
  setDraftValue(next);
1382
1382
  if (!resolvedNeedConfirm) {
1383
1383
  setCurrentValue(next);
1384
1384
  changeOpen(false);
1385
1385
  }
1386
- }, children: preset.label }, index)) }) : null,
1386
+ }, children: preset2.label }, index)) }) : null,
1387
1387
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "sia-date-panel__calendar", children: [
1388
1388
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1389
1389
  CalendarHeader,
@@ -1616,8 +1616,8 @@ function DateRangePicker({
1616
1616
  setCurrentValue(draftValue);
1617
1617
  changeOpen(false);
1618
1618
  }
1619
- function applyPreset(preset) {
1620
- const raw = resolveRangePreset(preset.value);
1619
+ function applyPreset(preset2) {
1620
+ const raw = resolveRangePreset(preset2.value);
1621
1621
  const next = [
1622
1622
  normalizeDateValue(raw[0], showTime),
1623
1623
  normalizeDateValue(raw[1], showTime, 1)
@@ -1753,7 +1753,7 @@ function DateRangePicker({
1753
1753
  confirmText: compactDateTime && showTime && activeIndex === 0 ? "\u4E0B\u4E00\u6B65" : "\u786E\u5B9A",
1754
1754
  extra: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1755
1755
  renderExtraFooter?.(),
1756
- presets?.map((preset, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => applyPreset(preset), children: preset.label }, index)),
1756
+ presets?.map((preset2, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => applyPreset(preset2), children: preset2.label }, index)),
1757
1757
  compactDateTime && showTime && activeIndex === 1 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => {
1758
1758
  setActiveIndex(0);
1759
1759
  setViewMonth(startOfMonth(parseDate(dayFromValue(draftValue[0])) ?? /* @__PURE__ */ new Date()));
@@ -1776,17 +1776,912 @@ function DateRangePicker({
1776
1776
  })(DatePicker || (DatePicker = {}));
1777
1777
 
1778
1778
  // src/components/Select.tsx
1779
- var import_react7 = require("react");
1779
+ var import_react14 = require("react");
1780
1780
 
1781
- // src/components/OverflowTags.tsx
1781
+ // src/components/Modal.tsx
1782
+ var import_react8 = require("react");
1783
+ var import_client = require("react-dom/client");
1784
+
1785
+ // src/components/Button.tsx
1782
1786
  var import_react6 = require("react");
1783
1787
  var import_jsx_runtime7 = require("react/jsx-runtime");
1788
+ var Button = (0, import_react6.forwardRef)(function Button2({
1789
+ variant = "default",
1790
+ size = "medium",
1791
+ loading = false,
1792
+ block = false,
1793
+ danger = false,
1794
+ icon,
1795
+ iconPosition = "start",
1796
+ className = "",
1797
+ children,
1798
+ disabled,
1799
+ onClick,
1800
+ style,
1801
+ ...props
1802
+ }, forwardedRef) {
1803
+ const localRef = (0, import_react6.useRef)(null);
1804
+ function setRef(node) {
1805
+ localRef.current = node;
1806
+ if (typeof forwardedRef === "function") forwardedRef(node);
1807
+ else if (forwardedRef) forwardedRef.current = node;
1808
+ }
1809
+ function handleClick(event) {
1810
+ const button = localRef.current;
1811
+ if (button && variant === "primary") {
1812
+ const rect = button.getBoundingClientRect();
1813
+ button.style.setProperty("--sia-wave-x", `${event.clientX - rect.left}px`);
1814
+ button.style.setProperty("--sia-wave-y", `${event.clientY - rect.top}px`);
1815
+ button.dataset.wave = "active";
1816
+ window.setTimeout(() => delete button.dataset.wave, 360);
1817
+ }
1818
+ onClick?.(event);
1819
+ }
1820
+ const mergedStyle = block ? { ...style, width: "100%" } : style ?? {};
1821
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1822
+ "button",
1823
+ {
1824
+ ref: setRef,
1825
+ type: "button",
1826
+ className: `sia-button sia-button--${variant} sia-button--${size}${danger ? " sia-button--danger" : ""} ${className}`.trim(),
1827
+ "aria-busy": loading || void 0,
1828
+ disabled: disabled || loading,
1829
+ onClick: handleClick,
1830
+ style: mergedStyle,
1831
+ ...props,
1832
+ children: [
1833
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sia-button__spinner", "aria-hidden": "true" }) : icon && iconPosition === "start" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sia-button__icon", children: icon }) : null,
1834
+ children !== void 0 && children !== null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children }) : null,
1835
+ !loading && icon && iconPosition === "end" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sia-button__icon", children: icon }) : null
1836
+ ]
1837
+ }
1838
+ );
1839
+ });
1840
+
1841
+ // src/components/Overlay.tsx
1842
+ var import_react7 = require("react");
1843
+ var import_react_dom2 = require("react-dom");
1844
+ var bodyLockCount = 0;
1845
+ var previousBodyOverflow = "";
1846
+ var overlayStack = [];
1847
+ function lockBodyScroll() {
1848
+ if (bodyLockCount === 0) {
1849
+ previousBodyOverflow = document.body.style.overflow;
1850
+ document.body.style.overflow = "hidden";
1851
+ }
1852
+ bodyLockCount += 1;
1853
+ return () => {
1854
+ bodyLockCount = Math.max(0, bodyLockCount - 1);
1855
+ if (bodyLockCount === 0) document.body.style.overflow = previousBodyOverflow;
1856
+ };
1857
+ }
1858
+ function focusableElements(container) {
1859
+ return [...container.querySelectorAll(
1860
+ 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
1861
+ )].filter((element) => !element.hidden && element.getAttribute("aria-hidden") !== "true");
1862
+ }
1863
+ function useOverlayLifecycle(open, panelRef, onRequestClose, keyboard = true) {
1864
+ const overlayIdRef = (0, import_react7.useRef)(/* @__PURE__ */ Symbol("sia-overlay"));
1865
+ const closeRef = (0, import_react7.useRef)(onRequestClose);
1866
+ closeRef.current = onRequestClose;
1867
+ (0, import_react7.useEffect)(() => {
1868
+ if (!open || typeof document === "undefined") return void 0;
1869
+ const overlayId = overlayIdRef.current;
1870
+ const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
1871
+ overlayStack.push(overlayId);
1872
+ const unlockBody = lockBodyScroll();
1873
+ const focusTimer = window.setTimeout(() => {
1874
+ const panel = panelRef.current;
1875
+ if (!panel) return;
1876
+ const [firstFocusable] = focusableElements(panel);
1877
+ (firstFocusable ?? panel).focus({ preventScroll: true });
1878
+ }, 0);
1879
+ function handleKeyDown(event) {
1880
+ if (overlayStack.at(-1) !== overlayId) return;
1881
+ if (event.key === "Escape" && keyboard) {
1882
+ event.preventDefault();
1883
+ closeRef.current();
1884
+ return;
1885
+ }
1886
+ if (event.key !== "Tab" || !panelRef.current) return;
1887
+ const focusable = focusableElements(panelRef.current);
1888
+ if (focusable.length === 0) {
1889
+ event.preventDefault();
1890
+ panelRef.current.focus();
1891
+ return;
1892
+ }
1893
+ const first = focusable[0];
1894
+ const last = focusable.at(-1);
1895
+ if (event.shiftKey && document.activeElement === first) {
1896
+ event.preventDefault();
1897
+ last.focus();
1898
+ } else if (!event.shiftKey && document.activeElement === last) {
1899
+ event.preventDefault();
1900
+ first.focus();
1901
+ }
1902
+ }
1903
+ document.addEventListener("keydown", handleKeyDown);
1904
+ return () => {
1905
+ window.clearTimeout(focusTimer);
1906
+ document.removeEventListener("keydown", handleKeyDown);
1907
+ const index = overlayStack.lastIndexOf(overlayId);
1908
+ if (index >= 0) overlayStack.splice(index, 1);
1909
+ unlockBody();
1910
+ previouslyFocused?.focus({ preventScroll: true });
1911
+ };
1912
+ }, [keyboard, open, panelRef]);
1913
+ }
1914
+ function OverlayPortal({ children, container }) {
1915
+ if (typeof document === "undefined") return null;
1916
+ const target = typeof container === "function" ? container() : container ?? document.body;
1917
+ return (0, import_react_dom2.createPortal)(children, target);
1918
+ }
1919
+
1920
+ // src/components/Modal.tsx
1921
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1922
+ var modalHandles = /* @__PURE__ */ new Set();
1923
+ var MODAL_MOTION_DURATION = 220;
1924
+ var typeIcons = {
1925
+ info: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "info", size: 23 }),
1926
+ success: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "circle-check", size: 23 }),
1927
+ warning: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "warning", size: 23 }),
1928
+ error: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "circle-close", size: 23 }),
1929
+ confirm: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "question", size: 23 })
1930
+ };
1931
+ var ModalRoot = (0, import_react8.forwardRef)(function Modal({
1932
+ open,
1933
+ title,
1934
+ children,
1935
+ footer,
1936
+ type = "default",
1937
+ okText = "\u786E\u5B9A",
1938
+ cancelText = "\u53D6\u6D88",
1939
+ showCancel = type === "default" || type === "confirm",
1940
+ confirmLoading = false,
1941
+ okButtonProps,
1942
+ cancelButtonProps,
1943
+ closable = true,
1944
+ maskClosable = true,
1945
+ keyboard = true,
1946
+ centered = false,
1947
+ width = 520,
1948
+ zIndex = 1e3,
1949
+ getContainer,
1950
+ onOk,
1951
+ onCancel,
1952
+ onOpenChange,
1953
+ afterOpenChange,
1954
+ className = "",
1955
+ style,
1956
+ ...props
1957
+ }, forwardedRef) {
1958
+ const localRef = (0, import_react8.useRef)(null);
1959
+ const titleId = (0, import_react8.useId)();
1960
+ const [submitting, setSubmitting] = (0, import_react8.useState)(false);
1961
+ const [rendered, setRendered] = (0, import_react8.useState)(open);
1962
+ const [closing, setClosing] = (0, import_react8.useState)(false);
1963
+ const afterOpenChangeRef = (0, import_react8.useRef)(afterOpenChange);
1964
+ afterOpenChangeRef.current = afterOpenChange;
1965
+ const submitLock = (0, import_react8.useRef)(false);
1966
+ (0, import_react8.useEffect)(() => {
1967
+ if (!open || !rendered) return void 0;
1968
+ const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
1969
+ return () => window.clearTimeout(timer);
1970
+ }, [open, rendered]);
1971
+ (0, import_react8.useEffect)(() => {
1972
+ if (open) {
1973
+ setRendered(true);
1974
+ setClosing(false);
1975
+ return void 0;
1976
+ }
1977
+ if (!rendered) return void 0;
1978
+ setClosing(true);
1979
+ const timer = window.setTimeout(() => {
1980
+ setRendered(false);
1981
+ setClosing(false);
1982
+ afterOpenChangeRef.current?.(false);
1983
+ }, MODAL_MOTION_DURATION);
1984
+ return () => window.clearTimeout(timer);
1985
+ }, [open, rendered]);
1986
+ function setRef(node) {
1987
+ localRef.current = node;
1988
+ if (typeof forwardedRef === "function") forwardedRef(node);
1989
+ else if (forwardedRef) forwardedRef.current = node;
1990
+ }
1991
+ function requestClose() {
1992
+ if (submitting || confirmLoading) return;
1993
+ onCancel?.();
1994
+ onOpenChange?.(false);
1995
+ }
1996
+ async function handleOk() {
1997
+ if (submitLock.current || confirmLoading) return;
1998
+ submitLock.current = true;
1999
+ if (!onOk) {
2000
+ onOpenChange?.(false);
2001
+ submitLock.current = false;
2002
+ return;
2003
+ }
2004
+ try {
2005
+ const result = onOk();
2006
+ if (result instanceof Promise) {
2007
+ setSubmitting(true);
2008
+ const resolved = await result;
2009
+ if (resolved !== false) onOpenChange?.(false);
2010
+ } else if (result !== false) {
2011
+ onOpenChange?.(false);
2012
+ }
2013
+ } catch {
2014
+ return;
2015
+ } finally {
2016
+ submitLock.current = false;
2017
+ setSubmitting(false);
2018
+ }
2019
+ }
2020
+ useOverlayLifecycle(rendered, localRef, requestClose, keyboard);
2021
+ if (!rendered) return null;
2022
+ const mergedStyle = {
2023
+ ...style,
2024
+ "--sia-modal-width": typeof width === "number" ? `${width}px` : width
2025
+ };
2026
+ const loading = submitting || confirmLoading;
2027
+ const defaultFooter = /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2028
+ showCancel ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { ...cancelButtonProps, onClick: requestClose, disabled: loading || cancelButtonProps?.disabled, children: cancelText }) : null,
2029
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { variant: "primary", ...okButtonProps, onClick: handleOk, loading, children: okText })
2030
+ ] });
2031
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(OverlayPortal, { container: getContainer, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2032
+ "div",
2033
+ {
2034
+ className: `sia-modal-root${centered ? " sia-modal-root--centered" : ""}`,
2035
+ "data-state": closing ? "closing" : "open",
2036
+ style: { zIndex },
2037
+ onMouseDown: (event) => {
2038
+ if (event.target === event.currentTarget && maskClosable) requestClose();
2039
+ },
2040
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2041
+ "div",
2042
+ {
2043
+ ref: setRef,
2044
+ className: `sia-modal sia-modal--${type} ${className}`.trim(),
2045
+ style: mergedStyle,
2046
+ role: "dialog",
2047
+ "aria-modal": "true",
2048
+ "aria-labelledby": title ? titleId : void 0,
2049
+ tabIndex: -1,
2050
+ ...props,
2051
+ children: [
2052
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "sia-modal__header", children: [
2053
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "sia-modal__heading", children: [
2054
+ typeIcons[type] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "sia-modal__type-icon", "aria-hidden": "true", children: typeIcons[type] }) : null,
2055
+ title ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { id: titleId, children: title }) : null
2056
+ ] }),
2057
+ closable ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "sia-modal__close", "aria-label": "\u5173\u95ED\u5BF9\u8BDD\u6846", onClick: requestClose, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "close", size: 17 }) }) : null
2058
+ ] }),
2059
+ children !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "sia-modal__body", children }) : null,
2060
+ footer !== null ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "sia-modal__footer", children: footer ?? defaultFooter }) : null
2061
+ ]
2062
+ }
2063
+ )
2064
+ }
2065
+ ) });
2066
+ });
2067
+ function openModal(config) {
2068
+ if (typeof document === "undefined") return { destroy() {
2069
+ }, update() {
2070
+ } };
2071
+ const container = document.createElement("div");
2072
+ container.className = "sia-modal-api-host";
2073
+ document.body.appendChild(container);
2074
+ const root = (0, import_client.createRoot)(container);
2075
+ let currentConfig = config;
2076
+ let currentOpen = true;
2077
+ let destroyed = false;
2078
+ let cleanupTimer;
2079
+ function cleanup() {
2080
+ if (destroyed) return;
2081
+ destroyed = true;
2082
+ if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
2083
+ root.unmount();
2084
+ container.remove();
2085
+ modalHandles.delete(handle);
2086
+ }
2087
+ function closeWithMotion() {
2088
+ if (destroyed || !currentOpen) return;
2089
+ currentOpen = false;
2090
+ render();
2091
+ cleanupTimer = window.setTimeout(cleanup, MODAL_MOTION_DURATION);
2092
+ }
2093
+ function render() {
2094
+ root.render(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
2095
+ currentConfig.onOpenChange?.(nextOpen);
2096
+ if (!nextOpen) closeWithMotion();
2097
+ } }));
2098
+ }
2099
+ const handle = {
2100
+ destroy: closeWithMotion,
2101
+ update(next) {
2102
+ if (destroyed) return;
2103
+ currentConfig = { ...currentConfig, ...next };
2104
+ render();
2105
+ }
2106
+ };
2107
+ modalHandles.add(handle);
2108
+ render();
2109
+ return handle;
2110
+ }
2111
+ function preset(type, defaults = {}) {
2112
+ return (config) => openModal({
2113
+ okText: type === "confirm" ? "\u786E\u5B9A" : "\u77E5\u9053\u4E86",
2114
+ showCancel: type === "confirm",
2115
+ closable: type !== "confirm",
2116
+ maskClosable: type !== "confirm",
2117
+ ...defaults,
2118
+ ...config,
2119
+ type
2120
+ });
2121
+ }
2122
+ var Modal2 = Object.assign(ModalRoot, {
2123
+ open: openModal,
2124
+ info: preset("info", { title: "\u63D0\u793A" }),
2125
+ success: preset("success", { title: "\u64CD\u4F5C\u6210\u529F" }),
2126
+ warning: preset("warning", { title: "\u8BF7\u6CE8\u610F" }),
2127
+ error: preset("error", { title: "\u64CD\u4F5C\u5931\u8D25" }),
2128
+ confirm: preset("confirm", { title: "\u786E\u8BA4\u64CD\u4F5C" }),
2129
+ destroyAll() {
2130
+ [...modalHandles].forEach((handle) => handle.destroy());
2131
+ }
2132
+ });
2133
+
2134
+ // src/components/Input.tsx
2135
+ var import_react9 = require("react");
2136
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2137
+ var Input = (0, import_react9.forwardRef)(function Input2({
2138
+ label,
2139
+ hint,
2140
+ status = "default",
2141
+ size = "medium",
2142
+ prefix,
2143
+ suffix,
2144
+ allowClear = false,
2145
+ onClear,
2146
+ showCount = false,
2147
+ placeholderMode,
2148
+ placeholder,
2149
+ className = "",
2150
+ id,
2151
+ disabled,
2152
+ value,
2153
+ defaultValue,
2154
+ maxLength,
2155
+ onChange,
2156
+ ...props
2157
+ }, forwardedRef) {
2158
+ const fallbackId = (0, import_react9.useId)();
2159
+ const inputId = id ?? fallbackId;
2160
+ const localRef = (0, import_react9.useRef)(null);
2161
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react9.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
2162
+ const currentText = value !== void 0 ? String(value) : uncontrolledValue;
2163
+ const hasValue = currentText.length > 0;
2164
+ const floatingPlaceholder = usePlaceholderMode(placeholderMode) === "floating" && Boolean(placeholder);
2165
+ const hintId = `${inputId}-hint`;
2166
+ const describedBy = [props["aria-describedby"], hint ? hintId : null].filter(Boolean).join(" ") || void 0;
2167
+ function setRef(node) {
2168
+ localRef.current = node;
2169
+ if (typeof forwardedRef === "function") forwardedRef(node);
2170
+ else if (forwardedRef) forwardedRef.current = node;
2171
+ }
2172
+ function handleChange(event) {
2173
+ if (maxLength !== void 0 && maxLength >= 0 && event.target.value.length > maxLength) {
2174
+ const valueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
2175
+ valueSetter?.call(event.target, event.target.value.slice(0, maxLength));
2176
+ }
2177
+ setUncontrolledValue(event.target.value);
2178
+ onChange?.(event);
2179
+ }
2180
+ function clearValue() {
2181
+ const input2 = localRef.current;
2182
+ if (!input2 || disabled) return;
2183
+ const valueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
2184
+ valueSetter?.call(input2, "");
2185
+ input2.dispatchEvent(new Event("input", { bubbles: true }));
2186
+ setUncontrolledValue("");
2187
+ input2.focus();
2188
+ onClear?.();
2189
+ }
2190
+ function handleControlMouseDown(event) {
2191
+ if (disabled || event.defaultPrevented || event.button !== 0) return;
2192
+ const target = event.target;
2193
+ if (!(target instanceof Element)) return;
2194
+ const interactive = target.closest("input, textarea, select, button, a[href], [tabindex], [contenteditable]:not([contenteditable='false']), [role='button'], [role='link']");
2195
+ if (interactive && event.currentTarget.contains(interactive) && !interactive.classList.contains("sia-input-control__clear")) return;
2196
+ event.preventDefault();
2197
+ localRef.current?.focus({ preventScroll: true });
2198
+ }
2199
+ const input = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2200
+ "input",
2201
+ {
2202
+ ...props,
2203
+ ref: setRef,
2204
+ id: inputId,
2205
+ className: "sia-input",
2206
+ disabled,
2207
+ value,
2208
+ defaultValue,
2209
+ maxLength,
2210
+ placeholder,
2211
+ "aria-describedby": describedBy,
2212
+ "aria-invalid": status === "error" || void 0,
2213
+ onChange: handleChange
2214
+ }
2215
+ );
2216
+ const control = /* @__PURE__ */ (0, import_jsx_runtime9.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: [
2217
+ prefix ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "sia-input-control__affix", children: prefix }) : null,
2218
+ floatingPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "sia-input-control__input-wrap", children: [
2219
+ input,
2220
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "sia-input-control__floating-placeholder", "aria-hidden": "true", children: placeholder })
2221
+ ] }) : input,
2222
+ allowClear && hasValue && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "sia-input-control__clear", type: "button", "aria-label": "\u6E05\u7A7A\u8F93\u5165", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
2223
+ suffix ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "sia-input-control__affix", children: suffix }) : null,
2224
+ showCount ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: `sia-input-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
2225
+ currentText.length,
2226
+ maxLength !== void 0 ? `/${maxLength}` : null
2227
+ ] }) : null
2228
+ ] });
2229
+ if (!label && !hint) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: `sia-field ${className}`.trim(), children: control });
2230
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: `sia-field ${className}`.trim(), children: [
2231
+ label ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "sia-field__label", htmlFor: inputId, children: label }) : null,
2232
+ control,
2233
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
2234
+ ] });
2235
+ });
2236
+
2237
+ // src/components/Checkbox.tsx
2238
+ var import_react10 = require("react");
2239
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2240
+ var CheckboxGroupContext = (0, import_react10.createContext)(null);
2241
+ var CheckboxRoot = (0, import_react10.forwardRef)(function Checkbox({ value, indeterminate = false, children, disabled, checked, defaultChecked, className = "", onChange, ...props }, forwardedRef) {
2242
+ const group = (0, import_react10.useContext)(CheckboxGroupContext);
2243
+ const localRef = (0, import_react10.useRef)(null);
2244
+ const fallbackId = (0, import_react10.useId)();
2245
+ const grouped = group !== null && value !== void 0;
2246
+ const currentChecked = grouped ? group.values.includes(value) : checked;
2247
+ (0, import_react10.useEffect)(() => {
2248
+ if (localRef.current) localRef.current.indeterminate = indeterminate;
2249
+ }, [indeterminate]);
2250
+ function setRef(node) {
2251
+ localRef.current = node;
2252
+ if (typeof forwardedRef === "function") forwardedRef(node);
2253
+ else if (forwardedRef) forwardedRef.current = node;
2254
+ }
2255
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: `sia-checkbox${disabled || group?.disabled ? " is-disabled" : ""} ${className}`.trim(), children: [
2256
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2257
+ "input",
2258
+ {
2259
+ ...props,
2260
+ ref: setRef,
2261
+ id: props.id ?? fallbackId,
2262
+ className: "sia-checkbox__input",
2263
+ type: "checkbox",
2264
+ name: group?.name ?? props.name,
2265
+ disabled: disabled || group?.disabled,
2266
+ checked: currentChecked,
2267
+ defaultChecked: grouped ? void 0 : defaultChecked,
2268
+ "aria-checked": indeterminate ? "mixed" : currentChecked,
2269
+ onChange: (event) => {
2270
+ if (grouped) group.toggle(value, event.currentTarget.checked);
2271
+ onChange?.(event.currentTarget.checked, event);
2272
+ }
2273
+ }
2274
+ ),
2275
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "sia-checkbox__control", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", {}) }),
2276
+ children !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "sia-checkbox__label", children }) : null
2277
+ ] });
2278
+ });
2279
+ function CheckboxGroup({
2280
+ value,
2281
+ defaultValue = [],
2282
+ options,
2283
+ disabled,
2284
+ name,
2285
+ className = "",
2286
+ children,
2287
+ onChange
2288
+ }) {
2289
+ const [values, setValues] = useControllableState({ value, defaultValue, onChange });
2290
+ const context = (0, import_react10.useMemo)(() => ({
2291
+ values,
2292
+ disabled,
2293
+ name,
2294
+ toggle(optionValue, checked) {
2295
+ const next = checked ? values.includes(optionValue) ? values : [...values, optionValue] : values.filter((item) => item !== optionValue);
2296
+ setValues(next);
2297
+ }
2298
+ }), [disabled, name, setValues, values]);
2299
+ 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: [
2300
+ options?.map((option) => {
2301
+ const normalized = typeof option === "object" ? option : { label: String(option), value: option };
2302
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CheckboxRoot, { value: normalized.value, disabled: normalized.disabled, children: normalized.label }, normalized.value);
2303
+ }),
2304
+ children
2305
+ ] }) });
2306
+ }
2307
+ var Checkbox2 = Object.assign(CheckboxRoot, { Group: CheckboxGroup });
2308
+
2309
+ // src/components/SelectionPanel.tsx
2310
+ var import_react12 = require("react");
2311
+
2312
+ // src/components/FloatingDisplay.tsx
2313
+ var import_react11 = require("react");
2314
+ var import_react_dom3 = require("react-dom");
2315
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2316
+ var FLOATING_GAP = 9;
2317
+ var FLOATING_VIEWPORT_PADDING = 8;
2318
+ var FLOATING_ARROW_EDGE_OFFSET = 16;
2319
+ var activeTooltipClose;
2320
+ function clampFloating(value, min, max) {
2321
+ return Math.min(Math.max(value, min), Math.max(min, max));
2322
+ }
2323
+ function resolveFloatingPosition(trigger, overlay, placement) {
2324
+ const viewportWidth = document.documentElement.clientWidth;
2325
+ const viewportHeight = document.documentElement.clientHeight;
2326
+ let resolvedPlacement = placement;
2327
+ if (placement.startsWith("top") && trigger.top - overlay.height - FLOATING_GAP < FLOATING_VIEWPORT_PADDING && trigger.bottom + overlay.height + FLOATING_GAP <= viewportHeight - FLOATING_VIEWPORT_PADDING) {
2328
+ resolvedPlacement = placement.replace("top", "bottom");
2329
+ } else if (placement.startsWith("bottom") && trigger.bottom + overlay.height + FLOATING_GAP > viewportHeight - FLOATING_VIEWPORT_PADDING && trigger.top - overlay.height - FLOATING_GAP >= FLOATING_VIEWPORT_PADDING) {
2330
+ resolvedPlacement = placement.replace("bottom", "top");
2331
+ } else if (placement === "left" && trigger.left - overlay.width - FLOATING_GAP < FLOATING_VIEWPORT_PADDING && trigger.right + overlay.width + FLOATING_GAP <= viewportWidth - FLOATING_VIEWPORT_PADDING) {
2332
+ resolvedPlacement = "right";
2333
+ } else if (placement === "right" && trigger.right + overlay.width + FLOATING_GAP > viewportWidth - FLOATING_VIEWPORT_PADDING && trigger.left - overlay.width - FLOATING_GAP >= FLOATING_VIEWPORT_PADDING) {
2334
+ resolvedPlacement = "left";
2335
+ }
2336
+ let top = trigger.top;
2337
+ let left = trigger.left;
2338
+ if (resolvedPlacement.startsWith("top") || resolvedPlacement.startsWith("bottom")) {
2339
+ top = resolvedPlacement.startsWith("top") ? trigger.top - overlay.height - FLOATING_GAP : trigger.bottom + FLOATING_GAP;
2340
+ left = resolvedPlacement.endsWith("-start") ? trigger.left : resolvedPlacement.endsWith("-end") ? trigger.right - overlay.width : trigger.left + (trigger.width - overlay.width) / 2;
2341
+ } else {
2342
+ top = trigger.top + (trigger.height - overlay.height) / 2;
2343
+ left = resolvedPlacement === "left" ? trigger.left - overlay.width - FLOATING_GAP : trigger.right + FLOATING_GAP;
2344
+ }
2345
+ top = clampFloating(top, FLOATING_VIEWPORT_PADDING, viewportHeight - overlay.height - FLOATING_VIEWPORT_PADDING);
2346
+ left = clampFloating(left, FLOATING_VIEWPORT_PADDING, viewportWidth - overlay.width - FLOATING_VIEWPORT_PADDING);
2347
+ const result = { top, left, placement: resolvedPlacement };
2348
+ if (resolvedPlacement.startsWith("top") || resolvedPlacement.startsWith("bottom")) {
2349
+ result.arrowX = resolvedPlacement.endsWith("-start") ? clampFloating(FLOATING_ARROW_EDGE_OFFSET, 8, overlay.width - 16) : resolvedPlacement.endsWith("-end") ? clampFloating(overlay.width - FLOATING_ARROW_EDGE_OFFSET - 8, 8, overlay.width - 16) : clampFloating(trigger.left + trigger.width / 2 - left - 4, 8, overlay.width - 16);
2350
+ } else {
2351
+ result.arrowY = clampFloating(trigger.top + trigger.height / 2 - top - 4, 8, overlay.height - 16);
2352
+ }
2353
+ return result;
2354
+ }
2355
+ function Floating({
2356
+ children,
2357
+ content,
2358
+ placement = "top",
2359
+ trigger = "hover",
2360
+ open,
2361
+ defaultOpen = false,
2362
+ mouseEnterDelay = 0.1,
2363
+ mouseLeaveDelay = 0.1,
2364
+ arrow = true,
2365
+ color,
2366
+ className = "",
2367
+ overlayClassName = "",
2368
+ role = "tooltip",
2369
+ onOpenChange
2370
+ }) {
2371
+ const rootRef = (0, import_react11.useRef)(null);
2372
+ const overlayRef = (0, import_react11.useRef)(null);
2373
+ const enterTimer = (0, import_react11.useRef)();
2374
+ const leaveTimer = (0, import_react11.useRef)();
2375
+ const contentId = (0, import_react11.useId)();
2376
+ const triggers = Array.isArray(trigger) ? trigger : [trigger];
2377
+ const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
2378
+ const [position, setPosition] = (0, import_react11.useState)();
2379
+ const setVisibleRef = (0, import_react11.useRef)(setVisible);
2380
+ setVisibleRef.current = setVisible;
2381
+ const closeSelfRef = (0, import_react11.useRef)();
2382
+ if (!closeSelfRef.current) closeSelfRef.current = () => setVisibleRef.current(false);
2383
+ const exclusiveTooltip = role === "tooltip" && triggers.includes("hover");
2384
+ function openNow() {
2385
+ if (exclusiveTooltip && activeTooltipClose !== closeSelfRef.current) {
2386
+ activeTooltipClose?.();
2387
+ activeTooltipClose = closeSelfRef.current;
2388
+ }
2389
+ setVisible(true);
2390
+ }
2391
+ function closeNow() {
2392
+ if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
2393
+ setVisible(false);
2394
+ }
2395
+ function clearTimers() {
2396
+ window.clearTimeout(enterTimer.current);
2397
+ window.clearTimeout(leaveTimer.current);
2398
+ }
2399
+ function show(delay = 0) {
2400
+ clearTimers();
2401
+ if (delay <= 0) openNow();
2402
+ else enterTimer.current = window.setTimeout(openNow, delay * 1e3);
2403
+ }
2404
+ function hide(delay = 0) {
2405
+ clearTimers();
2406
+ if (delay <= 0) closeNow();
2407
+ else leaveTimer.current = window.setTimeout(closeNow, delay * 1e3);
2408
+ }
2409
+ (0, import_react11.useEffect)(() => {
2410
+ if (!visible || !triggers.includes("click")) return;
2411
+ const close = (event) => {
2412
+ const target = event.target;
2413
+ if (!rootRef.current?.contains(target) && !overlayRef.current?.contains(target)) closeNow();
2414
+ };
2415
+ document.addEventListener("pointerdown", close);
2416
+ return () => document.removeEventListener("pointerdown", close);
2417
+ }, [triggers.join("|"), visible]);
2418
+ (0, import_react11.useLayoutEffect)(() => {
2419
+ if (!visible) {
2420
+ setPosition(void 0);
2421
+ return;
2422
+ }
2423
+ const update = () => {
2424
+ if (!rootRef.current || !overlayRef.current) return;
2425
+ setPosition(resolveFloatingPosition(rootRef.current.getBoundingClientRect(), overlayRef.current.getBoundingClientRect(), placement));
2426
+ };
2427
+ update();
2428
+ window.addEventListener("resize", update);
2429
+ window.addEventListener("scroll", update, true);
2430
+ const observer = new ResizeObserver(update);
2431
+ if (rootRef.current) observer.observe(rootRef.current);
2432
+ if (overlayRef.current) observer.observe(overlayRef.current);
2433
+ return () => {
2434
+ window.removeEventListener("resize", update);
2435
+ window.removeEventListener("scroll", update, true);
2436
+ observer.disconnect();
2437
+ };
2438
+ }, [children, content, placement, visible]);
2439
+ (0, import_react11.useEffect)(() => () => {
2440
+ clearTimers();
2441
+ if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
2442
+ }, []);
2443
+ const child = (0, import_react11.cloneElement)(children, {
2444
+ ...triggers.includes("hover") ? { onMouseEnter: (event) => {
2445
+ children.props.onMouseEnter?.(event);
2446
+ show(mouseEnterDelay);
2447
+ }, onMouseLeave: (event) => {
2448
+ children.props.onMouseLeave?.(event);
2449
+ hide(mouseLeaveDelay);
2450
+ } } : {},
2451
+ ...triggers.includes("focus") ? { onFocus: (event) => {
2452
+ children.props.onFocus?.(event);
2453
+ show();
2454
+ }, onBlur: (event) => {
2455
+ children.props.onBlur?.(event);
2456
+ hide();
2457
+ } } : {},
2458
+ ...triggers.includes("click") ? { onClick: (event) => {
2459
+ children.props.onClick?.(event);
2460
+ if (visible) closeNow();
2461
+ else openNow();
2462
+ } } : {},
2463
+ "aria-describedby": visible ? contentId : void 0
2464
+ });
2465
+ const overlay = visible && content !== null && content !== void 0 && typeof document !== "undefined" ? (0, import_react_dom3.createPortal)(
2466
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2467
+ "span",
2468
+ {
2469
+ ref: overlayRef,
2470
+ id: contentId,
2471
+ role,
2472
+ "data-custom-color": color ? "" : void 0,
2473
+ className: `sia-floating__overlay sia-floating__overlay--${position?.placement ?? placement} ${overlayClassName}`.trim(),
2474
+ style: {
2475
+ "--sia-floating-color": color,
2476
+ "--sia-floating-arrow-x": position?.arrowX == null ? void 0 : `${position.arrowX}px`,
2477
+ "--sia-floating-arrow-y": position?.arrowY == null ? void 0 : `${position.arrowY}px`,
2478
+ top: position?.top ?? 0,
2479
+ left: position?.left ?? 0,
2480
+ visibility: position ? "visible" : "hidden"
2481
+ },
2482
+ onMouseEnter: triggers.includes("hover") ? () => show() : void 0,
2483
+ onMouseLeave: triggers.includes("hover") ? () => hide(mouseLeaveDelay) : void 0,
2484
+ children: [
2485
+ content,
2486
+ arrow ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sia-floating__arrow" }) : null
2487
+ ]
2488
+ }
2489
+ ),
2490
+ document.body
2491
+ ) : null;
2492
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2493
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { ref: rootRef, className: `sia-floating ${className}`.trim(), children: child }),
2494
+ overlay
2495
+ ] });
2496
+ }
2497
+ function Tooltip(props) {
2498
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Floating, { ...props, content: props.title });
2499
+ }
2500
+
2501
+ // src/components/SelectionPanel.tsx
2502
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2503
+ function SelectionPanel({
2504
+ options,
2505
+ value,
2506
+ onChange,
2507
+ multiple = false,
2508
+ disabled = false,
2509
+ loading = false,
2510
+ showSearch = true,
2511
+ showActions = true,
2512
+ includeUnknownValues = true,
2513
+ searchValue,
2514
+ onSearch,
2515
+ selectedOnly = false,
2516
+ showValue = false,
2517
+ displayField = "label",
2518
+ columns = 1,
2519
+ maxHeight = 250,
2520
+ autoFocusSearch = false
2521
+ }) {
2522
+ const [localSearch, setLocalSearch] = (0, import_react12.useState)("");
2523
+ const search = searchValue ?? localSearch;
2524
+ const [scrollTop, setScrollTop] = (0, import_react12.useState)(0);
2525
+ const [active, setActive] = (0, import_react12.useState)();
2526
+ const listRef = (0, import_react12.useRef)(null);
2527
+ const id = (0, import_react12.useId)();
2528
+ const selected = (0, import_react12.useMemo)(() => new Set(value), [value]);
2529
+ const count = Math.max(1, Math.floor(columns));
2530
+ const allOptions = (0, import_react12.useMemo)(() => {
2531
+ if (!includeUnknownValues) return [...options];
2532
+ const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
2533
+ return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
2534
+ }, [options, value, includeUnknownValues]);
2535
+ const filtered = (0, import_react12.useMemo)(
2536
+ () => allOptions.filter((option) => (!selectedOnly || selected.has(option.value)) && (!search || option.optionType !== "divider" && [option.label, option.value].some((text) => String(text ?? "").toLowerCase().includes(search.toLowerCase())))),
2537
+ [allOptions, selectedOnly, selected, search]
2538
+ );
2539
+ const rows = (0, import_react12.useMemo)(() => {
2540
+ const groups = /* @__PURE__ */ new Map();
2541
+ filtered.forEach((option) => {
2542
+ const items = groups.get(option.group) ?? [];
2543
+ items.push(option);
2544
+ groups.set(option.group, items);
2545
+ });
2546
+ const rows2 = [];
2547
+ let top = 0;
2548
+ for (const [group, items] of groups) {
2549
+ if (group) {
2550
+ rows2.push({ key: `group-${rows2.length}`, title: group, top, height: 30 });
2551
+ top += 30;
2552
+ }
2553
+ for (let index = 0; index < items.length; index += count) {
2554
+ const height = showValue ? 48 : 34;
2555
+ rows2.push({ key: `row-${rows2.length}`, items: items.slice(index, index + count), top, height });
2556
+ top += height;
2557
+ }
2558
+ }
2559
+ return rows2;
2560
+ }, [filtered, count, showValue]);
2561
+ const totalHeight = rows.length ? rows[rows.length - 1].top + rows[rows.length - 1].height : 0;
2562
+ const virtual = filtered.length > 100;
2563
+ const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
2564
+ const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
2565
+ (0, import_react12.useEffect)(() => {
2566
+ setScrollTop(0);
2567
+ if (listRef.current) listRef.current.scrollTop = 0;
2568
+ setActive(void 0);
2569
+ }, [search, selectedOnly, count]);
2570
+ function toggle(option) {
2571
+ if (disabled || loading || option.disabled || option.optionType === "divider") return;
2572
+ setActive(option.value);
2573
+ onChange(multiple ? selected.has(option.value) ? value.filter((item) => item !== option.value) : [...value, option.value] : [option.value]);
2574
+ }
2575
+ function batch(operation) {
2576
+ if (disabled || loading) return;
2577
+ if (operation === "clear") {
2578
+ onChange([]);
2579
+ return;
2580
+ }
2581
+ const editable = new Set(enabled.map((option) => option.value));
2582
+ const retained = value.filter((item) => !editable.has(item));
2583
+ const add = enabled.filter((option) => operation === "all" || !selected.has(option.value)).map((option) => option.value);
2584
+ onChange([...retained, ...add]);
2585
+ }
2586
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "sia-selection-panel", children: [
2587
+ showSearch && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2588
+ Input,
2589
+ {
2590
+ "aria-label": "\u641C\u7D22\u9009\u9879",
2591
+ placeholder: "\u641C\u7D22",
2592
+ autoFocus: autoFocusSearch,
2593
+ value: search,
2594
+ allowClear: true,
2595
+ onChange: (event) => {
2596
+ setLocalSearch(event.target.value);
2597
+ onSearch?.(event.target.value);
2598
+ }
2599
+ }
2600
+ ),
2601
+ multiple && showActions && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "sia-selection-panel__actions", children: [
2602
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("all"), children: "\u5168\u9009" }),
2603
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !enabled.length, onClick: () => batch("invert"), children: "\u53CD\u9009" }),
2604
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { variant: "link", size: "small", disabled: disabled || loading || !value.length, onClick: () => batch("clear"), children: "\u6E05\u7A7A" }),
2605
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
2606
+ "\u5DF2\u9009 ",
2607
+ value.length,
2608
+ " \u9879"
2609
+ ] })
2610
+ ] }),
2611
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2612
+ "div",
2613
+ {
2614
+ ref: listRef,
2615
+ role: "listbox",
2616
+ "aria-label": "\u9009\u9879\u5217\u8868",
2617
+ "aria-multiselectable": multiple || void 0,
2618
+ tabIndex: disabled ? -1 : 0,
2619
+ className: "sia-selection-panel__list",
2620
+ style: { maxHeight },
2621
+ onScroll: (event) => setScrollTop(event.currentTarget.scrollTop),
2622
+ "aria-activedescendant": active !== void 0 ? `${id}-${typeof active}-${active}` : void 0,
2623
+ onKeyDown: (event) => {
2624
+ if (event.target instanceof HTMLInputElement) return;
2625
+ if (disabled || loading || !enabled.length) return;
2626
+ const index = enabled.findIndex((option) => option.value === active);
2627
+ if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
2628
+ event.preventDefault();
2629
+ 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)));
2630
+ const option = enabled[next];
2631
+ setActive(option.value);
2632
+ const row = rows.find((row2) => row2.items?.includes(option));
2633
+ if (row && listRef.current) {
2634
+ listRef.current.scrollTop = Math.max(0, row.top - maxHeight / 2);
2635
+ setScrollTop(listRef.current.scrollTop);
2636
+ }
2637
+ } else if ((event.key === "Enter" || event.key === " ") && index >= 0) {
2638
+ event.preventDefault();
2639
+ toggle(enabled[index]);
2640
+ }
2641
+ },
2642
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { role: "status", children: "\u52A0\u8F7D\u4E2D\u2026" }) : !rows.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "sia-selection-panel__empty", children: "\u6682\u65E0\u5339\u914D\u9009\u9879" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { height: totalHeight, position: "relative" }, children: renderedRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2643
+ "div",
2644
+ {
2645
+ className: row.title !== void 0 ? "sia-selection-panel__group" : "sia-selection-panel__row",
2646
+ style: { position: "absolute", top: row.top, height: row.height, width: "100%", gridTemplateColumns: `repeat(${count}, minmax(0, 1fr))` },
2647
+ children: row.title ?? row.items?.map((option, index) => option.optionType === "divider" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { role: "separator", className: "sia-selection-panel__divider" }, `divider-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tooltip, { title: option.disabled ? option.disabledTip : void 0, placement: "right", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2648
+ "div",
2649
+ {
2650
+ role: "option",
2651
+ id: `${id}-${typeof option.value}-${option.value}`,
2652
+ tabIndex: -1,
2653
+ "aria-selected": selected.has(option.value),
2654
+ "aria-disabled": disabled || option.disabled || void 0,
2655
+ className: `sia-selection-panel__option${active === option.value ? " is-active" : ""}`,
2656
+ onClick: (event) => {
2657
+ if (!event.target.closest(".sia-checkbox")) toggle(option);
2658
+ },
2659
+ children: multiple ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Checkbox2, { checked: selected.has(option.value), disabled: disabled || loading || option.disabled, tabIndex: -1, onChange: () => toggle(option), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "sia-selection-panel__text", children: [
2660
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
2661
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("small", { children: String(option.value) })
2662
+ ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "sia-selection-panel__text", children: [
2663
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sia-selection-panel__label", children: showValue || displayField === "label" ? option.label : String(option.value) }),
2664
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("small", { children: String(option.value) })
2665
+ ] })
2666
+ }
2667
+ ) }, `${typeof option.value}-${option.value}`))
2668
+ },
2669
+ row.key
2670
+ )) })
2671
+ }
2672
+ )
2673
+ ] });
2674
+ }
2675
+
2676
+ // src/components/OverflowTags.tsx
2677
+ var import_react13 = require("react");
2678
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1784
2679
  function OverflowTags({ items, maxCount, className = "", tagClassName, restClassName = "" }) {
1785
- const rootRef = (0, import_react6.useRef)(null);
1786
- const measureRef = (0, import_react6.useRef)(null);
2680
+ const rootRef = (0, import_react13.useRef)(null);
2681
+ const measureRef = (0, import_react13.useRef)(null);
1787
2682
  const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount) || 0));
1788
- const [visibleCount, setVisibleCount] = (0, import_react6.useState)(0);
1789
- (0, import_react6.useLayoutEffect)(() => {
2683
+ const [visibleCount, setVisibleCount] = (0, import_react13.useState)(0);
2684
+ (0, import_react13.useLayoutEffect)(() => {
1790
2685
  const root = rootRef.current;
1791
2686
  const measure = measureRef.current;
1792
2687
  if (!root || !measure) return;
@@ -1809,15 +2704,15 @@ function OverflowTags({ items, maxCount, className = "", tagClassName, restClass
1809
2704
  return () => observer.disconnect();
1810
2705
  }, [items, limit]);
1811
2706
  const count = Math.min(visibleCount, limit);
1812
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { ref: rootRef, className: `sia-overflow-tags ${className}`.trim(), children: [
1813
- items.slice(0, count).map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
1814
- items.length > count ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: `${tagClassName} sia-overflow-tags__rest ${restClassName}`.trim(), children: [
2707
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { ref: rootRef, className: `sia-overflow-tags ${className}`.trim(), children: [
2708
+ items.slice(0, count).map((item) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
2709
+ items.length > count ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: `${tagClassName} sia-overflow-tags__rest ${restClassName}`.trim(), children: [
1815
2710
  "+",
1816
2711
  items.length - count
1817
2712
  ] }) : null,
1818
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { ref: measureRef, className: "sia-overflow-tags__measure", "aria-hidden": "true", children: [
1819
- items.slice(0, limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
1820
- Array.from({ length: limit + 1 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: `${tagClassName} ${restClassName}`.trim(), children: [
2713
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { ref: measureRef, className: "sia-overflow-tags__measure", "aria-hidden": "true", children: [
2714
+ items.slice(0, limit).map((item) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: tagClassName, children: item.label }, item.key)),
2715
+ Array.from({ length: limit + 1 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: `${tagClassName} ${restClassName}`.trim(), children: [
1821
2716
  "+",
1822
2717
  items.length - index
1823
2718
  ] }, `rest-${index}`))
@@ -1826,13 +2721,16 @@ function OverflowTags({ items, maxCount, className = "", tagClassName, restClass
1826
2721
  }
1827
2722
 
1828
2723
  // src/components/Select.tsx
1829
- var import_jsx_runtime8 = require("react/jsx-runtime");
2724
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1830
2725
  function defaultFilterOption(query, option) {
1831
- return String(option.label).toLowerCase().includes(query.toLowerCase());
2726
+ const keyword = query.toLowerCase();
2727
+ return [option.label, option.value].some((value) => String(value).toLowerCase().includes(keyword));
1832
2728
  }
1833
- var Select = (0, import_react7.forwardRef)(function Select2({
2729
+ var Select = (0, import_react14.forwardRef)(function Select2({
1834
2730
  options,
1835
2731
  mode = "single",
2732
+ popupMode = "dropdown",
2733
+ modalConfig,
1836
2734
  value,
1837
2735
  defaultValue,
1838
2736
  onChange,
@@ -1843,17 +2741,19 @@ var Select = (0, import_react7.forwardRef)(function Select2({
1843
2741
  allowClear = false,
1844
2742
  loading = false,
1845
2743
  showSearch = false,
2744
+ showValue = false,
1846
2745
  allowInput = false,
1847
2746
  inputMaxLength,
1848
2747
  searchPlaceholder = "\u641C\u7D22\u9009\u9879",
1849
2748
  onSearch,
1850
2749
  filterOption = defaultFilterOption,
1851
- showSelectAll = false,
2750
+ showSelectAll = true,
2751
+ showActions = mode === "multiple",
1852
2752
  maxTagCount = 2,
1853
2753
  virtual = true,
1854
2754
  virtualThreshold = 100,
1855
2755
  listHeight = 256,
1856
- optionHeight = 34,
2756
+ optionHeight = showValue ? 54 : 34,
1857
2757
  disabled,
1858
2758
  className = "",
1859
2759
  id,
@@ -1861,18 +2761,20 @@ var Select = (0, import_react7.forwardRef)(function Select2({
1861
2761
  onKeyDown,
1862
2762
  ...props
1863
2763
  }, forwardedRef) {
1864
- const fallbackId = (0, import_react7.useId)();
2764
+ const fallbackId = (0, import_react14.useId)();
1865
2765
  const selectId = id ?? fallbackId;
1866
2766
  const listboxId = `${selectId}-listbox`;
1867
- const rootRef = (0, import_react7.useRef)(null);
1868
- const popupRef = (0, import_react7.useRef)(null);
1869
- const searchRef = (0, import_react7.useRef)(null);
1870
- const listRef = (0, import_react7.useRef)(null);
1871
- const [open, setOpen] = (0, import_react7.useState)(false);
1872
- const [query, setQuery] = (0, import_react7.useState)("");
1873
- const [activeIndex, setActiveIndex] = (0, import_react7.useState)(-1);
1874
- const [scrollTop, setScrollTop] = (0, import_react7.useState)(0);
1875
- const deferredQuery = (0, import_react7.useDeferredValue)(query.trim());
2767
+ const rootRef = (0, import_react14.useRef)(null);
2768
+ const popupRef = (0, import_react14.useRef)(null);
2769
+ const searchRef = (0, import_react14.useRef)(null);
2770
+ const listRef = (0, import_react14.useRef)(null);
2771
+ const [open, setOpen] = (0, import_react14.useState)(false);
2772
+ const [modalValues, setModalValues] = (0, import_react14.useState)([]);
2773
+ const [selectedOnly, setSelectedOnly] = (0, import_react14.useState)(false);
2774
+ const [query, setQuery] = (0, import_react14.useState)("");
2775
+ const [activeIndex, setActiveIndex] = (0, import_react14.useState)(-1);
2776
+ const [scrollTop, setScrollTop] = (0, import_react14.useState)(0);
2777
+ const deferredQuery = (0, import_react14.useDeferredValue)(query.trim());
1876
2778
  const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
1877
2779
  const [currentValue, setCurrentValue] = useControllableState({
1878
2780
  value,
@@ -1887,19 +2789,19 @@ var Select = (0, import_react7.forwardRef)(function Select2({
1887
2789
  }
1888
2790
  }
1889
2791
  });
1890
- const selectedValues = (0, import_react7.useMemo)(() => {
2792
+ const selectedValues = (0, import_react14.useMemo)(() => {
1891
2793
  if (mode === "multiple") return Array.isArray(currentValue) ? currentValue : currentValue === null ? [] : [currentValue];
1892
2794
  return Array.isArray(currentValue) ? currentValue.slice(0, 1) : currentValue === null ? [] : [currentValue];
1893
2795
  }, [currentValue, mode]);
1894
- const selectedValueSet = (0, import_react7.useMemo)(() => new Set(selectedValues), [selectedValues]);
1895
- const availableOptions = (0, import_react7.useMemo)(() => {
2796
+ const selectedValueSet = (0, import_react14.useMemo)(() => new Set(selectedValues), [selectedValues]);
2797
+ const availableOptions = (0, import_react14.useMemo)(() => {
1896
2798
  if (!allowInput) return options;
1897
2799
  const optionValueSet = new Set(options.map((option) => option.value));
1898
2800
  const selectedCustomOptions = selectedValues.filter((selectedValue) => !optionValueSet.has(selectedValue)).map((selectedValue) => ({ label: String(selectedValue), value: selectedValue }));
1899
2801
  return selectedCustomOptions.length ? [...selectedCustomOptions, ...options] : options;
1900
2802
  }, [allowInput, options, selectedValues]);
1901
- const selectedOptions = (0, import_react7.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
1902
- const filteredOptions = (0, import_react7.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
2803
+ const selectedOptions = (0, import_react14.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
2804
+ const filteredOptions = (0, import_react14.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
1903
2805
  const inputValue = query.trim();
1904
2806
  const exactInputOption = inputValue ? availableOptions.find((option) => String(option.value).toLowerCase() === inputValue.toLowerCase() || typeof option.label === "string" && option.label.toLowerCase() === inputValue.toLowerCase()) : void 0;
1905
2807
  const canSubmitInput = allowInput && Boolean(inputValue) && !exactInputOption;
@@ -1913,18 +2815,21 @@ var Select = (0, import_react7.forwardRef)(function Select2({
1913
2815
  const renderedOptions = virtualEnabled ? filteredOptions.slice(virtualStart, virtualEnd) : filteredOptions;
1914
2816
  const enabledFilteredOptions = filteredOptions.filter((option) => !option.disabled);
1915
2817
  const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((option) => selectedValueSet.has(option.value));
1916
- (0, import_react7.useEffect)(() => {
1917
- if (!open) return void 0;
2818
+ (0, import_react14.useEffect)(() => {
2819
+ if (!open || popupMode === "modal") return void 0;
1918
2820
  function closeFromOutside(event) {
1919
2821
  const target = event.target;
1920
2822
  if (!rootRef.current?.contains(target) && !popupRef.current?.contains(target)) closeDropdown();
1921
2823
  }
1922
2824
  document.addEventListener("mousedown", closeFromOutside);
1923
2825
  return () => document.removeEventListener("mousedown", closeFromOutside);
1924
- }, [open]);
1925
- (0, import_react7.useEffect)(() => {
2826
+ }, [open, popupMode]);
2827
+ (0, import_react14.useEffect)(() => {
1926
2828
  if (open && (showSearch || allowInput)) searchRef.current?.focus();
1927
2829
  }, [allowInput, open, showSearch]);
2830
+ (0, import_react14.useEffect)(() => {
2831
+ if (disabled || loading) closeDropdown();
2832
+ }, [disabled, loading]);
1928
2833
  function firstEnabledIndex() {
1929
2834
  return filteredOptions.findIndex((option) => !option.disabled);
1930
2835
  }
@@ -1937,6 +2842,10 @@ var Select = (0, import_react7.forwardRef)(function Select2({
1937
2842
  if (disabled || loading) return;
1938
2843
  const selectedIndex = filteredOptions.findIndex((option) => selectedValueSet.has(option.value) && !option.disabled);
1939
2844
  setActiveIndex(selectedIndex >= 0 ? selectedIndex : firstEnabledIndex());
2845
+ if (popupMode === "modal") {
2846
+ setModalValues([...selectedValues]);
2847
+ setSelectedOnly(false);
2848
+ }
1940
2849
  setOpen(true);
1941
2850
  }
1942
2851
  function keepActiveVisible(index) {
@@ -1991,10 +2900,15 @@ var Select = (0, import_react7.forwardRef)(function Select2({
1991
2900
  setScrollTop(0);
1992
2901
  }
1993
2902
  }
2903
+ function invertFiltered() {
2904
+ const enabled = new Set(enabledFilteredOptions.map((option) => option.value));
2905
+ setCurrentValue([...selectedValues.filter((value2) => !enabled.has(value2)), ...enabledFilteredOptions.filter((option) => !selectedValueSet.has(option.value)).map((option) => option.value)]);
2906
+ }
1994
2907
  function clearSelection() {
1995
2908
  setCurrentValue(multiple ? [] : null);
1996
2909
  }
1997
2910
  function handleInteractionKeyDown(event, fromSearch = false) {
2911
+ if (popupMode === "modal" && open) return;
1998
2912
  if (event.key === "ArrowDown" || event.key === "ArrowUp") {
1999
2913
  event.preventDefault();
2000
2914
  if (!open) openDropdown();
@@ -2041,7 +2955,7 @@ var Select = (0, import_react7.forwardRef)(function Select2({
2041
2955
  function renderOption(option, renderedIndex) {
2042
2956
  const optionIndex = virtualEnabled ? virtualStart + renderedIndex : renderedIndex;
2043
2957
  const selected = selectedValueSet.has(option.value);
2044
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2958
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2045
2959
  "div",
2046
2960
  {
2047
2961
  id: `${listboxId}-${optionIndex}`,
@@ -2054,16 +2968,26 @@ var Select = (0, import_react7.forwardRef)(function Select2({
2054
2968
  onMouseDown: (event) => event.preventDefault(),
2055
2969
  onClick: () => selectOption(option),
2056
2970
  children: [
2057
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: option.label }),
2058
- selected ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "check", size: 15 }) : null
2971
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "sia-select__option-content", children: [
2972
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "sia-select__option-label", children: option.label }),
2973
+ showValue ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("small", { className: "sia-select__option-value", children: String(option.value) }) : null
2974
+ ] }),
2975
+ selected ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "check", size: 15 }) : null
2059
2976
  ]
2060
2977
  },
2061
2978
  `${typeof option.value}-${option.value}`
2062
2979
  );
2063
2980
  }
2981
+ const modalAvailable = [...availableOptions, ...modalValues.filter((value2) => !availableOptions.some((option) => option.value === value2)).map((value2) => ({ value: value2, label: String(value2) }))];
2982
+ const modalFiltered = deferredQuery ? modalAvailable.filter((option) => filterOption(deferredQuery, option)) : modalAvailable;
2983
+ const modalEnabled = modalFiltered.filter((option) => !option.disabled && (!selectedOnly || modalValues.includes(option.value)));
2984
+ function modalBatch(operation) {
2985
+ const editable = new Set(modalEnabled.map((option) => option.value));
2986
+ setModalValues([...modalValues.filter((value2) => !editable.has(value2)), ...modalEnabled.filter((option) => operation === "all" || operation === "invert" && !modalValues.includes(option.value)).map((option) => option.value)]);
2987
+ }
2064
2988
  const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: hasValue, active: open });
2065
- return /* @__PURE__ */ (0, import_jsx_runtime8.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: [
2066
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2989
+ return /* @__PURE__ */ (0, import_jsx_runtime14.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: [
2990
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2067
2991
  "button",
2068
2992
  {
2069
2993
  ...props,
@@ -2072,45 +2996,37 @@ var Select = (0, import_react7.forwardRef)(function Select2({
2072
2996
  id: selectId,
2073
2997
  type: "button",
2074
2998
  role: "combobox",
2075
- "aria-controls": listboxId,
2999
+ "aria-controls": popupMode === "modal" ? void 0 : listboxId,
2076
3000
  "aria-expanded": open,
2077
- "aria-haspopup": "listbox",
2078
- "aria-activedescendant": open && activeIndex >= 0 ? `${listboxId}-${activeIndex}` : void 0,
3001
+ "aria-haspopup": popupMode === "modal" ? "dialog" : "listbox",
3002
+ "aria-activedescendant": popupMode === "dropdown" && open && activeIndex >= 0 ? `${listboxId}-${activeIndex}` : void 0,
2079
3003
  "aria-invalid": status === "error" || void 0,
2080
3004
  disabled,
2081
3005
  onClick: () => open ? closeDropdown() : openDropdown(),
2082
3006
  onKeyDown: handleTriggerKeyDown,
2083
3007
  children: [
2084
- multiple && hasValue ? /* @__PURE__ */ (0, import_jsx_runtime8.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_runtime8.jsx)("span", { className: `sia-select__value${hasValue ? "" : " is-placeholder"}`, children: selectedOptions[0]?.label ?? placeholder }),
2085
- loading ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "sia-select__spinner", "aria-hidden": "true" }) : null,
3008
+ multiple && hasValue ? /* @__PURE__ */ (0, import_jsx_runtime14.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_runtime14.jsx)("span", { className: `sia-select__value${hasValue ? "" : " is-placeholder"}`, children: selectedOptions[0]?.label ?? placeholder }),
3009
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "sia-select__spinner", "aria-hidden": "true" }) : null,
2086
3010
  floating.label,
2087
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { className: "sia-select__arrow", name: "chevron-down", size: 15 })
3011
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { className: "sia-select__arrow", name: "chevron-down", size: 15 })
2088
3012
  ]
2089
3013
  }
2090
3014
  ),
2091
- allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
2092
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open, className: "sia-select__dropdown", children: [
2093
- showSearch || allowInput ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "sia-select__search", children: [
2094
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "search", size: 15 }),
2095
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { ref: searchRef, value: query, maxLength: inputMaxLength, onChange: handleSearchChange, onKeyDown: (event) => handleInteractionKeyDown(event, true), placeholder: searchPlaceholder, "aria-label": searchPlaceholder })
3015
+ allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
3016
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: open && popupMode === "dropdown", className: "sia-select__dropdown", children: [
3017
+ showSearch || allowInput ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "sia-select__search", children: [
3018
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "search", size: 15 }),
3019
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("input", { ref: searchRef, value: query, maxLength: inputMaxLength, onChange: handleSearchChange, onKeyDown: (event) => handleInteractionKeyDown(event, true), placeholder: searchPlaceholder, "aria-label": searchPlaceholder })
2096
3020
  ] }) : null,
2097
- canSubmitInput ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "button", className: "sia-select__input-option", onMouseDown: (event) => event.preventDefault(), onClick: submitInputValue, children: [
2098
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "plus", size: 14 }),
2099
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
3021
+ canSubmitInput ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("button", { type: "button", className: "sia-select__input-option", onMouseDown: (event) => event.preventDefault(), onClick: submitInputValue, children: [
3022
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "plus", size: 14 }),
3023
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
2100
3024
  "\u4F7F\u7528\u201C",
2101
3025
  inputValue,
2102
3026
  "\u201D"
2103
3027
  ] })
2104
3028
  ] }) : null,
2105
- multiple && showSelectAll ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "sia-select__actions", children: [
2106
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", disabled: allFilteredSelected || enabledFilteredOptions.length === 0, onClick: selectAllFiltered, children: "\u5168\u9009" }),
2107
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", disabled: !hasValue, onClick: clearSelection, children: "\u6E05\u9664" }),
2108
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2109
- selectedValues.length,
2110
- " \u9879\u5DF2\u9009"
2111
- ] })
2112
- ] }) : null,
2113
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3029
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2114
3030
  "div",
2115
3031
  {
2116
3032
  ref: listRef,
@@ -2121,15 +3037,114 @@ var Select = (0, import_react7.forwardRef)(function Select2({
2121
3037
  "aria-multiselectable": multiple || void 0,
2122
3038
  style: { maxHeight: listHeight },
2123
3039
  onScroll: handleListScroll,
2124
- children: filteredOptions.length > 0 ? virtualEnabled ? /* @__PURE__ */ (0, import_jsx_runtime8.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_runtime8.jsx)("div", { className: "sia-select__empty", children: notFoundContent })
3040
+ children: filteredOptions.length > 0 ? virtualEnabled ? /* @__PURE__ */ (0, import_jsx_runtime14.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_runtime14.jsx)("div", { className: "sia-select__empty", children: notFoundContent })
2125
3041
  }
2126
- )
2127
- ] })
3042
+ ),
3043
+ showActions ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "sia-select__actions", children: [
3044
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
3045
+ "\u5171 ",
3046
+ filteredOptions.length,
3047
+ " \u6761"
3048
+ ] }),
3049
+ multiple && showSelectAll ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3050
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { variant: "link", size: "small", disabled: allFilteredSelected || !enabledFilteredOptions.length, onClick: selectAllFiltered, children: "\u5168\u9009" }),
3051
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { variant: "link", size: "small", disabled: !enabledFilteredOptions.length, onClick: invertFiltered, children: "\u53CD\u9009" })
3052
+ ] }) : null,
3053
+ multiple || allowClear ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { variant: "link", size: "small", danger: true, disabled: !hasValue, onClick: clearSelection, children: "\u6E05\u7A7A" }) : null
3054
+ ] }) : null
3055
+ ] }),
3056
+ popupMode === "modal" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3057
+ Modal2,
3058
+ {
3059
+ className: "sia-select-modal",
3060
+ open,
3061
+ title: modalConfig?.title ?? placeholder,
3062
+ width: modalConfig?.width ?? 900,
3063
+ onOpenChange: (next) => {
3064
+ if (!next) closeDropdown();
3065
+ },
3066
+ onCancel: closeDropdown,
3067
+ footer: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "sia-select-modal__footer", children: [
3068
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { children: modalConfig?.footerExtra }),
3069
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3070
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { onClick: closeDropdown, children: "\u53D6\u6D88" }),
3071
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { variant: "primary", disabled: disabled || loading, onClick: () => {
3072
+ setCurrentValue(multiple ? modalValues : modalValues[0] ?? null);
3073
+ closeDropdown();
3074
+ }, children: "\u786E\u5B9A" })
3075
+ ] })
3076
+ ] }),
3077
+ children: open ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3078
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "sia-select-modal__heading", children: [
3079
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { role: "tablist", "aria-label": "\u9009\u9879\u8303\u56F4", children: [
3080
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { role: "tab", "aria-selected": !selectedOnly, variant: "link", onClick: () => setSelectedOnly(false), children: "\u5168\u90E8" }),
3081
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Button, { role: "tab", "aria-selected": selectedOnly, variant: "link", onClick: () => setSelectedOnly(true), children: [
3082
+ "\u5DF2\u9009\u9879(",
3083
+ modalValues.length,
3084
+ ")"
3085
+ ] })
3086
+ ] }),
3087
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3088
+ Input,
3089
+ {
3090
+ "aria-label": searchPlaceholder,
3091
+ placeholder: searchPlaceholder,
3092
+ prefix: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "search", size: 14 }),
3093
+ value: query,
3094
+ allowClear: true,
3095
+ onChange: (event) => {
3096
+ setQuery(event.target.value);
3097
+ onSearch?.(event.target.value);
3098
+ }
3099
+ }
3100
+ )
3101
+ ] }),
3102
+ multiple && showSelectAll ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "sia-select-modal__actions", children: [
3103
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3104
+ Checkbox2,
3105
+ {
3106
+ checked: modalEnabled.length > 0 && modalEnabled.every((option) => modalValues.includes(option.value)),
3107
+ indeterminate: modalEnabled.some((option) => modalValues.includes(option.value)) && !modalEnabled.every((option) => modalValues.includes(option.value)),
3108
+ disabled: !modalEnabled.length,
3109
+ onChange: (checked) => modalBatch(checked ? "all" : "remove"),
3110
+ children: "\u5168\u9009"
3111
+ }
3112
+ ),
3113
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { variant: "link", size: "small", disabled: !modalEnabled.length, onClick: () => modalBatch("invert"), children: "\u53CD\u9009" }),
3114
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { variant: "link", size: "small", danger: true, disabled: !modalValues.length, onClick: () => setModalValues([]), children: "\u6E05\u7A7A" })
3115
+ ] }) : null,
3116
+ allowInput && canSubmitInput ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Button, { variant: "link", onClick: () => {
3117
+ setModalValues(multiple ? [.../* @__PURE__ */ new Set([...modalValues, inputValue])] : [inputValue]);
3118
+ setQuery("");
3119
+ }, children: [
3120
+ "\u4F7F\u7528\u201C",
3121
+ inputValue,
3122
+ "\u201D"
3123
+ ] }) : null,
3124
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3125
+ SelectionPanel,
3126
+ {
3127
+ options: modalFiltered,
3128
+ value: modalValues,
3129
+ onChange: setModalValues,
3130
+ multiple,
3131
+ selectedOnly,
3132
+ showValue,
3133
+ showSearch: false,
3134
+ showActions: false,
3135
+ includeUnknownValues: false,
3136
+ columns: modalConfig?.columns ?? 3,
3137
+ maxHeight: modalConfig?.maxHeight ?? 360
3138
+ }
3139
+ )
3140
+ ] }) : null
3141
+ }
3142
+ ) : null
2128
3143
  ] });
2129
3144
  });
2130
3145
 
2131
3146
  // src/components/SelectDateRange.tsx
2132
- var import_jsx_runtime9 = require("react/jsx-runtime");
3147
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2133
3148
  function SelectDateRange({
2134
3149
  options,
2135
3150
  value,
@@ -2151,8 +3166,8 @@ function SelectDateRange({
2151
3166
  }) {
2152
3167
  const initialValue = defaultValue ?? { select: options[0]?.value ?? "", range: ["", ""] };
2153
3168
  const [currentValue, setCurrentValue] = useControllableState({ value: value === void 0 ? void 0 : value && typeof value === "object" ? value : { select: "", range: ["", ""] }, defaultValue: initialValue, onChange });
2154
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: `sia-select-date-range sia-select-date-range--${size} ${className}`.trim(), role: "group", "aria-label": `${selectAriaLabel}\u4E0E${rangeAriaLabel}`, ...props, style: { ...style, "--sia-select-date-range-select-width": typeof selectWidth === "number" ? `${selectWidth}px` : selectWidth }, children: [
2155
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3169
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `sia-select-date-range sia-select-date-range--${size} ${className}`.trim(), role: "group", "aria-label": `${selectAriaLabel}\u4E0E${rangeAriaLabel}`, ...props, style: { ...style, "--sia-select-date-range-select-width": typeof selectWidth === "number" ? `${selectWidth}px` : selectWidth }, children: [
3170
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2156
3171
  Select,
2157
3172
  {
2158
3173
  className: "sia-select-date-range__select",
@@ -2170,7 +3185,7 @@ function SelectDateRange({
2170
3185
  }
2171
3186
  }
2172
3187
  ),
2173
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3188
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2174
3189
  DatePicker.RangePicker,
2175
3190
  {
2176
3191
  className: "sia-select-date-range__picker",