@sia.soul/sia-react-ui 0.1.39 → 0.1.41
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-LRGD2QDA.js → chunk-3Q3S6CDZ.js} +975 -929
- package/dist/{chunk-WR7XTQRU.js → chunk-IPDCEXQO.js} +149 -64
- package/dist/{chunk-GLS4WVIZ.js → chunk-LWVZEUGJ.js} +88 -89
- package/dist/{core-D4opRFkZ.d.cts → core-C2IieVNm.d.cts} +25 -12
- package/dist/{core-VNY_7WRq.d.ts → core-ZmKnvCFV.d.ts} +25 -12
- package/dist/core.cjs +1071 -978
- package/dist/core.css +64 -21
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +2 -2
- package/dist/index.cjs +751 -620
- package/dist/index.css +64 -21
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/{select-date-range-CtA-B8DB.d.cts → select-date-range-2galnCvZ.d.cts} +10 -5
- package/dist/{select-date-range-D9W_mmMq.d.ts → select-date-range-Dtj6XF9I.d.ts} +10 -5
- package/dist/select-date-range.cjs +164 -119
- package/dist/select-date-range.d.cts +1 -1
- package/dist/select-date-range.d.ts +1 -1
- 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,
|
|
@@ -2534,38 +2204,66 @@ var activeTooltipClose;
|
|
|
2534
2204
|
function clampFloating(value, min, max) {
|
|
2535
2205
|
return Math.min(Math.max(value, min), Math.max(min, max));
|
|
2536
2206
|
}
|
|
2537
|
-
function
|
|
2207
|
+
function normalizeFloatingPlacement(placement) {
|
|
2208
|
+
const aliases = {
|
|
2209
|
+
topLeft: "top-start",
|
|
2210
|
+
topRight: "top-end",
|
|
2211
|
+
bottomLeft: "bottom-start",
|
|
2212
|
+
bottomRight: "bottom-end",
|
|
2213
|
+
leftTop: "left-start",
|
|
2214
|
+
leftBottom: "left-end",
|
|
2215
|
+
rightTop: "right-start",
|
|
2216
|
+
rightBottom: "right-end"
|
|
2217
|
+
};
|
|
2218
|
+
return aliases[placement] ?? placement;
|
|
2219
|
+
}
|
|
2220
|
+
function resolveFloatingPosition(trigger, overlay, placement, pointAtCenter, adjust) {
|
|
2538
2221
|
const viewportWidth = document.documentElement.clientWidth;
|
|
2539
2222
|
const viewportHeight = document.documentElement.clientHeight;
|
|
2540
|
-
let resolvedPlacement = placement;
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
resolvedPlacement =
|
|
2223
|
+
let resolvedPlacement = normalizeFloatingPlacement(placement);
|
|
2224
|
+
const side = resolvedPlacement.split("-")[0];
|
|
2225
|
+
const available = { top: trigger.top, bottom: viewportHeight - trigger.bottom, left: trigger.left, right: viewportWidth - trigger.right };
|
|
2226
|
+
const opposite = { top: "bottom", bottom: "top", left: "right", right: "left" };
|
|
2227
|
+
const preferred = side;
|
|
2228
|
+
const other = opposite[preferred];
|
|
2229
|
+
const needed = (side === "top" || side === "bottom" ? overlay.height : overlay.width) + FLOATING_GAP + FLOATING_VIEWPORT_PADDING;
|
|
2230
|
+
if (adjust && available[preferred] < needed && available[other] > available[preferred]) {
|
|
2231
|
+
resolvedPlacement = resolvedPlacement.replace(preferred, other);
|
|
2549
2232
|
}
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2233
|
+
const vertical = resolvedPlacement.startsWith("top") || resolvedPlacement.startsWith("bottom");
|
|
2234
|
+
const start = resolvedPlacement.endsWith("-start");
|
|
2235
|
+
const end = resolvedPlacement.endsWith("-end");
|
|
2236
|
+
let top = vertical ? resolvedPlacement.startsWith("top") ? trigger.top - overlay.height - FLOATING_GAP : trigger.bottom + FLOATING_GAP : start ? trigger.top : end ? trigger.bottom - overlay.height : trigger.top + (trigger.height - overlay.height) / 2;
|
|
2237
|
+
let left = vertical ? start ? trigger.left : end ? trigger.right - overlay.width : trigger.left + (trigger.width - overlay.width) / 2 : resolvedPlacement.startsWith("left") ? trigger.left - overlay.width - FLOATING_GAP : trigger.right + FLOATING_GAP;
|
|
2238
|
+
if (adjust) {
|
|
2239
|
+
if (vertical) left = clampFloating(left, FLOATING_VIEWPORT_PADDING, viewportWidth - overlay.width - FLOATING_VIEWPORT_PADDING);
|
|
2240
|
+
else top = clampFloating(top, FLOATING_VIEWPORT_PADDING, viewportHeight - overlay.height - FLOATING_VIEWPORT_PADDING);
|
|
2558
2241
|
}
|
|
2559
|
-
top = clampFloating(top, FLOATING_VIEWPORT_PADDING, viewportHeight - overlay.height - FLOATING_VIEWPORT_PADDING);
|
|
2560
|
-
left = clampFloating(left, FLOATING_VIEWPORT_PADDING, viewportWidth - overlay.width - FLOATING_VIEWPORT_PADDING);
|
|
2561
2242
|
const result = { top, left, placement: resolvedPlacement };
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2243
|
+
const size = vertical ? trigger.width : trigger.height;
|
|
2244
|
+
const anchorStart = vertical ? trigger.left : trigger.top;
|
|
2245
|
+
const edge = Math.min(size / 2, FLOATING_ARROW_EDGE_OFFSET + 4);
|
|
2246
|
+
const target = anchorStart + (pointAtCenter || !start && !end ? size / 2 : start ? edge : size - edge);
|
|
2247
|
+
if (vertical) result.arrowX = clampFloating(target - left - 4, 8, overlay.width - 16);
|
|
2248
|
+
else result.arrowY = clampFloating(target - top - 4, 8, overlay.height - 16);
|
|
2567
2249
|
return result;
|
|
2568
2250
|
}
|
|
2251
|
+
function isFloatingAnchorHidden(anchor, rect) {
|
|
2252
|
+
let left = 0, top = 0, right = document.documentElement.clientWidth, bottom = document.documentElement.clientHeight;
|
|
2253
|
+
for (let parent = anchor.parentElement; parent; parent = parent.parentElement) {
|
|
2254
|
+
const css = getComputedStyle(parent);
|
|
2255
|
+
const bounds = parent.getBoundingClientRect();
|
|
2256
|
+
if (/(auto|scroll|hidden|clip)/.test(css.overflowX)) {
|
|
2257
|
+
left = Math.max(left, bounds.left);
|
|
2258
|
+
right = Math.min(right, bounds.right);
|
|
2259
|
+
}
|
|
2260
|
+
if (/(auto|scroll|hidden|clip)/.test(css.overflowY)) {
|
|
2261
|
+
top = Math.max(top, bounds.top);
|
|
2262
|
+
bottom = Math.min(bottom, bounds.bottom);
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
return rect.right <= left || rect.left >= right || rect.bottom <= top || rect.top >= bottom;
|
|
2266
|
+
}
|
|
2569
2267
|
function Floating({
|
|
2570
2268
|
children,
|
|
2571
2269
|
content,
|
|
@@ -2576,23 +2274,25 @@ function Floating({
|
|
|
2576
2274
|
mouseEnterDelay = 0.1,
|
|
2577
2275
|
mouseLeaveDelay = 0.1,
|
|
2578
2276
|
arrow = true,
|
|
2277
|
+
autoAdjustOverflow = true,
|
|
2579
2278
|
color,
|
|
2580
2279
|
className = "",
|
|
2581
2280
|
overlayClassName = "",
|
|
2582
2281
|
role = "tooltip",
|
|
2583
2282
|
onOpenChange
|
|
2584
2283
|
}) {
|
|
2585
|
-
const rootRef = (0,
|
|
2586
|
-
const
|
|
2587
|
-
const
|
|
2588
|
-
const
|
|
2589
|
-
const
|
|
2284
|
+
const rootRef = (0, import_react13.useRef)(null);
|
|
2285
|
+
const triggerElementRef = (0, import_react13.useRef)(null);
|
|
2286
|
+
const overlayRef = (0, import_react13.useRef)(null);
|
|
2287
|
+
const enterTimer = (0, import_react13.useRef)();
|
|
2288
|
+
const leaveTimer = (0, import_react13.useRef)();
|
|
2289
|
+
const contentId = (0, import_react13.useId)();
|
|
2590
2290
|
const triggers = Array.isArray(trigger) ? trigger : [trigger];
|
|
2591
2291
|
const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
|
|
2592
|
-
const [position, setPosition] = (0,
|
|
2593
|
-
const setVisibleRef = (0,
|
|
2292
|
+
const [position, setPosition] = (0, import_react13.useState)();
|
|
2293
|
+
const setVisibleRef = (0, import_react13.useRef)(setVisible);
|
|
2594
2294
|
setVisibleRef.current = setVisible;
|
|
2595
|
-
const closeSelfRef = (0,
|
|
2295
|
+
const closeSelfRef = (0, import_react13.useRef)();
|
|
2596
2296
|
if (!closeSelfRef.current) closeSelfRef.current = () => setVisibleRef.current(false);
|
|
2597
2297
|
const exclusiveTooltip = role === "tooltip" && triggers.includes("hover");
|
|
2598
2298
|
function openNow() {
|
|
@@ -2620,7 +2320,7 @@ function Floating({
|
|
|
2620
2320
|
if (delay <= 0) closeNow();
|
|
2621
2321
|
else leaveTimer.current = window.setTimeout(closeNow, delay * 1e3);
|
|
2622
2322
|
}
|
|
2623
|
-
(0,
|
|
2323
|
+
(0, import_react13.useEffect)(() => {
|
|
2624
2324
|
if (!visible || !triggers.includes("click")) return;
|
|
2625
2325
|
const close = (event) => {
|
|
2626
2326
|
const target = event.target;
|
|
@@ -2629,33 +2329,47 @@ function Floating({
|
|
|
2629
2329
|
document.addEventListener("pointerdown", close);
|
|
2630
2330
|
return () => document.removeEventListener("pointerdown", close);
|
|
2631
2331
|
}, [triggers.join("|"), visible]);
|
|
2632
|
-
(0,
|
|
2332
|
+
(0, import_react13.useLayoutEffect)(() => {
|
|
2633
2333
|
if (!visible) {
|
|
2634
2334
|
setPosition(void 0);
|
|
2635
2335
|
return;
|
|
2636
2336
|
}
|
|
2337
|
+
const getAnchor = () => {
|
|
2338
|
+
const root = rootRef.current;
|
|
2339
|
+
const target = triggerElementRef.current;
|
|
2340
|
+
return target && root?.contains(target) ? target : root?.firstElementChild ?? root;
|
|
2341
|
+
};
|
|
2637
2342
|
const update = () => {
|
|
2638
2343
|
if (!rootRef.current || !overlayRef.current) return;
|
|
2639
|
-
|
|
2344
|
+
const anchor2 = getAnchor();
|
|
2345
|
+
if (anchor2) {
|
|
2346
|
+
const rect = anchor2.getBoundingClientRect();
|
|
2347
|
+
const next = resolveFloatingPosition(rect, overlayRef.current.getBoundingClientRect(), placement, typeof arrow === "object" && !!arrow.pointAtCenter, autoAdjustOverflow);
|
|
2348
|
+
next.hidden = isFloatingAnchorHidden(anchor2, rect);
|
|
2349
|
+
setPosition(next);
|
|
2350
|
+
}
|
|
2640
2351
|
};
|
|
2641
2352
|
update();
|
|
2642
2353
|
window.addEventListener("resize", update);
|
|
2643
2354
|
window.addEventListener("scroll", update, true);
|
|
2644
2355
|
const observer = new ResizeObserver(update);
|
|
2645
2356
|
if (rootRef.current) observer.observe(rootRef.current);
|
|
2357
|
+
const anchor = getAnchor();
|
|
2358
|
+
if (anchor) observer.observe(anchor);
|
|
2646
2359
|
if (overlayRef.current) observer.observe(overlayRef.current);
|
|
2647
2360
|
return () => {
|
|
2648
2361
|
window.removeEventListener("resize", update);
|
|
2649
2362
|
window.removeEventListener("scroll", update, true);
|
|
2650
2363
|
observer.disconnect();
|
|
2651
2364
|
};
|
|
2652
|
-
}, [children, content, placement, visible]);
|
|
2653
|
-
(0,
|
|
2365
|
+
}, [children, content, placement, visible, autoAdjustOverflow, typeof arrow === "object" && arrow.pointAtCenter]);
|
|
2366
|
+
(0, import_react13.useEffect)(() => () => {
|
|
2654
2367
|
clearTimers();
|
|
2655
2368
|
if (activeTooltipClose === closeSelfRef.current) activeTooltipClose = void 0;
|
|
2656
2369
|
}, []);
|
|
2657
|
-
const child = (0,
|
|
2370
|
+
const child = (0, import_react13.cloneElement)(children, {
|
|
2658
2371
|
...triggers.includes("hover") ? { onMouseEnter: (event) => {
|
|
2372
|
+
triggerElementRef.current = event.currentTarget;
|
|
2659
2373
|
children.props.onMouseEnter?.(event);
|
|
2660
2374
|
show(mouseEnterDelay);
|
|
2661
2375
|
}, onMouseLeave: (event) => {
|
|
@@ -2663,6 +2377,7 @@ function Floating({
|
|
|
2663
2377
|
hide(mouseLeaveDelay);
|
|
2664
2378
|
} } : {},
|
|
2665
2379
|
...triggers.includes("focus") ? { onFocus: (event) => {
|
|
2380
|
+
triggerElementRef.current = event.currentTarget;
|
|
2666
2381
|
children.props.onFocus?.(event);
|
|
2667
2382
|
show();
|
|
2668
2383
|
}, onBlur: (event) => {
|
|
@@ -2670,6 +2385,7 @@ function Floating({
|
|
|
2670
2385
|
hide();
|
|
2671
2386
|
} } : {},
|
|
2672
2387
|
...triggers.includes("click") ? { onClick: (event) => {
|
|
2388
|
+
triggerElementRef.current = event.currentTarget;
|
|
2673
2389
|
children.props.onClick?.(event);
|
|
2674
2390
|
if (visible) closeNow();
|
|
2675
2391
|
else openNow();
|
|
@@ -2684,14 +2400,14 @@ function Floating({
|
|
|
2684
2400
|
id: contentId,
|
|
2685
2401
|
role,
|
|
2686
2402
|
"data-custom-color": color ? "" : void 0,
|
|
2687
|
-
className: `sia-floating__overlay sia-floating__overlay--${position?.placement ?? placement} ${overlayClassName}`.trim(),
|
|
2403
|
+
className: `sia-floating__overlay sia-floating__overlay--${position?.placement ?? normalizeFloatingPlacement(placement)} ${overlayClassName}`.trim(),
|
|
2688
2404
|
style: {
|
|
2689
2405
|
"--sia-floating-color": color,
|
|
2690
2406
|
"--sia-floating-arrow-x": position?.arrowX == null ? void 0 : `${position.arrowX}px`,
|
|
2691
2407
|
"--sia-floating-arrow-y": position?.arrowY == null ? void 0 : `${position.arrowY}px`,
|
|
2692
2408
|
top: position?.top ?? 0,
|
|
2693
2409
|
left: position?.left ?? 0,
|
|
2694
|
-
visibility: position ? "visible" : "hidden"
|
|
2410
|
+
visibility: position && !position.hidden ? "visible" : "hidden"
|
|
2695
2411
|
},
|
|
2696
2412
|
onMouseEnter: triggers.includes("hover") ? () => show() : void 0,
|
|
2697
2413
|
onMouseLeave: triggers.includes("hover") ? () => hide(mouseLeaveDelay) : void 0,
|
|
@@ -2759,11 +2475,11 @@ function Progress({
|
|
|
2759
2475
|
}
|
|
2760
2476
|
|
|
2761
2477
|
// src/components/DataDisplay.tsx
|
|
2762
|
-
var
|
|
2478
|
+
var import_react16 = require("react");
|
|
2763
2479
|
var import_react_dom5 = require("react-dom");
|
|
2764
2480
|
|
|
2765
2481
|
// src/components/Overlay.tsx
|
|
2766
|
-
var
|
|
2482
|
+
var import_react15 = require("react");
|
|
2767
2483
|
var import_react_dom4 = require("react-dom");
|
|
2768
2484
|
var bodyLockCount = 0;
|
|
2769
2485
|
var previousBodyOverflow = "";
|
|
@@ -2785,10 +2501,10 @@ function focusableElements(container) {
|
|
|
2785
2501
|
)].filter((element) => !element.hidden && element.getAttribute("aria-hidden") !== "true");
|
|
2786
2502
|
}
|
|
2787
2503
|
function useOverlayLifecycle(open, panelRef, onRequestClose, keyboard = true) {
|
|
2788
|
-
const overlayIdRef = (0,
|
|
2789
|
-
const closeRef = (0,
|
|
2504
|
+
const overlayIdRef = (0, import_react15.useRef)(/* @__PURE__ */ Symbol("sia-overlay"));
|
|
2505
|
+
const closeRef = (0, import_react15.useRef)(onRequestClose);
|
|
2790
2506
|
closeRef.current = onRequestClose;
|
|
2791
|
-
(0,
|
|
2507
|
+
(0, import_react15.useEffect)(() => {
|
|
2792
2508
|
if (!open || typeof document === "undefined") return void 0;
|
|
2793
2509
|
const overlayId = overlayIdRef.current;
|
|
2794
2510
|
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -2871,8 +2587,8 @@ function CollapsePanel({
|
|
|
2871
2587
|
destroyInactivePanel = false,
|
|
2872
2588
|
children
|
|
2873
2589
|
}) {
|
|
2874
|
-
const [keepChildren, setKeepChildren] = (0,
|
|
2875
|
-
(0,
|
|
2590
|
+
const [keepChildren, setKeepChildren] = (0, import_react16.useState)(open || forceRender || !destroyInactivePanel);
|
|
2591
|
+
(0, import_react16.useEffect)(() => {
|
|
2876
2592
|
if (open || forceRender || !destroyInactivePanel) {
|
|
2877
2593
|
setKeepChildren(true);
|
|
2878
2594
|
return void 0;
|
|
@@ -2886,7 +2602,7 @@ function CollapsePanel({
|
|
|
2886
2602
|
function Collapse({ items, activeKey, defaultActiveKey = [], accordion = false, bordered = true, ghost = false, destroyInactivePanel = false, expandIconPosition = "start", onChange, className = "", ...props }) {
|
|
2887
2603
|
const normalize = (key) => Array.isArray(key) ? [...key] : key === void 0 ? [] : [key];
|
|
2888
2604
|
const controlled = activeKey !== void 0;
|
|
2889
|
-
const [internal, setInternal] = (0,
|
|
2605
|
+
const [internal, setInternal] = (0, import_react16.useState)(normalize(defaultActiveKey));
|
|
2890
2606
|
const openKeys = controlled ? normalize(activeKey) : internal;
|
|
2891
2607
|
function toggle(item) {
|
|
2892
2608
|
if (item.disabled || item.collapsible === "disabled") return;
|
|
@@ -2916,16 +2632,16 @@ function Collapse({ items, activeKey, defaultActiveKey = [], accordion = false,
|
|
|
2916
2632
|
}) });
|
|
2917
2633
|
}
|
|
2918
2634
|
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,
|
|
2635
|
+
const previewRef = (0, import_react16.useRef)(null);
|
|
2636
|
+
const stageRef = (0, import_react16.useRef)(null);
|
|
2637
|
+
const [natural, setNatural] = (0, import_react16.useState)({ src: "", width: 0, height: 0 });
|
|
2638
|
+
const [area, setArea] = (0, import_react16.useState)({ width: 0, height: 0 });
|
|
2639
|
+
const [zoom, setZoom] = (0, import_react16.useState)(1);
|
|
2640
|
+
const [rotation, setRotation] = (0, import_react16.useState)(0);
|
|
2641
|
+
const [flip, setFlip] = (0, import_react16.useState)({ x: 1, y: 1 });
|
|
2642
|
+
const [pan, setPan] = (0, import_react16.useState)({ x: 0, y: 0 });
|
|
2643
|
+
const [failed, setFailed] = (0, import_react16.useState)(false);
|
|
2644
|
+
const drag = (0, import_react16.useRef)();
|
|
2929
2645
|
useOverlayLifecycle(open, previewRef, () => onOpenChange(false));
|
|
2930
2646
|
const reset = () => {
|
|
2931
2647
|
setZoom(1);
|
|
@@ -2934,11 +2650,11 @@ function ImagePreview({ open, src, alt = "", onOpenChange }) {
|
|
|
2934
2650
|
setPan({ x: 0, y: 0 });
|
|
2935
2651
|
drag.current = void 0;
|
|
2936
2652
|
};
|
|
2937
|
-
(0,
|
|
2653
|
+
(0, import_react16.useEffect)(() => {
|
|
2938
2654
|
reset();
|
|
2939
2655
|
setFailed(false);
|
|
2940
2656
|
}, [open, src]);
|
|
2941
|
-
(0,
|
|
2657
|
+
(0, import_react16.useEffect)(() => {
|
|
2942
2658
|
const stage = stageRef.current;
|
|
2943
2659
|
if (!open || !stage) return;
|
|
2944
2660
|
const measure = () => {
|
|
@@ -3024,10 +2740,10 @@ function useFloatingPlaceholder({ mode, placeholder, filled, active = false }) {
|
|
|
3024
2740
|
}
|
|
3025
2741
|
|
|
3026
2742
|
// src/components/Select.tsx
|
|
3027
|
-
var
|
|
2743
|
+
var import_react23 = require("react");
|
|
3028
2744
|
|
|
3029
2745
|
// src/components/Modal.tsx
|
|
3030
|
-
var
|
|
2746
|
+
var import_react17 = require("react");
|
|
3031
2747
|
var import_client3 = require("react-dom/client");
|
|
3032
2748
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3033
2749
|
var modalHandles = /* @__PURE__ */ new Set();
|
|
@@ -3039,7 +2755,7 @@ var typeIcons = {
|
|
|
3039
2755
|
error: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "circle-close", size: 23 }),
|
|
3040
2756
|
confirm: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "question", size: 23 })
|
|
3041
2757
|
};
|
|
3042
|
-
var ModalRoot = (0,
|
|
2758
|
+
var ModalRoot = (0, import_react17.forwardRef)(function Modal({
|
|
3043
2759
|
open,
|
|
3044
2760
|
title,
|
|
3045
2761
|
children,
|
|
@@ -3065,302 +2781,679 @@ var ModalRoot = (0, import_react18.forwardRef)(function Modal({
|
|
|
3065
2781
|
onOpenChange,
|
|
3066
2782
|
afterOpenChange,
|
|
3067
2783
|
className = "",
|
|
3068
|
-
style,
|
|
2784
|
+
style,
|
|
2785
|
+
...props
|
|
2786
|
+
}, forwardedRef) {
|
|
2787
|
+
const localRef = (0, import_react17.useRef)(null);
|
|
2788
|
+
const titleId = (0, import_react17.useId)();
|
|
2789
|
+
const [submitting, setSubmitting] = (0, import_react17.useState)(false);
|
|
2790
|
+
const [rendered, setRendered] = (0, import_react17.useState)(open);
|
|
2791
|
+
const [closing, setClosing] = (0, import_react17.useState)(false);
|
|
2792
|
+
const afterOpenChangeRef = (0, import_react17.useRef)(afterOpenChange);
|
|
2793
|
+
afterOpenChangeRef.current = afterOpenChange;
|
|
2794
|
+
const submitLock = (0, import_react17.useRef)(false);
|
|
2795
|
+
(0, import_react17.useEffect)(() => {
|
|
2796
|
+
if (!open || !rendered) return void 0;
|
|
2797
|
+
const timer = window.setTimeout(() => afterOpenChangeRef.current?.(true), MODAL_MOTION_DURATION);
|
|
2798
|
+
return () => window.clearTimeout(timer);
|
|
2799
|
+
}, [open, rendered]);
|
|
2800
|
+
(0, import_react17.useEffect)(() => {
|
|
2801
|
+
if (open) {
|
|
2802
|
+
setRendered(true);
|
|
2803
|
+
setClosing(false);
|
|
2804
|
+
return void 0;
|
|
2805
|
+
}
|
|
2806
|
+
if (!rendered) return void 0;
|
|
2807
|
+
setClosing(true);
|
|
2808
|
+
const timer = window.setTimeout(() => {
|
|
2809
|
+
setRendered(false);
|
|
2810
|
+
setClosing(false);
|
|
2811
|
+
afterOpenChangeRef.current?.(false);
|
|
2812
|
+
}, MODAL_MOTION_DURATION);
|
|
2813
|
+
return () => window.clearTimeout(timer);
|
|
2814
|
+
}, [open, rendered]);
|
|
2815
|
+
function setRef(node) {
|
|
2816
|
+
localRef.current = node;
|
|
2817
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
2818
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
2819
|
+
}
|
|
2820
|
+
function requestClose() {
|
|
2821
|
+
if (submitting || confirmLoading) return;
|
|
2822
|
+
onCancel?.();
|
|
2823
|
+
onOpenChange?.(false);
|
|
2824
|
+
}
|
|
2825
|
+
async function handleOk() {
|
|
2826
|
+
if (submitLock.current || confirmLoading) return;
|
|
2827
|
+
submitLock.current = true;
|
|
2828
|
+
if (!onOk) {
|
|
2829
|
+
onOpenChange?.(false);
|
|
2830
|
+
submitLock.current = false;
|
|
2831
|
+
return;
|
|
2832
|
+
}
|
|
2833
|
+
try {
|
|
2834
|
+
const result = onOk();
|
|
2835
|
+
if (result instanceof Promise) {
|
|
2836
|
+
setSubmitting(true);
|
|
2837
|
+
const resolved = await result;
|
|
2838
|
+
if (resolved !== false) onOpenChange?.(false);
|
|
2839
|
+
} else if (result !== false) {
|
|
2840
|
+
onOpenChange?.(false);
|
|
2841
|
+
}
|
|
2842
|
+
} catch {
|
|
2843
|
+
return;
|
|
2844
|
+
} finally {
|
|
2845
|
+
submitLock.current = false;
|
|
2846
|
+
setSubmitting(false);
|
|
2847
|
+
}
|
|
2848
|
+
}
|
|
2849
|
+
useOverlayLifecycle(rendered, localRef, requestClose, keyboard);
|
|
2850
|
+
if (!rendered) return null;
|
|
2851
|
+
const mergedStyle = {
|
|
2852
|
+
...height !== void 0 ? { display: "flex", flexDirection: "column", height, maxHeight: "calc(100dvh - 48px)" } : {},
|
|
2853
|
+
...style,
|
|
2854
|
+
"--sia-modal-width": typeof width === "number" ? `${width}px` : width
|
|
2855
|
+
};
|
|
2856
|
+
const loading = submitting || confirmLoading;
|
|
2857
|
+
const defaultFooter = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
2858
|
+
showCancel ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { ...cancelButtonProps, onClick: requestClose, disabled: loading || cancelButtonProps?.disabled, children: cancelText }) : null,
|
|
2859
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Button, { variant: "primary", ...okButtonProps, onClick: handleOk, loading, children: okText })
|
|
2860
|
+
] });
|
|
2861
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(OverlayPortal, { container: getContainer, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2862
|
+
"div",
|
|
2863
|
+
{
|
|
2864
|
+
className: `sia-modal-root${centered ? " sia-modal-root--centered" : ""}`,
|
|
2865
|
+
"data-state": closing ? "closing" : "open",
|
|
2866
|
+
style: { zIndex },
|
|
2867
|
+
onMouseDown: (event) => {
|
|
2868
|
+
if (event.target === event.currentTarget && maskClosable) requestClose();
|
|
2869
|
+
},
|
|
2870
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2871
|
+
"div",
|
|
2872
|
+
{
|
|
2873
|
+
ref: setRef,
|
|
2874
|
+
className: `sia-modal sia-modal--${type} ${className}`.trim(),
|
|
2875
|
+
style: mergedStyle,
|
|
2876
|
+
role: "dialog",
|
|
2877
|
+
"aria-modal": "true",
|
|
2878
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
2879
|
+
tabIndex: -1,
|
|
2880
|
+
...withTitleTooltip(props),
|
|
2881
|
+
children: [
|
|
2882
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-modal__header", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
|
|
2883
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-modal__heading", children: [
|
|
2884
|
+
typeIcons[type] ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "sia-modal__type-icon", "aria-hidden": "true", children: typeIcons[type] }) : null,
|
|
2885
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("strong", { id: titleId, children: title }) : null
|
|
2886
|
+
] }),
|
|
2887
|
+
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
|
|
2888
|
+
] }),
|
|
2889
|
+
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,
|
|
2890
|
+
footer !== null ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "sia-modal__footer", style: height !== void 0 ? { flexShrink: 0 } : void 0, children: [
|
|
2891
|
+
footer === void 0 && footerExtra != null ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { marginRight: "auto" }, children: footerExtra }) : null,
|
|
2892
|
+
footer ?? defaultFooter
|
|
2893
|
+
] }) : null
|
|
2894
|
+
]
|
|
2895
|
+
}
|
|
2896
|
+
)
|
|
2897
|
+
}
|
|
2898
|
+
) });
|
|
2899
|
+
});
|
|
2900
|
+
function openModal(config) {
|
|
2901
|
+
if (typeof document === "undefined") return { destroy() {
|
|
2902
|
+
}, update() {
|
|
2903
|
+
} };
|
|
2904
|
+
const container = document.createElement("div");
|
|
2905
|
+
container.className = "sia-modal-api-host";
|
|
2906
|
+
document.body.appendChild(container);
|
|
2907
|
+
const root = (0, import_client3.createRoot)(container);
|
|
2908
|
+
let currentConfig = config;
|
|
2909
|
+
let currentOpen = true;
|
|
2910
|
+
let destroyed = false;
|
|
2911
|
+
let cleanupTimer;
|
|
2912
|
+
function cleanup2() {
|
|
2913
|
+
if (destroyed) return;
|
|
2914
|
+
destroyed = true;
|
|
2915
|
+
if (cleanupTimer !== void 0) window.clearTimeout(cleanupTimer);
|
|
2916
|
+
root.unmount();
|
|
2917
|
+
container.remove();
|
|
2918
|
+
modalHandles.delete(handle);
|
|
2919
|
+
}
|
|
2920
|
+
function closeWithMotion() {
|
|
2921
|
+
if (destroyed || !currentOpen) return;
|
|
2922
|
+
currentOpen = false;
|
|
2923
|
+
render();
|
|
2924
|
+
cleanupTimer = window.setTimeout(cleanup2, MODAL_MOTION_DURATION);
|
|
2925
|
+
}
|
|
2926
|
+
function render() {
|
|
2927
|
+
root.render(/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModalRoot, { ...currentConfig, open: currentOpen, onOpenChange: (nextOpen) => {
|
|
2928
|
+
currentConfig.onOpenChange?.(nextOpen);
|
|
2929
|
+
if (!nextOpen) closeWithMotion();
|
|
2930
|
+
} }));
|
|
2931
|
+
}
|
|
2932
|
+
const handle = {
|
|
2933
|
+
destroy: closeWithMotion,
|
|
2934
|
+
update(next) {
|
|
2935
|
+
if (destroyed) return;
|
|
2936
|
+
currentConfig = { ...currentConfig, ...next };
|
|
2937
|
+
render();
|
|
2938
|
+
}
|
|
2939
|
+
};
|
|
2940
|
+
modalHandles.add(handle);
|
|
2941
|
+
render();
|
|
2942
|
+
return handle;
|
|
2943
|
+
}
|
|
2944
|
+
function preset(type, defaults = {}) {
|
|
2945
|
+
return (config) => openModal({
|
|
2946
|
+
okText: type === "confirm" ? "\u786E\u5B9A" : "\u77E5\u9053\u4E86",
|
|
2947
|
+
showCancel: type === "confirm",
|
|
2948
|
+
closable: type !== "confirm",
|
|
2949
|
+
maskClosable: type !== "confirm",
|
|
2950
|
+
...defaults,
|
|
2951
|
+
...config,
|
|
2952
|
+
type
|
|
2953
|
+
});
|
|
2954
|
+
}
|
|
2955
|
+
var Modal2 = Object.assign(ModalRoot, {
|
|
2956
|
+
/** 直接打开实例,返回可用于更新或关闭的操作句柄。 */
|
|
2957
|
+
open: openModal,
|
|
2958
|
+
/** 显示普通信息提示。 */
|
|
2959
|
+
info: preset("info", { title: "\u63D0\u793A" }),
|
|
2960
|
+
/** 显示成功提示。 */
|
|
2961
|
+
success: preset("success", { title: "\u64CD\u4F5C\u6210\u529F" }),
|
|
2962
|
+
/** 显示警告提示。 */
|
|
2963
|
+
warning: preset("warning", { title: "\u8BF7\u6CE8\u610F" }),
|
|
2964
|
+
/** 显示错误提示。 */
|
|
2965
|
+
error: preset("error", { title: "\u64CD\u4F5C\u5931\u8D25" }),
|
|
2966
|
+
/** 打开确认弹框,支持异步确认;返回 false 可阻止关闭。 */
|
|
2967
|
+
confirm: preset("confirm", { title: "\u786E\u8BA4\u64CD\u4F5C" }),
|
|
2968
|
+
/** 关闭由此 API 打开的所有弹层。 */
|
|
2969
|
+
destroyAll() {
|
|
2970
|
+
[...modalHandles].forEach((handle) => handle.destroy());
|
|
2971
|
+
}
|
|
2972
|
+
});
|
|
2973
|
+
|
|
2974
|
+
// src/components/Input.tsx
|
|
2975
|
+
var import_react18 = require("react");
|
|
2976
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2977
|
+
var Input = (0, import_react18.forwardRef)(function Input2({
|
|
2978
|
+
label,
|
|
2979
|
+
hint,
|
|
2980
|
+
status = "default",
|
|
2981
|
+
size: sizeProp,
|
|
2982
|
+
prefix,
|
|
2983
|
+
suffix,
|
|
2984
|
+
allowClear = true,
|
|
2985
|
+
onClear,
|
|
2986
|
+
showCount = false,
|
|
2987
|
+
placeholderMode,
|
|
2988
|
+
placeholder,
|
|
2989
|
+
className = "",
|
|
2990
|
+
id,
|
|
2991
|
+
disabled,
|
|
2992
|
+
value,
|
|
2993
|
+
defaultValue,
|
|
2994
|
+
maxLength,
|
|
2995
|
+
onChange,
|
|
3069
2996
|
...props
|
|
3070
2997
|
}, forwardedRef) {
|
|
2998
|
+
const size = useControlSize(sizeProp);
|
|
2999
|
+
const fallbackId = (0, import_react18.useId)();
|
|
3000
|
+
const inputId = id ?? fallbackId;
|
|
3071
3001
|
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]);
|
|
3002
|
+
const [uncontrolledValue, setUncontrolledValue] = (0, import_react18.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
|
|
3003
|
+
const currentText = value !== void 0 ? String(value) : uncontrolledValue;
|
|
3004
|
+
const hasValue = currentText.length > 0;
|
|
3005
|
+
const floatingPlaceholder = usePlaceholderMode(placeholderMode) === "floating" && Boolean(placeholder);
|
|
3006
|
+
const hintId = `${inputId}-hint`;
|
|
3007
|
+
const describedBy = [props["aria-describedby"], hint ? hintId : null].filter(Boolean).join(" ") || void 0;
|
|
3099
3008
|
function setRef(node) {
|
|
3100
3009
|
localRef.current = node;
|
|
3101
3010
|
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
3102
3011
|
else if (forwardedRef) forwardedRef.current = node;
|
|
3103
3012
|
}
|
|
3104
|
-
function
|
|
3105
|
-
if (
|
|
3106
|
-
|
|
3107
|
-
|
|
3013
|
+
function handleChange(event) {
|
|
3014
|
+
if (maxLength !== void 0 && maxLength >= 0 && event.target.value.length > maxLength) {
|
|
3015
|
+
const valueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
|
|
3016
|
+
valueSetter?.call(event.target, event.target.value.slice(0, maxLength));
|
|
3017
|
+
}
|
|
3018
|
+
setUncontrolledValue(event.target.value);
|
|
3019
|
+
onChange?.(event);
|
|
3108
3020
|
}
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3021
|
+
function clearValue() {
|
|
3022
|
+
const input2 = localRef.current;
|
|
3023
|
+
if (!input2 || disabled) return;
|
|
3024
|
+
const valueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
|
|
3025
|
+
valueSetter?.call(input2, "");
|
|
3026
|
+
input2.dispatchEvent(new Event("input", { bubbles: true }));
|
|
3027
|
+
setUncontrolledValue("");
|
|
3028
|
+
input2.focus();
|
|
3029
|
+
onClear?.();
|
|
3030
|
+
}
|
|
3031
|
+
function handleControlMouseDown(event) {
|
|
3032
|
+
if (disabled || event.defaultPrevented || event.button !== 0) return;
|
|
3033
|
+
const target = event.target;
|
|
3034
|
+
if (!(target instanceof Element)) return;
|
|
3035
|
+
const interactive = target.closest("input, textarea, select, button, a[href], [tabindex], [contenteditable]:not([contenteditable='false']), [role='button'], [role='link']");
|
|
3036
|
+
if (interactive && event.currentTarget.contains(interactive) && !interactive.classList.contains("sia-input-control__clear")) return;
|
|
3037
|
+
event.preventDefault();
|
|
3038
|
+
localRef.current?.focus({ preventScroll: true });
|
|
3039
|
+
}
|
|
3040
|
+
const input = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3041
|
+
"input",
|
|
3042
|
+
{
|
|
3043
|
+
...withTitleTooltip(props),
|
|
3044
|
+
ref: setRef,
|
|
3045
|
+
id: inputId,
|
|
3046
|
+
className: "sia-input",
|
|
3047
|
+
disabled,
|
|
3048
|
+
value,
|
|
3049
|
+
defaultValue,
|
|
3050
|
+
maxLength,
|
|
3051
|
+
placeholder,
|
|
3052
|
+
"aria-describedby": describedBy,
|
|
3053
|
+
"aria-invalid": status === "error" || void 0,
|
|
3054
|
+
onChange: handleChange
|
|
3116
3055
|
}
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3056
|
+
);
|
|
3057
|
+
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: [
|
|
3058
|
+
prefix ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-input-control__affix", children: prefix }) : null,
|
|
3059
|
+
floatingPlaceholder ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "sia-input-control__input-wrap", children: [
|
|
3060
|
+
input,
|
|
3061
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-input-control__floating-placeholder", "aria-hidden": "true", children: placeholder })
|
|
3062
|
+
] }) : input,
|
|
3063
|
+
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,
|
|
3064
|
+
suffix ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sia-input-control__affix", children: suffix }) : null,
|
|
3065
|
+
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: [
|
|
3066
|
+
currentText.length,
|
|
3067
|
+
maxLength !== void 0 ? `/${maxLength}` : null
|
|
3068
|
+
] }) : null
|
|
3069
|
+
] });
|
|
3070
|
+
if (!label && !hint) return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: `sia-field ${className}`.trim(), children: control });
|
|
3071
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: `sia-field ${className}`.trim(), children: [
|
|
3072
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { className: "sia-field__label", htmlFor: inputId, children: label }) : null,
|
|
3073
|
+
control,
|
|
3074
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { id: hintId, className: `sia-field__hint sia-field__hint--${status}`, children: hint }) : null
|
|
3075
|
+
] });
|
|
3076
|
+
});
|
|
3077
|
+
|
|
3078
|
+
// src/components/SelectionPanel.tsx
|
|
3079
|
+
var import_react21 = require("react");
|
|
3080
|
+
|
|
3081
|
+
// src/components/FloatingScrollbarProvider.tsx
|
|
3082
|
+
var import_react20 = require("react");
|
|
3083
|
+
|
|
3084
|
+
// src/components/useScrollbarProximity.ts
|
|
3085
|
+
var import_react19 = require("react");
|
|
3086
|
+
var users = 0;
|
|
3087
|
+
var cleanup;
|
|
3088
|
+
function useScrollbarProximity() {
|
|
3089
|
+
(0, import_react19.useEffect)(() => {
|
|
3090
|
+
if (users++ === 0) {
|
|
3091
|
+
let frame = 0;
|
|
3092
|
+
let x = -Infinity;
|
|
3093
|
+
let y = -Infinity;
|
|
3094
|
+
const nearby = /* @__PURE__ */ new Set();
|
|
3095
|
+
const clear = () => {
|
|
3096
|
+
nearby.forEach((track) => track.removeAttribute("data-scrollbar-near"));
|
|
3097
|
+
nearby.clear();
|
|
3098
|
+
};
|
|
3099
|
+
const update = () => {
|
|
3100
|
+
frame = 0;
|
|
3101
|
+
const next = /* @__PURE__ */ new Set();
|
|
3102
|
+
document.querySelectorAll(".sia-scrollbar-track").forEach((track) => {
|
|
3103
|
+
const rect = track.getBoundingClientRect();
|
|
3104
|
+
const proximity = Number.parseFloat(getComputedStyle(track).getPropertyValue("--sia-scrollbar-proximity")) || 16;
|
|
3105
|
+
if (rect.width && rect.height && x >= rect.left - proximity && x <= rect.right + proximity && y >= rect.top - proximity && y <= rect.bottom + proximity) {
|
|
3106
|
+
next.add(track);
|
|
3107
|
+
if (!nearby.has(track)) track.setAttribute("data-scrollbar-near", "true");
|
|
3108
|
+
}
|
|
3109
|
+
});
|
|
3110
|
+
nearby.forEach((track) => {
|
|
3111
|
+
if (!next.has(track)) track.removeAttribute("data-scrollbar-near");
|
|
3112
|
+
});
|
|
3113
|
+
nearby.clear();
|
|
3114
|
+
next.forEach((track) => nearby.add(track));
|
|
3115
|
+
};
|
|
3116
|
+
const move = (event) => {
|
|
3117
|
+
if (event.pointerType === "touch") return;
|
|
3118
|
+
x = event.clientX;
|
|
3119
|
+
y = event.clientY;
|
|
3120
|
+
if (!frame) frame = requestAnimationFrame(update);
|
|
3121
|
+
};
|
|
3122
|
+
const leave = () => {
|
|
3123
|
+
x = y = -Infinity;
|
|
3124
|
+
clear();
|
|
3125
|
+
};
|
|
3126
|
+
document.addEventListener("pointermove", move, { passive: true });
|
|
3127
|
+
document.documentElement.addEventListener("pointerleave", leave);
|
|
3128
|
+
window.addEventListener("blur", leave);
|
|
3129
|
+
cleanup = () => {
|
|
3130
|
+
if (frame) cancelAnimationFrame(frame);
|
|
3131
|
+
document.removeEventListener("pointermove", move);
|
|
3132
|
+
document.documentElement.removeEventListener("pointerleave", leave);
|
|
3133
|
+
window.removeEventListener("blur", leave);
|
|
3134
|
+
clear();
|
|
3135
|
+
};
|
|
3136
|
+
}
|
|
3137
|
+
return () => {
|
|
3138
|
+
if (--users === 0) {
|
|
3139
|
+
cleanup?.();
|
|
3140
|
+
cleanup = void 0;
|
|
3141
|
+
}
|
|
3142
|
+
};
|
|
3143
|
+
}, []);
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
// src/components/FloatingScrollbarProvider.tsx
|
|
3147
|
+
var scrollableOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
|
|
3148
|
+
var clippingOverflow = /* @__PURE__ */ new Set(["auto", "scroll", "overlay", "hidden", "clip"]);
|
|
3149
|
+
function isRootScroller(target) {
|
|
3150
|
+
return target === document.scrollingElement || target === document.documentElement;
|
|
3151
|
+
}
|
|
3152
|
+
function canScroll(target, axis) {
|
|
3153
|
+
if (target.matches(".sia-table__viewport, [data-sia-native-scrollbar]")) return false;
|
|
3154
|
+
if (isRootScroller(target)) {
|
|
3155
|
+
return axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
3156
|
+
}
|
|
3157
|
+
const style = getComputedStyle(target);
|
|
3158
|
+
const overflow = axis === "horizontal" ? style.overflowX : style.overflowY;
|
|
3159
|
+
const hasOverflow = axis === "horizontal" ? target.scrollWidth > target.clientWidth + 1 : target.scrollHeight > target.clientHeight + 1;
|
|
3160
|
+
return hasOverflow && scrollableOverflow.has(overflow);
|
|
3161
|
+
}
|
|
3162
|
+
function visibleRect(target) {
|
|
3163
|
+
if (isRootScroller(target)) {
|
|
3164
|
+
return { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0, width: window.innerWidth, height: window.innerHeight };
|
|
3165
|
+
}
|
|
3166
|
+
const ownRect = target.getBoundingClientRect();
|
|
3167
|
+
let top = Math.max(0, ownRect.top);
|
|
3168
|
+
let right = Math.min(window.innerWidth, ownRect.right);
|
|
3169
|
+
let bottom = Math.min(window.innerHeight, ownRect.bottom);
|
|
3170
|
+
let left = Math.max(0, ownRect.left);
|
|
3171
|
+
let parent = target.parentElement;
|
|
3172
|
+
while (parent && parent !== document.body && parent !== document.documentElement) {
|
|
3173
|
+
const style = getComputedStyle(parent);
|
|
3174
|
+
const clipX = clippingOverflow.has(style.overflowX);
|
|
3175
|
+
const clipY = clippingOverflow.has(style.overflowY);
|
|
3176
|
+
if (clipX || clipY) {
|
|
3177
|
+
const rect = parent.getBoundingClientRect();
|
|
3178
|
+
if (clipX) {
|
|
3179
|
+
left = Math.max(left, rect.left);
|
|
3180
|
+
right = Math.min(right, rect.right);
|
|
3181
|
+
}
|
|
3182
|
+
if (clipY) {
|
|
3183
|
+
top = Math.max(top, rect.top);
|
|
3184
|
+
bottom = Math.min(bottom, rect.bottom);
|
|
3125
3185
|
}
|
|
3126
|
-
} catch {
|
|
3127
|
-
return;
|
|
3128
|
-
} finally {
|
|
3129
|
-
submitLock.current = false;
|
|
3130
|
-
setSubmitting(false);
|
|
3131
3186
|
}
|
|
3187
|
+
parent = parent.parentElement;
|
|
3132
3188
|
}
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3189
|
+
return {
|
|
3190
|
+
top,
|
|
3191
|
+
right,
|
|
3192
|
+
bottom,
|
|
3193
|
+
left,
|
|
3194
|
+
width: Math.max(0, right - left),
|
|
3195
|
+
height: Math.max(0, bottom - top)
|
|
3139
3196
|
};
|
|
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
|
-
|
|
3197
|
+
}
|
|
3198
|
+
function createTrack(axis) {
|
|
3199
|
+
const track = document.createElement("div");
|
|
3200
|
+
const thumb = document.createElement("div");
|
|
3201
|
+
track.className = `sia-scrollbar-track sia-floating-scrollbar sia-floating-scrollbar--${axis}`;
|
|
3202
|
+
thumb.className = "sia-floating-scrollbar__thumb";
|
|
3203
|
+
track.dataset.axis = axis;
|
|
3204
|
+
track.setAttribute("aria-hidden", "true");
|
|
3205
|
+
track.append(thumb);
|
|
3206
|
+
return { track, thumb };
|
|
3207
|
+
}
|
|
3208
|
+
function FloatingScrollbarProvider({ disabled = false, targetRef }) {
|
|
3209
|
+
useScrollbarProximity();
|
|
3210
|
+
(0, import_react20.useEffect)(() => {
|
|
3211
|
+
if (disabled) return;
|
|
3212
|
+
const layer = document.createElement("div");
|
|
3213
|
+
layer.className = "sia-floating-scrollbar-layer";
|
|
3214
|
+
layer.setAttribute("aria-hidden", "true");
|
|
3215
|
+
document.body.append(layer);
|
|
3216
|
+
const entries = /* @__PURE__ */ new Map();
|
|
3217
|
+
let scanFrame = 0;
|
|
3218
|
+
let updateFrame = 0;
|
|
3219
|
+
const setEntryVisible = (entry, visible) => {
|
|
3220
|
+
entry.horizontalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
3221
|
+
entry.verticalTrack.classList.toggle("sia-floating-scrollbar--visible", visible);
|
|
3222
|
+
};
|
|
3223
|
+
const showEntry = (entry) => {
|
|
3224
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
3225
|
+
entry.hideTimer = null;
|
|
3226
|
+
setEntryVisible(entry, true);
|
|
3227
|
+
};
|
|
3228
|
+
const scheduleHide = (entry, delay = 500) => {
|
|
3229
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
3230
|
+
entry.hideTimer = window.setTimeout(() => {
|
|
3231
|
+
entry.hideTimer = null;
|
|
3232
|
+
if (!entry.hoveringTarget && !entry.hoveringTrack && !entry.dragging) setEntryVisible(entry, false);
|
|
3233
|
+
}, delay);
|
|
3234
|
+
};
|
|
3235
|
+
const updateEntry = (entry) => {
|
|
3236
|
+
const { target, horizontalTrack, horizontalThumb, verticalTrack, verticalThumb } = entry;
|
|
3237
|
+
const hasHorizontal = canScroll(target, "horizontal");
|
|
3238
|
+
const hasVertical = canScroll(target, "vertical");
|
|
3239
|
+
const rect = visibleRect(target);
|
|
3240
|
+
const thickness = 10;
|
|
3241
|
+
horizontalTrack.hidden = !hasHorizontal || rect.width <= thickness || rect.height <= 0;
|
|
3242
|
+
verticalTrack.hidden = !hasVertical || rect.height <= thickness || rect.width <= 0;
|
|
3243
|
+
if (!horizontalTrack.hidden) {
|
|
3244
|
+
const trackWidth = Math.max(0, rect.width - (hasVertical ? thickness : 0));
|
|
3245
|
+
const thumbWidth = Math.max(24, Math.min(trackWidth, trackWidth * target.clientWidth / target.scrollWidth));
|
|
3246
|
+
const travel = Math.max(0, trackWidth - thumbWidth);
|
|
3247
|
+
const maxScroll = Math.max(1, target.scrollWidth - target.clientWidth);
|
|
3248
|
+
horizontalTrack.style.left = `${rect.left}px`;
|
|
3249
|
+
horizontalTrack.style.top = `${rect.bottom - thickness}px`;
|
|
3250
|
+
horizontalTrack.style.width = `${trackWidth}px`;
|
|
3251
|
+
horizontalTrack.style.height = `${thickness}px`;
|
|
3252
|
+
horizontalThumb.style.width = `${thumbWidth}px`;
|
|
3253
|
+
horizontalThumb.style.transform = `translate3d(${travel * target.scrollLeft / maxScroll}px, 0, 0)`;
|
|
3254
|
+
}
|
|
3255
|
+
if (!verticalTrack.hidden) {
|
|
3256
|
+
const trackHeight = Math.max(0, rect.height - (hasHorizontal ? thickness : 0));
|
|
3257
|
+
const thumbHeight = Math.max(24, Math.min(trackHeight, trackHeight * target.clientHeight / target.scrollHeight));
|
|
3258
|
+
const travel = Math.max(0, trackHeight - thumbHeight);
|
|
3259
|
+
const maxScroll = Math.max(1, target.scrollHeight - target.clientHeight);
|
|
3260
|
+
verticalTrack.style.left = `${rect.right - thickness}px`;
|
|
3261
|
+
verticalTrack.style.top = `${rect.top}px`;
|
|
3262
|
+
verticalTrack.style.width = `${thickness}px`;
|
|
3263
|
+
verticalTrack.style.height = `${trackHeight}px`;
|
|
3264
|
+
verticalThumb.style.height = `${thumbHeight}px`;
|
|
3265
|
+
verticalThumb.style.transform = `translate3d(0, ${travel * target.scrollTop / maxScroll}px, 0)`;
|
|
3266
|
+
}
|
|
3267
|
+
};
|
|
3268
|
+
const scheduleUpdateAll = () => {
|
|
3269
|
+
if (updateFrame) return;
|
|
3270
|
+
updateFrame = window.requestAnimationFrame(() => {
|
|
3271
|
+
updateFrame = 0;
|
|
3272
|
+
entries.forEach(updateEntry);
|
|
3273
|
+
});
|
|
3274
|
+
};
|
|
3275
|
+
const bindTrackDrag = (entry, axis, track, thumb) => {
|
|
3276
|
+
const target = entry.target;
|
|
3277
|
+
const onTrackPointerEnter = () => {
|
|
3278
|
+
entry.hoveringTrack = true;
|
|
3279
|
+
showEntry(entry);
|
|
3280
|
+
};
|
|
3281
|
+
const onTrackPointerLeave = () => {
|
|
3282
|
+
entry.hoveringTrack = false;
|
|
3283
|
+
scheduleHide(entry);
|
|
3284
|
+
};
|
|
3285
|
+
const onTrackPointerDown = (event) => {
|
|
3286
|
+
if (event.target === thumb || event.button !== 0) return;
|
|
3287
|
+
event.preventDefault();
|
|
3288
|
+
event.stopPropagation();
|
|
3289
|
+
const trackRect = track.getBoundingClientRect();
|
|
3290
|
+
const thumbRect = thumb.getBoundingClientRect();
|
|
3291
|
+
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
3292
|
+
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
3293
|
+
const pointer = axis === "vertical" ? event.clientY - trackRect.top : event.clientX - trackRect.left;
|
|
3294
|
+
const ratio = Math.max(0, Math.min(1, (pointer - thumbLength / 2) / Math.max(1, trackLength - thumbLength)));
|
|
3295
|
+
if (axis === "vertical") target.scrollTop = ratio * (target.scrollHeight - target.clientHeight);
|
|
3296
|
+
else target.scrollLeft = ratio * (target.scrollWidth - target.clientWidth);
|
|
3297
|
+
};
|
|
3298
|
+
const onThumbPointerDown = (event) => {
|
|
3299
|
+
if (event.button !== 0) return;
|
|
3300
|
+
event.preventDefault();
|
|
3301
|
+
event.stopPropagation();
|
|
3302
|
+
entry.dragging = true;
|
|
3303
|
+
showEntry(entry);
|
|
3304
|
+
thumb.setPointerCapture(event.pointerId);
|
|
3305
|
+
const startPointer = axis === "vertical" ? event.clientY : event.clientX;
|
|
3306
|
+
const startScroll = axis === "vertical" ? target.scrollTop : target.scrollLeft;
|
|
3307
|
+
const trackRect = track.getBoundingClientRect();
|
|
3308
|
+
const thumbRect = thumb.getBoundingClientRect();
|
|
3309
|
+
const trackLength = axis === "vertical" ? trackRect.height : trackRect.width;
|
|
3310
|
+
const thumbLength = axis === "vertical" ? thumbRect.height : thumbRect.width;
|
|
3311
|
+
const maxScroll = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
|
|
3312
|
+
const travel = Math.max(1, trackLength - thumbLength);
|
|
3313
|
+
const onPointerMove = (moveEvent) => {
|
|
3314
|
+
if (moveEvent.pointerId !== event.pointerId) return;
|
|
3315
|
+
const pointer = axis === "vertical" ? moveEvent.clientY : moveEvent.clientX;
|
|
3316
|
+
const nextScroll = startScroll + (pointer - startPointer) * maxScroll / travel;
|
|
3317
|
+
if (axis === "vertical") target.scrollTop = nextScroll;
|
|
3318
|
+
else target.scrollLeft = nextScroll;
|
|
3319
|
+
};
|
|
3320
|
+
const onPointerUp = (upEvent) => {
|
|
3321
|
+
if (upEvent.pointerId !== event.pointerId) return;
|
|
3322
|
+
entry.dragging = false;
|
|
3323
|
+
thumb.releasePointerCapture(event.pointerId);
|
|
3324
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
3325
|
+
window.removeEventListener("pointerup", onPointerUp);
|
|
3326
|
+
window.removeEventListener("pointercancel", onPointerUp);
|
|
3327
|
+
scheduleHide(entry);
|
|
3328
|
+
};
|
|
3329
|
+
window.addEventListener("pointermove", onPointerMove);
|
|
3330
|
+
window.addEventListener("pointerup", onPointerUp);
|
|
3331
|
+
window.addEventListener("pointercancel", onPointerUp);
|
|
3332
|
+
};
|
|
3333
|
+
track.addEventListener("pointerenter", onTrackPointerEnter);
|
|
3334
|
+
track.addEventListener("pointerleave", onTrackPointerLeave);
|
|
3335
|
+
track.addEventListener("pointerdown", onTrackPointerDown);
|
|
3336
|
+
thumb.addEventListener("pointerdown", onThumbPointerDown);
|
|
3337
|
+
return () => {
|
|
3338
|
+
track.removeEventListener("pointerenter", onTrackPointerEnter);
|
|
3339
|
+
track.removeEventListener("pointerleave", onTrackPointerLeave);
|
|
3340
|
+
track.removeEventListener("pointerdown", onTrackPointerDown);
|
|
3341
|
+
thumb.removeEventListener("pointerdown", onThumbPointerDown);
|
|
3342
|
+
};
|
|
3343
|
+
};
|
|
3344
|
+
const resizeObserver = new ResizeObserver((observedEntries) => {
|
|
3345
|
+
observedEntries.forEach(({ target }) => {
|
|
3346
|
+
const entry = entries.get(target);
|
|
3347
|
+
if (entry) updateEntry(entry);
|
|
3348
|
+
});
|
|
3349
|
+
});
|
|
3350
|
+
const addTarget = (target) => {
|
|
3351
|
+
if (entries.has(target)) return;
|
|
3352
|
+
const horizontal = createTrack("horizontal");
|
|
3353
|
+
const vertical = createTrack("vertical");
|
|
3354
|
+
layer.append(horizontal.track, vertical.track);
|
|
3355
|
+
const onPointerEnter = () => {
|
|
3356
|
+
const entry2 = entries.get(target);
|
|
3357
|
+
if (!entry2) return;
|
|
3358
|
+
entry2.hoveringTarget = true;
|
|
3359
|
+
showEntry(entry2);
|
|
3360
|
+
};
|
|
3361
|
+
const onPointerLeave = () => {
|
|
3362
|
+
const entry2 = entries.get(target);
|
|
3363
|
+
if (!entry2) return;
|
|
3364
|
+
entry2.hoveringTarget = false;
|
|
3365
|
+
scheduleHide(entry2);
|
|
3366
|
+
};
|
|
3367
|
+
const onScroll = () => {
|
|
3368
|
+
const entry2 = entries.get(target);
|
|
3369
|
+
if (!entry2) return;
|
|
3370
|
+
updateEntry(entry2);
|
|
3371
|
+
showEntry(entry2);
|
|
3372
|
+
scheduleHide(entry2, 700);
|
|
3373
|
+
};
|
|
3374
|
+
target.addEventListener("pointerenter", onPointerEnter);
|
|
3375
|
+
target.addEventListener("pointerleave", onPointerLeave);
|
|
3376
|
+
target.addEventListener("scroll", onScroll, { passive: true });
|
|
3377
|
+
const entry = {
|
|
3378
|
+
target,
|
|
3379
|
+
horizontalTrack: horizontal.track,
|
|
3380
|
+
horizontalThumb: horizontal.thumb,
|
|
3381
|
+
verticalTrack: vertical.track,
|
|
3382
|
+
verticalThumb: vertical.thumb,
|
|
3383
|
+
hideTimer: null,
|
|
3384
|
+
hoveringTarget: target.matches(":hover"),
|
|
3385
|
+
hoveringTrack: false,
|
|
3386
|
+
dragging: false,
|
|
3387
|
+
cleanup: () => void 0
|
|
3388
|
+
};
|
|
3389
|
+
const cleanupHorizontal = bindTrackDrag(entry, "horizontal", horizontal.track, horizontal.thumb);
|
|
3390
|
+
const cleanupVertical = bindTrackDrag(entry, "vertical", vertical.track, vertical.thumb);
|
|
3391
|
+
entry.cleanup = () => {
|
|
3392
|
+
if (entry.hideTimer !== null) window.clearTimeout(entry.hideTimer);
|
|
3393
|
+
cleanupHorizontal();
|
|
3394
|
+
cleanupVertical();
|
|
3395
|
+
target.removeEventListener("pointerenter", onPointerEnter);
|
|
3396
|
+
target.removeEventListener("pointerleave", onPointerLeave);
|
|
3397
|
+
target.removeEventListener("scroll", onScroll);
|
|
3398
|
+
resizeObserver.unobserve(target);
|
|
3399
|
+
target.removeAttribute("data-sia-floating-scrollbar");
|
|
3400
|
+
horizontal.track.remove();
|
|
3401
|
+
vertical.track.remove();
|
|
3402
|
+
};
|
|
3403
|
+
entries.set(target, entry);
|
|
3404
|
+
target.setAttribute("data-sia-floating-scrollbar", "");
|
|
3405
|
+
resizeObserver.observe(target);
|
|
3406
|
+
updateEntry(entry);
|
|
3407
|
+
if (entry.hoveringTarget) showEntry(entry);
|
|
3408
|
+
};
|
|
3409
|
+
const removeTarget = (target) => {
|
|
3410
|
+
const entry = entries.get(target);
|
|
3411
|
+
if (!entry) return;
|
|
3412
|
+
entry.cleanup();
|
|
3413
|
+
entries.delete(target);
|
|
3414
|
+
};
|
|
3415
|
+
const scanTargets = () => {
|
|
3416
|
+
scanFrame = 0;
|
|
3417
|
+
const candidates = (targetRef ? [targetRef.current] : [document.scrollingElement, ...document.querySelectorAll("*")]).filter((target) => target instanceof HTMLElement);
|
|
3418
|
+
const nextTargets = /* @__PURE__ */ new Set();
|
|
3419
|
+
candidates.forEach((target) => {
|
|
3420
|
+
if (canScroll(target, "horizontal") || canScroll(target, "vertical")) {
|
|
3421
|
+
nextTargets.add(target);
|
|
3422
|
+
if (entries.has(target) || !target.hasAttribute("data-sia-floating-scrollbar")) addTarget(target);
|
|
3179
3423
|
}
|
|
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
|
-
});
|
|
3424
|
+
});
|
|
3425
|
+
entries.forEach((_entry, target) => {
|
|
3426
|
+
if (!target.isConnected || !nextTargets.has(target)) removeTarget(target);
|
|
3427
|
+
else updateEntry(_entry);
|
|
3428
|
+
});
|
|
3429
|
+
};
|
|
3430
|
+
const scheduleScan = () => {
|
|
3431
|
+
if (scanFrame) return;
|
|
3432
|
+
scanFrame = window.requestAnimationFrame(scanTargets);
|
|
3433
|
+
};
|
|
3434
|
+
const mutationObserver = new MutationObserver((mutations) => {
|
|
3435
|
+
if (mutations.some((mutation) => !layer.contains(mutation.target))) scheduleScan();
|
|
3436
|
+
});
|
|
3437
|
+
mutationObserver.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
|
|
3438
|
+
window.addEventListener("resize", scheduleScan);
|
|
3439
|
+
window.addEventListener("scroll", scheduleUpdateAll, true);
|
|
3440
|
+
scheduleScan();
|
|
3441
|
+
return () => {
|
|
3442
|
+
mutationObserver.disconnect();
|
|
3443
|
+
resizeObserver.disconnect();
|
|
3444
|
+
window.removeEventListener("resize", scheduleScan);
|
|
3445
|
+
window.removeEventListener("scroll", scheduleUpdateAll, true);
|
|
3446
|
+
if (scanFrame) window.cancelAnimationFrame(scanFrame);
|
|
3447
|
+
if (updateFrame) window.cancelAnimationFrame(updateFrame);
|
|
3448
|
+
entries.forEach((entry) => entry.cleanup());
|
|
3449
|
+
entries.clear();
|
|
3450
|
+
layer.remove();
|
|
3451
|
+
};
|
|
3452
|
+
}, [disabled, targetRef]);
|
|
3453
|
+
return null;
|
|
3238
3454
|
}
|
|
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
3455
|
|
|
3362
3456
|
// src/components/SelectionPanel.tsx
|
|
3363
|
-
var import_react20 = require("react");
|
|
3364
3457
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3365
3458
|
function SelectionPanel({
|
|
3366
3459
|
options,
|
|
@@ -3382,26 +3475,26 @@ function SelectionPanel({
|
|
|
3382
3475
|
maxHeight = 250,
|
|
3383
3476
|
autoFocusSearch = false
|
|
3384
3477
|
}) {
|
|
3385
|
-
const [localSearch, setLocalSearch] = (0,
|
|
3478
|
+
const [localSearch, setLocalSearch] = (0, import_react21.useState)("");
|
|
3386
3479
|
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,
|
|
3480
|
+
const [scrollTop, setScrollTop] = (0, import_react21.useState)(0);
|
|
3481
|
+
const [active, setActive] = (0, import_react21.useState)();
|
|
3482
|
+
const [keyboardActive, setKeyboardActive] = (0, import_react21.useState)(false);
|
|
3483
|
+
const [deselectedHover, setDeselectedHover] = (0, import_react21.useState)();
|
|
3484
|
+
const listRef = (0, import_react21.useRef)(null);
|
|
3485
|
+
const id = (0, import_react21.useId)();
|
|
3486
|
+
const selected = (0, import_react21.useMemo)(() => new Set(value), [value]);
|
|
3394
3487
|
const count = Math.max(1, Math.floor(columns));
|
|
3395
|
-
const allOptions = (0,
|
|
3488
|
+
const allOptions = (0, import_react21.useMemo)(() => {
|
|
3396
3489
|
if (!includeUnknownValues) return [...options];
|
|
3397
3490
|
const known = new Set(options.filter((option) => option.optionType !== "divider").map((option) => option.value));
|
|
3398
3491
|
return [...value.filter((item) => !known.has(item)).map((item) => ({ value: item, label: String(item), group: "\u81EA\u5B9A\u4E49\u503C" })), ...options];
|
|
3399
3492
|
}, [options, value, includeUnknownValues]);
|
|
3400
|
-
const filtered = (0,
|
|
3493
|
+
const filtered = (0, import_react21.useMemo)(
|
|
3401
3494
|
() => 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
3495
|
[allOptions, selectedOnly, selected, search]
|
|
3403
3496
|
);
|
|
3404
|
-
const rows = (0,
|
|
3497
|
+
const rows = (0, import_react21.useMemo)(() => {
|
|
3405
3498
|
const groups = /* @__PURE__ */ new Map();
|
|
3406
3499
|
filtered.forEach((option) => {
|
|
3407
3500
|
const items = groups.get(option.group) ?? [];
|
|
@@ -3427,7 +3520,7 @@ function SelectionPanel({
|
|
|
3427
3520
|
const virtual = filtered.length > 100;
|
|
3428
3521
|
const renderedRows = virtual ? rows.filter((row) => row.top + row.height >= scrollTop - 100 && row.top <= scrollTop + maxHeight + 100) : rows;
|
|
3429
3522
|
const enabled = filtered.filter((option) => !option.disabled && option.optionType !== "divider");
|
|
3430
|
-
(0,
|
|
3523
|
+
(0, import_react21.useEffect)(() => {
|
|
3431
3524
|
setScrollTop(0);
|
|
3432
3525
|
if (listRef.current) listRef.current.scrollTop = 0;
|
|
3433
3526
|
setActive(void 0);
|
|
@@ -3552,14 +3645,14 @@ function SelectionPanel({
|
|
|
3552
3645
|
}
|
|
3553
3646
|
|
|
3554
3647
|
// src/components/OverflowTags.tsx
|
|
3555
|
-
var
|
|
3648
|
+
var import_react22 = require("react");
|
|
3556
3649
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3557
3650
|
function OverflowTags({ items, maxCount: maxCount2, className = "", tagClassName, restClassName = "" }) {
|
|
3558
|
-
const rootRef = (0,
|
|
3559
|
-
const measureRef = (0,
|
|
3651
|
+
const rootRef = (0, import_react22.useRef)(null);
|
|
3652
|
+
const measureRef = (0, import_react22.useRef)(null);
|
|
3560
3653
|
const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount2) || 0));
|
|
3561
|
-
const [visibleCount, setVisibleCount] = (0,
|
|
3562
|
-
(0,
|
|
3654
|
+
const [visibleCount, setVisibleCount] = (0, import_react22.useState)(0);
|
|
3655
|
+
(0, import_react22.useLayoutEffect)(() => {
|
|
3563
3656
|
const root = rootRef.current;
|
|
3564
3657
|
const measure = measureRef.current;
|
|
3565
3658
|
if (!root || !measure) return;
|
|
@@ -3604,7 +3697,7 @@ function defaultFilterOption(query, option) {
|
|
|
3604
3697
|
const keyword = query.toLowerCase();
|
|
3605
3698
|
return [option.label, option.value].some((value) => String(value).toLowerCase().includes(keyword));
|
|
3606
3699
|
}
|
|
3607
|
-
var Select = (0,
|
|
3700
|
+
var Select = (0, import_react23.forwardRef)(function Select2({
|
|
3608
3701
|
options,
|
|
3609
3702
|
mode = "single",
|
|
3610
3703
|
popupMode: popupModeProp,
|
|
@@ -3642,27 +3735,27 @@ var Select = (0, import_react22.forwardRef)(function Select2({
|
|
|
3642
3735
|
...props
|
|
3643
3736
|
}, forwardedRef) {
|
|
3644
3737
|
const size = useControlSize(sizeProp);
|
|
3645
|
-
const fallbackId = (0,
|
|
3738
|
+
const fallbackId = (0, import_react23.useId)();
|
|
3646
3739
|
const selectId = id ?? fallbackId;
|
|
3647
3740
|
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,
|
|
3741
|
+
const rootRef = (0, import_react23.useRef)(null);
|
|
3742
|
+
const popupRef = (0, import_react23.useRef)(null);
|
|
3743
|
+
const searchRef = (0, import_react23.useRef)(null);
|
|
3744
|
+
const listRef = (0, import_react23.useRef)(null);
|
|
3745
|
+
const [open, setOpen] = (0, import_react23.useState)(false);
|
|
3653
3746
|
const automaticMode = popupModeProp ?? (options.length > modalThreshold ? "modal" : "dropdown");
|
|
3654
|
-
const [openedMode, setOpenedMode] = (0,
|
|
3747
|
+
const [openedMode, setOpenedMode] = (0, import_react23.useState)(automaticMode);
|
|
3655
3748
|
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,
|
|
3749
|
+
const [modalValues, setModalValues] = (0, import_react23.useState)([]);
|
|
3750
|
+
const [modalSubmitting, setModalSubmitting] = (0, import_react23.useState)(false);
|
|
3751
|
+
const modalSubmitLock = (0, import_react23.useRef)(false);
|
|
3752
|
+
const [selectedOnly, setSelectedOnly] = (0, import_react23.useState)(false);
|
|
3753
|
+
const [query, setQuery] = (0, import_react23.useState)("");
|
|
3754
|
+
const [activeIndex, setActiveIndex] = (0, import_react23.useState)(-1);
|
|
3755
|
+
const [scrollTop, setScrollTop] = (0, import_react23.useState)(0);
|
|
3756
|
+
const [dropdownFontSize, setDropdownFontSize] = (0, import_react23.useState)();
|
|
3757
|
+
const pendingSelectedScroll = (0, import_react23.useRef)(false);
|
|
3758
|
+
const deferredQuery = (0, import_react23.useDeferredValue)(query.trim());
|
|
3666
3759
|
const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
|
|
3667
3760
|
const [currentValue, setCurrentValue] = useControllableState({
|
|
3668
3761
|
value,
|
|
@@ -3677,20 +3770,20 @@ var Select = (0, import_react22.forwardRef)(function Select2({
|
|
|
3677
3770
|
}
|
|
3678
3771
|
}
|
|
3679
3772
|
});
|
|
3680
|
-
const selectedValues = (0,
|
|
3773
|
+
const selectedValues = (0, import_react23.useMemo)(() => {
|
|
3681
3774
|
if (currentValue == null || currentValue === "" && !options.some((option) => option.value === "")) return [];
|
|
3682
3775
|
if (mode === "multiple") return Array.isArray(currentValue) ? currentValue : currentValue === null ? [] : [currentValue];
|
|
3683
3776
|
return Array.isArray(currentValue) ? currentValue.slice(0, 1) : currentValue === null ? [] : [currentValue];
|
|
3684
3777
|
}, [currentValue, mode, options]);
|
|
3685
|
-
const selectedValueSet = (0,
|
|
3686
|
-
const availableOptions = (0,
|
|
3778
|
+
const selectedValueSet = (0, import_react23.useMemo)(() => new Set(selectedValues), [selectedValues]);
|
|
3779
|
+
const availableOptions = (0, import_react23.useMemo)(() => {
|
|
3687
3780
|
if (!allowInput) return options;
|
|
3688
3781
|
const optionValueSet = new Set(options.map((option) => option.value));
|
|
3689
3782
|
const selectedCustomOptions = selectedValues.filter((selectedValue) => !optionValueSet.has(selectedValue)).map((selectedValue) => ({ label: String(selectedValue), value: selectedValue }));
|
|
3690
3783
|
return selectedCustomOptions.length ? [...selectedCustomOptions, ...options] : options;
|
|
3691
3784
|
}, [allowInput, options, selectedValues]);
|
|
3692
|
-
const selectedOptions = (0,
|
|
3693
|
-
const filteredOptions = (0,
|
|
3785
|
+
const selectedOptions = (0, import_react23.useMemo)(() => selectedValues.map((selectedValue) => availableOptions.find((option) => option.value === selectedValue)).filter((option) => option !== void 0), [availableOptions, selectedValues]);
|
|
3786
|
+
const filteredOptions = (0, import_react23.useMemo)(() => deferredQuery ? availableOptions.filter((option) => filterOption(deferredQuery, option)) : availableOptions, [availableOptions, deferredQuery, filterOption]);
|
|
3694
3787
|
const inputValue = query.trim();
|
|
3695
3788
|
const exactInputOption = inputValue ? availableOptions.find((option) => String(option.value).toLowerCase() === inputValue.toLowerCase() || typeof option.label === "string" && option.label.toLowerCase() === inputValue.toLowerCase()) : void 0;
|
|
3696
3789
|
const canSubmitInput = allowInput && Boolean(inputValue) && !exactInputOption;
|
|
@@ -3704,7 +3797,7 @@ var Select = (0, import_react22.forwardRef)(function Select2({
|
|
|
3704
3797
|
const renderedOptions = virtualEnabled ? filteredOptions.slice(virtualStart, virtualEnd) : filteredOptions;
|
|
3705
3798
|
const enabledFilteredOptions = filteredOptions.filter((option) => !option.disabled);
|
|
3706
3799
|
const allFilteredSelected = enabledFilteredOptions.length > 0 && enabledFilteredOptions.every((option) => selectedValueSet.has(option.value));
|
|
3707
|
-
(0,
|
|
3800
|
+
(0, import_react23.useEffect)(() => {
|
|
3708
3801
|
if (!open || popupMode === "modal") return void 0;
|
|
3709
3802
|
function closeFromOutside(event) {
|
|
3710
3803
|
const target = event.target;
|
|
@@ -3713,13 +3806,13 @@ var Select = (0, import_react22.forwardRef)(function Select2({
|
|
|
3713
3806
|
document.addEventListener("mousedown", closeFromOutside);
|
|
3714
3807
|
return () => document.removeEventListener("mousedown", closeFromOutside);
|
|
3715
3808
|
}, [open, popupMode]);
|
|
3716
|
-
(0,
|
|
3809
|
+
(0, import_react23.useEffect)(() => {
|
|
3717
3810
|
if (open && (showSearch || allowInput)) searchRef.current?.focus();
|
|
3718
3811
|
}, [allowInput, open, showSearch]);
|
|
3719
|
-
(0,
|
|
3812
|
+
(0, import_react23.useEffect)(() => {
|
|
3720
3813
|
if (disabled || loading) closeDropdown();
|
|
3721
3814
|
}, [disabled, loading]);
|
|
3722
|
-
(0,
|
|
3815
|
+
(0, import_react23.useEffect)(() => {
|
|
3723
3816
|
if (!open || popupMode !== "dropdown" || !pendingSelectedScroll.current || query) return;
|
|
3724
3817
|
const index = filteredOptions.findIndex((option) => selectedValueSet.has(option.value));
|
|
3725
3818
|
if (index < 0) return;
|
|
@@ -3734,7 +3827,7 @@ var Select = (0, import_react22.forwardRef)(function Select2({
|
|
|
3734
3827
|
});
|
|
3735
3828
|
return () => cancelAnimationFrame(frame);
|
|
3736
3829
|
}, [open, popupMode, filteredOptions, selectedValueSet, virtualEnabled, optionHeight, query]);
|
|
3737
|
-
(0,
|
|
3830
|
+
(0, import_react23.useLayoutEffect)(() => {
|
|
3738
3831
|
if (!open || popupMode !== "dropdown") return;
|
|
3739
3832
|
const trigger = rootRef.current?.querySelector(".sia-select__trigger");
|
|
3740
3833
|
if (trigger) setDropdownFontSize(getComputedStyle(trigger).fontSize);
|
|
@@ -4075,7 +4168,7 @@ var Select = (0, import_react22.forwardRef)(function Select2({
|
|
|
4075
4168
|
});
|
|
4076
4169
|
|
|
4077
4170
|
// src/components/Upload.tsx
|
|
4078
|
-
var
|
|
4171
|
+
var import_react24 = require("react");
|
|
4079
4172
|
|
|
4080
4173
|
// src/components/uploadFiles.ts
|
|
4081
4174
|
function acceptsUploadFile(file, accept) {
|
|
@@ -4314,8 +4407,8 @@ var message = {
|
|
|
4314
4407
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4315
4408
|
var LIST_IGNORE = /* @__PURE__ */ Symbol("SIA_UPLOAD_LIST_IGNORE");
|
|
4316
4409
|
function useThumbnail(file, accept) {
|
|
4317
|
-
const [local, setLocal] = (0,
|
|
4318
|
-
(0,
|
|
4410
|
+
const [local, setLocal] = (0, import_react24.useState)();
|
|
4411
|
+
(0, import_react24.useEffect)(() => {
|
|
4319
4412
|
if (!file?.thumbUrl && file?.originFileObj?.type.startsWith("image/")) {
|
|
4320
4413
|
const url = URL.createObjectURL(file.originFileObj);
|
|
4321
4414
|
setLocal(url);
|
|
@@ -4327,9 +4420,9 @@ function useThumbnail(file, accept) {
|
|
|
4327
4420
|
}
|
|
4328
4421
|
function UploadItem({ file, files, props, actions }) {
|
|
4329
4422
|
const source = useThumbnail(file, props.accept);
|
|
4330
|
-
const [failed, setFailed] = (0,
|
|
4331
|
-
const [downloading, setDownloading] = (0,
|
|
4332
|
-
const downloadingRef = (0,
|
|
4423
|
+
const [failed, setFailed] = (0, import_react24.useState)(false);
|
|
4424
|
+
const [downloading, setDownloading] = (0, import_react24.useState)(false);
|
|
4425
|
+
const downloadingRef = (0, import_react24.useRef)(false);
|
|
4333
4426
|
const canPreview = !!(source || file.url || file.originFileObj || props.onPreview);
|
|
4334
4427
|
const canDownload = !!(file.url || file.originFileObj || props.downloadRequest);
|
|
4335
4428
|
async function download() {
|
|
@@ -4345,7 +4438,7 @@ function UploadItem({ file, files, props, actions }) {
|
|
|
4345
4438
|
setDownloading(false);
|
|
4346
4439
|
}
|
|
4347
4440
|
}
|
|
4348
|
-
(0,
|
|
4441
|
+
(0, import_react24.useEffect)(() => setFailed(false), [source]);
|
|
4349
4442
|
const node = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `sia-upload__item sia-upload__item--${file.status ?? "ready"}`, children: [
|
|
4350
4443
|
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
4444
|
/* @__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 +4459,7 @@ function UploadItem({ file, files, props, actions }) {
|
|
|
4366
4459
|
] });
|
|
4367
4460
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: props.itemRender ? props.itemRender(node, file, files, actions) : node });
|
|
4368
4461
|
}
|
|
4369
|
-
var UploadRoot = (0,
|
|
4462
|
+
var UploadRoot = (0, import_react24.forwardRef)(function UploadRoot2({
|
|
4370
4463
|
accept,
|
|
4371
4464
|
multiple = false,
|
|
4372
4465
|
directory = false,
|
|
@@ -4404,19 +4497,19 @@ var UploadRoot = (0, import_react23.forwardRef)(function UploadRoot2({
|
|
|
4404
4497
|
const cardWidth = cardDimension(typeof cardSize === "number" ? cardSize : cardSize?.width);
|
|
4405
4498
|
const cardHeight = cardDimension(typeof cardSize === "number" ? cardSize : cardSize?.height);
|
|
4406
4499
|
const compactCard = listType === "picture-card" && (cardWidth < 88 || cardHeight < 88);
|
|
4407
|
-
const inputRef = (0,
|
|
4408
|
-
const [internalFiles, setInternalFiles] = (0,
|
|
4500
|
+
const inputRef = (0, import_react24.useRef)(null);
|
|
4501
|
+
const [internalFiles, setInternalFiles] = (0, import_react24.useState)(defaultFileList);
|
|
4409
4502
|
const files = fileList ?? internalFiles;
|
|
4410
|
-
const filesRef = (0,
|
|
4503
|
+
const filesRef = (0, import_react24.useRef)(files);
|
|
4411
4504
|
filesRef.current = files;
|
|
4412
|
-
const tasks = (0,
|
|
4413
|
-
const mounted = (0,
|
|
4414
|
-
const [dragging, setDragging] = (0,
|
|
4415
|
-
const [preview, setPreview] = (0,
|
|
4505
|
+
const tasks = (0, import_react24.useRef)(/* @__PURE__ */ new Map());
|
|
4506
|
+
const mounted = (0, import_react24.useRef)(true);
|
|
4507
|
+
const [dragging, setDragging] = (0, import_react24.useState)(false);
|
|
4508
|
+
const [preview, setPreview] = (0, import_react24.useState)();
|
|
4416
4509
|
const previewSource = useThumbnail(preview, accept);
|
|
4417
4510
|
const limit = maxCount2 === void 0 || !Number.isFinite(maxCount2) ? Infinity : Math.max(0, Math.floor(maxCount2));
|
|
4418
4511
|
const full = files.length >= limit;
|
|
4419
|
-
const current = (0,
|
|
4512
|
+
const current = (0, import_react24.useRef)({ disabled, directory, recursive });
|
|
4420
4513
|
current.current = { disabled, directory, recursive };
|
|
4421
4514
|
function cancel(uid) {
|
|
4422
4515
|
const task = tasks.current.get(uid);
|
|
@@ -4428,14 +4521,14 @@ var UploadRoot = (0, import_react23.forwardRef)(function UploadRoot2({
|
|
|
4428
4521
|
}
|
|
4429
4522
|
task?.finish();
|
|
4430
4523
|
}
|
|
4431
|
-
(0,
|
|
4524
|
+
(0, import_react24.useEffect)(() => {
|
|
4432
4525
|
mounted.current = true;
|
|
4433
4526
|
return () => {
|
|
4434
4527
|
mounted.current = false;
|
|
4435
4528
|
[...tasks.current.keys()].forEach(cancel);
|
|
4436
4529
|
};
|
|
4437
4530
|
}, []);
|
|
4438
|
-
(0,
|
|
4531
|
+
(0, import_react24.useEffect)(() => {
|
|
4439
4532
|
for (const uid of tasks.current.keys()) if (!files.some((file) => file.uid === uid)) cancel(uid);
|
|
4440
4533
|
if (preview && !files.some((file) => file.uid === preview.uid)) setPreview(void 0);
|
|
4441
4534
|
}, [files, preview]);
|
|
@@ -4541,7 +4634,7 @@ var UploadRoot = (0, import_react23.forwardRef)(function UploadRoot2({
|
|
|
4541
4634
|
} catch {
|
|
4542
4635
|
}
|
|
4543
4636
|
}
|
|
4544
|
-
(0,
|
|
4637
|
+
(0, import_react24.useImperativeHandle)(ref, () => ({
|
|
4545
4638
|
upload: async (uid) => {
|
|
4546
4639
|
await Promise.all(filesRef.current.filter((file) => (!uid || file.uid === uid) && file.status !== "done").map(start));
|
|
4547
4640
|
},
|
|
@@ -4663,7 +4756,7 @@ var UploadRoot = (0, import_react23.forwardRef)(function UploadRoot2({
|
|
|
4663
4756
|
}
|
|
4664
4757
|
);
|
|
4665
4758
|
});
|
|
4666
|
-
var UploadDragger = (0,
|
|
4759
|
+
var UploadDragger = (0, import_react24.forwardRef)(function UploadDragger2({ hint = "\u652F\u6301\u5355\u4E2A\u6216\u6279\u91CF\u4E0A\u4F20", children, className = "", ...props }, ref) {
|
|
4667
4760
|
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
4761
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { name: "upload", size: 32 }),
|
|
4669
4762
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("strong", { children: [
|
|
@@ -4704,12 +4797,12 @@ function Breadcrumb({ items, separator = "/", itemRender, className = "", ...pro
|
|
|
4704
4797
|
}
|
|
4705
4798
|
|
|
4706
4799
|
// src/components/Typography.tsx
|
|
4707
|
-
var
|
|
4800
|
+
var import_react26 = require("react");
|
|
4708
4801
|
|
|
4709
4802
|
// src/components/TextArea.tsx
|
|
4710
|
-
var
|
|
4803
|
+
var import_react25 = require("react");
|
|
4711
4804
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4712
|
-
var TextArea = (0,
|
|
4805
|
+
var TextArea = (0, import_react25.forwardRef)(function TextArea2({
|
|
4713
4806
|
label,
|
|
4714
4807
|
hint,
|
|
4715
4808
|
status = "default",
|
|
@@ -4727,9 +4820,9 @@ var TextArea = (0, import_react24.forwardRef)(function TextArea2({
|
|
|
4727
4820
|
...props
|
|
4728
4821
|
}, ref) {
|
|
4729
4822
|
const size = useControlSize(sizeProp);
|
|
4730
|
-
const fallbackId = (0,
|
|
4823
|
+
const fallbackId = (0, import_react25.useId)();
|
|
4731
4824
|
const textAreaId = id ?? fallbackId;
|
|
4732
|
-
const [uncontrolledValue, setUncontrolledValue] = (0,
|
|
4825
|
+
const [uncontrolledValue, setUncontrolledValue] = (0, import_react25.useState)(() => defaultValue === void 0 ? "" : String(defaultValue));
|
|
4733
4826
|
const currentText = value !== void 0 ? String(value) : uncontrolledValue;
|
|
4734
4827
|
const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: currentText.length > 0 });
|
|
4735
4828
|
const hintId = `${textAreaId}-hint`;
|
|
@@ -4790,26 +4883,26 @@ function TypographyContent({
|
|
|
4790
4883
|
className = "",
|
|
4791
4884
|
...props
|
|
4792
4885
|
}) {
|
|
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,
|
|
4886
|
+
const contentRef = (0, import_react26.useRef)(null);
|
|
4887
|
+
const editRef = (0, import_react26.useRef)(null);
|
|
4888
|
+
const timer = (0, import_react26.useRef)();
|
|
4889
|
+
const [localText, setLocalText] = (0, import_react26.useState)();
|
|
4890
|
+
const [draft, setDraft] = (0, import_react26.useState)("");
|
|
4891
|
+
const [editing, setEditing] = (0, import_react26.useState)(false);
|
|
4892
|
+
const [copied, setCopied] = (0, import_react26.useState)(false);
|
|
4893
|
+
const [copyError, setCopyError] = (0, import_react26.useState)(false);
|
|
4894
|
+
const [expanded, setExpanded] = (0, import_react26.useState)(false);
|
|
4895
|
+
const [overflow, setOverflow] = (0, import_react26.useState)(false);
|
|
4803
4896
|
const editConfig = typeof editable === "object" ? editable : void 0;
|
|
4804
4897
|
const content = editConfig?.text ?? localText ?? children;
|
|
4805
4898
|
const requestedRows = typeof ellipsis === "object" ? ellipsis.rows ?? 1 : 1;
|
|
4806
4899
|
const rows = Number.isFinite(requestedRows) ? Math.max(1, Math.floor(requestedRows)) : 1;
|
|
4807
4900
|
const expandable = typeof ellipsis === "object" && ellipsis.expandable;
|
|
4808
|
-
(0,
|
|
4901
|
+
(0, import_react26.useEffect)(() => {
|
|
4809
4902
|
setLocalText(void 0);
|
|
4810
4903
|
}, [children]);
|
|
4811
|
-
(0,
|
|
4812
|
-
(0,
|
|
4904
|
+
(0, import_react26.useEffect)(() => () => clearTimeout(timer.current), []);
|
|
4905
|
+
(0, import_react26.useLayoutEffect)(() => {
|
|
4813
4906
|
const element = contentRef.current;
|
|
4814
4907
|
if (!element || !ellipsis || editing || expanded) return;
|
|
4815
4908
|
const measure = () => setOverflow(element.scrollHeight > element.clientHeight + 1 || element.scrollWidth > element.clientWidth + 1);
|
|
@@ -4927,10 +5020,10 @@ var Typography = Object.assign(TypographyRoot, {
|
|
|
4927
5020
|
});
|
|
4928
5021
|
|
|
4929
5022
|
// src/components/FloatButton.tsx
|
|
4930
|
-
var
|
|
5023
|
+
var import_react27 = require("react");
|
|
4931
5024
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
4932
|
-
var GroupShape = (0,
|
|
4933
|
-
var FloatButtonRoot = (0,
|
|
5025
|
+
var GroupShape = (0, import_react27.createContext)(void 0);
|
|
5026
|
+
var FloatButtonRoot = (0, import_react27.forwardRef)(function FloatButton({
|
|
4934
5027
|
icon,
|
|
4935
5028
|
description,
|
|
4936
5029
|
tooltip,
|
|
@@ -4943,7 +5036,7 @@ var FloatButtonRoot = (0, import_react26.forwardRef)(function FloatButton({
|
|
|
4943
5036
|
children,
|
|
4944
5037
|
...props
|
|
4945
5038
|
}, ref) {
|
|
4946
|
-
const groupShape = (0,
|
|
5039
|
+
const groupShape = (0, import_react27.useContext)(GroupShape);
|
|
4947
5040
|
const label = props["aria-label"] ?? (typeof tooltip === "string" ? tooltip : typeof description === "string" ? description : "\u60AC\u6D6E\u64CD\u4F5C");
|
|
4948
5041
|
const button = /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4949
5042
|
"button",
|
|
@@ -4981,10 +5074,10 @@ function FloatButtonGroup({
|
|
|
4981
5074
|
...props
|
|
4982
5075
|
}) {
|
|
4983
5076
|
const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
|
|
4984
|
-
const rootRef = (0,
|
|
4985
|
-
const triggerRef = (0,
|
|
4986
|
-
const id = (0,
|
|
4987
|
-
(0,
|
|
5077
|
+
const rootRef = (0, import_react27.useRef)(null);
|
|
5078
|
+
const triggerRef = (0, import_react27.useRef)(null);
|
|
5079
|
+
const id = (0, import_react27.useId)();
|
|
5080
|
+
(0, import_react27.useEffect)(() => {
|
|
4988
5081
|
if (!trigger || !visible) return;
|
|
4989
5082
|
const close = (event) => {
|
|
4990
5083
|
if (!rootRef.current?.contains(event.target)) setVisible(false);
|
|
@@ -5038,8 +5131,8 @@ function FloatButtonGroup({
|
|
|
5038
5131
|
) });
|
|
5039
5132
|
}
|
|
5040
5133
|
function FloatButtonBackTop({ target, visibilityHeight = 400, behavior = "smooth", onClick, icon, tooltip = "\u8FD4\u56DE\u9876\u90E8", ...props }) {
|
|
5041
|
-
const [visible, setVisible] = (0,
|
|
5042
|
-
(0,
|
|
5134
|
+
const [visible, setVisible] = (0, import_react27.useState)(false);
|
|
5135
|
+
(0, import_react27.useEffect)(() => {
|
|
5043
5136
|
const element = target ? target() : window;
|
|
5044
5137
|
if (!element) return;
|
|
5045
5138
|
const update = () => setVisible((element === window ? window.scrollY : element.scrollTop) >= visibilityHeight);
|