@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/{chunk-GLS4WVIZ.js → chunk-6TLANQVX.js} +1 -1
- package/dist/{chunk-WR7XTQRU.js → chunk-CEZ4GW3X.js} +96 -50
- package/dist/{chunk-LRGD2QDA.js → chunk-ZTJUFVJO.js} +820 -820
- package/dist/{core-D4opRFkZ.d.cts → core-BAHoW7_e.d.cts} +2 -2
- package/dist/{core-VNY_7WRq.d.ts → core-fn8h4yRg.d.ts} +2 -2
- package/dist/core.cjs +996 -949
- package/dist/core.css +46 -18
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +2 -2
- package/dist/index.cjs +534 -487
- package/dist/index.css +46 -18
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/select-date-range.js +2 -2
- package/package.json +1 -1
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
|
|
1842
|
-
var
|
|
1843
|
-
function
|
|
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
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
const
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
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
|
-
|
|
1894
|
-
|
|
1895
|
-
cleanup = void 0;
|
|
1896
|
-
}
|
|
1964
|
+
cancelled = true;
|
|
1965
|
+
cancelAnimationFrame(frame);
|
|
1897
1966
|
};
|
|
1898
|
-
}, []);
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
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
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
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
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
const
|
|
1930
|
-
const
|
|
1931
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
2113
|
+
var import_react12 = require("react");
|
|
2444
2114
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2445
|
-
var CheckboxGroupContext = (0,
|
|
2446
|
-
var CheckboxRoot = (0,
|
|
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,
|
|
2449
|
-
const localRef = (0,
|
|
2450
|
-
const fallbackId = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
2586
|
-
const overlayRef = (0,
|
|
2587
|
-
const enterTimer = (0,
|
|
2588
|
-
const leaveTimer = (0,
|
|
2589
|
-
const contentId = (0,
|
|
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,
|
|
2593
|
-
const setVisibleRef = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
2323
|
+
(0, import_react13.useEffect)(() => () => {
|
|
2654
2324
|
clearTimers();
|
|
2655
2325
|
if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
|
|
2656
2326
|
}, []);
|
|
2657
|
-
const child = (0,
|
|
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
|
|
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
|
|
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,
|
|
2789
|
-
const closeRef = (0,
|
|
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,
|
|
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,
|
|
2875
|
-
(0,
|
|
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,
|
|
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,
|
|
2920
|
-
const stageRef = (0,
|
|
2921
|
-
const [natural, setNatural] = (0,
|
|
2922
|
-
const [area, setArea] = (0,
|
|
2923
|
-
const [zoom, setZoom] = (0,
|
|
2924
|
-
const [rotation, setRotation] = (0,
|
|
2925
|
-
const [flip, setFlip] = (0,
|
|
2926
|
-
const [pan, setPan] = (0,
|
|
2927
|
-
const [failed, setFailed] = (0,
|
|
2928
|
-
const drag = (0,
|
|
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,
|
|
2607
|
+
(0, import_react16.useEffect)(() => {
|
|
2938
2608
|
reset();
|
|
2939
2609
|
setFailed(false);
|
|
2940
2610
|
}, [open, src]);
|
|
2941
|
-
(0,
|
|
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
|
|
2697
|
+
var import_react23 = require("react");
|
|
3028
2698
|
|
|
3029
2699
|
// src/components/Modal.tsx
|
|
3030
|
-
var
|
|
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,
|
|
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
|
|
3073
|
-
const
|
|
3074
|
-
const
|
|
3075
|
-
const
|
|
3076
|
-
const
|
|
3077
|
-
|
|
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
|
|
3105
|
-
if (
|
|
3106
|
-
|
|
3107
|
-
|
|
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
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
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
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
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
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
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
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
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
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
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,
|
|
3432
|
+
const [localSearch, setLocalSearch] = (0, import_react21.useState)("");
|
|
3386
3433
|
const search = searchValue ?? localSearch;
|
|
3387
|
-
const [scrollTop, setScrollTop] = (0,
|
|
3388
|
-
const [active, setActive] = (0,
|
|
3389
|
-
const [keyboardActive, setKeyboardActive] = (0,
|
|
3390
|
-
const [deselectedHover, setDeselectedHover] = (0,
|
|
3391
|
-
const listRef = (0,
|
|
3392
|
-
const id = (0,
|
|
3393
|
-
const selected = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
3559
|
-
const measureRef = (0,
|
|
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,
|
|
3562
|
-
(0,
|
|
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,
|
|
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,
|
|
3692
|
+
const fallbackId = (0, import_react23.useId)();
|
|
3646
3693
|
const selectId = id ?? fallbackId;
|
|
3647
3694
|
const listboxId = `${selectId}-listbox`;
|
|
3648
|
-
const rootRef = (0,
|
|
3649
|
-
const popupRef = (0,
|
|
3650
|
-
const searchRef = (0,
|
|
3651
|
-
const listRef = (0,
|
|
3652
|
-
const [open, setOpen] = (0,
|
|
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,
|
|
3701
|
+
const [openedMode, setOpenedMode] = (0, import_react23.useState)(automaticMode);
|
|
3655
3702
|
const popupMode = open ? openedMode : automaticMode;
|
|
3656
|
-
const [modalValues, setModalValues] = (0,
|
|
3657
|
-
const [modalSubmitting, setModalSubmitting] = (0,
|
|
3658
|
-
const modalSubmitLock = (0,
|
|
3659
|
-
const [selectedOnly, setSelectedOnly] = (0,
|
|
3660
|
-
const [query, setQuery] = (0,
|
|
3661
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
3662
|
-
const [scrollTop, setScrollTop] = (0,
|
|
3663
|
-
const [dropdownFontSize, setDropdownFontSize] = (0,
|
|
3664
|
-
const pendingSelectedScroll = (0,
|
|
3665
|
-
const deferredQuery = (0,
|
|
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,
|
|
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,
|
|
3686
|
-
const availableOptions = (0,
|
|
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,
|
|
3693
|
-
const filteredOptions = (0,
|
|
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,
|
|
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,
|
|
3763
|
+
(0, import_react23.useEffect)(() => {
|
|
3717
3764
|
if (open && (showSearch || allowInput)) searchRef.current?.focus();
|
|
3718
3765
|
}, [allowInput, open, showSearch]);
|
|
3719
|
-
(0,
|
|
3766
|
+
(0, import_react23.useEffect)(() => {
|
|
3720
3767
|
if (disabled || loading) closeDropdown();
|
|
3721
3768
|
}, [disabled, loading]);
|
|
3722
|
-
(0,
|
|
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,
|
|
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
|
|
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,
|
|
4318
|
-
(0,
|
|
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,
|
|
4331
|
-
const [downloading, setDownloading] = (0,
|
|
4332
|
-
const downloadingRef = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
4408
|
-
const [internalFiles, setInternalFiles] = (0,
|
|
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,
|
|
4457
|
+
const filesRef = (0, import_react24.useRef)(files);
|
|
4411
4458
|
filesRef.current = files;
|
|
4412
|
-
const tasks = (0,
|
|
4413
|
-
const mounted = (0,
|
|
4414
|
-
const [dragging, setDragging] = (0,
|
|
4415
|
-
const [preview, setPreview] = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
4754
|
+
var import_react26 = require("react");
|
|
4708
4755
|
|
|
4709
4756
|
// src/components/TextArea.tsx
|
|
4710
|
-
var
|
|
4757
|
+
var import_react25 = require("react");
|
|
4711
4758
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4712
|
-
var TextArea = (0,
|
|
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,
|
|
4777
|
+
const fallbackId = (0, import_react25.useId)();
|
|
4731
4778
|
const textAreaId = id ?? fallbackId;
|
|
4732
|
-
const [uncontrolledValue, setUncontrolledValue] = (0,
|
|
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,
|
|
4794
|
-
const editRef = (0,
|
|
4795
|
-
const timer = (0,
|
|
4796
|
-
const [localText, setLocalText] = (0,
|
|
4797
|
-
const [draft, setDraft] = (0,
|
|
4798
|
-
const [editing, setEditing] = (0,
|
|
4799
|
-
const [copied, setCopied] = (0,
|
|
4800
|
-
const [copyError, setCopyError] = (0,
|
|
4801
|
-
const [expanded, setExpanded] = (0,
|
|
4802
|
-
const [overflow, setOverflow] = (0,
|
|
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,
|
|
4855
|
+
(0, import_react26.useEffect)(() => {
|
|
4809
4856
|
setLocalText(void 0);
|
|
4810
4857
|
}, [children]);
|
|
4811
|
-
(0,
|
|
4812
|
-
(0,
|
|
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
|
|
4977
|
+
var import_react27 = require("react");
|
|
4931
4978
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
4932
|
-
var GroupShape = (0,
|
|
4933
|
-
var FloatButtonRoot = (0,
|
|
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,
|
|
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,
|
|
4985
|
-
const triggerRef = (0,
|
|
4986
|
-
const id = (0,
|
|
4987
|
-
(0,
|
|
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,
|
|
5042
|
-
(0,
|
|
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);
|