@openspecui/web 2.3.4 → 2.3.5
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/assets/CanvasRenderer-DLCesp1A.js +1 -0
- package/dist/assets/WebGLRenderer-DYT9IbsA.js +1 -0
- package/dist/assets/WebGPURenderer-CYfC6MR9.js +1 -0
- package/dist/assets/browserAll-CmR4zgGr.js +1 -0
- package/dist/assets/{dist-CyMw4R35.js → dist-5fi0H1tv.js} +1 -1
- package/dist/assets/{dist-BURffNKn.js → dist-9w-ZAZ0x.js} +1 -1
- package/dist/assets/{dist-EecJWaiB.js → dist-AstaMS2N.js} +1 -1
- package/dist/assets/{dist-C4qVWCwa.js → dist-BY07yBep.js} +1 -1
- package/dist/assets/dist-BkrPETxD.js +1 -0
- package/dist/assets/dist-DABwUepA.js +1 -0
- package/dist/assets/{dist-0r-fEysT.js → dist-DDChZc3A.js} +1 -1
- package/dist/assets/{dist-C_hvHrdB.js → dist-DQMVt2X6.js} +1 -1
- package/dist/assets/{dist-Dw21sB44.js → dist-DTgAMGJk.js} +1 -1
- package/dist/assets/{dist-BkfyzqOP.js → dist-DtkkWh_t.js} +1 -1
- package/dist/assets/dist-hgHsmBgz.js +1 -0
- package/dist/assets/{dist-D5aqbpvI.js → dist-j40sCais.js} +1 -1
- package/dist/assets/{ghostty-web-Dz4JIhSO.js → ghostty-web-BRCaoYqS.js} +1 -1
- package/dist/assets/index-C0tlID-0.css +1 -0
- package/dist/assets/index-CUgehjti.js +1578 -0
- package/dist/assets/{init-B8PdfdJA.js → init-CIIgfU1P.js} +1 -1
- package/dist/assets/trpc-2zCd4YGO.js +1 -0
- package/dist/assets/webworkerAll-CwuSdyaU.js +1 -0
- package/dist/index.html +2 -2
- package/dist-ssg/client/.vite/ssr-manifest.json +15 -15
- package/dist-ssg/client/assets/CanvasRenderer-vRzYl9FZ.js +1 -0
- package/dist-ssg/client/assets/WebGLRenderer-BrfpRfdk.js +1 -0
- package/dist-ssg/client/assets/WebGPURenderer-r7TRWUkD.js +1 -0
- package/dist-ssg/client/assets/browserAll-D7igzN7y.js +1 -0
- package/dist-ssg/client/assets/{dist-Djq8HFE5.js → dist-BFqpuvkT.js} +1 -1
- package/dist-ssg/client/assets/{dist-D9LLad4O.js → dist-BNNep2NV.js} +1 -1
- package/dist-ssg/client/assets/{dist-BTUS8_Kw.js → dist-B_u-l1Yw.js} +1 -1
- package/dist-ssg/client/assets/{dist-DXnJ5xkX.js → dist-CRvuTuq9.js} +1 -1
- package/dist-ssg/client/assets/{dist-C77YNQqE.js → dist-CXGBVAg6.js} +1 -1
- package/dist-ssg/client/assets/{dist-DTnge_6G.js → dist-ClTBYSyP.js} +1 -1
- package/dist-ssg/client/assets/{dist-BARr54Cb.js → dist-CmH6Ad9e.js} +1 -1
- package/dist-ssg/client/assets/{dist-B7XHcG34.js → dist-DBjExBIn.js} +1 -1
- package/dist-ssg/client/assets/{dist-CXFa4KDE.js → dist-DKZbBcYn.js} +1 -1
- package/dist-ssg/client/assets/dist-Ky-fb63H.js +1 -0
- package/dist-ssg/client/assets/dist-tjvftgmy.js +1 -0
- package/dist-ssg/client/assets/dist-y9aZTMms.js +1 -0
- package/dist-ssg/client/assets/{ghostty-web-BUrM4LmE.js → ghostty-web-PY5w9Rgq.js} +1 -1
- package/dist-ssg/client/assets/index-DvpLdKST.css +2 -0
- package/dist-ssg/client/assets/{index.ssg-BU1Brmat.js → index.ssg-yS5IzoBe.js} +94 -104
- package/dist-ssg/client/assets/{init-C5vrHUuy.js → init-zJql3EoS.js} +1 -1
- package/dist-ssg/client/assets/trpc-Z2U-lHEj.js +1 -0
- package/dist-ssg/client/assets/webworkerAll-_OODBDte.js +1 -0
- package/dist-ssg/client/index.ssg.html +2 -2
- package/dist-ssg/server/entry-server.js +409 -107
- package/package.json +1 -1
- package/dist/assets/CanvasRenderer-yznXxqwr.js +0 -1
- package/dist/assets/WebGLRenderer-B23oVGNL.js +0 -1
- package/dist/assets/WebGPURenderer-Cug1nwkB.js +0 -1
- package/dist/assets/browserAll-u3VqlriV.js +0 -1
- package/dist/assets/dist-COUYL3BZ.js +0 -1
- package/dist/assets/dist-hmhW0TeA.js +0 -1
- package/dist/assets/dist-zq2gg3Qj.js +0 -1
- package/dist/assets/index-C5SoNGIA.css +0 -1
- package/dist/assets/index-CEpXtWXm.js +0 -1588
- package/dist/assets/trpc-BYEnVZ4c.js +0 -1
- package/dist/assets/webworkerAll-BiDEVq-n.js +0 -1
- package/dist-ssg/client/assets/CanvasRenderer-BCXK2PVZ.js +0 -1
- package/dist-ssg/client/assets/WebGLRenderer-i-T4B6u4.js +0 -1
- package/dist-ssg/client/assets/WebGPURenderer-H88EZaPN.js +0 -1
- package/dist-ssg/client/assets/browserAll-Ae_1KSeb.js +0 -1
- package/dist-ssg/client/assets/dist-D_3RMJZl.js +0 -1
- package/dist-ssg/client/assets/dist-ENBjyU2l.js +0 -1
- package/dist-ssg/client/assets/dist-VCVOuFg2.js +0 -1
- package/dist-ssg/client/assets/index-BE9cyYzu.css +0 -2
- package/dist-ssg/client/assets/trpc-3tg7hkky.js +0 -1
- package/dist-ssg/client/assets/webworkerAll-eiudlEPb.js +0 -1
|
@@ -7433,7 +7433,7 @@ function useSearch(opts) {
|
|
|
7433
7433
|
}
|
|
7434
7434
|
//#endregion
|
|
7435
7435
|
//#region ../../node_modules/.pnpm/@tanstack+react-router@1.139.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@tanstack/react-router/dist/esm/utils.js
|
|
7436
|
-
var useLayoutEffect$
|
|
7436
|
+
var useLayoutEffect$7 = typeof window !== "undefined" ? import_react.useLayoutEffect : import_react.useEffect;
|
|
7437
7437
|
function usePrevious(value) {
|
|
7438
7438
|
const ref = import_react.useRef({
|
|
7439
7439
|
value,
|
|
@@ -8353,7 +8353,7 @@ function Transitioner() {
|
|
|
8353
8353
|
unsub();
|
|
8354
8354
|
};
|
|
8355
8355
|
}, [router, router.history]);
|
|
8356
|
-
useLayoutEffect$
|
|
8356
|
+
useLayoutEffect$7(() => {
|
|
8357
8357
|
if (typeof window !== "undefined" && router.ssr || mountLoadForRouter.current.router === router && mountLoadForRouter.current.mounted) return;
|
|
8358
8358
|
mountLoadForRouter.current = {
|
|
8359
8359
|
router,
|
|
@@ -8368,7 +8368,7 @@ function Transitioner() {
|
|
|
8368
8368
|
};
|
|
8369
8369
|
tryLoad();
|
|
8370
8370
|
}, [router]);
|
|
8371
|
-
useLayoutEffect$
|
|
8371
|
+
useLayoutEffect$7(() => {
|
|
8372
8372
|
if (previousIsLoading && !isLoading) router.emit({
|
|
8373
8373
|
type: "onLoad",
|
|
8374
8374
|
...getLocationChangeInfo(router.state)
|
|
@@ -8378,7 +8378,7 @@ function Transitioner() {
|
|
|
8378
8378
|
router,
|
|
8379
8379
|
isLoading
|
|
8380
8380
|
]);
|
|
8381
|
-
useLayoutEffect$
|
|
8381
|
+
useLayoutEffect$7(() => {
|
|
8382
8382
|
if (previousIsPagePending && !isPagePending) router.emit({
|
|
8383
8383
|
type: "onBeforeRouteMount",
|
|
8384
8384
|
...getLocationChangeInfo(router.state)
|
|
@@ -8388,7 +8388,7 @@ function Transitioner() {
|
|
|
8388
8388
|
previousIsPagePending,
|
|
8389
8389
|
router
|
|
8390
8390
|
]);
|
|
8391
|
-
useLayoutEffect$
|
|
8391
|
+
useLayoutEffect$7(() => {
|
|
8392
8392
|
if (previousIsAnyPending && !isAnyPending) {
|
|
8393
8393
|
const changeInfo = getLocationChangeInfo(router.state);
|
|
8394
8394
|
router.emit({
|
|
@@ -39494,8 +39494,9 @@ function waitForDomCommit() {
|
|
|
39494
39494
|
setTimeout(finish, 0);
|
|
39495
39495
|
});
|
|
39496
39496
|
}
|
|
39497
|
-
function
|
|
39497
|
+
function filterAfterEntries(entries, beforeEntries, intent) {
|
|
39498
39498
|
if (beforeEntries.length === 0) return entries;
|
|
39499
|
+
if (intent.kind === "tab-carousel") return entries;
|
|
39499
39500
|
const beforeElements = new Set(beforeEntries.map(([element]) => element));
|
|
39500
39501
|
return entries.filter(([element]) => !beforeElements.has(element));
|
|
39501
39502
|
}
|
|
@@ -39503,15 +39504,15 @@ async function collectSettledAfterEntries(beforeEntries, collectAfterEntries, in
|
|
|
39503
39504
|
if (!collectAfterEntries) return [];
|
|
39504
39505
|
if (intent.kind === "route-detail" && beforeEntries.length > 0) return waitForNamedEntriesReady({
|
|
39505
39506
|
expectedNames: beforeEntries.map(([, name]) => name),
|
|
39506
|
-
collectEntries: () =>
|
|
39507
|
+
collectEntries: () => filterAfterEntries(collectAfterEntries(), beforeEntries, intent)
|
|
39507
39508
|
});
|
|
39508
39509
|
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
39509
|
-
const entries =
|
|
39510
|
+
const entries = filterAfterEntries(collectAfterEntries(), beforeEntries, intent);
|
|
39510
39511
|
if (entries.length > 0 || beforeEntries.length === 0) return entries;
|
|
39511
39512
|
await Promise.resolve();
|
|
39512
39513
|
await waitForDomCommit();
|
|
39513
39514
|
}
|
|
39514
|
-
return
|
|
39515
|
+
return filterAfterEntries(collectAfterEntries(), beforeEntries, intent);
|
|
39515
39516
|
}
|
|
39516
39517
|
function setIntentDataset(intent) {
|
|
39517
39518
|
const root = document.documentElement;
|
|
@@ -73681,16 +73682,6 @@ var tabsStyleText = (id) => {
|
|
|
73681
73682
|
transform: scaleX(0.5);
|
|
73682
73683
|
}
|
|
73683
73684
|
|
|
73684
|
-
#${id}[data-tabs-variant='default'] .tabs-button > button.tab-selected {
|
|
73685
|
-
background-image: linear-gradient(
|
|
73686
|
-
to bottom,
|
|
73687
|
-
transparent,
|
|
73688
|
-
transparent calc(100% - 2px),
|
|
73689
|
-
var(--primary) calc(100% - 2px),
|
|
73690
|
-
var(--primary)
|
|
73691
|
-
);
|
|
73692
|
-
}
|
|
73693
|
-
|
|
73694
73685
|
#${id} .tabs-strip {
|
|
73695
73686
|
background-image: linear-gradient(
|
|
73696
73687
|
to bottom,
|
|
@@ -73728,11 +73719,17 @@ function TabsImpl({ tabs, selectedTab: controlled, onTabChange, onTabClose, onTa
|
|
|
73728
73719
|
const dropIndicatorRef = (0, import_react.useRef)(null);
|
|
73729
73720
|
const contentOrderRef = (0, import_react.useRef)(tabs.map((tab) => tab.id));
|
|
73730
73721
|
const rootRef = (0, import_react.useRef)(null);
|
|
73722
|
+
const headerRef = (0, import_react.useRef)(null);
|
|
73723
|
+
const headerShellRef = (0, import_react.useRef)(null);
|
|
73724
|
+
const headerForegroundRef = (0, import_react.useRef)(null);
|
|
73725
|
+
const selectionIndicatorRef = (0, import_react.useRef)(null);
|
|
73726
|
+
const tabsButtonRef = (0, import_react.useRef)(null);
|
|
73731
73727
|
const triggerRefs = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
73732
73728
|
const panelRefs = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
73733
73729
|
const activeTab = controlled ?? uncontrolled;
|
|
73734
73730
|
const reorderable = typeof onTabOrderChange === "function" && tabs.length > 1;
|
|
73735
73731
|
const tabIds = tabs.map((tab) => tab.id);
|
|
73732
|
+
const tabLayoutSignature = tabIds.join("|");
|
|
73736
73733
|
const tabsById = (0, import_react.useMemo)(() => new Map(tabs.map((tab) => [tab.id, tab])), [tabs]);
|
|
73737
73734
|
const contentTabs = (0, import_react.useMemo)(() => {
|
|
73738
73735
|
const nextOrder = buildStableContentTabIds(contentOrderRef.current, tabIds);
|
|
@@ -73752,10 +73749,69 @@ function TabsImpl({ tabs, selectedTab: controlled, onTabChange, onTabClose, onTa
|
|
|
73752
73749
|
getPanel(tabId) {
|
|
73753
73750
|
return panelRefs.current.get(tabId) ?? null;
|
|
73754
73751
|
},
|
|
73752
|
+
getHeaderShell() {
|
|
73753
|
+
return headerShellRef.current;
|
|
73754
|
+
},
|
|
73755
|
+
getHeaderForeground() {
|
|
73756
|
+
return headerForegroundRef.current;
|
|
73757
|
+
},
|
|
73758
|
+
getSelectionIndicator() {
|
|
73759
|
+
return selectionIndicatorRef.current;
|
|
73760
|
+
},
|
|
73755
73761
|
getActiveTabId() {
|
|
73756
73762
|
return activeTab || null;
|
|
73757
73763
|
}
|
|
73758
73764
|
}), [activeTab]);
|
|
73765
|
+
const syncSelectionIndicator = (0, import_react.useCallback)(() => {
|
|
73766
|
+
const indicator = selectionIndicatorRef.current;
|
|
73767
|
+
const header = headerRef.current;
|
|
73768
|
+
const activeTrigger = activeTab ? triggerRefs.current.get(activeTab) : null;
|
|
73769
|
+
if (!indicator) return;
|
|
73770
|
+
if (variant !== "default" || !header || !activeTrigger) {
|
|
73771
|
+
indicator.style.opacity = "0";
|
|
73772
|
+
indicator.style.width = "0px";
|
|
73773
|
+
indicator.style.height = "0px";
|
|
73774
|
+
indicator.style.transform = "translate(0px, 0px)";
|
|
73775
|
+
return;
|
|
73776
|
+
}
|
|
73777
|
+
const headerRect = header.getBoundingClientRect();
|
|
73778
|
+
const triggerRect = activeTrigger.getBoundingClientRect();
|
|
73779
|
+
indicator.style.opacity = "1";
|
|
73780
|
+
indicator.style.width = `${triggerRect.width}px`;
|
|
73781
|
+
indicator.style.height = `${triggerRect.height}px`;
|
|
73782
|
+
indicator.style.transform = `translate(${triggerRect.left - headerRect.left}px, ${triggerRect.top - headerRect.top}px)`;
|
|
73783
|
+
}, [activeTab, variant]);
|
|
73784
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
73785
|
+
syncSelectionIndicator();
|
|
73786
|
+
}, [syncSelectionIndicator, tabLayoutSignature]);
|
|
73787
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
73788
|
+
if (variant !== "default") return;
|
|
73789
|
+
const tabsButton = tabsButtonRef.current;
|
|
73790
|
+
if (!tabsButton) return;
|
|
73791
|
+
const handleScroll = () => {
|
|
73792
|
+
syncSelectionIndicator();
|
|
73793
|
+
};
|
|
73794
|
+
tabsButton.addEventListener("scroll", handleScroll, { passive: true });
|
|
73795
|
+
if (typeof ResizeObserver === "undefined") return () => {
|
|
73796
|
+
tabsButton.removeEventListener("scroll", handleScroll);
|
|
73797
|
+
};
|
|
73798
|
+
const observer = new ResizeObserver(() => {
|
|
73799
|
+
syncSelectionIndicator();
|
|
73800
|
+
});
|
|
73801
|
+
observer.observe(tabsButton);
|
|
73802
|
+
if (headerRef.current) observer.observe(headerRef.current);
|
|
73803
|
+
const activeTrigger = activeTab ? triggerRefs.current.get(activeTab) : null;
|
|
73804
|
+
if (activeTrigger) observer.observe(activeTrigger);
|
|
73805
|
+
return () => {
|
|
73806
|
+
tabsButton.removeEventListener("scroll", handleScroll);
|
|
73807
|
+
observer.disconnect();
|
|
73808
|
+
};
|
|
73809
|
+
}, [
|
|
73810
|
+
activeTab,
|
|
73811
|
+
syncSelectionIndicator,
|
|
73812
|
+
tabLayoutSignature,
|
|
73813
|
+
variant
|
|
73814
|
+
]);
|
|
73759
73815
|
const handleChange = (id) => {
|
|
73760
73816
|
if (!controlled) setUncontrolled(id);
|
|
73761
73817
|
onTabChange?.(id);
|
|
@@ -73835,77 +73891,115 @@ function TabsImpl({ tabs, selectedTab: controlled, onTabChange, onTabClose, onTa
|
|
|
73835
73891
|
event.dataTransfer.dropEffect = "move";
|
|
73836
73892
|
}, [reorderable]);
|
|
73837
73893
|
if (tabs.length === 0) return null;
|
|
73838
|
-
const headerClassName = variant === "terminal" ? "tabs-header bg-terminal text-terminal-foreground sticky top-0 z-20 flex min-w-0 items-stretch" : "tabs-header
|
|
73839
|
-
const stripClassName = variant === "terminal" ? "tabs-strip min-w-0 flex-1 bg-terminal px-4" : "tabs-strip
|
|
73894
|
+
const headerClassName = variant === "terminal" ? "tabs-header bg-terminal text-terminal-foreground sticky top-0 z-20 flex min-w-0 items-stretch" : "tabs-header relative sticky top-0 z-20 min-w-0";
|
|
73895
|
+
const stripClassName = variant === "terminal" ? "tabs-strip min-w-0 flex-1 bg-terminal px-4" : "tabs-strip min-w-0 flex-1 rounded-l-md px-4";
|
|
73840
73896
|
const listClassName = variant === "terminal" ? "tabs-button scrollbar-none flex min-w-0 gap-1 overflow-x-auto pt-2" : "tabs-button scrollbar-none flex min-w-0 gap-1 overflow-x-auto";
|
|
73841
|
-
const buttonBaseClassName = `group relative m-0 flex h-full shrink-0 items-center gap-2 px-2 text-sm font-medium transition-colors ${variant === "terminal" ? "rounded-t-[8px] py-1" : "py-2"}`;
|
|
73842
|
-
const activeButtonClassName = variant === "terminal" ? "tab-selected bg-background text-foreground" : "tab-selected
|
|
73897
|
+
const buttonBaseClassName = `group relative z-10 m-0 flex h-full shrink-0 items-center gap-2 px-2 text-sm font-medium transition-colors ${variant === "terminal" ? "rounded-t-[8px] py-1" : "py-2"}`;
|
|
73898
|
+
const activeButtonClassName = variant === "terminal" ? "tab-selected bg-background text-foreground" : "tab-selected text-foreground";
|
|
73843
73899
|
const inactiveButtonClassName = variant === "terminal" ? "bg-terminal text-terminal-foreground/80 hover:bg-terminal hover:text-terminal-foreground" : "text-muted-foreground hover:bg-background/35 hover:text-foreground";
|
|
73844
|
-
const actionsClassName = variant === "terminal" ? "tabs-actions border-border bg-terminal text-terminal-foreground flex shrink-0 items-center border-b px-1" : "tabs-actions
|
|
73900
|
+
const actionsClassName = variant === "terminal" ? "tabs-actions border-border bg-terminal text-terminal-foreground flex shrink-0 items-center border-b px-1" : "tabs-actions border-zinc-500/15 flex shrink-0 items-center rounded-r-md border-l px-1";
|
|
73845
73901
|
const handleTabBarDoubleClick = (event) => {
|
|
73846
73902
|
if (!onTabBarDoubleClick) return;
|
|
73847
73903
|
if (event.target.closest("[data-tab-item=\"true\"]")) return;
|
|
73848
73904
|
onTabBarDoubleClick();
|
|
73849
73905
|
};
|
|
73906
|
+
const tabButtons = tabs.map((tab) => {
|
|
73907
|
+
const dragIndicatorStyle = dropIndicator?.tabId === tab.id ? { boxShadow: dropIndicator.position === "before" ? "inset 2px 0 0 var(--border)" : "inset -2px 0 0 var(--border)" } : void 0;
|
|
73908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
73909
|
+
ref: (element) => {
|
|
73910
|
+
triggerRefs.current.set(tab.id, element);
|
|
73911
|
+
},
|
|
73912
|
+
"data-tab-item": "true",
|
|
73913
|
+
"data-tab-id": tab.id,
|
|
73914
|
+
draggable: reorderable,
|
|
73915
|
+
onClick: () => handleChange(tab.id),
|
|
73916
|
+
onDragStart: (event) => handleDragStart(event, tab.id),
|
|
73917
|
+
onDragEnd: handleDragEnd,
|
|
73918
|
+
onDragOver: (event) => handleItemDragOver(event, tab.id),
|
|
73919
|
+
onDrop: (event) => handleItemDrop(event, tab.id),
|
|
73920
|
+
className: `${buttonBaseClassName} ${activeTab === tab.id ? activeButtonClassName : inactiveButtonClassName} ${reorderable ? "cursor-grab active:cursor-grabbing" : ""}`,
|
|
73921
|
+
style: dragIndicatorStyle,
|
|
73922
|
+
children: [
|
|
73923
|
+
tab.icon,
|
|
73924
|
+
tab.label,
|
|
73925
|
+
tab.closable && onTabClose && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
73926
|
+
role: "button",
|
|
73927
|
+
tabIndex: 0,
|
|
73928
|
+
onClick: (event) => {
|
|
73929
|
+
event.stopPropagation();
|
|
73930
|
+
onTabClose(tab.id);
|
|
73931
|
+
},
|
|
73932
|
+
onKeyDown: (event) => {
|
|
73933
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
73934
|
+
event.stopPropagation();
|
|
73935
|
+
onTabClose(tab.id);
|
|
73936
|
+
}
|
|
73937
|
+
},
|
|
73938
|
+
draggable: false,
|
|
73939
|
+
className: `hover:text-foreground -mr-1 rounded p-0.5 transition ${tab.closeButtonVisibility === "always" ? "opacity-100" : "opacity-0 group-hover:opacity-100 [button:hover>&]:opacity-100"} ${activeTab === tab.id ? "text-current/80" : "text-muted-foreground"}`,
|
|
73940
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X$2, { className: "h-3 w-3" })
|
|
73941
|
+
})
|
|
73942
|
+
]
|
|
73943
|
+
}, tab.id);
|
|
73944
|
+
});
|
|
73850
73945
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
73851
73946
|
id,
|
|
73852
73947
|
ref: rootRef,
|
|
73853
73948
|
"data-tabs-variant": variant,
|
|
73854
73949
|
className: `relative isolate flex min-h-0 min-w-0 flex-1 flex-col ${className}`,
|
|
73855
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.
|
|
73950
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73951
|
+
ref: headerRef,
|
|
73856
73952
|
className: headerClassName,
|
|
73857
|
-
children:
|
|
73953
|
+
children: variant === "default" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
73954
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73955
|
+
ref: headerShellRef,
|
|
73956
|
+
"data-tabs-header-shell": "true",
|
|
73957
|
+
className: "tabs-header-shell bg-card/95 pointer-events-none absolute inset-0 z-0 rounded-md border border-zinc-500/15 shadow-[inset_0_-1px_0_color-mix(in_srgb,var(--border)_85%,transparent)] backdrop-blur-sm"
|
|
73958
|
+
}),
|
|
73959
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73960
|
+
className: "pointer-events-none absolute inset-0 z-10",
|
|
73961
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73962
|
+
ref: selectionIndicatorRef,
|
|
73963
|
+
"data-tabs-selection-indicator": "true",
|
|
73964
|
+
"aria-hidden": "true",
|
|
73965
|
+
className: "tabs-selection-indicator border-primary bg-background/70 duration-280 absolute left-0 top-0 rounded-md border-b-2 opacity-0 shadow-[inset_0_-1px_0_color-mix(in_srgb,var(--border)_85%,transparent)] transition-[transform,width,height,opacity] ease-[cubic-bezier(0.22,1,0.36,1)]"
|
|
73966
|
+
})
|
|
73967
|
+
}),
|
|
73968
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
73969
|
+
ref: headerForegroundRef,
|
|
73970
|
+
"data-tabs-header-foreground": "true",
|
|
73971
|
+
className: "tabs-header-foreground relative z-20 flex min-w-0 items-stretch",
|
|
73972
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73973
|
+
className: stripClassName,
|
|
73974
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73975
|
+
ref: tabsButtonRef,
|
|
73976
|
+
className: listClassName,
|
|
73977
|
+
onDoubleClick: handleTabBarDoubleClick,
|
|
73978
|
+
onDragOver: handleListDragOver,
|
|
73979
|
+
onDrop: handleListDrop,
|
|
73980
|
+
children: tabButtons
|
|
73981
|
+
})
|
|
73982
|
+
}), actions && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73983
|
+
"data-tabs-actions": "true",
|
|
73984
|
+
className: actionsClassName,
|
|
73985
|
+
children: actions
|
|
73986
|
+
})]
|
|
73987
|
+
})
|
|
73988
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73858
73989
|
className: stripClassName,
|
|
73859
73990
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73991
|
+
ref: tabsButtonRef,
|
|
73860
73992
|
className: listClassName,
|
|
73861
73993
|
onDoubleClick: handleTabBarDoubleClick,
|
|
73862
73994
|
onDragOver: handleListDragOver,
|
|
73863
73995
|
onDrop: handleListDrop,
|
|
73864
|
-
children:
|
|
73865
|
-
const dragIndicatorStyle = dropIndicator?.tabId === tab.id ? { boxShadow: dropIndicator.position === "before" ? "inset 2px 0 0 var(--border)" : "inset -2px 0 0 var(--border)" } : void 0;
|
|
73866
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
|
|
73867
|
-
ref: (element) => {
|
|
73868
|
-
triggerRefs.current.set(tab.id, element);
|
|
73869
|
-
},
|
|
73870
|
-
"data-tab-item": "true",
|
|
73871
|
-
"data-tab-id": tab.id,
|
|
73872
|
-
draggable: reorderable,
|
|
73873
|
-
onClick: () => handleChange(tab.id),
|
|
73874
|
-
onDragStart: (event) => handleDragStart(event, tab.id),
|
|
73875
|
-
onDragEnd: handleDragEnd,
|
|
73876
|
-
onDragOver: (event) => handleItemDragOver(event, tab.id),
|
|
73877
|
-
onDrop: (event) => handleItemDrop(event, tab.id),
|
|
73878
|
-
className: `${buttonBaseClassName} ${activeTab === tab.id ? activeButtonClassName : inactiveButtonClassName} ${reorderable ? "cursor-grab active:cursor-grabbing" : ""}`,
|
|
73879
|
-
style: dragIndicatorStyle,
|
|
73880
|
-
children: [
|
|
73881
|
-
tab.icon,
|
|
73882
|
-
tab.label,
|
|
73883
|
-
tab.closable && onTabClose && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
73884
|
-
role: "button",
|
|
73885
|
-
tabIndex: 0,
|
|
73886
|
-
onClick: (event) => {
|
|
73887
|
-
event.stopPropagation();
|
|
73888
|
-
onTabClose(tab.id);
|
|
73889
|
-
},
|
|
73890
|
-
onKeyDown: (event) => {
|
|
73891
|
-
if (event.key === "Enter" || event.key === " ") {
|
|
73892
|
-
event.stopPropagation();
|
|
73893
|
-
onTabClose(tab.id);
|
|
73894
|
-
}
|
|
73895
|
-
},
|
|
73896
|
-
draggable: false,
|
|
73897
|
-
className: `hover:text-foreground -mr-1 rounded p-0.5 transition ${tab.closeButtonVisibility === "always" ? "opacity-100" : "opacity-0 group-hover:opacity-100 [button:hover>&]:opacity-100"} ${activeTab === tab.id ? "text-current/80" : "text-muted-foreground"}`,
|
|
73898
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X$2, { className: "h-3 w-3" })
|
|
73899
|
-
})
|
|
73900
|
-
]
|
|
73901
|
-
}, tab.id);
|
|
73902
|
-
})
|
|
73996
|
+
children: tabButtons
|
|
73903
73997
|
})
|
|
73904
73998
|
}), actions && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73905
73999
|
"data-tabs-actions": "true",
|
|
73906
74000
|
className: actionsClassName,
|
|
73907
74001
|
children: actions
|
|
73908
|
-
})]
|
|
74002
|
+
})] })
|
|
73909
74003
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
73910
74004
|
className: "relative flex min-h-0 flex-1 overflow-hidden",
|
|
73911
74005
|
children: contentTabs.map((tab) => tab.unmountOnHide ? activeTab === tab.id && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
@@ -73935,6 +74029,10 @@ var Tabs = (0, import_react.forwardRef)(TabsImpl);
|
|
|
73935
74029
|
var DATA_VISIBLE_HEIGHT = "tabVisibleHeight";
|
|
73936
74030
|
var DATA_TOP_INSET = "tabTopInset";
|
|
73937
74031
|
var DATA_SCROLL_OFFSET = "tabScrollOffset";
|
|
74032
|
+
var DATA_LAYOUT_BRIDGE = "tabLayoutBridge";
|
|
74033
|
+
var DATA_LAYOUT_BRIDGE_BASE_PADDING = "tabLayoutBridgeBasePadding";
|
|
74034
|
+
var DATA_LAYOUT_BRIDGE_INLINE_PADDING = "tabLayoutBridgeInlinePadding";
|
|
74035
|
+
var TAB_SCROLL_ROOT_SELECTOR = "[data-tab-scroll-root=\"true\"]";
|
|
73938
74036
|
function clamp$2(value, min, max) {
|
|
73939
74037
|
return Math.min(Math.max(value, min), max);
|
|
73940
74038
|
}
|
|
@@ -73944,6 +74042,63 @@ function maxViewportScroll(viewport) {
|
|
|
73944
74042
|
function maxPanelScroll(panel, visibleHeight) {
|
|
73945
74043
|
return Math.max(panel.scrollHeight - visibleHeight, 0);
|
|
73946
74044
|
}
|
|
74045
|
+
function readPanelLayoutBridge(panel) {
|
|
74046
|
+
return Number(panel.dataset[DATA_LAYOUT_BRIDGE] ?? "0") || 0;
|
|
74047
|
+
}
|
|
74048
|
+
function ensurePanelLayoutBridgeState(panel) {
|
|
74049
|
+
panel.dataset[DATA_LAYOUT_BRIDGE_BASE_PADDING] ||= window.getComputedStyle(panel).paddingBottom;
|
|
74050
|
+
panel.dataset[DATA_LAYOUT_BRIDGE_INLINE_PADDING] ||= panel.style.paddingBottom;
|
|
74051
|
+
}
|
|
74052
|
+
function setPanelLayoutBridge(panel, extraHeight) {
|
|
74053
|
+
ensurePanelLayoutBridgeState(panel);
|
|
74054
|
+
const normalizedHeight = Math.max(Math.ceil(extraHeight), 0);
|
|
74055
|
+
panel.dataset[DATA_LAYOUT_BRIDGE] = String(normalizedHeight);
|
|
74056
|
+
if (normalizedHeight <= 0) {
|
|
74057
|
+
panel.style.paddingBottom = panel.dataset[DATA_LAYOUT_BRIDGE_INLINE_PADDING] ?? "";
|
|
74058
|
+
return;
|
|
74059
|
+
}
|
|
74060
|
+
const basePadding = panel.dataset[DATA_LAYOUT_BRIDGE_BASE_PADDING] ?? "0px";
|
|
74061
|
+
panel.style.paddingBottom = `calc(${basePadding} + ${normalizedHeight}px)`;
|
|
74062
|
+
}
|
|
74063
|
+
function restoreViewportScroll(viewport, panel, targetScrollTop) {
|
|
74064
|
+
const applyScrollTop = () => {
|
|
74065
|
+
if (!viewport.isConnected || !panel.isConnected) return true;
|
|
74066
|
+
const existingBridge = readPanelLayoutBridge(panel);
|
|
74067
|
+
const baseMaxViewportScroll = Math.max(maxViewportScroll(viewport) - existingBridge, 0);
|
|
74068
|
+
setPanelLayoutBridge(panel, Math.max(targetScrollTop - baseMaxViewportScroll, 0));
|
|
74069
|
+
const nextScrollTop = clamp$2(targetScrollTop, 0, maxViewportScroll(viewport));
|
|
74070
|
+
viewport.scrollTop = nextScrollTop;
|
|
74071
|
+
return viewport.scrollTop === nextScrollTop;
|
|
74072
|
+
};
|
|
74073
|
+
if (applyScrollTop() || typeof requestAnimationFrame !== "function") return;
|
|
74074
|
+
let retriesRemaining = 10;
|
|
74075
|
+
const retry = () => {
|
|
74076
|
+
if (applyScrollTop() || retriesRemaining <= 0) return;
|
|
74077
|
+
retriesRemaining -= 1;
|
|
74078
|
+
requestAnimationFrame(retry);
|
|
74079
|
+
};
|
|
74080
|
+
requestAnimationFrame(retry);
|
|
74081
|
+
}
|
|
74082
|
+
function hasVerticalScrollBehavior(overflowY) {
|
|
74083
|
+
return overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay";
|
|
74084
|
+
}
|
|
74085
|
+
function findScrollableDescendant(panel) {
|
|
74086
|
+
const walker = document.createTreeWalker(panel, NodeFilter.SHOW_ELEMENT);
|
|
74087
|
+
let candidate = null;
|
|
74088
|
+
while (walker.nextNode()) {
|
|
74089
|
+
const node = walker.currentNode;
|
|
74090
|
+
if (!(node instanceof HTMLElement)) continue;
|
|
74091
|
+
if (!hasVerticalScrollBehavior(window.getComputedStyle(node).overflowY) || node.scrollHeight <= node.clientHeight) continue;
|
|
74092
|
+
if (node.scrollTop > 0) return node;
|
|
74093
|
+
candidate ??= node;
|
|
74094
|
+
}
|
|
74095
|
+
return candidate;
|
|
74096
|
+
}
|
|
74097
|
+
function resolveContentScrollRoot(panel) {
|
|
74098
|
+
const markedRoot = panel.matches(TAB_SCROLL_ROOT_SELECTOR) ? panel : panel.querySelector(TAB_SCROLL_ROOT_SELECTOR);
|
|
74099
|
+
if (markedRoot) return markedRoot;
|
|
74100
|
+
return findScrollableDescendant(panel);
|
|
74101
|
+
}
|
|
73947
74102
|
function panelDocumentTop(panel, viewport) {
|
|
73948
74103
|
const panelRect = panel.getBoundingClientRect();
|
|
73949
74104
|
const viewportRect = viewport.getBoundingClientRect();
|
|
@@ -73981,40 +74136,99 @@ function restorePanel(panel, previousStyles) {
|
|
|
73981
74136
|
panel.style.overflowY = previousStyles.overflowY;
|
|
73982
74137
|
clearFrozenMetrics(panel);
|
|
73983
74138
|
}
|
|
74139
|
+
function restoreContentScrollRoot(element, targetScrollTop) {
|
|
74140
|
+
if (!element) return;
|
|
74141
|
+
const applyScrollTop = () => {
|
|
74142
|
+
if (!element.isConnected) return true;
|
|
74143
|
+
element.scrollTop = targetScrollTop;
|
|
74144
|
+
return element.scrollTop === targetScrollTop;
|
|
74145
|
+
};
|
|
74146
|
+
if (applyScrollTop() || typeof requestAnimationFrame !== "function") return;
|
|
74147
|
+
let retriesRemaining = 10;
|
|
74148
|
+
const retry = () => {
|
|
74149
|
+
if (applyScrollTop() || retriesRemaining <= 0) return;
|
|
74150
|
+
retriesRemaining -= 1;
|
|
74151
|
+
requestAnimationFrame(retry);
|
|
74152
|
+
};
|
|
74153
|
+
requestAnimationFrame(retry);
|
|
74154
|
+
}
|
|
74155
|
+
function normalizeViewportSelectors(viewportSelector) {
|
|
74156
|
+
return typeof viewportSelector === "string" ? viewportSelector.split(",").map((selector) => selector.trim()) : [...viewportSelector];
|
|
74157
|
+
}
|
|
74158
|
+
function resolveViewportBoundary(panel, viewportSelector) {
|
|
74159
|
+
const selectors = normalizeViewportSelectors(viewportSelector);
|
|
74160
|
+
for (const selector of selectors) {
|
|
74161
|
+
if (!selector) continue;
|
|
74162
|
+
try {
|
|
74163
|
+
const match = panel.closest(selector);
|
|
74164
|
+
if (match instanceof HTMLElement) return match;
|
|
74165
|
+
} catch {
|
|
74166
|
+
return null;
|
|
74167
|
+
}
|
|
74168
|
+
}
|
|
74169
|
+
return null;
|
|
74170
|
+
}
|
|
74171
|
+
function resolveScrollViewport(panel, boundary) {
|
|
74172
|
+
let current = panel.parentElement;
|
|
74173
|
+
while (current) {
|
|
74174
|
+
if (hasVerticalScrollBehavior(window.getComputedStyle(current).overflowY) && current.scrollHeight > current.clientHeight) return current;
|
|
74175
|
+
if (boundary && current === boundary) break;
|
|
74176
|
+
current = current.parentElement;
|
|
74177
|
+
}
|
|
74178
|
+
if (!boundary) return null;
|
|
74179
|
+
if (hasVerticalScrollBehavior(window.getComputedStyle(boundary).overflowY)) return boundary;
|
|
74180
|
+
return null;
|
|
74181
|
+
}
|
|
73984
74182
|
function resolveTabScrollElements(handle, tabId, viewportSelector) {
|
|
73985
74183
|
if (!viewportSelector) return null;
|
|
73986
74184
|
const panel = handle?.getPanel(tabId);
|
|
73987
74185
|
if (!(panel instanceof HTMLElement)) return null;
|
|
73988
|
-
|
|
73989
|
-
try {
|
|
73990
|
-
viewport = panel.closest(viewportSelector);
|
|
73991
|
-
} catch {
|
|
73992
|
-
return null;
|
|
73993
|
-
}
|
|
74186
|
+
const viewport = resolveScrollViewport(panel, resolveViewportBoundary(panel, viewportSelector));
|
|
73994
74187
|
if (!(viewport instanceof HTMLElement)) return null;
|
|
73995
74188
|
return {
|
|
73996
74189
|
panel,
|
|
74190
|
+
contentScrollRoot: resolveContentScrollRoot(panel),
|
|
73997
74191
|
viewport
|
|
73998
74192
|
};
|
|
73999
74193
|
}
|
|
74194
|
+
function restorePanelContentScroll(panel, snapshot) {
|
|
74195
|
+
if (!(panel instanceof HTMLElement) || !snapshot) return;
|
|
74196
|
+
const contentScrollRoot = resolveContentScrollRoot(panel);
|
|
74197
|
+
if (contentScrollRoot && contentScrollRoot !== panel) restoreContentScrollRoot(contentScrollRoot, snapshot.contentScrollTop);
|
|
74198
|
+
}
|
|
74199
|
+
function restorePanelViewportScroll(panel, viewport, snapshot) {
|
|
74200
|
+
if (!(panel instanceof HTMLElement) || !(viewport instanceof HTMLElement)) return;
|
|
74201
|
+
if (!snapshot) {
|
|
74202
|
+
setPanelLayoutBridge(panel, 0);
|
|
74203
|
+
return;
|
|
74204
|
+
}
|
|
74205
|
+
restoreViewportScroll(viewport, panel, snapshot.viewportScrollTop);
|
|
74206
|
+
}
|
|
74000
74207
|
function captureTabScrollMemory(elements) {
|
|
74001
|
-
const { panel, viewport } = elements;
|
|
74208
|
+
const { panel, contentScrollRoot, viewport } = elements;
|
|
74002
74209
|
const panelRect = panel.getBoundingClientRect();
|
|
74003
74210
|
const viewportRect = viewport.getBoundingClientRect();
|
|
74004
74211
|
const visibleHeight = clamp$2(Math.min(panelRect.bottom, viewportRect.bottom) - Math.max(panelRect.top, viewportRect.top), 0, viewport.clientHeight);
|
|
74005
74212
|
if (visibleHeight <= 0) return null;
|
|
74006
74213
|
const topInset = Math.max(panelRect.top - viewportRect.top, 0);
|
|
74214
|
+
const innerScrollTop = clamp$2(Math.max(viewportRect.top - panelRect.top, 0), 0, maxPanelScroll(panel, visibleHeight));
|
|
74007
74215
|
return {
|
|
74008
|
-
|
|
74216
|
+
contentScrollTop: contentScrollRoot && contentScrollRoot !== panel ? contentScrollRoot.scrollTop : 0,
|
|
74217
|
+
innerScrollTop,
|
|
74009
74218
|
topInset,
|
|
74010
|
-
visibleHeight
|
|
74219
|
+
visibleHeight,
|
|
74220
|
+
viewportScrollTop: viewport.scrollTop
|
|
74011
74221
|
};
|
|
74012
74222
|
}
|
|
74013
74223
|
function freezeOutgoingTab(elements, snapshot) {
|
|
74014
74224
|
const previousStyles = applyFrozenStyles(elements.panel, snapshot);
|
|
74225
|
+
if (elements.contentScrollRoot && elements.contentScrollRoot !== elements.panel) restoreContentScrollRoot(elements.contentScrollRoot, snapshot.contentScrollTop);
|
|
74015
74226
|
elements.panel.scrollTop = snapshot.innerScrollTop;
|
|
74016
74227
|
if (snapshot.innerScrollTop > 0) elements.viewport.scrollTop = clamp$2(elements.viewport.scrollTop - snapshot.innerScrollTop, 0, maxViewportScroll(elements.viewport));
|
|
74017
74228
|
return {
|
|
74229
|
+
contentScrollRoot: elements.contentScrollRoot && elements.contentScrollRoot !== elements.panel ? elements.contentScrollRoot : null,
|
|
74230
|
+
contentScrollTop: snapshot.contentScrollTop,
|
|
74231
|
+
finalViewportScrollTop: snapshot.viewportScrollTop,
|
|
74018
74232
|
panel: elements.panel,
|
|
74019
74233
|
previousStyles,
|
|
74020
74234
|
viewport: elements.viewport
|
|
@@ -74022,26 +74236,32 @@ function freezeOutgoingTab(elements, snapshot) {
|
|
|
74022
74236
|
}
|
|
74023
74237
|
function freezeIncomingTab(elements, snapshot) {
|
|
74024
74238
|
const normalizedSnapshot = {
|
|
74239
|
+
contentScrollTop: elements.contentScrollRoot && elements.contentScrollRoot !== elements.panel ? snapshot.contentScrollTop : 0,
|
|
74025
74240
|
topInset: clamp$2(snapshot.topInset, 0, elements.viewport.clientHeight),
|
|
74026
74241
|
visibleHeight: clamp$2(snapshot.visibleHeight, 1, elements.viewport.clientHeight),
|
|
74027
|
-
innerScrollTop: 0
|
|
74242
|
+
innerScrollTop: 0,
|
|
74243
|
+
viewportScrollTop: snapshot.viewportScrollTop
|
|
74028
74244
|
};
|
|
74029
74245
|
normalizedSnapshot.innerScrollTop = clamp$2(snapshot.innerScrollTop, 0, maxPanelScroll(elements.panel, normalizedSnapshot.visibleHeight));
|
|
74030
74246
|
const nextViewportScrollTop = clamp$2(panelDocumentTop(elements.panel, elements.viewport) - normalizedSnapshot.topInset, 0, maxViewportScroll(elements.viewport));
|
|
74031
74247
|
const previousStyles = applyFrozenStyles(elements.panel, normalizedSnapshot);
|
|
74032
74248
|
elements.viewport.scrollTop = nextViewportScrollTop;
|
|
74249
|
+
if (elements.contentScrollRoot && elements.contentScrollRoot !== elements.panel) restoreContentScrollRoot(elements.contentScrollRoot, normalizedSnapshot.contentScrollTop);
|
|
74033
74250
|
elements.panel.scrollTop = normalizedSnapshot.innerScrollTop;
|
|
74034
74251
|
return {
|
|
74252
|
+
contentScrollRoot: elements.contentScrollRoot && elements.contentScrollRoot !== elements.panel ? elements.contentScrollRoot : null,
|
|
74253
|
+
contentScrollTop: normalizedSnapshot.contentScrollTop,
|
|
74254
|
+
finalViewportScrollTop: snapshot.viewportScrollTop,
|
|
74035
74255
|
panel: elements.panel,
|
|
74036
74256
|
previousStyles,
|
|
74037
74257
|
viewport: elements.viewport
|
|
74038
74258
|
};
|
|
74039
74259
|
}
|
|
74040
74260
|
function finalizeFrozenIncomingTab(state) {
|
|
74041
|
-
const transferScrollTop = state.panel.scrollTop;
|
|
74042
74261
|
restorePanel(state.panel, state.previousStyles);
|
|
74043
|
-
state.viewport
|
|
74262
|
+
restoreViewportScroll(state.viewport, state.panel, state.finalViewportScrollTop);
|
|
74044
74263
|
state.panel.scrollTop = 0;
|
|
74264
|
+
if (state.contentScrollRoot) restoreContentScrollRoot(state.contentScrollRoot, state.contentScrollTop);
|
|
74045
74265
|
}
|
|
74046
74266
|
function cleanupFrozenTab(state) {
|
|
74047
74267
|
restorePanel(state.panel, state.previousStyles);
|
|
@@ -74072,6 +74292,11 @@ function resolveTabArea(pathname, area) {
|
|
|
74072
74292
|
if (area) return area;
|
|
74073
74293
|
return isStaticMode() ? "main" : navController.getAreaForPath(pathname);
|
|
74074
74294
|
}
|
|
74295
|
+
function normalizeViewportSelectorOption(viewportSelector) {
|
|
74296
|
+
if (!viewportSelector) return;
|
|
74297
|
+
const normalized = (typeof viewportSelector === "string" ? viewportSelector.split(",") : [...viewportSelector]).map((selector) => selector.trim()).filter((selector) => selector.length > 0);
|
|
74298
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
74299
|
+
}
|
|
74075
74300
|
function readWindowLocation() {
|
|
74076
74301
|
if (typeof window === "undefined") return SERVER_LOCATION;
|
|
74077
74302
|
return {
|
|
@@ -74126,6 +74351,12 @@ function useRoutedTabsLocation() {
|
|
|
74126
74351
|
function collectTabEntries(handle, tabId) {
|
|
74127
74352
|
if (!handle) return [];
|
|
74128
74353
|
const entries = [];
|
|
74354
|
+
const headerShell = handle.getHeaderShell();
|
|
74355
|
+
if (headerShell) entries.push([headerShell, "vt-tab-header-shell"]);
|
|
74356
|
+
const selectionIndicator = handle.getSelectionIndicator();
|
|
74357
|
+
if (selectionIndicator) entries.push([selectionIndicator, "vt-tab-edge"]);
|
|
74358
|
+
const headerForeground = handle.getHeaderForeground();
|
|
74359
|
+
if (headerForeground) entries.push([headerForeground, "vt-tab-header-foreground"]);
|
|
74129
74360
|
const panel = handle.getPanel(tabId);
|
|
74130
74361
|
if (panel) entries.push([panel, "vt-tab-panel"]);
|
|
74131
74362
|
return entries;
|
|
@@ -74133,8 +74364,11 @@ function collectTabEntries(handle, tabId) {
|
|
|
74133
74364
|
function useRoutedCarouselTabs({ queryKey, tabs, initialTab, area, history = "replace", allowUnknownSelection = false, viewportSelector }) {
|
|
74134
74365
|
const { location, router } = useRoutedTabsLocation();
|
|
74135
74366
|
const tabsRef = (0, import_react.useRef)(null);
|
|
74367
|
+
const viewportSelectorValue = (0, import_react.useMemo)(() => normalizeViewportSelectorOption(viewportSelector), [typeof viewportSelector === "string" ? viewportSelector : (viewportSelector ?? []).join("\0")]);
|
|
74136
74368
|
const scrollMemoryByTabRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
74137
74369
|
const frozenTabsRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
74370
|
+
const frozenTabTokenRef = (0, import_react.useRef)(0);
|
|
74371
|
+
const skipNextRestoreTabRef = (0, import_react.useRef)(null);
|
|
74138
74372
|
const selectedFromLocation = (0, import_react.useMemo)(() => resolveSelectedTab({
|
|
74139
74373
|
tabs,
|
|
74140
74374
|
queryKey,
|
|
@@ -74159,7 +74393,7 @@ function useRoutedCarouselTabs({ queryKey, tabs, initialTab, area, history = "re
|
|
|
74159
74393
|
selectedFromLocation,
|
|
74160
74394
|
selectedTab,
|
|
74161
74395
|
tabs,
|
|
74162
|
-
viewportSelector
|
|
74396
|
+
viewportSelector: viewportSelectorValue
|
|
74163
74397
|
});
|
|
74164
74398
|
latestRef.current = {
|
|
74165
74399
|
allowUnknownSelection,
|
|
@@ -74171,45 +74405,89 @@ function useRoutedCarouselTabs({ queryKey, tabs, initialTab, area, history = "re
|
|
|
74171
74405
|
selectedFromLocation,
|
|
74172
74406
|
selectedTab,
|
|
74173
74407
|
tabs,
|
|
74174
|
-
viewportSelector
|
|
74408
|
+
viewportSelector: viewportSelectorValue
|
|
74175
74409
|
};
|
|
74176
|
-
const cleanupFrozenTabById = (0, import_react.useCallback)((tabId) => {
|
|
74177
|
-
const
|
|
74178
|
-
if (!
|
|
74179
|
-
cleanupFrozenTab(
|
|
74410
|
+
const cleanupFrozenTabById = (0, import_react.useCallback)((tabId, token) => {
|
|
74411
|
+
const frozenEntry = frozenTabsRef.current.get(tabId);
|
|
74412
|
+
if (!frozenEntry || token != null && frozenEntry.token !== token) return;
|
|
74413
|
+
cleanupFrozenTab(frozenEntry.state);
|
|
74180
74414
|
frozenTabsRef.current.delete(tabId);
|
|
74181
74415
|
}, []);
|
|
74182
74416
|
const cleanupAllFrozenTabs = (0, import_react.useCallback)(() => {
|
|
74183
|
-
for (const
|
|
74417
|
+
for (const frozenEntry of frozenTabsRef.current.values()) cleanupFrozenTab(frozenEntry.state);
|
|
74184
74418
|
frozenTabsRef.current.clear();
|
|
74185
74419
|
}, []);
|
|
74186
|
-
const
|
|
74420
|
+
const captureTabSnapshot = (0, import_react.useCallback)((tabId, nextViewportSelector) => {
|
|
74421
|
+
const elements = resolveTabScrollElements(tabsRef.current, tabId, nextViewportSelector);
|
|
74422
|
+
if (!elements) return null;
|
|
74423
|
+
return captureTabScrollMemory(elements);
|
|
74424
|
+
}, []);
|
|
74425
|
+
const captureOutgoingTab = (0, import_react.useCallback)((tabId, nextViewportSelector, snapshotOverride) => {
|
|
74187
74426
|
const elements = resolveTabScrollElements(tabsRef.current, tabId, nextViewportSelector);
|
|
74188
74427
|
if (!elements) return;
|
|
74189
|
-
const snapshot = captureTabScrollMemory(elements);
|
|
74428
|
+
const snapshot = snapshotOverride ?? captureTabScrollMemory(elements);
|
|
74190
74429
|
if (!snapshot) return;
|
|
74191
74430
|
scrollMemoryByTabRef.current.set(tabId, snapshot);
|
|
74192
74431
|
cleanupFrozenTabById(tabId);
|
|
74193
|
-
|
|
74432
|
+
const token = ++frozenTabTokenRef.current;
|
|
74433
|
+
frozenTabsRef.current.set(tabId, {
|
|
74434
|
+
token,
|
|
74435
|
+
state: freezeOutgoingTab(elements, snapshot)
|
|
74436
|
+
});
|
|
74437
|
+
return token;
|
|
74194
74438
|
}, [cleanupFrozenTabById]);
|
|
74195
|
-
const prepareIncomingTab = (0, import_react.useCallback)((tabId, nextViewportSelector) => {
|
|
74439
|
+
const prepareIncomingTab = (0, import_react.useCallback)((tabId, nextViewportSelector, fallbackSnapshot) => {
|
|
74196
74440
|
const elements = resolveTabScrollElements(tabsRef.current, tabId, nextViewportSelector);
|
|
74197
|
-
if (!elements) return
|
|
74198
|
-
const snapshot = scrollMemoryByTabRef.current.get(tabId) ?? captureTabScrollMemory(elements);
|
|
74199
|
-
if (!snapshot) return
|
|
74441
|
+
if (!elements) return null;
|
|
74442
|
+
const snapshot = scrollMemoryByTabRef.current.get(tabId) ?? fallbackSnapshot ?? captureTabScrollMemory(elements);
|
|
74443
|
+
if (!snapshot) return null;
|
|
74444
|
+
if (!scrollMemoryByTabRef.current.has(tabId)) scrollMemoryByTabRef.current.set(tabId, snapshot);
|
|
74200
74445
|
cleanupFrozenTabById(tabId);
|
|
74201
|
-
|
|
74202
|
-
|
|
74446
|
+
const token = ++frozenTabTokenRef.current;
|
|
74447
|
+
frozenTabsRef.current.set(tabId, {
|
|
74448
|
+
token,
|
|
74449
|
+
state: freezeIncomingTab(elements, snapshot)
|
|
74450
|
+
});
|
|
74451
|
+
return token;
|
|
74203
74452
|
}, [cleanupFrozenTabById]);
|
|
74204
|
-
const finalizeIncomingTab = (0, import_react.useCallback)((tabId) => {
|
|
74205
|
-
const
|
|
74206
|
-
if (!
|
|
74207
|
-
finalizeFrozenIncomingTab(
|
|
74453
|
+
const finalizeIncomingTab = (0, import_react.useCallback)((tabId, token) => {
|
|
74454
|
+
const frozenEntry = frozenTabsRef.current.get(tabId);
|
|
74455
|
+
if (!frozenEntry || token != null && frozenEntry.token !== token) return;
|
|
74456
|
+
finalizeFrozenIncomingTab(frozenEntry.state);
|
|
74208
74457
|
frozenTabsRef.current.delete(tabId);
|
|
74209
74458
|
}, []);
|
|
74210
74459
|
(0, import_react.useEffect)(() => {
|
|
74211
74460
|
setSelectedTabState((current) => current === selectedFromLocation ? current : selectedFromLocation);
|
|
74212
74461
|
}, [selectedFromLocation]);
|
|
74462
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
74463
|
+
if (skipNextRestoreTabRef.current === selectedTab) {
|
|
74464
|
+
skipNextRestoreTabRef.current = null;
|
|
74465
|
+
return;
|
|
74466
|
+
}
|
|
74467
|
+
const snapshot = scrollMemoryByTabRef.current.get(selectedTab);
|
|
74468
|
+
const elements = resolveTabScrollElements(tabsRef.current, selectedTab, viewportSelectorValue);
|
|
74469
|
+
const panel = elements?.panel ?? tabsRef.current?.getPanel(selectedTab) ?? null;
|
|
74470
|
+
restorePanelContentScroll(panel, snapshot);
|
|
74471
|
+
restorePanelViewportScroll(panel, elements?.viewport ?? null, snapshot);
|
|
74472
|
+
}, [selectedTab, viewportSelectorValue]);
|
|
74473
|
+
(0, import_react.useEffect)(() => {
|
|
74474
|
+
const elements = resolveTabScrollElements(tabsRef.current, selectedTab, viewportSelectorValue);
|
|
74475
|
+
const contentScrollRoot = elements?.contentScrollRoot;
|
|
74476
|
+
if (!elements || !contentScrollRoot || contentScrollRoot === elements.panel) return;
|
|
74477
|
+
const rememberContentScroll = () => {
|
|
74478
|
+
const existingSnapshot = scrollMemoryByTabRef.current.get(selectedTab);
|
|
74479
|
+
if (!existingSnapshot) return;
|
|
74480
|
+
scrollMemoryByTabRef.current.set(selectedTab, {
|
|
74481
|
+
...existingSnapshot,
|
|
74482
|
+
contentScrollTop: contentScrollRoot.scrollTop
|
|
74483
|
+
});
|
|
74484
|
+
};
|
|
74485
|
+
rememberContentScroll();
|
|
74486
|
+
contentScrollRoot.addEventListener("scroll", rememberContentScroll, { passive: true });
|
|
74487
|
+
return () => {
|
|
74488
|
+
contentScrollRoot.removeEventListener("scroll", rememberContentScroll);
|
|
74489
|
+
};
|
|
74490
|
+
}, [selectedTab, viewportSelectorValue]);
|
|
74213
74491
|
(0, import_react.useEffect)(() => {
|
|
74214
74492
|
const validIds = new Set(tabs.map((tab) => tab.id));
|
|
74215
74493
|
for (const tabId of scrollMemoryByTabRef.current.keys()) if (!validIds.has(tabId)) scrollMemoryByTabRef.current.delete(tabId);
|
|
@@ -74226,6 +74504,7 @@ function useRoutedCarouselTabs({ queryKey, tabs, initialTab, area, history = "re
|
|
|
74226
74504
|
const { allowUnknownSelection: allowUnknown, area: latestArea, history: defaultHistory, location: latestLocation, queryKey: latestQueryKey, router: latestRouter, selectedFromLocation: latestSelectedFromLocation, selectedTab: currentTab, tabs: latestTabs, viewportSelector: latestViewportSelector } = latestRef.current;
|
|
74227
74505
|
if (!new Set(latestTabs.map((tab) => tab.id)).has(nextTabId) && !allowUnknown) return;
|
|
74228
74506
|
const nextHistory = options?.history ?? defaultHistory;
|
|
74507
|
+
const transferScroll = options?.transferScroll ?? true;
|
|
74229
74508
|
if (currentTab === nextTabId && latestSelectedFromLocation === nextTabId) return;
|
|
74230
74509
|
const commitSelection = () => {
|
|
74231
74510
|
setSelectedTabState(nextTabId);
|
|
@@ -74249,18 +74528,40 @@ function useRoutedCarouselTabs({ queryKey, tabs, initialTab, area, history = "re
|
|
|
74249
74528
|
}
|
|
74250
74529
|
navController.push(nextArea, href, latestLocation.state);
|
|
74251
74530
|
};
|
|
74531
|
+
if (!transferScroll) {
|
|
74532
|
+
const outgoingSnapshot = captureTabSnapshot(currentTab, latestViewportSelector);
|
|
74533
|
+
if (outgoingSnapshot) scrollMemoryByTabRef.current.set(currentTab, outgoingSnapshot);
|
|
74534
|
+
skipNextRestoreTabRef.current = nextTabId;
|
|
74535
|
+
if (!options?.animate || currentTab === nextTabId) {
|
|
74536
|
+
commitSelection();
|
|
74537
|
+
return;
|
|
74538
|
+
}
|
|
74539
|
+
runViewTransition({
|
|
74540
|
+
intent: {
|
|
74541
|
+
area: resolveTabArea(latestLocation.pathname, latestArea),
|
|
74542
|
+
kind: "tab-carousel",
|
|
74543
|
+
direction: "forward"
|
|
74544
|
+
},
|
|
74545
|
+
collectBeforeEntries: () => collectTabEntries(tabsRef.current, currentTab),
|
|
74546
|
+
collectAfterEntries: () => collectTabEntries(tabsRef.current, nextTabId),
|
|
74547
|
+
update: commitSelection
|
|
74548
|
+
});
|
|
74549
|
+
return;
|
|
74550
|
+
}
|
|
74252
74551
|
const runSelectionWithScrollTransfer = (animated) => {
|
|
74253
|
-
|
|
74552
|
+
const outgoingSnapshot = captureTabSnapshot(currentTab, latestViewportSelector);
|
|
74553
|
+
const incomingSeedSnapshot = scrollMemoryByTabRef.current.get(nextTabId) ?? outgoingSnapshot ?? captureTabSnapshot(nextTabId, latestViewportSelector);
|
|
74554
|
+
const outgoingToken = captureOutgoingTab(currentTab, latestViewportSelector, outgoingSnapshot);
|
|
74254
74555
|
if (!animated) {
|
|
74255
74556
|
(0, import_react_dom.flushSync)(() => {
|
|
74256
74557
|
commitSelection();
|
|
74257
74558
|
});
|
|
74258
|
-
prepareIncomingTab(nextTabId, latestViewportSelector);
|
|
74259
|
-
finalizeIncomingTab(nextTabId);
|
|
74260
|
-
cleanupFrozenTabById(currentTab);
|
|
74559
|
+
const incomingToken = prepareIncomingTab(nextTabId, latestViewportSelector, incomingSeedSnapshot);
|
|
74560
|
+
if (incomingToken != null) finalizeIncomingTab(nextTabId, incomingToken);
|
|
74561
|
+
if (outgoingToken != null) cleanupFrozenTabById(currentTab, outgoingToken);
|
|
74261
74562
|
return;
|
|
74262
74563
|
}
|
|
74263
|
-
let
|
|
74564
|
+
let incomingToken = null;
|
|
74264
74565
|
runViewTransition({
|
|
74265
74566
|
intent: {
|
|
74266
74567
|
area: resolveTabArea(latestLocation.pathname, latestArea),
|
|
@@ -74269,14 +74570,14 @@ function useRoutedCarouselTabs({ queryKey, tabs, initialTab, area, history = "re
|
|
|
74269
74570
|
},
|
|
74270
74571
|
collectBeforeEntries: () => collectTabEntries(tabsRef.current, currentTab),
|
|
74271
74572
|
collectAfterEntries: () => {
|
|
74272
|
-
if (
|
|
74573
|
+
if (incomingToken == null) incomingToken = prepareIncomingTab(nextTabId, latestViewportSelector, incomingSeedSnapshot);
|
|
74273
74574
|
return collectTabEntries(tabsRef.current, nextTabId);
|
|
74274
74575
|
},
|
|
74275
74576
|
update: commitSelection
|
|
74276
74577
|
}).finally(() => {
|
|
74277
|
-
if (
|
|
74278
|
-
finalizeIncomingTab(nextTabId);
|
|
74279
|
-
cleanupFrozenTabById(currentTab);
|
|
74578
|
+
if (incomingToken == null) incomingToken = prepareIncomingTab(nextTabId, latestViewportSelector, incomingSeedSnapshot);
|
|
74579
|
+
if (incomingToken != null) finalizeIncomingTab(nextTabId, incomingToken);
|
|
74580
|
+
if (outgoingToken != null) cleanupFrozenTabById(currentTab, outgoingToken);
|
|
74280
74581
|
});
|
|
74281
74582
|
};
|
|
74282
74583
|
if (!options?.animate || currentTab === nextTabId) {
|
|
@@ -74293,6 +74594,7 @@ function useRoutedCarouselTabs({ queryKey, tabs, initialTab, area, history = "re
|
|
|
74293
74594
|
runSelectionWithScrollTransfer(true);
|
|
74294
74595
|
}, [
|
|
74295
74596
|
captureOutgoingTab,
|
|
74597
|
+
captureTabSnapshot,
|
|
74296
74598
|
cleanupFrozenTabById,
|
|
74297
74599
|
finalizeIncomingTab,
|
|
74298
74600
|
prepareIncomingTab
|