@sia.soul/sia-react-ui 0.1.39 → 0.1.40

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
@@ -1831,505 +1831,162 @@ function Tag({
1831
1831
  }
1832
1832
 
1833
1833
  // src/components/Tabs.tsx
1834
- var import_react12 = require("react");
1835
-
1836
- // src/components/FloatingScrollbarProvider.tsx
1837
- var import_react11 = require("react");
1838
-
1839
- // src/components/useScrollbarProximity.ts
1840
1834
  var import_react10 = require("react");
1841
- var users = 0;
1842
- var cleanup;
1843
- function useScrollbarProximity() {
1835
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1836
+ var import_react11 = require("react");
1837
+ function Tabs({
1838
+ items,
1839
+ activeKey,
1840
+ defaultActiveKey,
1841
+ onChange,
1842
+ onAfterChange,
1843
+ deferContent = false,
1844
+ type = "line",
1845
+ size = "medium",
1846
+ tabPosition,
1847
+ orientation = "horizontal",
1848
+ centered = false,
1849
+ tabBarTitle,
1850
+ tabBarExtraContent,
1851
+ contentGap,
1852
+ destroyInactiveTabPane = true,
1853
+ closable = false,
1854
+ onEdit,
1855
+ tabContextMenu,
1856
+ onTabContextMenuClick,
1857
+ className = "",
1858
+ ...props
1859
+ }) {
1860
+ const firstEnabledKey = items.find((item) => !item.disabled)?.key ?? "";
1861
+ const [internalActiveKey, setInternalActiveKey] = (0, import_react10.useState)(defaultActiveKey ?? firstEnabledKey);
1862
+ const currentKey = activeKey ?? internalActiveKey;
1863
+ const selectedKey = items.some((item) => item.key === currentKey && !item.disabled) ? currentKey : firstEnabledKey;
1864
+ const baseId = (0, import_react10.useId)().replace(/:/g, "");
1865
+ const enabledItems = (0, import_react10.useMemo)(() => items.filter((item) => !item.disabled), [items]);
1866
+ const resolvedPosition = tabPosition ?? (orientation === "vertical" ? "left" : "top");
1867
+ const resolvedOrientation = resolvedPosition === "left" || resolvedPosition === "right" ? "vertical" : "horizontal";
1868
+ const sliding = ["capsule", "line", "underline", "tech", "tech-line"].includes(type);
1869
+ const listRef = (0, import_react10.useRef)(null);
1870
+ const indicatorRef = (0, import_react10.useRef)(null);
1871
+ const moreRef = (0, import_react10.useRef)(null);
1872
+ const [overflow, setOverflow] = (0, import_react10.useState)({ count: items.length, width: 0 });
1873
+ const [moreOpen, setMoreOpen] = (0, import_react10.useState)(false);
1874
+ const visibleCount = resolvedOrientation === "horizontal" ? overflow.count : items.length;
1875
+ const hiddenItems = items.slice(visibleCount);
1876
+ (0, import_react10.useLayoutEffect)(() => {
1877
+ const list = listRef.current;
1878
+ if (!list || resolvedOrientation !== "horizontal") return;
1879
+ const entries = Array.from(list.children).filter((node) => node instanceof HTMLElement && node.hasAttribute("data-tab-entry"));
1880
+ const measure = () => {
1881
+ const css = getComputedStyle(list);
1882
+ const gap = parseFloat(css.columnGap) || 0;
1883
+ const padding = (parseFloat(css.paddingLeft) || 0) + (parseFloat(css.paddingRight) || 0);
1884
+ const widths = entries.map((node) => node.getBoundingClientRect().width);
1885
+ const total = widths.reduce((sum, width2) => sum + width2, 0) + gap * Math.max(0, widths.length - 1);
1886
+ const available = Math.max(0, list.clientWidth - padding);
1887
+ let count = widths.length;
1888
+ if (total > available + 0.5) {
1889
+ const moreWidth = moreRef.current?.getBoundingClientRect().width ?? 36;
1890
+ let used = moreWidth;
1891
+ count = 0;
1892
+ for (const width2 of widths) {
1893
+ if (used + gap + width2 > available + 0.5) break;
1894
+ used += gap + width2;
1895
+ count++;
1896
+ }
1897
+ }
1898
+ const width = Math.ceil(total + padding + (parseFloat(css.borderLeftWidth) || 0) + (parseFloat(css.borderRightWidth) || 0));
1899
+ setOverflow((previous) => previous.count === count && previous.width === width ? previous : { count, width });
1900
+ };
1901
+ measure();
1902
+ const observer = new ResizeObserver(measure);
1903
+ observer.observe(list);
1904
+ entries.forEach((entry) => observer.observe(entry));
1905
+ return () => observer.disconnect();
1906
+ }, [items, type, size, closable, resolvedOrientation, tabBarTitle, tabBarExtraContent]);
1907
+ const [contentState, setContentState] = (0, import_react10.useState)(() => ({ key: selectedKey, visited: /* @__PURE__ */ new Set([selectedKey]) }));
1908
+ const settledKeyRef = (0, import_react10.useRef)(selectedKey);
1909
+ const afterChangeRef = (0, import_react10.useRef)(onAfterChange);
1910
+ (0, import_react10.useLayoutEffect)(() => {
1911
+ afterChangeRef.current = onAfterChange;
1912
+ }, [onAfterChange]);
1913
+ (0, import_react10.useLayoutEffect)(() => {
1914
+ if (!sliding) return;
1915
+ const list = listRef.current;
1916
+ const indicator = indicatorRef.current;
1917
+ if (!list || !indicator) return;
1918
+ function updateIndicator() {
1919
+ if (!list || !indicator) return;
1920
+ const active = list.querySelector('[role="tab"][aria-selected="true"]');
1921
+ if (!active || active.closest('[data-tab-hidden="true"]')) {
1922
+ indicator.style.visibility = "hidden";
1923
+ return;
1924
+ }
1925
+ const listRect = list.getBoundingClientRect();
1926
+ const rect = active.getBoundingClientRect();
1927
+ const currentRect = active.getBoundingClientRect();
1928
+ indicator.style.transform = `translate(${currentRect.left - listRect.left - list.clientLeft + list.scrollLeft}px, ${currentRect.top - listRect.top - list.clientTop + list.scrollTop}px)`;
1929
+ indicator.style.width = `${rect.width}px`;
1930
+ indicator.style.height = `${rect.height}px`;
1931
+ indicator.style.visibility = "visible";
1932
+ if (!indicator.dataset.ready) {
1933
+ indicator.getBoundingClientRect();
1934
+ indicator.dataset.ready = "true";
1935
+ }
1936
+ }
1937
+ updateIndicator();
1938
+ const observer = new ResizeObserver(updateIndicator);
1939
+ observer.observe(list);
1940
+ list.querySelectorAll('[role="tab"]').forEach((tab) => observer.observe(tab));
1941
+ return () => observer.disconnect();
1942
+ }, [sliding, type, selectedKey, items, size, resolvedPosition, centered, closable, visibleCount]);
1844
1943
  (0, import_react10.useEffect)(() => {
1845
- if (users++ === 0) {
1846
- let frame = 0;
1847
- let x = -Infinity;
1848
- let y = -Infinity;
1849
- const nearby = /* @__PURE__ */ new Set();
1850
- const clear = () => {
1851
- nearby.forEach((track) => track.removeAttribute("data-scrollbar-near"));
1852
- nearby.clear();
1853
- };
1854
- const update = () => {
1855
- frame = 0;
1856
- const next = /* @__PURE__ */ new Set();
1857
- document.querySelectorAll(".sia-scrollbar-track").forEach((track) => {
1858
- const rect = track.getBoundingClientRect();
1859
- const proximity = Number.parseFloat(getComputedStyle(track).getPropertyValue("--sia-scrollbar-proximity")) || 16;
1860
- if (rect.width && rect.height && x >= rect.left - proximity && x <= rect.right + proximity && y >= rect.top - proximity && y <= rect.bottom + proximity) {
1861
- next.add(track);
1862
- if (!nearby.has(track)) track.setAttribute("data-scrollbar-near", "true");
1863
- }
1864
- });
1865
- nearby.forEach((track) => {
1866
- if (!next.has(track)) track.removeAttribute("data-scrollbar-near");
1867
- });
1868
- nearby.clear();
1869
- next.forEach((track) => nearby.add(track));
1870
- };
1871
- const move = (event) => {
1872
- if (event.pointerType === "touch") return;
1873
- x = event.clientX;
1874
- y = event.clientY;
1875
- if (!frame) frame = requestAnimationFrame(update);
1876
- };
1877
- const leave = () => {
1878
- x = y = -Infinity;
1879
- clear();
1880
- };
1881
- document.addEventListener("pointermove", move, { passive: true });
1882
- document.documentElement.addEventListener("pointerleave", leave);
1883
- window.addEventListener("blur", leave);
1884
- cleanup = () => {
1885
- if (frame) cancelAnimationFrame(frame);
1886
- document.removeEventListener("pointermove", move);
1887
- document.documentElement.removeEventListener("pointerleave", leave);
1888
- window.removeEventListener("blur", leave);
1889
- clear();
1944
+ let cancelled = false;
1945
+ let frame = 0;
1946
+ frame = requestAnimationFrame(() => {
1947
+ const indicator = indicatorRef.current;
1948
+ if (indicator) getComputedStyle(indicator).transform;
1949
+ const animations = indicator?.getAnimations() ?? [];
1950
+ const complete = () => {
1951
+ if (cancelled) return;
1952
+ setContentState((previous) => ({ key: selectedKey, visited: new Set([...previous.visited].filter((key) => items.some((item) => item.key === key))).add(selectedKey) }));
1953
+ if (settledKeyRef.current !== selectedKey) {
1954
+ settledKeyRef.current = selectedKey;
1955
+ afterChangeRef.current?.(selectedKey);
1956
+ }
1890
1957
  };
1891
- }
1958
+ if (!animations.length) complete();
1959
+ else Promise.allSettled(animations.map((animation) => animation.finished)).then(() => {
1960
+ if (!cancelled) frame = requestAnimationFrame(complete);
1961
+ });
1962
+ });
1892
1963
  return () => {
1893
- if (--users === 0) {
1894
- cleanup?.();
1895
- cleanup = void 0;
1896
- }
1964
+ cancelled = true;
1965
+ cancelAnimationFrame(frame);
1897
1966
  };
1898
- }, []);
1899
- }
1900
-
1901
- // src/components/FloatingScrollbarProvider.tsx
1902
- var scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
1903
- var clippingOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay", "hidden", "clip"]);
1904
- function isRootScroller(target) {
1905
- return target === document.scrollingElement || target === document.documentElement;
1906
- }
1907
- function canScroll(target, axis) {
1908
- if (target.matches(".sia-table__viewport, [data-sia-native-scrollbar]")) return false;
1909
- if (isRootScroller(target)) {
1910
- return axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
1967
+ }, [selectedKey, type, deferContent]);
1968
+ const contentKey = deferContent ? contentState.key : selectedKey;
1969
+ function selectTab(key) {
1970
+ if (key === selectedKey) return;
1971
+ if (activeKey === void 0) setInternalActiveKey(key);
1972
+ onChange?.(key);
1911
1973
  }
1912
- const style = getComputedStyle(target);
1913
- const overflow = axis === "horizontal" ? style.overflowX : style.overflowY;
1914
- const hasOverflow = axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
1915
- return hasOverflow && scrollableOverflow.has(overflow);
1916
- }
1917
- function visibleRect(target) {
1918
- if (isRootScroller(target)) {
1919
- return { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0, width: window.innerWidth, height: window.innerHeight };
1974
+ function focusAndSelect(key) {
1975
+ selectTab(key);
1976
+ if (items.findIndex((item) => item.key === key) >= visibleCount) moreRef.current?.focus();
1977
+ else document.getElementById(`${baseId}-tab-${key}`)?.focus();
1920
1978
  }
1921
- const ownRect = target.getBoundingClientRect();
1922
- let top = Math.max(0, ownRect.top);
1923
- let right = Math.min(window.innerWidth, ownRect.right);
1924
- let bottom = Math.min(window.innerHeight, ownRect.bottom);
1925
- let left = Math.max(0, ownRect.left);
1926
- let parent = target.parentElement;
1927
- while (parent && parent !== document.body && parent !== document.documentElement) {
1928
- const style = getComputedStyle(parent);
1929
- const clipX = clippingOverflow.has(style.overflowX);
1930
- const clipY = clippingOverflow.has(style.overflowY);
1931
- if (clipX || clipY) {
1932
- const rect = parent.getBoundingClientRect();
1933
- if (clipX) {
1934
- left = Math.max(left, rect.left);
1935
- right = Math.min(right, rect.right);
1936
- }
1937
- if (clipY) {
1938
- top = Math.max(top, rect.top);
1939
- bottom = Math.min(bottom, rect.bottom);
1940
- }
1941
- }
1942
- parent = parent.parentElement;
1943
- }
1944
- return {
1945
- top,
1946
- right,
1947
- bottom,
1948
- left,
1949
- width: Math.max(0, right - left),
1950
- height: Math.max(0, bottom - top)
1951
- };
1952
- }
1953
- function createTrack(axis) {
1954
- const track = document.createElement("div");
1955
- const thumb = document.createElement("div");
1956
- track.className = `sia-scrollbar-track sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
1957
- thumb.className = "sia-floating-scrollbar__thumb";
1958
- track.dataset.axis = axis;
1959
- track.setAttribute("aria-hidden", "true");
1960
- track.append(thumb);
1961
- return { track, thumb };
1962
- }
1963
- function FloatingScrollbarProvider({ disabled = false, targetRef }) {
1964
- useScrollbarProximity();
1965
- (0, import_react11.useEffect)(() => {
1966
- if (disabled) return;
1967
- const layer = document.createElement("div");
1968
- layer.className = "sia-floating-scrollbar-layer";
1969
- layer.setAttribute("aria-hidden", "true");
1970
- document.body.append(layer);
1971
- const entries = /* @__PURE__ */ new Map();
1972
- let scanFrame = 0;
1973
- let updateFrame = 0;
1974
- const setEntryVisible = (entry, visible) => {
1975
- entry.horizontalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
1976
- entry.verticalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
1977
- };
1978
- const showEntry = (entry) => {
1979
- if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
1980
- entry.hideTimer = null;
1981
- setEntryVisible(entry, true);
1982
- };
1983
- const scheduleHide = (entry, delay = 500) => {
1984
- if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
1985
- entry.hideTimer = window.setTimeout(() => {
1986
- entry.hideTimer = null;
1987
- if (!entry.hoveringTarget && !entry.hoveringTrack && !entry.dragging) setEntryVisible(entry, false);
1988
- }, delay);
1989
- };
1990
- const updateEntry = (entry) => {
1991
- const { target, horizontalTrack, horizontalThumb, verticalTrack, verticalThumb } = entry;
1992
- const hasHorizontal = canScroll(target, "horizontal");
1993
- const hasVertical = canScroll(target, "vertical");
1994
- const rect = visibleRect(target);
1995
- const thickness = 10;
1996
- horizontalTrack.hidden = !hasHorizontal || rect.width <= thickness || rect.height <= 0;
1997
- verticalTrack.hidden = !hasVertical || rect.height <= thickness || rect.width <= 0;
1998
- if (!horizontalTrack.hidden) {
1999
- const trackWidth = Math.max(0, rect.width - (hasVertical ? thickness : 0));
2000
- const thumbWidth = Math.max(24, Math.min(trackWidth, trackWidth * target.clientWidth / target.scrollWidth));
2001
- const travel = Math.max(0, trackWidth - thumbWidth);
2002
- const maxScroll = Math.max(1, target.scrollWidth - target.clientWidth);
2003
- horizontalTrack.style.left = `${rect.left}px`;
2004
- horizontalTrack.style.top = `${rect.bottom - thickness}px`;
2005
- horizontalTrack.style.width = `${trackWidth}px`;
2006
- horizontalTrack.style.height = `${thickness}px`;
2007
- horizontalThumb.style.width = `${thumbWidth}px`;
2008
- horizontalThumb.style.transform = `translate3d(${travel * target.scrollLeft / maxScroll}px, 0, 0)`;
2009
- }
2010
- if (!verticalTrack.hidden) {
2011
- const trackHeight = Math.max(0, rect.height - (hasHorizontal ? thickness : 0));
2012
- const thumbHeight = Math.max(24, Math.min(trackHeight, trackHeight * target.clientHeight / target.scrollHeight));
2013
- const travel = Math.max(0, trackHeight - thumbHeight);
2014
- const maxScroll = Math.max(1, target.scrollHeight - target.clientHeight);
2015
- verticalTrack.style.left = `${rect.right - thickness}px`;
2016
- verticalTrack.style.top = `${rect.top}px`;
2017
- verticalTrack.style.width = `${thickness}px`;
2018
- verticalTrack.style.height = `${trackHeight}px`;
2019
- verticalThumb.style.height = `${thumbHeight}px`;
2020
- verticalThumb.style.transform = `translate3d(0, ${travel * target.scrollTop / maxScroll}px, 0)`;
2021
- }
2022
- };
2023
- const scheduleUpdateAll = () => {
2024
- if (updateFrame) return;
2025
- updateFrame = window.requestAnimationFrame(() => {
2026
- updateFrame = 0;
2027
- entries.forEach(updateEntry);
2028
- });
2029
- };
2030
- const bindTrackDrag = (entry, axis, track, thumb) => {
2031
- const target = entry.target;
2032
- const onTrackPointerEnter = () => {
2033
- entry.hoveringTrack = true;
2034
- showEntry(entry);
2035
- };
2036
- const onTrackPointerLeave = () => {
2037
- entry.hoveringTrack = false;
2038
- scheduleHide(entry);
2039
- };
2040
- const onTrackPointerDown = (event) => {
2041
- if (event.target === thumb || event.button !== 0) return;
2042
- event.preventDefault();
2043
- event.stopPropagation();
2044
- const trackRect = track.getBoundingClientRect();
2045
- const thumbRect = thumb.getBoundingClientRect();
2046
- const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
2047
- const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
2048
- const pointer = axis === "vertical" ? event.clientY - trackRect.top : event.clientX - trackRect.left;
2049
- const ratio = Math.max(0, Math.min(1, (pointer - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
2050
- if (axis === "vertical") target.scrollTop = ratio * (target.scrollHeight - target.clientHeight);
2051
- else target.scrollLeft = ratio * (target.scrollWidth - target.clientWidth);
2052
- };
2053
- const onThumbPointerDown = (event) => {
2054
- if (event.button !== 0) return;
2055
- event.preventDefault();
2056
- event.stopPropagation();
2057
- entry.dragging = true;
2058
- showEntry(entry);
2059
- thumb.setPointerCapture(event.pointerId);
2060
- const startPointer = axis === "vertical" ? event.clientY : event.clientX;
2061
- const startScroll = axis === "vertical" ? target.scrollTop : target.scrollLeft;
2062
- const trackRect = track.getBoundingClientRect();
2063
- const thumbRect = thumb.getBoundingClientRect();
2064
- const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
2065
- const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
2066
- const maxScroll = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
2067
- const travel = Math.max(1, trackLength - thumbLength);
2068
- const onPointerMove = (moveEvent) => {
2069
- if (moveEvent.pointerId !== event.pointerId) return;
2070
- const pointer = axis === "vertical" ? moveEvent.clientY : moveEvent.clientX;
2071
- const nextScroll = startScroll + (pointer - startPointer) * maxScroll / travel;
2072
- if (axis === "vertical") target.scrollTop = nextScroll;
2073
- else target.scrollLeft = nextScroll;
2074
- };
2075
- const onPointerUp = (upEvent) => {
2076
- if (upEvent.pointerId !== event.pointerId) return;
2077
- entry.dragging = false;
2078
- thumb.releasePointerCapture(event.pointerId);
2079
- window.removeEventListener("pointermove", onPointerMove);
2080
- window.removeEventListener("pointerup", onPointerUp);
2081
- window.removeEventListener("pointercancel", onPointerUp);
2082
- scheduleHide(entry);
2083
- };
2084
- window.addEventListener("pointermove", onPointerMove);
2085
- window.addEventListener("pointerup", onPointerUp);
2086
- window.addEventListener("pointercancel", onPointerUp);
2087
- };
2088
- track.addEventListener("pointerenter", onTrackPointerEnter);
2089
- track.addEventListener("pointerleave", onTrackPointerLeave);
2090
- track.addEventListener("pointerdown", onTrackPointerDown);
2091
- thumb.addEventListener("pointerdown", onThumbPointerDown);
2092
- return () => {
2093
- track.removeEventListener("pointerenter", onTrackPointerEnter);
2094
- track.removeEventListener("pointerleave", onTrackPointerLeave);
2095
- track.removeEventListener("pointerdown", onTrackPointerDown);
2096
- thumb.removeEventListener("pointerdown", onThumbPointerDown);
2097
- };
2098
- };
2099
- const resizeObserver = new ResizeObserver((observedEntries) => {
2100
- observedEntries.forEach(({ target }) => {
2101
- const entry = entries.get(target);
2102
- if (entry) updateEntry(entry);
2103
- });
2104
- });
2105
- const addTarget = (target) => {
2106
- if (entries.has(target)) return;
2107
- const horizontal = createTrack("horizontal");
2108
- const vertical = createTrack("vertical");
2109
- layer.append(horizontal.track, vertical.track);
2110
- const onPointerEnter = () => {
2111
- const entry2 = entries.get(target);
2112
- if (!entry2) return;
2113
- entry2.hoveringTarget = true;
2114
- showEntry(entry2);
2115
- };
2116
- const onPointerLeave = () => {
2117
- const entry2 = entries.get(target);
2118
- if (!entry2) return;
2119
- entry2.hoveringTarget = false;
2120
- scheduleHide(entry2);
2121
- };
2122
- const onScroll = () => {
2123
- const entry2 = entries.get(target);
2124
- if (!entry2) return;
2125
- updateEntry(entry2);
2126
- showEntry(entry2);
2127
- scheduleHide(entry2, 700);
2128
- };
2129
- target.addEventListener("pointerenter", onPointerEnter);
2130
- target.addEventListener("pointerleave", onPointerLeave);
2131
- target.addEventListener("scroll", onScroll, { passive: true });
2132
- const entry = {
2133
- target,
2134
- horizontalTrack: horizontal.track,
2135
- horizontalThumb: horizontal.thumb,
2136
- verticalTrack: vertical.track,
2137
- verticalThumb: vertical.thumb,
2138
- hideTimer: null,
2139
- hoveringTarget: target.matches(":hover"),
2140
- hoveringTrack: false,
2141
- dragging: false,
2142
- cleanup: () => void 0
2143
- };
2144
- const cleanupHorizontal = bindTrackDrag(entry, "horizontal", horizontal.track, horizontal.thumb);
2145
- const cleanupVertical = bindTrackDrag(entry, "vertical", vertical.track, vertical.thumb);
2146
- entry.cleanup = () => {
2147
- if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
2148
- cleanupHorizontal();
2149
- cleanupVertical();
2150
- target.removeEventListener("pointerenter", onPointerEnter);
2151
- target.removeEventListener("pointerleave", onPointerLeave);
2152
- target.removeEventListener("scroll", onScroll);
2153
- resizeObserver.unobserve(target);
2154
- target.removeAttribute("data-sia-floating-scrollbar");
2155
- horizontal.track.remove();
2156
- vertical.track.remove();
2157
- };
2158
- entries.set(target, entry);
2159
- target.setAttribute("data-sia-floating-scrollbar", "");
2160
- resizeObserver.observe(target);
2161
- updateEntry(entry);
2162
- if (entry.hoveringTarget) showEntry(entry);
2163
- };
2164
- const removeTarget = (target) => {
2165
- const entry = entries.get(target);
2166
- if (!entry) return;
2167
- entry.cleanup();
2168
- entries.delete(target);
2169
- };
2170
- const scanTargets = () => {
2171
- scanFrame = 0;
2172
- const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
2173
- const nextTargets = /* @__PURE__ */ new Set();
2174
- candidates.forEach((target) => {
2175
- if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
2176
- nextTargets.add(target);
2177
- if (entries.has(target) || !target.hasAttribute("data-sia-floating-scrollbar")) addTarget(target);
2178
- }
2179
- });
2180
- entries.forEach((_entry, target) => {
2181
- if (!target.isConnected || !nextTargets.has(target)) removeTarget(target);
2182
- else updateEntry(_entry);
2183
- });
2184
- };
2185
- const scheduleScan = () => {
2186
- if (scanFrame) return;
2187
- scanFrame = window.requestAnimationFrame(scanTargets);
2188
- };
2189
- const mutationObserver = new MutationObserver((mutations) => {
2190
- if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
2191
- });
2192
- mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
2193
- window.addEventListener("resize", scheduleScan);
2194
- window.addEventListener("scroll", scheduleUpdateAll, true);
2195
- scheduleScan();
2196
- return () => {
2197
- mutationObserver.disconnect();
2198
- resizeObserver.disconnect();
2199
- window.removeEventListener("resize", scheduleScan);
2200
- window.removeEventListener("scroll", scheduleUpdateAll, true);
2201
- if (scanFrame) window.cancelAnimationFrame(scanFrame);
2202
- if (updateFrame) window.cancelAnimationFrame(updateFrame);
2203
- entries.forEach((entry) => entry.cleanup());
2204
- entries.clear();
2205
- layer.remove();
2206
- };
2207
- }, [disabled, targetRef]);
2208
- return null;
2209
- }
2210
-
2211
- // src/components/Tabs.tsx
2212
- var import_jsx_runtime11 = require("react/jsx-runtime");
2213
- function Tabs({
2214
- items,
2215
- activeKey,
2216
- defaultActiveKey,
2217
- onChange,
2218
- onAfterChange,
2219
- deferContent = false,
2220
- type = "line",
2221
- size = "medium",
2222
- tabPosition,
2223
- orientation = "horizontal",
2224
- centered = false,
2225
- tabBarTitle,
2226
- tabBarExtraContent,
2227
- contentGap,
2228
- destroyInactiveTabPane = true,
2229
- closable = false,
2230
- onEdit,
2231
- tabContextMenu,
2232
- onTabContextMenuClick,
2233
- className = "",
2234
- ...props
2235
- }) {
2236
- const firstEnabledKey = items.find((item) => !item.disabled)?.key ?? "";
2237
- const [internalActiveKey, setInternalActiveKey] = (0, import_react12.useState)(defaultActiveKey ?? firstEnabledKey);
2238
- const currentKey = activeKey ?? internalActiveKey;
2239
- const selectedKey = items.some((item) => item.key === currentKey && !item.disabled) ? currentKey : firstEnabledKey;
2240
- const baseId = (0, import_react12.useId)().replace(/:/g, "");
2241
- const enabledItems = (0, import_react12.useMemo)(() => items.filter((item) => !item.disabled), [items]);
2242
- const resolvedPosition = tabPosition ?? (orientation === "vertical" ? "left" : "top");
2243
- const resolvedOrientation = resolvedPosition === "left" || resolvedPosition === "right" ? "vertical" : "horizontal";
2244
- const sliding = ["capsule", "line", "underline", "tech", "tech-line"].includes(type);
2245
- const listRef = (0, import_react12.useRef)(null);
2246
- const indicatorRef = (0, import_react12.useRef)(null);
2247
- const [contentState, setContentState] = (0, import_react12.useState)(() => ({ key: selectedKey, visited: /* @__PURE__ */ new Set([selectedKey]) }));
2248
- const settledKeyRef = (0, import_react12.useRef)(selectedKey);
2249
- const afterChangeRef = (0, import_react12.useRef)(onAfterChange);
2250
- (0, import_react12.useLayoutEffect)(() => {
2251
- afterChangeRef.current = onAfterChange;
2252
- }, [onAfterChange]);
2253
- (0, import_react12.useLayoutEffect)(() => {
2254
- if (!sliding) return;
2255
- const list = listRef.current;
2256
- const indicator = indicatorRef.current;
2257
- if (!list || !indicator) return;
2258
- function updateIndicator() {
2259
- if (!list || !indicator) return;
2260
- const active = list.querySelector('[role="tab"][aria-selected="true"]');
2261
- if (!active) {
2262
- indicator.style.visibility = "hidden";
2263
- return;
2264
- }
2265
- const listRect = list.getBoundingClientRect();
2266
- const rect = active.getBoundingClientRect();
2267
- if (type === "tech-line" && resolvedOrientation === "horizontal") {
2268
- if (rect.left < listRect.left) list.scrollLeft += rect.left - listRect.left;
2269
- else if (rect.right > listRect.right) list.scrollLeft += rect.right - listRect.right;
2270
- }
2271
- const currentRect = active.getBoundingClientRect();
2272
- indicator.style.transform = `translate(${currentRect.left - listRect.left - list.clientLeft + list.scrollLeft}px, ${currentRect.top - listRect.top - list.clientTop + list.scrollTop}px)`;
2273
- indicator.style.width = `${rect.width}px`;
2274
- indicator.style.height = `${rect.height}px`;
2275
- indicator.style.visibility = "visible";
2276
- if (!indicator.dataset.ready) {
2277
- indicator.getBoundingClientRect();
2278
- indicator.dataset.ready = "true";
2279
- }
2280
- }
2281
- updateIndicator();
2282
- const observer = new ResizeObserver(updateIndicator);
2283
- observer.observe(list);
2284
- list.querySelectorAll('[role="tab"]').forEach((tab) => observer.observe(tab));
2285
- return () => observer.disconnect();
2286
- }, [sliding, type, selectedKey, items, size, resolvedPosition, centered, closable]);
2287
- (0, import_react12.useEffect)(() => {
2288
- let cancelled = false;
2289
- let frame = 0;
2290
- frame = requestAnimationFrame(() => {
2291
- const indicator = indicatorRef.current;
2292
- if (indicator) getComputedStyle(indicator).transform;
2293
- const animations = indicator?.getAnimations() ?? [];
2294
- const complete = () => {
2295
- if (cancelled) return;
2296
- setContentState((previous) => ({ key: selectedKey, visited: new Set([...previous.visited].filter((key) => items.some((item) => item.key === key))).add(selectedKey) }));
2297
- if (settledKeyRef.current !== selectedKey) {
2298
- settledKeyRef.current = selectedKey;
2299
- afterChangeRef.current?.(selectedKey);
2300
- }
2301
- };
2302
- if (!animations.length) complete();
2303
- else Promise.allSettled(animations.map((animation) => animation.finished)).then(() => {
2304
- if (!cancelled) frame = requestAnimationFrame(complete);
2305
- });
2306
- });
2307
- return () => {
2308
- cancelled = true;
2309
- cancelAnimationFrame(frame);
2310
- };
2311
- }, [selectedKey, type, deferContent]);
2312
- const contentKey = deferContent ? contentState.key : selectedKey;
2313
- function selectTab(key) {
2314
- if (key === selectedKey) return;
2315
- if (activeKey === void 0) setInternalActiveKey(key);
2316
- onChange?.(key);
2317
- }
2318
- function focusAndSelect(key) {
2319
- selectTab(key);
2320
- document.getElementById(`${baseId}-tab-${key}`)?.focus();
2321
- }
2322
- function handleKeyDown(event, key) {
2323
- const previousKey = resolvedOrientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
2324
- const nextKey = resolvedOrientation === "horizontal" ? "ArrowRight" : "ArrowDown";
2325
- if (![previousKey, nextKey, "Home", "End"].includes(event.key) || enabledItems.length === 0) return;
2326
- event.preventDefault();
2327
- const currentIndex = Math.max(0, enabledItems.findIndex((item) => item.key === key));
2328
- if (event.key === "Home") return focusAndSelect(enabledItems[0].key);
2329
- if (event.key === "End") return focusAndSelect(enabledItems[enabledItems.length - 1].key);
2330
- const offset = event.key === nextKey ? 1 : -1;
2331
- const nextIndex = (currentIndex + offset + enabledItems.length) % enabledItems.length;
2332
- focusAndSelect(enabledItems[nextIndex].key);
1979
+ function handleKeyDown(event, key) {
1980
+ const previousKey = resolvedOrientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
1981
+ const nextKey = resolvedOrientation === "horizontal" ? "ArrowRight" : "ArrowDown";
1982
+ if (![previousKey, nextKey, "Home", "End"].includes(event.key) || enabledItems.length === 0) return;
1983
+ event.preventDefault();
1984
+ const currentIndex = Math.max(0, enabledItems.findIndex((item) => item.key === key));
1985
+ if (event.key === "Home") return focusAndSelect(enabledItems[0].key);
1986
+ if (event.key === "End") return focusAndSelect(enabledItems[enabledItems.length - 1].key);
1987
+ const offset = event.key === nextKey ? 1 : -1;
1988
+ const nextIndex = (currentIndex + offset + enabledItems.length) % enabledItems.length;
1989
+ focusAndSelect(enabledItems[nextIndex].key);
2333
1990
  }
2334
1991
  const hasPanels = items.some((item) => item.children !== void 0);
2335
1992
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
@@ -2339,54 +1996,53 @@ function Tabs({
2339
1996
  ...withTitleTooltip(props),
2340
1997
  children: [
2341
1998
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "sia-tabs__header", children: [
2342
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FloatingScrollbarProvider, { targetRef: listRef, disabled: type !== "tech-line" || resolvedOrientation !== "horizontal" }),
2343
1999
  tabBarTitle ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "sia-tabs__title", children: [
2344
2000
  tabBarTitle,
2345
2001
  type === "tech-line" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "sia-tabs__title-connector", viewBox: "0 0 32 40", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M0 39.25 H5 Q8 39.25 10 35.25 L28 3.75 Q29 1.75 32 1.75", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinejoin: "round" }) }) : null
2346
2002
  ] }) : null,
2347
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { ref: listRef, className: `sia-tabs__list${sliding ? " sia-tabs__list--sliding" : ""}`, role: "tablist", "aria-orientation": resolvedOrientation, children: [
2003
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { ref: listRef, style: resolvedOrientation === "horizontal" && overflow.width ? { width: overflow.width } : void 0, className: `sia-tabs__list${sliding ? " sia-tabs__list--sliding" : ""}`, role: "tablist", "aria-orientation": resolvedOrientation, children: [
2348
2004
  sliding ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { ref: indicatorRef, className: `sia-tabs__indicator${type === "capsule" ? " sia-tabs__capsule-indicator" : ""}`, "aria-hidden": "true", children: type === "tech-line" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sia-tabs__indicator-shape", "aria-hidden": "true" }) : null }, type) : null,
2349
- items.map((item) => {
2005
+ items.map((item, index) => {
2350
2006
  const selected = item.key === selectedKey;
2351
2007
  const canClose = item.closable ?? closable;
2352
- const tabNode = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: `sia-tabs__tab-wrap${canClose ? " is-closable" : ""}`, children: [
2353
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2354
- "button",
2355
- {
2356
- id: `${baseId}-tab-${item.key}`,
2357
- type: "button",
2358
- className: "sia-tabs__tab",
2359
- role: "tab",
2360
- "aria-selected": selected,
2361
- "aria-controls": hasPanels ? `${baseId}-panel-${item.key}` : void 0,
2362
- tabIndex: selected ? 0 : -1,
2363
- disabled: item.disabled,
2364
- onClick: () => selectTab(item.key),
2365
- onKeyDown: (event) => handleKeyDown(event, item.key),
2366
- children: [
2367
- type === "tech-line" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sia-tabs__tab-shape", "aria-hidden": "true" }) : null,
2368
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sia-tabs__icon", children: item.icon }) : null,
2369
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: item.label })
2370
- ]
2371
- }
2372
- ),
2373
- canClose ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2374
- "button",
2375
- {
2376
- type: "button",
2377
- className: "sia-tabs__close",
2378
- "aria-label": `\u5173\u95ED${typeof item.label === "string" ? item.label : "\u6807\u7B7E\u9875"}`,
2379
- disabled: item.disabled,
2380
- onClick: () => onEdit?.(item.key, "remove"),
2381
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "close", size: 12 })
2382
- }
2383
- ) : null
2384
- ] }, item.key);
2385
2008
  const contextMenuItems = typeof tabContextMenu === "function" ? tabContextMenu(item) : tabContextMenu;
2009
+ const entryProps = { "data-tab-entry": "", "data-tab-hidden": index >= visibleCount, "aria-hidden": index >= visibleCount || void 0 };
2010
+ const tabNode = /* @__PURE__ */ (0, import_react11.createElement)("span", { ...!contextMenuItems?.length ? entryProps : {}, className: `sia-tabs__tab-wrap${canClose ? " is-closable" : ""}`, key: item.key }, /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2011
+ "button",
2012
+ {
2013
+ id: `${baseId}-tab-${item.key}`,
2014
+ type: "button",
2015
+ className: "sia-tabs__tab",
2016
+ role: "tab",
2017
+ "aria-selected": selected,
2018
+ "aria-controls": hasPanels ? `${baseId}-panel-${item.key}` : void 0,
2019
+ tabIndex: selected ? 0 : -1,
2020
+ disabled: item.disabled,
2021
+ onClick: () => selectTab(item.key),
2022
+ onKeyDown: (event) => handleKeyDown(event, item.key),
2023
+ children: [
2024
+ type === "tech-line" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sia-tabs__tab-shape", "aria-hidden": "true" }) : null,
2025
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sia-tabs__icon", children: item.icon }) : null,
2026
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: item.label })
2027
+ ]
2028
+ }
2029
+ ), canClose ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2030
+ "button",
2031
+ {
2032
+ type: "button",
2033
+ className: "sia-tabs__close",
2034
+ "aria-label": `\u5173\u95ED${typeof item.label === "string" ? item.label : "\u6807\u7B7E\u9875"}`,
2035
+ disabled: item.disabled,
2036
+ onClick: () => onEdit?.(item.key, "remove"),
2037
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "close", size: 12 })
2038
+ }
2039
+ ) : null);
2386
2040
  if (!contextMenuItems?.length) return tabNode;
2387
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2041
+ return /* @__PURE__ */ (0, import_react11.createElement)(
2388
2042
  Dropdown,
2389
2043
  {
2044
+ ...entryProps,
2045
+ key: item.key,
2390
2046
  className: "sia-tabs__tab-context-trigger",
2391
2047
  popupClassName: "sia-tabs__tab-context-menu",
2392
2048
  trigger: ["contextMenu"],
@@ -2395,12 +2051,26 @@ function Tabs({
2395
2051
  items: contextMenuItems,
2396
2052
  selectable: false,
2397
2053
  onClick: (info) => onTabContextMenuClick?.({ ...info, tabKey: item.key, tab: item })
2398
- },
2399
- children: tabNode
2054
+ }
2400
2055
  },
2401
- item.key
2056
+ tabNode
2402
2057
  );
2403
- })
2058
+ }),
2059
+ resolvedOrientation === "horizontal" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2060
+ Dropdown,
2061
+ {
2062
+ className: "sia-tabs__more",
2063
+ "data-tab-hidden": !hiddenItems.length,
2064
+ trigger: ["hover", "click"],
2065
+ placement: "bottomRight",
2066
+ showTriggerIcon: false,
2067
+ autoFocus: true,
2068
+ open: moreOpen && hiddenItems.length > 0,
2069
+ onOpenChange: setMoreOpen,
2070
+ menu: { items: hiddenItems.map((item) => ({ key: item.key, label: item.label, icon: item.icon, disabled: item.disabled })), selectedKeys: [selectedKey], onClick: (info) => selectTab(info.key) },
2071
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { ref: moreRef, variant: "text", icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "more-horizontal" }), "aria-label": "\u66F4\u591A\u9009\u9879\u5361", onKeyDown: (event) => handleKeyDown(event, selectedKey), className: hiddenItems.some((item) => item.key === selectedKey) ? "is-active" : void 0 })
2072
+ }
2073
+ ) : null
2404
2074
  ] }),
2405
2075
  tabBarExtraContent ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "sia-tabs__extra", children: tabBarExtraContent }) : null
2406
2076
  ] }),
@@ -2431,26 +2101,26 @@ function Tabs({
2431
2101
  }
2432
2102
 
2433
2103
  // src/components/Feedback.tsx
2434
- var import_react15 = require("react");
2104
+ var import_react14 = require("react");
2435
2105
  var import_react_dom3 = require("react-dom");
2436
2106
  var import_client2 = require("react-dom/client");
2437
2107
 
2438
2108
  // src/components/FloatingDisplay.tsx
2439
- var import_react14 = require("react");
2109
+ var import_react13 = require("react");
2440
2110
  var import_react_dom2 = require("react-dom");
2441
2111
 
2442
2112
  // src/components/Checkbox.tsx
2443
- var import_react13 = require("react");
2113
+ var import_react12 = require("react");
2444
2114
  var import_jsx_runtime12 = require("react/jsx-runtime");
2445
- var CheckboxGroupContext = (0, import_react13.createContext)(null);
2446
- var CheckboxRoot = (0, import_react13.forwardRef)(function Checkbox({ value, size: sizeProp, indeterminate = false, children, disabled, checked, defaultChecked, className = "", onChange, ...props }, forwardedRef) {
2115
+ var CheckboxGroupContext = (0, import_react12.createContext)(null);
2116
+ var CheckboxRoot = (0, import_react12.forwardRef)(function Checkbox({ value, size: sizeProp, indeterminate = false, children, disabled, checked, defaultChecked, className = "", onChange, ...props }, forwardedRef) {
2447
2117
  const size = useControlSize(sizeProp);
2448
- const group = (0, import_react13.useContext)(CheckboxGroupContext);
2449
- const localRef = (0, import_react13.useRef)(null);
2450
- const fallbackId = (0, import_react13.useId)();
2118
+ const group = (0, import_react12.useContext)(CheckboxGroupContext);
2119
+ const localRef = (0, import_react12.useRef)(null);
2120
+ const fallbackId = (0, import_react12.useId)();
2451
2121
  const grouped = group !== null && value !== void 0;
2452
2122
  const currentChecked = grouped ? group.values.includes(value) : checked;
2453
- (0, import_react13.useEffect)(() => {
2123
+ (0, import_react12.useEffect)(() => {
2454
2124
  if (localRef.current) localRef.current.indeterminate = indeterminate;
2455
2125
  }, [indeterminate]);
2456
2126
  function setRef(node) {
@@ -2503,7 +2173,7 @@ function CheckboxGroup({
2503
2173
  gap: gap === void 0 ? void 0 : typeof gap === "number" ? Math.max(0, gap) : `${Math.max(0, gap[0])}px ${Math.max(0, gap[1])}px`
2504
2174
  };
2505
2175
  const [values, setValues] = useControllableState({ value, defaultValue, onChange });
2506
- const context = (0, import_react13.useMemo)(() => ({
2176
+ const context = (0, import_react12.useMemo)(() => ({
2507
2177
  values,
2508
2178
  disabled,
2509
2179
  name,
@@ -2582,17 +2252,17 @@ function Floating({
2582
2252
  role = "tooltip",
2583
2253
  onOpenChange
2584
2254
  }) {
2585
- const rootRef = (0, import_react14.useRef)(null);
2586
- const overlayRef = (0, import_react14.useRef)(null);
2587
- const enterTimer = (0, import_react14.useRef)();
2588
- const leaveTimer = (0, import_react14.useRef)();
2589
- const contentId = (0, import_react14.useId)();
2255
+ const rootRef = (0, import_react13.useRef)(null);
2256
+ const overlayRef = (0, import_react13.useRef)(null);
2257
+ const enterTimer = (0, import_react13.useRef)();
2258
+ const leaveTimer = (0, import_react13.useRef)();
2259
+ const contentId = (0, import_react13.useId)();
2590
2260
  const triggers = Array.isArray(trigger) ? trigger : [trigger];
2591
2261
  const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
2592
- const [position, setPosition] = (0, import_react14.useState)();
2593
- const setVisibleRef = (0, import_react14.useRef)(setVisible);
2262
+ const [position, setPosition] = (0, import_react13.useState)();
2263
+ const setVisibleRef = (0, import_react13.useRef)(setVisible);
2594
2264
  setVisibleRef.current = setVisible;
2595
- const closeSelfRef = (0, import_react14.useRef)();
2265
+ const closeSelfRef = (0, import_react13.useRef)();
2596
2266
  if (!closeSelfRef.current) closeSelfRef.current = () => setVisibleRef.current(false);
2597
2267
  const exclusiveTooltip = role === "tooltip" && triggers.includes("hover");
2598
2268
  function openNow() {
@@ -2620,7 +2290,7 @@ function Floating({
2620
2290
  if (delay <= 0) closeNow();
2621
2291
  else leaveTimer.current = window.setTimeout(closeNow, delay * 1e3);
2622
2292
  }
2623
- (0, import_react14.useEffect)(() => {
2293
+ (0, import_react13.useEffect)(() => {
2624
2294
  if (!visible || !triggers.includes("click")) return;
2625
2295
  const close = (event) => {
2626
2296
  const target = event.target;
@@ -2629,7 +2299,7 @@ function Floating({
2629
2299
  document.addEventListener("pointerdown", close);
2630
2300
  return () => document.removeEventListener("pointerdown", close);
2631
2301
  }, [triggers.join("|"), visible]);
2632
- (0, import_react14.useLayoutEffect)(() => {
2302
+ (0, import_react13.useLayoutEffect)(() => {
2633
2303
  if (!visible) {
2634
2304
  setPosition(void 0);
2635
2305
  return;
@@ -2650,11 +2320,11 @@ function Floating({
2650
2320
  observer.disconnect();
2651
2321
  };
2652
2322
  }, [children, content, placement, visible]);
2653
- (0, import_react14.useEffect)(() => () => {
2323
+ (0, import_react13.useEffect)(() => () => {
2654
2324
  clearTimers();
2655
2325
  if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
2656
2326
  }, []);
2657
- const child = (0, import_react14.cloneElement)(children, {
2327
+ const child = (0, import_react13.cloneElement)(children, {
2658
2328
  ...triggers.includes("hover") ? { onMouseEnter: (event) => {
2659
2329
  children.props.onMouseEnter?.(event);
2660
2330
  show(mouseEnterDelay);
@@ -2759,11 +2429,11 @@ function Progress({
2759
2429
  }
2760
2430
 
2761
2431
  // src/components/DataDisplay.tsx
2762
- var import_react17 = require("react");
2432
+ var import_react16 = require("react");
2763
2433
  var import_react_dom5 = require("react-dom");
2764
2434
 
2765
2435
  // src/components/Overlay.tsx
2766
- var import_react16 = require("react");
2436
+ var import_react15 = require("react");
2767
2437
  var import_react_dom4 = require("react-dom");
2768
2438
  var bodyLockCount = 0;
2769
2439
  var previousBodyOverflow = "";
@@ -2785,10 +2455,10 @@ function focusableElements(container) {
2785
2455
  )].filter((element) => !element.hidden && element.getAttribute("aria-hidden") !== "true");
2786
2456
  }
2787
2457
  function useOverlayLifecycle(open, panelRef, onRequestClose, keyboard = true) {
2788
- const overlayIdRef = (0, import_react16.useRef)(/* @__PURE__ */ Symbol("sia-overlay"));
2789
- const closeRef = (0, import_react16.useRef)(onRequestClose);
2458
+ const overlayIdRef = (0, import_react15.useRef)(/* @__PURE__ */ Symbol("sia-overlay"));
2459
+ const closeRef = (0, import_react15.useRef)(onRequestClose);
2790
2460
  closeRef.current = onRequestClose;
2791
- (0, import_react16.useEffect)(() => {
2461
+ (0, import_react15.useEffect)(() => {
2792
2462
  if (!open || typeof document === "undefined") return void 0;
2793
2463
  const overlayId = overlayIdRef.current;
2794
2464
  const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
@@ -2871,8 +2541,8 @@ function CollapsePanel({
2871
2541
  destroyInactivePanel = false,
2872
2542
  children
2873
2543
  }) {
2874
- const [keepChildren, setKeepChildren] = (0, import_react17.useState)(open || forceRender || !destroyInactivePanel);
2875
- (0, import_react17.useEffect)(() => {
2544
+ const [keepChildren, setKeepChildren] = (0, import_react16.useState)(open || forceRender || !destroyInactivePanel);
2545
+ (0, import_react16.useEffect)(() => {
2876
2546
  if (open || forceRender || !destroyInactivePanel) {
2877
2547
  setKeepChildren(true);
2878
2548
  return void 0;
@@ -2886,7 +2556,7 @@ function CollapsePanel({
2886
2556
  function Collapse({ items, activeKey, defaultActiveKey = [], accordion = false, bordered = true, ghost = false, destroyInactivePanel = false, expandIconPosition = "start", onChange, className = "", ...props }) {
2887
2557
  const normalize = (key) => Array.isArray(key) ? [...key] : key === void 0 ? [] : [key];
2888
2558
  const controlled = activeKey !== void 0;
2889
- const [internal, setInternal] = (0, import_react17.useState)(normalize(defaultActiveKey));
2559
+ const [internal, setInternal] = (0, import_react16.useState)(normalize(defaultActiveKey));
2890
2560
  const openKeys = controlled ? normalize(activeKey) : internal;
2891
2561
  function toggle(item) {
2892
2562
  if (item.disabled || item.collapsible === "disabled") return;
@@ -2916,16 +2586,16 @@ function Collapse({ items, activeKey, defaultActiveKey = [], accordion = false,
2916
2586
  }) });
2917
2587
  }
2918
2588
  function ImagePreview({ open, src, alt = "", onOpenChange }) {
2919
- const previewRef = (0, import_react17.useRef)(null);
2920
- const stageRef = (0, import_react17.useRef)(null);
2921
- const [natural, setNatural] = (0, import_react17.useState)({ src: "", width: 0, height: 0 });
2922
- const [area, setArea] = (0, import_react17.useState)({ width: 0, height: 0 });
2923
- const [zoom, setZoom] = (0, import_react17.useState)(1);
2924
- const [rotation, setRotation] = (0, import_react17.useState)(0);
2925
- const [flip, setFlip] = (0, import_react17.useState)({ x: 1, y: 1 });
2926
- const [pan, setPan] = (0, import_react17.useState)({ x: 0, y: 0 });
2927
- const [failed, setFailed] = (0, import_react17.useState)(false);
2928
- const drag = (0, import_react17.useRef)();
2589
+ const previewRef = (0, import_react16.useRef)(null);
2590
+ const stageRef = (0, import_react16.useRef)(null);
2591
+ const [natural, setNatural] = (0, import_react16.useState)({ src: "", width: 0, height: 0 });
2592
+ const [area, setArea] = (0, import_react16.useState)({ width: 0, height: 0 });
2593
+ const [zoom, setZoom] = (0, import_react16.useState)(1);
2594
+ const [rotation, setRotation] = (0, import_react16.useState)(0);
2595
+ const [flip, setFlip] = (0, import_react16.useState)({ x: 1, y: 1 });
2596
+ const [pan, setPan] = (0, import_react16.useState)({ x: 0, y: 0 });
2597
+ const [failed, setFailed] = (0, import_react16.useState)(false);
2598
+ const drag = (0, import_react16.useRef)();
2929
2599
  useOverlayLifecycle(open, previewRef, () => onOpenChange(false));
2930
2600
  const reset = () => {
2931
2601
  setZoom(1);
@@ -2934,11 +2604,11 @@ function ImagePreview({ open, src, alt = "", onOpenChange }) {
2934
2604
  setPan({ x: 0, y: 0 });
2935
2605
  drag.current = void 0;
2936
2606
  };
2937
- (0, import_react17.useEffect)(() => {
2607
+ (0, import_react16.useEffect)(() => {
2938
2608
  reset();
2939
2609
  setFailed(false);
2940
2610
  }, [open, src]);
2941
- (0, import_react17.useEffect)(() => {
2611
+ (0, import_react16.useEffect)(() => {
2942
2612
  const stage = stageRef.current;
2943
2613
  if (!open || !stage) return;
2944
2614
  const measure = () => {
@@ -3024,10 +2694,10 @@ function useFloatingPlaceholder({ mode, placeholder, filled, active = false }) {
3024
2694
  }
3025
2695
 
3026
2696
  // src/components/Select.tsx
3027
- var import_react22 = require("react");
2697
+ var import_react23 = require("react");
3028
2698
 
3029
2699
  // src/components/Modal.tsx
3030
- var import_react18 = require("react");
2700
+ var import_react17 = require("react");
3031
2701
  var import_client3 = require("react-dom/client");
3032
2702
  var import_jsx_runtime17 = require("react/jsx-runtime");
3033
2703
  var modalHandles = /* @__PURE__ */ new Set();
@@ -3039,7 +2709,7 @@ var typeIcons = {
3039
2709
  error: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "circle-close", size: 23 }),
3040
2710
  confirm: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "question", size: 23 })
3041
2711
  };
3042
- var ModalRoot = (0, import_react18.forwardRef)(function Modal({
2712
+ var ModalRoot = (0, import_react17.forwardRef)(function Modal({
3043
2713
  open,
3044
2714
  title,
3045
2715
  children,
@@ -3065,302 +2735,679 @@ var ModalRoot = (0, import_react18.forwardRef)(function Modal({
3065
2735
  onOpenChange,
3066
2736
  afterOpenChange,
3067
2737
  className = "",
3068
- style,
2738
+ style,
2739
+ ...props
2740
+ }, forwardedRef) {
2741
+ const localRef = (0, import_react17.useRef)(null);
2742
+ const titleId = (0, import_react17.useId)();
2743
+ const [submitting, setSubmitting] = (0, import_react17.useState)(false);
2744
+ const [rendered, setRendered] = (0, import_react17.useState)(open);
2745
+ const [closing, setClosing] = (0, import_react17.useState)(false);
2746
+ const afterOpenChangeRef = (0, import_react17.useRef)(afterOpenChange);
2747
+ afterOpenChangeRef.current = afterOpenChange;
2748
+ const submitLock = (0, import_react17.useRef)(false);
2749
+ (0, import_react17.useEffect)(() => {
2750
+ if (!open || !rendered) return void 0;
2751
+ const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
2752
+ return () => window.clearTimeout(timer);
2753
+ }, [open, rendered]);
2754
+ (0, import_react17.useEffect)(() => {
2755
+ if (open) {
2756
+ setRendered(true);
2757
+ setClosing(false);
2758
+ return void 0;
2759
+ }
2760
+ if (!rendered) return void 0;
2761
+ setClosing(true);
2762
+ const timer = window.setTimeout(() => {
2763
+ setRendered(false);
2764
+ setClosing(false);
2765
+ afterOpenChangeRef.current?.(false);
2766
+ }, MODAL_MOTION_DURATION);
2767
+ return () => window.clearTimeout(timer);
2768
+ }, [open, rendered]);
2769
+ function setRef(node) {
2770
+ localRef.current = node;
2771
+ if (typeof forwardedRef === "function") forwardedRef(node);
2772
+ else if (forwardedRef) forwardedRef.current = node;
2773
+ }
2774
+ function requestClose() {
2775
+ if (submitting || confirmLoading) return;
2776
+ onCancel?.();
2777
+ onOpenChange?.(false);
2778
+ }
2779
+ async function handleOk() {
2780
+ if (submitLock.current || confirmLoading) return;
2781
+ submitLock.current = true;
2782
+ if (!onOk) {
2783
+ onOpenChange?.(false);
2784
+ submitLock.current = false;
2785
+ return;
2786
+ }
2787
+ try {
2788
+ const result = onOk();
2789
+ if (result instanceof Promise) {
2790
+ setSubmitting(true);
2791
+ const resolved = await result;
2792
+ if (resolved !== false) onOpenChange?.(false);
2793
+ } else if (result !== false) {
2794
+ onOpenChange?.(false);
2795
+ }
2796
+ } catch {
2797
+ return;
2798
+ } finally {
2799
+ submitLock.current = false;
2800
+ setSubmitting(false);
2801
+ }
2802
+ }
2803
+ useOverlayLifecycle(rendered, localRef, requestClose, keyboard);
2804
+ if (!rendered) return null;
2805
+ const mergedStyle = {
2806
+ ...height !== void 0 ? { display: "flex", flexDirection: "column", height, maxHeight: "calc(100dvh - 48px)" } : {},
2807
+ ...style,
2808
+ "--sia-modal-width": typeof width === "number" ? `${width}px` : width
2809
+ };
2810
+ const loading = submitting || confirmLoading;
2811
+ const defaultFooter = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
2812
+ showCancel ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { ...cancelButtonProps, onClick: requestClose, disabled: loading || cancelButtonProps?.disabled, children: cancelText }) : null,
2813
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { variant: "primary", ...okButtonProps, onClick: handleOk, loading, children: okText })
2814
+ ] });
2815
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(OverlayPortal, { container: getContainer, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2816
+ "div",
2817
+ {
2818
+ className: `sia-modal-root${centered ? " sia-modal-root--centered" : ""}`,
2819
+ "data-state": closing ? "closing" : "open",
2820
+ style: { zIndex },
2821
+ onMouseDown: (event) => {
2822
+ if (event.target === event.currentTarget && maskClosable) requestClose();
2823
+ },
2824
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2825
+ "div",
2826
+ {
2827
+ ref: setRef,
2828
+ className: `sia-modal sia-modal--${type} ${className}`.trim(),
2829
+ style: mergedStyle,
2830
+ role: "dialog",
2831
+ "aria-modal": "true",
2832
+ "aria-labelledby": title ? titleId : void 0,
2833
+ tabIndex: -1,
2834
+ ...withTitleTooltip(props),
2835
+ children: [
2836
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-modal__header", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
2837
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-modal__heading", children: [
2838
+ typeIcons[type] ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "sia-modal__type-icon", "aria-hidden": "true", children: typeIcons[type] }) : null,
2839
+ title ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("strong", { id: titleId, children: title }) : null
2840
+ ] }),
2841
+ closable ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "sia-modal__close", "aria-label": "\u5173\u95ED\u5BF9\u8BDD\u6846", onClick: requestClose, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "close", size: 17 }) }) : null
2842
+ ] }),
2843
+ children !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "sia-modal__body", style: height !== void 0 ? { flex: 1, minHeight: 0, overflow: "auto" } : void 0, children }) : null,
2844
+ footer !== null ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-modal__footer", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
2845
+ footer === void 0 && footerExtra != null ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { marginRight: "auto" }, children: footerExtra }) : null,
2846
+ footer ?? defaultFooter
2847
+ ] }) : null
2848
+ ]
2849
+ }
2850
+ )
2851
+ }
2852
+ ) });
2853
+ });
2854
+ function openModal(config) {
2855
+ if (typeof document === "undefined") return { destroy() {
2856
+ }, update() {
2857
+ } };
2858
+ const container = document.createElement("div");
2859
+ container.className = "sia-modal-api-host";
2860
+ document.body.appendChild(container);
2861
+ const root = (0, import_client3.createRoot)(container);
2862
+ let currentConfig = config;
2863
+ let currentOpen = true;
2864
+ let destroyed = false;
2865
+ let cleanupTimer;
2866
+ function cleanup2() {
2867
+ if (destroyed) return;
2868
+ destroyed = true;
2869
+ if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
2870
+ root.unmount();
2871
+ container.remove();
2872
+ modalHandles.delete(handle);
2873
+ }
2874
+ function closeWithMotion() {
2875
+ if (destroyed || !currentOpen) return;
2876
+ currentOpen = false;
2877
+ render();
2878
+ cleanupTimer = window.setTimeout(cleanup2, MODAL_MOTION_DURATION);
2879
+ }
2880
+ function render() {
2881
+ root.render(/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
2882
+ currentConfig.onOpenChange?.(nextOpen);
2883
+ if (!nextOpen) closeWithMotion();
2884
+ } }));
2885
+ }
2886
+ const handle = {
2887
+ destroy: closeWithMotion,
2888
+ update(next) {
2889
+ if (destroyed) return;
2890
+ currentConfig = { ...currentConfig, ...next };
2891
+ render();
2892
+ }
2893
+ };
2894
+ modalHandles.add(handle);
2895
+ render();
2896
+ return handle;
2897
+ }
2898
+ function preset(type, defaults = {}) {
2899
+ return (config) => openModal({
2900
+ okText: type === "confirm" ? "\u786E\u5B9A" : "\u77E5\u9053\u4E86",
2901
+ showCancel: type === "confirm",
2902
+ closable: type !== "confirm",
2903
+ maskClosable: type !== "confirm",
2904
+ ...defaults,
2905
+ ...config,
2906
+ type
2907
+ });
2908
+ }
2909
+ var Modal2 = Object.assign(ModalRoot, {
2910
+ /** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
2911
+ open: openModal,
2912
+ /** 显示普通信息提示。 */
2913
+ info: preset("info", { title: "\u63D0\u793A" }),
2914
+ /** 显示成功提示。 */
2915
+ success: preset("success", { title: "\u64CD\u4F5C\u6210\u529F" }),
2916
+ /** 显示警告提示。 */
2917
+ warning: preset("warning", { title: "\u8BF7\u6CE8\u610F" }),
2918
+ /** 显示错误提示。 */
2919
+ error: preset("error", { title: "\u64CD\u4F5C\u5931\u8D25" }),
2920
+ /** 打开确认弹框,支持异步确认;返回 false 可阻止关闭。 */
2921
+ confirm: preset("confirm", { title: "\u786E\u8BA4\u64CD\u4F5C" }),
2922
+ /** 关闭由此 API 打开的所有弹层。 */
2923
+ destroyAll() {
2924
+ [...modalHandles].forEach((handle) => handle.destroy());
2925
+ }
2926
+ });
2927
+
2928
+ // src/components/Input.tsx
2929
+ var import_react18 = require("react");
2930
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2931
+ var Input = (0, import_react18.forwardRef)(function Input2({
2932
+ label,
2933
+ hint,
2934
+ status = "default",
2935
+ size: sizeProp,
2936
+ prefix,
2937
+ suffix,
2938
+ allowClear = true,
2939
+ onClear,
2940
+ showCount = false,
2941
+ placeholderMode,
2942
+ placeholder,
2943
+ className = "",
2944
+ id,
2945
+ disabled,
2946
+ value,
2947
+ defaultValue,
2948
+ maxLength,
2949
+ onChange,
3069
2950
  ...props
3070
2951
  }, forwardedRef) {
2952
+ const size = useControlSize(sizeProp);
2953
+ const fallbackId = (0, import_react18.useId)();
2954
+ const inputId = id ?? fallbackId;
3071
2955
  const localRef = (0, import_react18.useRef)(null);
3072
- const titleId = (0, import_react18.useId)();
3073
- const [submitting, setSubmitting] = (0, import_react18.useState)(false);
3074
- const [rendered, setRendered] = (0, import_react18.useState)(open);
3075
- const [closing, setClosing] = (0, import_react18.useState)(false);
3076
- const afterOpenChangeRef = (0, import_react18.useRef)(afterOpenChange);
3077
- afterOpenChangeRef.current = afterOpenChange;
3078
- const submitLock = (0, import_react18.useRef)(false);
3079
- (0, import_react18.useEffect)(() => {
3080
- if (!open || !rendered) return void 0;
3081
- const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
3082
- return () => window.clearTimeout(timer);
3083
- }, [open, rendered]);
3084
- (0, import_react18.useEffect)(() => {
3085
- if (open) {
3086
- setRendered(true);
3087
- setClosing(false);
3088
- return void 0;
3089
- }
3090
- if (!rendered) return void 0;
3091
- setClosing(true);
3092
- const timer = window.setTimeout(() => {
3093
- setRendered(false);
3094
- setClosing(false);
3095
- afterOpenChangeRef.current?.(false);
3096
- }, MODAL_MOTION_DURATION);
3097
- return () => window.clearTimeout(timer);
3098
- }, [open, rendered]);
2956
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react18.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
2957
+ const currentText = value !== void 0 ? String(value) : uncontrolledValue;
2958
+ const hasValue = currentText.length > 0;
2959
+ const floatingPlaceholder = usePlaceholderMode(placeholderMode) === "floating" && Boolean(placeholder);
2960
+ const hintId = `${inputId}-hint`;
2961
+ const describedBy = [props["aria-describedby"], hint ? hintId : null].filter(Boolean).join(" ") || void 0;
3099
2962
  function setRef(node) {
3100
2963
  localRef.current = node;
3101
2964
  if (typeof forwardedRef === "function") forwardedRef(node);
3102
2965
  else if (forwardedRef) forwardedRef.current = node;
3103
2966
  }
3104
- function requestClose() {
3105
- if (submitting || confirmLoading) return;
3106
- onCancel?.();
3107
- onOpenChange?.(false);
2967
+ function handleChange(event) {
2968
+ if (maxLength !== void 0 && maxLength >= 0 && event.target.value.length > maxLength) {
2969
+ const valueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
2970
+ valueSetter?.call(event.target, event.target.value.slice(0, maxLength));
2971
+ }
2972
+ setUncontrolledValue(event.target.value);
2973
+ onChange?.(event);
3108
2974
  }
3109
- async function handleOk() {
3110
- if (submitLock.current || confirmLoading) return;
3111
- submitLock.current = true;
3112
- if (!onOk) {
3113
- onOpenChange?.(false);
3114
- submitLock.current = false;
3115
- return;
2975
+ function clearValue() {
2976
+ const input2 = localRef.current;
2977
+ if (!input2 || disabled) return;
2978
+ const valueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
2979
+ valueSetter?.call(input2, "");
2980
+ input2.dispatchEvent(new Event("input", { bubbles: true }));
2981
+ setUncontrolledValue("");
2982
+ input2.focus();
2983
+ onClear?.();
2984
+ }
2985
+ function handleControlMouseDown(event) {
2986
+ if (disabled || event.defaultPrevented || event.button !== 0) return;
2987
+ const target = event.target;
2988
+ if (!(target instanceof Element)) return;
2989
+ const interactive = target.closest("input, textarea, select, button, a[href], [tabindex], [contenteditable]:not([contenteditable='false']), [role='button'], [role='link']");
2990
+ if (interactive && event.currentTarget.contains(interactive) && !interactive.classList.contains("sia-input-control__clear")) return;
2991
+ event.preventDefault();
2992
+ localRef.current?.focus({ preventScroll: true });
2993
+ }
2994
+ const input = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2995
+ "input",
2996
+ {
2997
+ ...withTitleTooltip(props),
2998
+ ref: setRef,
2999
+ id: inputId,
3000
+ className: "sia-input",
3001
+ disabled,
3002
+ value,
3003
+ defaultValue,
3004
+ maxLength,
3005
+ placeholder,
3006
+ "aria-describedby": describedBy,
3007
+ "aria-invalid": status === "error" || void 0,
3008
+ onChange: handleChange
3116
3009
  }
3117
- try {
3118
- const result = onOk();
3119
- if (result instanceof Promise) {
3120
- setSubmitting(true);
3121
- const resolved = await result;
3122
- if (resolved !== false) onOpenChange?.(false);
3123
- } else if (result !== false) {
3124
- onOpenChange?.(false);
3010
+ );
3011
+ const control = /* @__PURE__ */ (0, import_jsx_runtime18.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: [
3012
+ prefix ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-input-control__affix", children: prefix }) : null,
3013
+ floatingPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "sia-input-control__input-wrap", children: [
3014
+ input,
3015
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-input-control__floating-placeholder", "aria-hidden": "true", children: placeholder })
3016
+ ] }) : input,
3017
+ allowClear && hasValue && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { className: "sia-input-control__clear", type: "button", "aria-label": "\u6E05\u7A7A\u8F93\u5165", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
3018
+ suffix ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-input-control__affix", children: suffix }) : null,
3019
+ showCount ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: `sia-input-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
3020
+ currentText.length,
3021
+ maxLength !== void 0 ? `/${maxLength}` : null
3022
+ ] }) : null
3023
+ ] });
3024
+ if (!label && !hint) return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: `sia-field ${className}`.trim(), children: control });
3025
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: `sia-field ${className}`.trim(), children: [
3026
+ label ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { className: "sia-field__label", htmlFor: inputId, children: label }) : null,
3027
+ control,
3028
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
3029
+ ] });
3030
+ });
3031
+
3032
+ // src/components/SelectionPanel.tsx
3033
+ var import_react21 = require("react");
3034
+
3035
+ // src/components/FloatingScrollbarProvider.tsx
3036
+ var import_react20 = require("react");
3037
+
3038
+ // src/components/useScrollbarProximity.ts
3039
+ var import_react19 = require("react");
3040
+ var users = 0;
3041
+ var cleanup;
3042
+ function useScrollbarProximity() {
3043
+ (0, import_react19.useEffect)(() => {
3044
+ if (users++ === 0) {
3045
+ let frame = 0;
3046
+ let x = -Infinity;
3047
+ let y = -Infinity;
3048
+ const nearby = /* @__PURE__ */ new Set();
3049
+ const clear = () => {
3050
+ nearby.forEach((track) => track.removeAttribute("data-scrollbar-near"));
3051
+ nearby.clear();
3052
+ };
3053
+ const update = () => {
3054
+ frame = 0;
3055
+ const next = /* @__PURE__ */ new Set();
3056
+ document.querySelectorAll(".sia-scrollbar-track").forEach((track) => {
3057
+ const rect = track.getBoundingClientRect();
3058
+ const proximity = Number.parseFloat(getComputedStyle(track).getPropertyValue("--sia-scrollbar-proximity")) || 16;
3059
+ if (rect.width && rect.height && x >= rect.left - proximity && x <= rect.right + proximity && y >= rect.top - proximity && y <= rect.bottom + proximity) {
3060
+ next.add(track);
3061
+ if (!nearby.has(track)) track.setAttribute("data-scrollbar-near", "true");
3062
+ }
3063
+ });
3064
+ nearby.forEach((track) => {
3065
+ if (!next.has(track)) track.removeAttribute("data-scrollbar-near");
3066
+ });
3067
+ nearby.clear();
3068
+ next.forEach((track) => nearby.add(track));
3069
+ };
3070
+ const move = (event) => {
3071
+ if (event.pointerType === "touch") return;
3072
+ x = event.clientX;
3073
+ y = event.clientY;
3074
+ if (!frame) frame = requestAnimationFrame(update);
3075
+ };
3076
+ const leave = () => {
3077
+ x = y = -Infinity;
3078
+ clear();
3079
+ };
3080
+ document.addEventListener("pointermove", move, { passive: true });
3081
+ document.documentElement.addEventListener("pointerleave", leave);
3082
+ window.addEventListener("blur", leave);
3083
+ cleanup = () => {
3084
+ if (frame) cancelAnimationFrame(frame);
3085
+ document.removeEventListener("pointermove", move);
3086
+ document.documentElement.removeEventListener("pointerleave", leave);
3087
+ window.removeEventListener("blur", leave);
3088
+ clear();
3089
+ };
3090
+ }
3091
+ return () => {
3092
+ if (--users === 0) {
3093
+ cleanup?.();
3094
+ cleanup = void 0;
3095
+ }
3096
+ };
3097
+ }, []);
3098
+ }
3099
+
3100
+ // src/components/FloatingScrollbarProvider.tsx
3101
+ var scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
3102
+ var clippingOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay", "hidden", "clip"]);
3103
+ function isRootScroller(target) {
3104
+ return target === document.scrollingElement || target === document.documentElement;
3105
+ }
3106
+ function canScroll(target, axis) {
3107
+ if (target.matches(".sia-table__viewport, [data-sia-native-scrollbar]")) return false;
3108
+ if (isRootScroller(target)) {
3109
+ return axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
3110
+ }
3111
+ const style = getComputedStyle(target);
3112
+ const overflow = axis === "horizontal" ? style.overflowX : style.overflowY;
3113
+ const hasOverflow = axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
3114
+ return hasOverflow && scrollableOverflow.has(overflow);
3115
+ }
3116
+ function visibleRect(target) {
3117
+ if (isRootScroller(target)) {
3118
+ return { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0, width: window.innerWidth, height: window.innerHeight };
3119
+ }
3120
+ const ownRect = target.getBoundingClientRect();
3121
+ let top = Math.max(0, ownRect.top);
3122
+ let right = Math.min(window.innerWidth, ownRect.right);
3123
+ let bottom = Math.min(window.innerHeight, ownRect.bottom);
3124
+ let left = Math.max(0, ownRect.left);
3125
+ let parent = target.parentElement;
3126
+ while (parent && parent !== document.body && parent !== document.documentElement) {
3127
+ const style = getComputedStyle(parent);
3128
+ const clipX = clippingOverflow.has(style.overflowX);
3129
+ const clipY = clippingOverflow.has(style.overflowY);
3130
+ if (clipX || clipY) {
3131
+ const rect = parent.getBoundingClientRect();
3132
+ if (clipX) {
3133
+ left = Math.max(left, rect.left);
3134
+ right = Math.min(right, rect.right);
3135
+ }
3136
+ if (clipY) {
3137
+ top = Math.max(top, rect.top);
3138
+ bottom = Math.min(bottom, rect.bottom);
3125
3139
  }
3126
- } catch {
3127
- return;
3128
- } finally {
3129
- submitLock.current = false;
3130
- setSubmitting(false);
3131
3140
  }
3141
+ parent = parent.parentElement;
3132
3142
  }
3133
- useOverlayLifecycle(rendered, localRef, requestClose, keyboard);
3134
- if (!rendered) return null;
3135
- const mergedStyle = {
3136
- ...height !== void 0 ? { display: "flex", flexDirection: "column", height, maxHeight: "calc(100dvh - 48px)" } : {},
3137
- ...style,
3138
- "--sia-modal-width": typeof width === "number" ? `${width}px` : width
3143
+ return {
3144
+ top,
3145
+ right,
3146
+ bottom,
3147
+ left,
3148
+ width: Math.max(0, right - left),
3149
+ height: Math.max(0, bottom - top)
3139
3150
  };
3140
- const loading = submitting || confirmLoading;
3141
- const defaultFooter = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
3142
- showCancel ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { ...cancelButtonProps, onClick: requestClose, disabled: loading || cancelButtonProps?.disabled, children: cancelText }) : null,
3143
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { variant: "primary", ...okButtonProps, onClick: handleOk, loading, children: okText })
3144
- ] });
3145
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(OverlayPortal, { container: getContainer, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3146
- "div",
3147
- {
3148
- className: `sia-modal-root${centered ? " sia-modal-root--centered" : ""}`,
3149
- "data-state": closing ? "closing" : "open",
3150
- style: { zIndex },
3151
- onMouseDown: (event) => {
3152
- if (event.target === event.currentTarget && maskClosable) requestClose();
3153
- },
3154
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3155
- "div",
3156
- {
3157
- ref: setRef,
3158
- className: `sia-modal sia-modal--${type} ${className}`.trim(),
3159
- style: mergedStyle,
3160
- role: "dialog",
3161
- "aria-modal": "true",
3162
- "aria-labelledby": title ? titleId : void 0,
3163
- tabIndex: -1,
3164
- ...withTitleTooltip(props),
3165
- children: [
3166
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-modal__header", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
3167
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-modal__heading", children: [
3168
- typeIcons[type] ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "sia-modal__type-icon", "aria-hidden": "true", children: typeIcons[type] }) : null,
3169
- title ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("strong", { id: titleId, children: title }) : null
3170
- ] }),
3171
- closable ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "sia-modal__close", "aria-label": "\u5173\u95ED\u5BF9\u8BDD\u6846", onClick: requestClose, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "close", size: 17 }) }) : null
3172
- ] }),
3173
- children !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "sia-modal__body", style: height !== void 0 ? { flex: 1, minHeight: 0, overflow: "auto" } : void 0, children }) : null,
3174
- footer !== null ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-modal__footer", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
3175
- footer === void 0 && footerExtra != null ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { marginRight: "auto" }, children: footerExtra }) : null,
3176
- footer ?? defaultFooter
3177
- ] }) : null
3178
- ]
3151
+ }
3152
+ function createTrack(axis) {
3153
+ const track = document.createElement("div");
3154
+ const thumb = document.createElement("div");
3155
+ track.className = `sia-scrollbar-track sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
3156
+ thumb.className = "sia-floating-scrollbar__thumb";
3157
+ track.dataset.axis = axis;
3158
+ track.setAttribute("aria-hidden", "true");
3159
+ track.append(thumb);
3160
+ return { track, thumb };
3161
+ }
3162
+ function FloatingScrollbarProvider({ disabled = false, targetRef }) {
3163
+ useScrollbarProximity();
3164
+ (0, import_react20.useEffect)(() => {
3165
+ if (disabled) return;
3166
+ const layer = document.createElement("div");
3167
+ layer.className = "sia-floating-scrollbar-layer";
3168
+ layer.setAttribute("aria-hidden", "true");
3169
+ document.body.append(layer);
3170
+ const entries = /* @__PURE__ */ new Map();
3171
+ let scanFrame = 0;
3172
+ let updateFrame = 0;
3173
+ const setEntryVisible = (entry, visible) => {
3174
+ entry.horizontalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
3175
+ entry.verticalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
3176
+ };
3177
+ const showEntry = (entry) => {
3178
+ if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
3179
+ entry.hideTimer = null;
3180
+ setEntryVisible(entry, true);
3181
+ };
3182
+ const scheduleHide = (entry, delay = 500) => {
3183
+ if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
3184
+ entry.hideTimer = window.setTimeout(() => {
3185
+ entry.hideTimer = null;
3186
+ if (!entry.hoveringTarget && !entry.hoveringTrack && !entry.dragging) setEntryVisible(entry, false);
3187
+ }, delay);
3188
+ };
3189
+ const updateEntry = (entry) => {
3190
+ const { target, horizontalTrack, horizontalThumb, verticalTrack, verticalThumb } = entry;
3191
+ const hasHorizontal = canScroll(target, "horizontal");
3192
+ const hasVertical = canScroll(target, "vertical");
3193
+ const rect = visibleRect(target);
3194
+ const thickness = 10;
3195
+ horizontalTrack.hidden = !hasHorizontal || rect.width <= thickness || rect.height <= 0;
3196
+ verticalTrack.hidden = !hasVertical || rect.height <= thickness || rect.width <= 0;
3197
+ if (!horizontalTrack.hidden) {
3198
+ const trackWidth = Math.max(0, rect.width - (hasVertical ? thickness : 0));
3199
+ const thumbWidth = Math.max(24, Math.min(trackWidth, trackWidth * target.clientWidth / target.scrollWidth));
3200
+ const travel = Math.max(0, trackWidth - thumbWidth);
3201
+ const maxScroll = Math.max(1, target.scrollWidth - target.clientWidth);
3202
+ horizontalTrack.style.left = `${rect.left}px`;
3203
+ horizontalTrack.style.top = `${rect.bottom - thickness}px`;
3204
+ horizontalTrack.style.width = `${trackWidth}px`;
3205
+ horizontalTrack.style.height = `${thickness}px`;
3206
+ horizontalThumb.style.width = `${thumbWidth}px`;
3207
+ horizontalThumb.style.transform = `translate3d(${travel * target.scrollLeft / maxScroll}px, 0, 0)`;
3208
+ }
3209
+ if (!verticalTrack.hidden) {
3210
+ const trackHeight = Math.max(0, rect.height - (hasHorizontal ? thickness : 0));
3211
+ const thumbHeight = Math.max(24, Math.min(trackHeight, trackHeight * target.clientHeight / target.scrollHeight));
3212
+ const travel = Math.max(0, trackHeight - thumbHeight);
3213
+ const maxScroll = Math.max(1, target.scrollHeight - target.clientHeight);
3214
+ verticalTrack.style.left = `${rect.right - thickness}px`;
3215
+ verticalTrack.style.top = `${rect.top}px`;
3216
+ verticalTrack.style.width = `${thickness}px`;
3217
+ verticalTrack.style.height = `${trackHeight}px`;
3218
+ verticalThumb.style.height = `${thumbHeight}px`;
3219
+ verticalThumb.style.transform = `translate3d(0, ${travel * target.scrollTop / maxScroll}px, 0)`;
3220
+ }
3221
+ };
3222
+ const scheduleUpdateAll = () => {
3223
+ if (updateFrame) return;
3224
+ updateFrame = window.requestAnimationFrame(() => {
3225
+ updateFrame = 0;
3226
+ entries.forEach(updateEntry);
3227
+ });
3228
+ };
3229
+ const bindTrackDrag = (entry, axis, track, thumb) => {
3230
+ const target = entry.target;
3231
+ const onTrackPointerEnter = () => {
3232
+ entry.hoveringTrack = true;
3233
+ showEntry(entry);
3234
+ };
3235
+ const onTrackPointerLeave = () => {
3236
+ entry.hoveringTrack = false;
3237
+ scheduleHide(entry);
3238
+ };
3239
+ const onTrackPointerDown = (event) => {
3240
+ if (event.target === thumb || event.button !== 0) return;
3241
+ event.preventDefault();
3242
+ event.stopPropagation();
3243
+ const trackRect = track.getBoundingClientRect();
3244
+ const thumbRect = thumb.getBoundingClientRect();
3245
+ const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
3246
+ const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
3247
+ const pointer = axis === "vertical" ? event.clientY - trackRect.top : event.clientX - trackRect.left;
3248
+ const ratio = Math.max(0, Math.min(1, (pointer - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
3249
+ if (axis === "vertical") target.scrollTop = ratio * (target.scrollHeight - target.clientHeight);
3250
+ else target.scrollLeft = ratio * (target.scrollWidth - target.clientWidth);
3251
+ };
3252
+ const onThumbPointerDown = (event) => {
3253
+ if (event.button !== 0) return;
3254
+ event.preventDefault();
3255
+ event.stopPropagation();
3256
+ entry.dragging = true;
3257
+ showEntry(entry);
3258
+ thumb.setPointerCapture(event.pointerId);
3259
+ const startPointer = axis === "vertical" ? event.clientY : event.clientX;
3260
+ const startScroll = axis === "vertical" ? target.scrollTop : target.scrollLeft;
3261
+ const trackRect = track.getBoundingClientRect();
3262
+ const thumbRect = thumb.getBoundingClientRect();
3263
+ const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
3264
+ const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
3265
+ const maxScroll = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
3266
+ const travel = Math.max(1, trackLength - thumbLength);
3267
+ const onPointerMove = (moveEvent) => {
3268
+ if (moveEvent.pointerId !== event.pointerId) return;
3269
+ const pointer = axis === "vertical" ? moveEvent.clientY : moveEvent.clientX;
3270
+ const nextScroll = startScroll + (pointer - startPointer) * maxScroll / travel;
3271
+ if (axis === "vertical") target.scrollTop = nextScroll;
3272
+ else target.scrollLeft = nextScroll;
3273
+ };
3274
+ const onPointerUp = (upEvent) => {
3275
+ if (upEvent.pointerId !== event.pointerId) return;
3276
+ entry.dragging = false;
3277
+ thumb.releasePointerCapture(event.pointerId);
3278
+ window.removeEventListener("pointermove", onPointerMove);
3279
+ window.removeEventListener("pointerup", onPointerUp);
3280
+ window.removeEventListener("pointercancel", onPointerUp);
3281
+ scheduleHide(entry);
3282
+ };
3283
+ window.addEventListener("pointermove", onPointerMove);
3284
+ window.addEventListener("pointerup", onPointerUp);
3285
+ window.addEventListener("pointercancel", onPointerUp);
3286
+ };
3287
+ track.addEventListener("pointerenter", onTrackPointerEnter);
3288
+ track.addEventListener("pointerleave", onTrackPointerLeave);
3289
+ track.addEventListener("pointerdown", onTrackPointerDown);
3290
+ thumb.addEventListener("pointerdown", onThumbPointerDown);
3291
+ return () => {
3292
+ track.removeEventListener("pointerenter", onTrackPointerEnter);
3293
+ track.removeEventListener("pointerleave", onTrackPointerLeave);
3294
+ track.removeEventListener("pointerdown", onTrackPointerDown);
3295
+ thumb.removeEventListener("pointerdown", onThumbPointerDown);
3296
+ };
3297
+ };
3298
+ const resizeObserver = new ResizeObserver((observedEntries) => {
3299
+ observedEntries.forEach(({ target }) => {
3300
+ const entry = entries.get(target);
3301
+ if (entry) updateEntry(entry);
3302
+ });
3303
+ });
3304
+ const addTarget = (target) => {
3305
+ if (entries.has(target)) return;
3306
+ const horizontal = createTrack("horizontal");
3307
+ const vertical = createTrack("vertical");
3308
+ layer.append(horizontal.track, vertical.track);
3309
+ const onPointerEnter = () => {
3310
+ const entry2 = entries.get(target);
3311
+ if (!entry2) return;
3312
+ entry2.hoveringTarget = true;
3313
+ showEntry(entry2);
3314
+ };
3315
+ const onPointerLeave = () => {
3316
+ const entry2 = entries.get(target);
3317
+ if (!entry2) return;
3318
+ entry2.hoveringTarget = false;
3319
+ scheduleHide(entry2);
3320
+ };
3321
+ const onScroll = () => {
3322
+ const entry2 = entries.get(target);
3323
+ if (!entry2) return;
3324
+ updateEntry(entry2);
3325
+ showEntry(entry2);
3326
+ scheduleHide(entry2, 700);
3327
+ };
3328
+ target.addEventListener("pointerenter", onPointerEnter);
3329
+ target.addEventListener("pointerleave", onPointerLeave);
3330
+ target.addEventListener("scroll", onScroll, { passive: true });
3331
+ const entry = {
3332
+ target,
3333
+ horizontalTrack: horizontal.track,
3334
+ horizontalThumb: horizontal.thumb,
3335
+ verticalTrack: vertical.track,
3336
+ verticalThumb: vertical.thumb,
3337
+ hideTimer: null,
3338
+ hoveringTarget: target.matches(":hover"),
3339
+ hoveringTrack: false,
3340
+ dragging: false,
3341
+ cleanup: () => void 0
3342
+ };
3343
+ const cleanupHorizontal = bindTrackDrag(entry, "horizontal", horizontal.track, horizontal.thumb);
3344
+ const cleanupVertical = bindTrackDrag(entry, "vertical", vertical.track, vertical.thumb);
3345
+ entry.cleanup = () => {
3346
+ if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
3347
+ cleanupHorizontal();
3348
+ cleanupVertical();
3349
+ target.removeEventListener("pointerenter", onPointerEnter);
3350
+ target.removeEventListener("pointerleave", onPointerLeave);
3351
+ target.removeEventListener("scroll", onScroll);
3352
+ resizeObserver.unobserve(target);
3353
+ target.removeAttribute("data-sia-floating-scrollbar");
3354
+ horizontal.track.remove();
3355
+ vertical.track.remove();
3356
+ };
3357
+ entries.set(target, entry);
3358
+ target.setAttribute("data-sia-floating-scrollbar", "");
3359
+ resizeObserver.observe(target);
3360
+ updateEntry(entry);
3361
+ if (entry.hoveringTarget) showEntry(entry);
3362
+ };
3363
+ const removeTarget = (target) => {
3364
+ const entry = entries.get(target);
3365
+ if (!entry) return;
3366
+ entry.cleanup();
3367
+ entries.delete(target);
3368
+ };
3369
+ const scanTargets = () => {
3370
+ scanFrame = 0;
3371
+ const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
3372
+ const nextTargets = /* @__PURE__ */ new Set();
3373
+ candidates.forEach((target) => {
3374
+ if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
3375
+ nextTargets.add(target);
3376
+ if (entries.has(target) || !target.hasAttribute("data-sia-floating-scrollbar")) addTarget(target);
3179
3377
  }
3180
- )
3181
- }
3182
- ) });
3183
- });
3184
- function openModal(config) {
3185
- if (typeof document === "undefined") return { destroy() {
3186
- }, update() {
3187
- } };
3188
- const container = document.createElement("div");
3189
- container.className = "sia-modal-api-host";
3190
- document.body.appendChild(container);
3191
- const root = (0, import_client3.createRoot)(container);
3192
- let currentConfig = config;
3193
- let currentOpen = true;
3194
- let destroyed = false;
3195
- let cleanupTimer;
3196
- function cleanup2() {
3197
- if (destroyed) return;
3198
- destroyed = true;
3199
- if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
3200
- root.unmount();
3201
- container.remove();
3202
- modalHandles.delete(handle);
3203
- }
3204
- function closeWithMotion() {
3205
- if (destroyed || !currentOpen) return;
3206
- currentOpen = false;
3207
- render();
3208
- cleanupTimer = window.setTimeout(cleanup2, MODAL_MOTION_DURATION);
3209
- }
3210
- function render() {
3211
- root.render(/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
3212
- currentConfig.onOpenChange?.(nextOpen);
3213
- if (!nextOpen) closeWithMotion();
3214
- } }));
3215
- }
3216
- const handle = {
3217
- destroy: closeWithMotion,
3218
- update(next) {
3219
- if (destroyed) return;
3220
- currentConfig = { ...currentConfig, ...next };
3221
- render();
3222
- }
3223
- };
3224
- modalHandles.add(handle);
3225
- render();
3226
- return handle;
3227
- }
3228
- function preset(type, defaults = {}) {
3229
- return (config) => openModal({
3230
- okText: type === "confirm" ? "\u786E\u5B9A" : "\u77E5\u9053\u4E86",
3231
- showCancel: type === "confirm",
3232
- closable: type !== "confirm",
3233
- maskClosable: type !== "confirm",
3234
- ...defaults,
3235
- ...config,
3236
- type
3237
- });
3378
+ });
3379
+ entries.forEach((_entry, target) => {
3380
+ if (!target.isConnected || !nextTargets.has(target)) removeTarget(target);
3381
+ else updateEntry(_entry);
3382
+ });
3383
+ };
3384
+ const scheduleScan = () => {
3385
+ if (scanFrame) return;
3386
+ scanFrame = window.requestAnimationFrame(scanTargets);
3387
+ };
3388
+ const mutationObserver = new MutationObserver((mutations) => {
3389
+ if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
3390
+ });
3391
+ mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
3392
+ window.addEventListener("resize", scheduleScan);
3393
+ window.addEventListener("scroll", scheduleUpdateAll, true);
3394
+ scheduleScan();
3395
+ return () => {
3396
+ mutationObserver.disconnect();
3397
+ resizeObserver.disconnect();
3398
+ window.removeEventListener("resize", scheduleScan);
3399
+ window.removeEventListener("scroll", scheduleUpdateAll, true);
3400
+ if (scanFrame) window.cancelAnimationFrame(scanFrame);
3401
+ if (updateFrame) window.cancelAnimationFrame(updateFrame);
3402
+ entries.forEach((entry) => entry.cleanup());
3403
+ entries.clear();
3404
+ layer.remove();
3405
+ };
3406
+ }, [disabled, targetRef]);
3407
+ return null;
3238
3408
  }
3239
- var Modal2 = Object.assign(ModalRoot, {
3240
- /** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
3241
- open: openModal,
3242
- /** 显示普通信息提示。 */
3243
- info: preset("info", { title: "\u63D0\u793A" }),
3244
- /** 显示成功提示。 */
3245
- success: preset("success", { title: "\u64CD\u4F5C\u6210\u529F" }),
3246
- /** 显示警告提示。 */
3247
- warning: preset("warning", { title: "\u8BF7\u6CE8\u610F" }),
3248
- /** 显示错误提示。 */
3249
- error: preset("error", { title: "\u64CD\u4F5C\u5931\u8D25" }),
3250
- /** 打开确认弹框,支持异步确认;返回 false 可阻止关闭。 */
3251
- confirm: preset("confirm", { title: "\u786E\u8BA4\u64CD\u4F5C" }),
3252
- /** 关闭由此 API 打开的所有弹层。 */
3253
- destroyAll() {
3254
- [...modalHandles].forEach((handle) => handle.destroy());
3255
- }
3256
- });
3257
-
3258
- // src/components/Input.tsx
3259
- var import_react19 = require("react");
3260
- var import_jsx_runtime18 = require("react/jsx-runtime");
3261
- var Input = (0, import_react19.forwardRef)(function Input2({
3262
- label,
3263
- hint,
3264
- status = "default",
3265
- size: sizeProp,
3266
- prefix,
3267
- suffix,
3268
- allowClear = true,
3269
- onClear,
3270
- showCount = false,
3271
- placeholderMode,
3272
- placeholder,
3273
- className = "",
3274
- id,
3275
- disabled,
3276
- value,
3277
- defaultValue,
3278
- maxLength,
3279
- onChange,
3280
- ...props
3281
- }, forwardedRef) {
3282
- const size = useControlSize(sizeProp);
3283
- const fallbackId = (0, import_react19.useId)();
3284
- const inputId = id ?? fallbackId;
3285
- const localRef = (0, import_react19.useRef)(null);
3286
- const [uncontrolledValue, setUncontrolledValue] = (0, import_react19.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
3287
- const currentText = value !== void 0 ? String(value) : uncontrolledValue;
3288
- const hasValue = currentText.length > 0;
3289
- const floatingPlaceholder = usePlaceholderMode(placeholderMode) === "floating" && Boolean(placeholder);
3290
- const hintId = `${inputId}-hint`;
3291
- const describedBy = [props["aria-describedby"], hint ? hintId : null].filter(Boolean).join(" ") || void 0;
3292
- function setRef(node) {
3293
- localRef.current = node;
3294
- if (typeof forwardedRef === "function") forwardedRef(node);
3295
- else if (forwardedRef) forwardedRef.current = node;
3296
- }
3297
- function handleChange(event) {
3298
- if (maxLength !== void 0 && maxLength >= 0 && event.target.value.length > maxLength) {
3299
- const valueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
3300
- valueSetter?.call(event.target, event.target.value.slice(0, maxLength));
3301
- }
3302
- setUncontrolledValue(event.target.value);
3303
- onChange?.(event);
3304
- }
3305
- function clearValue() {
3306
- const input2 = localRef.current;
3307
- if (!input2 || disabled) return;
3308
- const valueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
3309
- valueSetter?.call(input2, "");
3310
- input2.dispatchEvent(new Event("input", { bubbles: true }));
3311
- setUncontrolledValue("");
3312
- input2.focus();
3313
- onClear?.();
3314
- }
3315
- function handleControlMouseDown(event) {
3316
- if (disabled || event.defaultPrevented || event.button !== 0) return;
3317
- const target = event.target;
3318
- if (!(target instanceof Element)) return;
3319
- const interactive = target.closest("input, textarea, select, button, a[href], [tabindex], [contenteditable]:not([contenteditable='false']), [role='button'], [role='link']");
3320
- if (interactive && event.currentTarget.contains(interactive) && !interactive.classList.contains("sia-input-control__clear")) return;
3321
- event.preventDefault();
3322
- localRef.current?.focus({ preventScroll: true });
3323
- }
3324
- const input = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3325
- "input",
3326
- {
3327
- ...withTitleTooltip(props),
3328
- ref: setRef,
3329
- id: inputId,
3330
- className: "sia-input",
3331
- disabled,
3332
- value,
3333
- defaultValue,
3334
- maxLength,
3335
- placeholder,
3336
- "aria-describedby": describedBy,
3337
- "aria-invalid": status === "error" || void 0,
3338
- onChange: handleChange
3339
- }
3340
- );
3341
- const control = /* @__PURE__ */ (0, import_jsx_runtime18.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: [
3342
- prefix ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-input-control__affix", children: prefix }) : null,
3343
- floatingPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "sia-input-control__input-wrap", children: [
3344
- input,
3345
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-input-control__floating-placeholder", "aria-hidden": "true", children: placeholder })
3346
- ] }) : input,
3347
- allowClear && hasValue && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { className: "sia-input-control__clear", type: "button", "aria-label": "\u6E05\u7A7A\u8F93\u5165", onClick: clearValue, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
3348
- suffix ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-input-control__affix", children: suffix }) : null,
3349
- showCount ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: `sia-input-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
3350
- currentText.length,
3351
- maxLength !== void 0 ? `/${maxLength}` : null
3352
- ] }) : null
3353
- ] });
3354
- if (!label && !hint) return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: `sia-field ${className}`.trim(), children: control });
3355
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: `sia-field ${className}`.trim(), children: [
3356
- label ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { className: "sia-field__label", htmlFor: inputId, children: label }) : null,
3357
- control,
3358
- hint ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
3359
- ] });
3360
- });
3361
3409
 
3362
3410
  // src/components/SelectionPanel.tsx
3363
- var import_react20 = require("react");
3364
3411
  var import_jsx_runtime19 = require("react/jsx-runtime");
3365
3412
  function SelectionPanel({
3366
3413
  options,
@@ -3382,26 +3429,26 @@ function SelectionPanel({
3382
3429
  maxHeight = 250,
3383
3430
  autoFocusSearch = false
3384
3431
  }) {
3385
- const [localSearch, setLocalSearch] = (0, import_react20.useState)("");
3432
+ const [localSearch, setLocalSearch] = (0, import_react21.useState)("");
3386
3433
  const search = searchValue ?? localSearch;
3387
- const [scrollTop, setScrollTop] = (0, import_react20.useState)(0);
3388
- const [active, setActive] = (0, import_react20.useState)();
3389
- const [keyboardActive, setKeyboardActive] = (0, import_react20.useState)(false);
3390
- const [deselectedHover, setDeselectedHover] = (0, import_react20.useState)();
3391
- const listRef = (0, import_react20.useRef)(null);
3392
- const id = (0, import_react20.useId)();
3393
- const selected = (0, import_react20.useMemo)(() => new Set(value), [value]);
3434
+ const [scrollTop, setScrollTop] = (0, import_react21.useState)(0);
3435
+ const [active, setActive] = (0, import_react21.useState)();
3436
+ const [keyboardActive, setKeyboardActive] = (0, import_react21.useState)(false);
3437
+ const [deselectedHover, setDeselectedHover] = (0, import_react21.useState)();
3438
+ const listRef = (0, import_react21.useRef)(null);
3439
+ const id = (0, import_react21.useId)();
3440
+ const selected = (0, import_react21.useMemo)(() => new Set(value), [value]);
3394
3441
  const count = Math.max(1, Math.floor(columns));
3395
- const allOptions = (0, import_react20.useMemo)(() => {
3442
+ const allOptions = (0, import_react21.useMemo)(() => {
3396
3443
  if (!includeUnknownValues) return [...options];
3397
3444
  const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
3398
3445
  return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
3399
3446
  }, [options, value, includeUnknownValues]);
3400
- const filtered = (0, import_react20.useMemo)(
3447
+ const filtered = (0, import_react21.useMemo)(
3401
3448
  () => allOptions.filter((option) => (!selectedOnly || selected.has(option.value)) && (!search || option.optionType !== "divider" && [option.label, option.value].some((text) => String(text ?? "").toLowerCase().includes(search.toLowerCase())))),
3402
3449
  [allOptions, selectedOnly, selected, search]
3403
3450
  );
3404
- const rows = (0, import_react20.useMemo)(() => {
3451
+ const rows = (0, import_react21.useMemo)(() => {
3405
3452
  const groups = /* @__PURE__ */ new Map();
3406
3453
  filtered.forEach((option) => {
3407
3454
  const items = groups.get(option.group) ?? [];
@@ -3427,7 +3474,7 @@ function SelectionPanel({
3427
3474
  const virtual = filtered.length > 100;
3428
3475
  const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
3429
3476
  const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
3430
- (0, import_react20.useEffect)(() => {
3477
+ (0, import_react21.useEffect)(() => {
3431
3478
  setScrollTop(0);
3432
3479
  if (listRef.current) listRef.current.scrollTop = 0;
3433
3480
  setActive(void 0);
@@ -3552,14 +3599,14 @@ function SelectionPanel({
3552
3599
  }
3553
3600
 
3554
3601
  // src/components/OverflowTags.tsx
3555
- var import_react21 = require("react");
3602
+ var import_react22 = require("react");
3556
3603
  var import_jsx_runtime20 = require("react/jsx-runtime");
3557
3604
  function OverflowTags({ items, maxCount: maxCount2, className = "", tagClassName, restClassName = "" }) {
3558
- const rootRef = (0, import_react21.useRef)(null);
3559
- const measureRef = (0, import_react21.useRef)(null);
3605
+ const rootRef = (0, import_react22.useRef)(null);
3606
+ const measureRef = (0, import_react22.useRef)(null);
3560
3607
  const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount2) || 0));
3561
- const [visibleCount, setVisibleCount] = (0, import_react21.useState)(0);
3562
- (0, import_react21.useLayoutEffect)(() => {
3608
+ const [visibleCount, setVisibleCount] = (0, import_react22.useState)(0);
3609
+ (0, import_react22.useLayoutEffect)(() => {
3563
3610
  const root = rootRef.current;
3564
3611
  const measure = measureRef.current;
3565
3612
  if (!root || !measure) return;
@@ -3604,7 +3651,7 @@ function defaultFilterOption(query, option) {
3604
3651
  const keyword = query.toLowerCase();
3605
3652
  return [option.label, option.value].some((value) => String(value).toLowerCase().includes(keyword));
3606
3653
  }
3607
- var Select = (0, import_react22.forwardRef)(function Select2({
3654
+ var Select = (0, import_react23.forwardRef)(function Select2({
3608
3655
  options,
3609
3656
  mode = "single",
3610
3657
  popupMode: popupModeProp,
@@ -3642,27 +3689,27 @@ var Select = (0, import_react22.forwardRef)(function Select2({
3642
3689
  ...props
3643
3690
  }, forwardedRef) {
3644
3691
  const size = useControlSize(sizeProp);
3645
- const fallbackId = (0, import_react22.useId)();
3692
+ const fallbackId = (0, import_react23.useId)();
3646
3693
  const selectId = id ?? fallbackId;
3647
3694
  const listboxId = `${selectId}-listbox`;
3648
- const rootRef = (0, import_react22.useRef)(null);
3649
- const popupRef = (0, import_react22.useRef)(null);
3650
- const searchRef = (0, import_react22.useRef)(null);
3651
- const listRef = (0, import_react22.useRef)(null);
3652
- const [open, setOpen] = (0, import_react22.useState)(false);
3695
+ const rootRef = (0, import_react23.useRef)(null);
3696
+ const popupRef = (0, import_react23.useRef)(null);
3697
+ const searchRef = (0, import_react23.useRef)(null);
3698
+ const listRef = (0, import_react23.useRef)(null);
3699
+ const [open, setOpen] = (0, import_react23.useState)(false);
3653
3700
  const automaticMode = popupModeProp ?? (options.length > modalThreshold ? "modal" : "dropdown");
3654
- const [openedMode, setOpenedMode] = (0, import_react22.useState)(automaticMode);
3701
+ const [openedMode, setOpenedMode] = (0, import_react23.useState)(automaticMode);
3655
3702
  const popupMode = open ? openedMode : automaticMode;
3656
- const [modalValues, setModalValues] = (0, import_react22.useState)([]);
3657
- const [modalSubmitting, setModalSubmitting] = (0, import_react22.useState)(false);
3658
- const modalSubmitLock = (0, import_react22.useRef)(false);
3659
- const [selectedOnly, setSelectedOnly] = (0, import_react22.useState)(false);
3660
- const [query, setQuery] = (0, import_react22.useState)("");
3661
- const [activeIndex, setActiveIndex] = (0, import_react22.useState)(-1);
3662
- const [scrollTop, setScrollTop] = (0, import_react22.useState)(0);
3663
- const [dropdownFontSize, setDropdownFontSize] = (0, import_react22.useState)();
3664
- const pendingSelectedScroll = (0, import_react22.useRef)(false);
3665
- const deferredQuery = (0, import_react22.useDeferredValue)(query.trim());
3703
+ const [modalValues, setModalValues] = (0, import_react23.useState)([]);
3704
+ const [modalSubmitting, setModalSubmitting] = (0, import_react23.useState)(false);
3705
+ const modalSubmitLock = (0, import_react23.useRef)(false);
3706
+ const [selectedOnly, setSelectedOnly] = (0, import_react23.useState)(false);
3707
+ const [query, setQuery] = (0, import_react23.useState)("");
3708
+ const [activeIndex, setActiveIndex] = (0, import_react23.useState)(-1);
3709
+ const [scrollTop, setScrollTop] = (0, import_react23.useState)(0);
3710
+ const [dropdownFontSize, setDropdownFontSize] = (0, import_react23.useState)();
3711
+ const pendingSelectedScroll = (0, import_react23.useRef)(false);
3712
+ const deferredQuery = (0, import_react23.useDeferredValue)(query.trim());
3666
3713
  const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
3667
3714
  const [currentValue, setCurrentValue] = useControllableState({
3668
3715
  value,
@@ -3677,20 +3724,20 @@ var Select = (0, import_react22.forwardRef)(function Select2({
3677
3724
  }
3678
3725
  }
3679
3726
  });
3680
- const selectedValues = (0, import_react22.useMemo)(() => {
3727
+ const selectedValues = (0, import_react23.useMemo)(() => {
3681
3728
  if (currentValue == null || currentValue === "" && !options.some((option) => option.value === "")) return [];
3682
3729
  if (mode === "multiple") return Array.isArray(currentValue) ? currentValue : currentValue === null ? [] : [currentValue];
3683
3730
  return Array.isArray(currentValue) ? currentValue.slice(0, 1) : currentValue === null ? [] : [currentValue];
3684
3731
  }, [currentValue, mode, options]);
3685
- const selectedValueSet = (0, import_react22.useMemo)(() => new Set(selectedValues), [selectedValues]);
3686
- const availableOptions = (0, import_react22.useMemo)(() => {
3732
+ const selectedValueSet = (0, import_react23.useMemo)(() => new Set(selectedValues), [selectedValues]);
3733
+ const availableOptions = (0, import_react23.useMemo)(() => {
3687
3734
  if (!allowInput) return options;
3688
3735
  const optionValueSet = new Set(options.map((option) => option.value));
3689
3736
  const selectedCustomOptions = selectedValues.filter((selectedValue) => !optionValueSet.has(selectedValue)).map((selectedValue) => ({ label: String(selectedValue), value: selectedValue }));
3690
3737
  return selectedCustomOptions.length ? [...selectedCustomOptions, ...options] : options;
3691
3738
  }, [allowInput, options, selectedValues]);
3692
- const selectedOptions = (0, import_react22.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
3693
- const filteredOptions = (0, import_react22.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
3739
+ const selectedOptions = (0, import_react23.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
3740
+ const filteredOptions = (0, import_react23.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
3694
3741
  const inputValue = query.trim();
3695
3742
  const exactInputOption = inputValue ? availableOptions.find((option) => String(option.value).toLowerCase() === inputValue.toLowerCase() || typeof option.label === "string" && option.label.toLowerCase() === inputValue.toLowerCase()) : void 0;
3696
3743
  const canSubmitInput = allowInput && Boolean(inputValue) && !exactInputOption;
@@ -3704,7 +3751,7 @@ var Select = (0, import_react22.forwardRef)(function Select2({
3704
3751
  const renderedOptions = virtualEnabled ? filteredOptions.slice(virtualStart, virtualEnd) : filteredOptions;
3705
3752
  const enabledFilteredOptions = filteredOptions.filter((option) => !option.disabled);
3706
3753
  const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((option) => selectedValueSet.has(option.value));
3707
- (0, import_react22.useEffect)(() => {
3754
+ (0, import_react23.useEffect)(() => {
3708
3755
  if (!open || popupMode === "modal") return void 0;
3709
3756
  function closeFromOutside(event) {
3710
3757
  const target = event.target;
@@ -3713,13 +3760,13 @@ var Select = (0, import_react22.forwardRef)(function Select2({
3713
3760
  document.addEventListener("mousedown", closeFromOutside);
3714
3761
  return () => document.removeEventListener("mousedown", closeFromOutside);
3715
3762
  }, [open, popupMode]);
3716
- (0, import_react22.useEffect)(() => {
3763
+ (0, import_react23.useEffect)(() => {
3717
3764
  if (open && (showSearch || allowInput)) searchRef.current?.focus();
3718
3765
  }, [allowInput, open, showSearch]);
3719
- (0, import_react22.useEffect)(() => {
3766
+ (0, import_react23.useEffect)(() => {
3720
3767
  if (disabled || loading) closeDropdown();
3721
3768
  }, [disabled, loading]);
3722
- (0, import_react22.useEffect)(() => {
3769
+ (0, import_react23.useEffect)(() => {
3723
3770
  if (!open || popupMode !== "dropdown" || !pendingSelectedScroll.current || query) return;
3724
3771
  const index = filteredOptions.findIndex((option) => selectedValueSet.has(option.value));
3725
3772
  if (index < 0) return;
@@ -3734,7 +3781,7 @@ var Select = (0, import_react22.forwardRef)(function Select2({
3734
3781
  });
3735
3782
  return () => cancelAnimationFrame(frame);
3736
3783
  }, [open, popupMode, filteredOptions, selectedValueSet, virtualEnabled, optionHeight, query]);
3737
- (0, import_react22.useLayoutEffect)(() => {
3784
+ (0, import_react23.useLayoutEffect)(() => {
3738
3785
  if (!open || popupMode !== "dropdown") return;
3739
3786
  const trigger = rootRef.current?.querySelector(".sia-select__trigger");
3740
3787
  if (trigger) setDropdownFontSize(getComputedStyle(trigger).fontSize);
@@ -4075,7 +4122,7 @@ var Select = (0, import_react22.forwardRef)(function Select2({
4075
4122
  });
4076
4123
 
4077
4124
  // src/components/Upload.tsx
4078
- var import_react23 = require("react");
4125
+ var import_react24 = require("react");
4079
4126
 
4080
4127
  // src/components/uploadFiles.ts
4081
4128
  function acceptsUploadFile(file, accept) {
@@ -4314,8 +4361,8 @@ var message = {
4314
4361
  var import_jsx_runtime23 = require("react/jsx-runtime");
4315
4362
  var LIST_IGNORE = /* @__PURE__ */ Symbol("SIA_UPLOAD_LIST_IGNORE");
4316
4363
  function useThumbnail(file, accept) {
4317
- const [local, setLocal] = (0, import_react23.useState)();
4318
- (0, import_react23.useEffect)(() => {
4364
+ const [local, setLocal] = (0, import_react24.useState)();
4365
+ (0, import_react24.useEffect)(() => {
4319
4366
  if (!file?.thumbUrl && file?.originFileObj?.type.startsWith("image/")) {
4320
4367
  const url = URL.createObjectURL(file.originFileObj);
4321
4368
  setLocal(url);
@@ -4327,9 +4374,9 @@ function useThumbnail(file, accept) {
4327
4374
  }
4328
4375
  function UploadItem({ file, files, props, actions }) {
4329
4376
  const source = useThumbnail(file, props.accept);
4330
- const [failed, setFailed] = (0, import_react23.useState)(false);
4331
- const [downloading, setDownloading] = (0, import_react23.useState)(false);
4332
- const downloadingRef = (0, import_react23.useRef)(false);
4377
+ const [failed, setFailed] = (0, import_react24.useState)(false);
4378
+ const [downloading, setDownloading] = (0, import_react24.useState)(false);
4379
+ const downloadingRef = (0, import_react24.useRef)(false);
4333
4380
  const canPreview = !!(source || file.url || file.originFileObj || props.onPreview);
4334
4381
  const canDownload = !!(file.url || file.originFileObj || props.downloadRequest);
4335
4382
  async function download() {
@@ -4345,7 +4392,7 @@ function UploadItem({ file, files, props, actions }) {
4345
4392
  setDownloading(false);
4346
4393
  }
4347
4394
  }
4348
- (0, import_react23.useEffect)(() => setFailed(false), [source]);
4395
+ (0, import_react24.useEffect)(() => setFailed(false), [source]);
4349
4396
  const node = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `sia-upload__item sia-upload__item--${file.status ?? "ready"}`, children: [
4350
4397
  props.listType !== "text" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Button, { variant: "text", className: "sia-upload__thumbnail", "aria-label": `\u9884\u89C8\u7F29\u7565\u56FE ${file.name}`, onClick: actions.preview, disabled: !canPreview, children: source && !failed ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: source, alt: file.name, onError: () => setFailed(true) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { name: file.type?.startsWith("image/") ? "image" : "file", size: 28 }) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { name: file.status === "done" ? "circle-check" : "file", size: 16 }),
4351
4398
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "sia-upload__name", ...withTitleTooltip({ title: file.relativePath || file.name }), children: file.url ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("a", { href: file.url, target: "_blank", rel: "noreferrer", children: file.name }) : file.name }),
@@ -4366,7 +4413,7 @@ function UploadItem({ file, files, props, actions }) {
4366
4413
  ] });
4367
4414
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: props.itemRender ? props.itemRender(node, file, files, actions) : node });
4368
4415
  }
4369
- var UploadRoot = (0, import_react23.forwardRef)(function UploadRoot2({
4416
+ var UploadRoot = (0, import_react24.forwardRef)(function UploadRoot2({
4370
4417
  accept,
4371
4418
  multiple = false,
4372
4419
  directory = false,
@@ -4404,19 +4451,19 @@ var UploadRoot = (0, import_react23.forwardRef)(function UploadRoot2({
4404
4451
  const cardWidth = cardDimension(typeof cardSize === "number" ? cardSize : cardSize?.width);
4405
4452
  const cardHeight = cardDimension(typeof cardSize === "number" ? cardSize : cardSize?.height);
4406
4453
  const compactCard = listType === "picture-card" && (cardWidth < 88 || cardHeight < 88);
4407
- const inputRef = (0, import_react23.useRef)(null);
4408
- const [internalFiles, setInternalFiles] = (0, import_react23.useState)(defaultFileList);
4454
+ const inputRef = (0, import_react24.useRef)(null);
4455
+ const [internalFiles, setInternalFiles] = (0, import_react24.useState)(defaultFileList);
4409
4456
  const files = fileList ?? internalFiles;
4410
- const filesRef = (0, import_react23.useRef)(files);
4457
+ const filesRef = (0, import_react24.useRef)(files);
4411
4458
  filesRef.current = files;
4412
- const tasks = (0, import_react23.useRef)(/* @__PURE__ */ new Map());
4413
- const mounted = (0, import_react23.useRef)(true);
4414
- const [dragging, setDragging] = (0, import_react23.useState)(false);
4415
- const [preview, setPreview] = (0, import_react23.useState)();
4459
+ const tasks = (0, import_react24.useRef)(/* @__PURE__ */ new Map());
4460
+ const mounted = (0, import_react24.useRef)(true);
4461
+ const [dragging, setDragging] = (0, import_react24.useState)(false);
4462
+ const [preview, setPreview] = (0, import_react24.useState)();
4416
4463
  const previewSource = useThumbnail(preview, accept);
4417
4464
  const limit = maxCount2 === void 0 || !Number.isFinite(maxCount2) ? Infinity : Math.max(0, Math.floor(maxCount2));
4418
4465
  const full = files.length >= limit;
4419
- const current = (0, import_react23.useRef)({ disabled, directory, recursive });
4466
+ const current = (0, import_react24.useRef)({ disabled, directory, recursive });
4420
4467
  current.current = { disabled, directory, recursive };
4421
4468
  function cancel(uid) {
4422
4469
  const task = tasks.current.get(uid);
@@ -4428,14 +4475,14 @@ var UploadRoot = (0, import_react23.forwardRef)(function UploadRoot2({
4428
4475
  }
4429
4476
  task?.finish();
4430
4477
  }
4431
- (0, import_react23.useEffect)(() => {
4478
+ (0, import_react24.useEffect)(() => {
4432
4479
  mounted.current = true;
4433
4480
  return () => {
4434
4481
  mounted.current = false;
4435
4482
  [...tasks.current.keys()].forEach(cancel);
4436
4483
  };
4437
4484
  }, []);
4438
- (0, import_react23.useEffect)(() => {
4485
+ (0, import_react24.useEffect)(() => {
4439
4486
  for (const uid of tasks.current.keys()) if (!files.some((file) => file.uid === uid)) cancel(uid);
4440
4487
  if (preview && !files.some((file) => file.uid === preview.uid)) setPreview(void 0);
4441
4488
  }, [files, preview]);
@@ -4541,7 +4588,7 @@ var UploadRoot = (0, import_react23.forwardRef)(function UploadRoot2({
4541
4588
  } catch {
4542
4589
  }
4543
4590
  }
4544
- (0, import_react23.useImperativeHandle)(ref, () => ({
4591
+ (0, import_react24.useImperativeHandle)(ref, () => ({
4545
4592
  upload: async (uid) => {
4546
4593
  await Promise.all(filesRef.current.filter((file) => (!uid || file.uid === uid) && file.status !== "done").map(start));
4547
4594
  },
@@ -4663,7 +4710,7 @@ var UploadRoot = (0, import_react23.forwardRef)(function UploadRoot2({
4663
4710
  }
4664
4711
  );
4665
4712
  });
4666
- var UploadDragger = (0, import_react23.forwardRef)(function UploadDragger2({ hint = "\u652F\u6301\u5355\u4E2A\u6216\u6279\u91CF\u4E0A\u4F20", children, className = "", ...props }, ref) {
4713
+ var UploadDragger = (0, import_react24.forwardRef)(function UploadDragger2({ hint = "\u652F\u6301\u5355\u4E2A\u6216\u6279\u91CF\u4E0A\u4F20", children, className = "", ...props }, ref) {
4667
4714
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(UploadRoot, { ...props, ref, className: `sia-upload-dragger ${className}`.trim(), children: children ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "sia-upload-dragger__content", children: [
4668
4715
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { name: "upload", size: 32 }),
4669
4716
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("strong", { children: [
@@ -4704,12 +4751,12 @@ function Breadcrumb({ items, separator = "/", itemRender, className = "", ...pro
4704
4751
  }
4705
4752
 
4706
4753
  // src/components/Typography.tsx
4707
- var import_react25 = require("react");
4754
+ var import_react26 = require("react");
4708
4755
 
4709
4756
  // src/components/TextArea.tsx
4710
- var import_react24 = require("react");
4757
+ var import_react25 = require("react");
4711
4758
  var import_jsx_runtime25 = require("react/jsx-runtime");
4712
- var TextArea = (0, import_react24.forwardRef)(function TextArea2({
4759
+ var TextArea = (0, import_react25.forwardRef)(function TextArea2({
4713
4760
  label,
4714
4761
  hint,
4715
4762
  status = "default",
@@ -4727,9 +4774,9 @@ var TextArea = (0, import_react24.forwardRef)(function TextArea2({
4727
4774
  ...props
4728
4775
  }, ref) {
4729
4776
  const size = useControlSize(sizeProp);
4730
- const fallbackId = (0, import_react24.useId)();
4777
+ const fallbackId = (0, import_react25.useId)();
4731
4778
  const textAreaId = id ?? fallbackId;
4732
- const [uncontrolledValue, setUncontrolledValue] = (0, import_react24.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
4779
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react25.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
4733
4780
  const currentText = value !== void 0 ? String(value) : uncontrolledValue;
4734
4781
  const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: currentText.length > 0 });
4735
4782
  const hintId = `${textAreaId}-hint`;
@@ -4790,26 +4837,26 @@ function TypographyContent({
4790
4837
  className = "",
4791
4838
  ...props
4792
4839
  }) {
4793
- const contentRef = (0, import_react25.useRef)(null);
4794
- const editRef = (0, import_react25.useRef)(null);
4795
- const timer = (0, import_react25.useRef)();
4796
- const [localText, setLocalText] = (0, import_react25.useState)();
4797
- const [draft, setDraft] = (0, import_react25.useState)("");
4798
- const [editing, setEditing] = (0, import_react25.useState)(false);
4799
- const [copied, setCopied] = (0, import_react25.useState)(false);
4800
- const [copyError, setCopyError] = (0, import_react25.useState)(false);
4801
- const [expanded, setExpanded] = (0, import_react25.useState)(false);
4802
- const [overflow, setOverflow] = (0, import_react25.useState)(false);
4840
+ const contentRef = (0, import_react26.useRef)(null);
4841
+ const editRef = (0, import_react26.useRef)(null);
4842
+ const timer = (0, import_react26.useRef)();
4843
+ const [localText, setLocalText] = (0, import_react26.useState)();
4844
+ const [draft, setDraft] = (0, import_react26.useState)("");
4845
+ const [editing, setEditing] = (0, import_react26.useState)(false);
4846
+ const [copied, setCopied] = (0, import_react26.useState)(false);
4847
+ const [copyError, setCopyError] = (0, import_react26.useState)(false);
4848
+ const [expanded, setExpanded] = (0, import_react26.useState)(false);
4849
+ const [overflow, setOverflow] = (0, import_react26.useState)(false);
4803
4850
  const editConfig = typeof editable === "object" ? editable : void 0;
4804
4851
  const content = editConfig?.text ?? localText ?? children;
4805
4852
  const requestedRows = typeof ellipsis === "object" ? ellipsis.rows ?? 1 : 1;
4806
4853
  const rows = Number.isFinite(requestedRows) ? Math.max(1, Math.floor(requestedRows)) : 1;
4807
4854
  const expandable = typeof ellipsis === "object" && ellipsis.expandable;
4808
- (0, import_react25.useEffect)(() => {
4855
+ (0, import_react26.useEffect)(() => {
4809
4856
  setLocalText(void 0);
4810
4857
  }, [children]);
4811
- (0, import_react25.useEffect)(() => () => clearTimeout(timer.current), []);
4812
- (0, import_react25.useLayoutEffect)(() => {
4858
+ (0, import_react26.useEffect)(() => () => clearTimeout(timer.current), []);
4859
+ (0, import_react26.useLayoutEffect)(() => {
4813
4860
  const element = contentRef.current;
4814
4861
  if (!element || !ellipsis || editing || expanded) return;
4815
4862
  const measure = () => setOverflow(element.scrollHeight > element.clientHeight + 1 || element.scrollWidth > element.clientWidth + 1);
@@ -4927,10 +4974,10 @@ var Typography = Object.assign(TypographyRoot, {
4927
4974
  });
4928
4975
 
4929
4976
  // src/components/FloatButton.tsx
4930
- var import_react26 = require("react");
4977
+ var import_react27 = require("react");
4931
4978
  var import_jsx_runtime27 = require("react/jsx-runtime");
4932
- var GroupShape = (0, import_react26.createContext)(void 0);
4933
- var FloatButtonRoot = (0, import_react26.forwardRef)(function FloatButton({
4979
+ var GroupShape = (0, import_react27.createContext)(void 0);
4980
+ var FloatButtonRoot = (0, import_react27.forwardRef)(function FloatButton({
4934
4981
  icon,
4935
4982
  description,
4936
4983
  tooltip,
@@ -4943,7 +4990,7 @@ var FloatButtonRoot = (0, import_react26.forwardRef)(function FloatButton({
4943
4990
  children,
4944
4991
  ...props
4945
4992
  }, ref) {
4946
- const groupShape = (0, import_react26.useContext)(GroupShape);
4993
+ const groupShape = (0, import_react27.useContext)(GroupShape);
4947
4994
  const label = props["aria-label"] ?? (typeof tooltip === "string" ? tooltip : typeof description === "string" ? description : "\u60AC\u6D6E\u64CD\u4F5C");
4948
4995
  const button = /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4949
4996
  "button",
@@ -4981,10 +5028,10 @@ function FloatButtonGroup({
4981
5028
  ...props
4982
5029
  }) {
4983
5030
  const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
4984
- const rootRef = (0, import_react26.useRef)(null);
4985
- const triggerRef = (0, import_react26.useRef)(null);
4986
- const id = (0, import_react26.useId)();
4987
- (0, import_react26.useEffect)(() => {
5031
+ const rootRef = (0, import_react27.useRef)(null);
5032
+ const triggerRef = (0, import_react27.useRef)(null);
5033
+ const id = (0, import_react27.useId)();
5034
+ (0, import_react27.useEffect)(() => {
4988
5035
  if (!trigger || !visible) return;
4989
5036
  const close = (event) => {
4990
5037
  if (!rootRef.current?.contains(event.target)) setVisible(false);
@@ -5038,8 +5085,8 @@ function FloatButtonGroup({
5038
5085
  ) });
5039
5086
  }
5040
5087
  function FloatButtonBackTop({ target, visibilityHeight = 400, behavior = "smooth", onClick, icon, tooltip = "\u8FD4\u56DE\u9876\u90E8", ...props }) {
5041
- const [visible, setVisible] = (0, import_react26.useState)(false);
5042
- (0, import_react26.useEffect)(() => {
5088
+ const [visible, setVisible] = (0, import_react27.useState)(false);
5089
+ (0, import_react27.useEffect)(() => {
5043
5090
  const element = target ? target() : window;
5044
5091
  if (!element) return;
5045
5092
  const update = () => setVisible((element === window ? window.scrollY : element.scrollTop) >= visibilityHeight);