@dreamlake/dockit 0.2.11 → 0.2.13
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.
|
@@ -5,6 +5,7 @@ import { tabForUrl, TABS, urlInTab } from "../lib/tabs.js";
|
|
|
5
5
|
import { pages } from "../lib/navigation.js";
|
|
6
6
|
import { useHiddenToggle } from "../lib/use-hidden-toggle.js";
|
|
7
7
|
const SPRING = "cubic-bezier(0.4, 0.7, 0.3, 1)";
|
|
8
|
+
const SSR_BAR_BOTTOM = -13;
|
|
8
9
|
function TabStrip() {
|
|
9
10
|
const { urlPathname } = usePageContext();
|
|
10
11
|
const activeTab = tabForUrl(urlPathname);
|
|
@@ -21,28 +22,31 @@ function TabStrip() {
|
|
|
21
22
|
const [bar, setBar] = useState({
|
|
22
23
|
left: 0,
|
|
23
24
|
width: 0,
|
|
25
|
+
bottom: SSR_BAR_BOTTOM,
|
|
24
26
|
ready: false
|
|
25
27
|
});
|
|
26
28
|
const targetTab = hovered ?? activeTab;
|
|
27
|
-
|
|
29
|
+
function measure() {
|
|
28
30
|
const container = containerRef.current;
|
|
29
31
|
const target = linkRefs.current[targetTab];
|
|
30
32
|
if (!container || !target) return;
|
|
31
33
|
const cR = container.getBoundingClientRect();
|
|
32
34
|
const tR = target.getBoundingClientRect();
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
const hR = container.closest("header")?.getBoundingClientRect();
|
|
36
|
+
const next = {
|
|
37
|
+
left: tR.left - cR.left,
|
|
38
|
+
width: tR.width,
|
|
39
|
+
bottom: hR ? cR.bottom - hR.bottom : SSR_BAR_BOTTOM,
|
|
40
|
+
ready: true
|
|
41
|
+
};
|
|
42
|
+
setBar(
|
|
43
|
+
(prev) => prev.ready && prev.left === next.left && prev.width === next.width && prev.bottom === next.bottom ? prev : next
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
useLayoutEffect(measure);
|
|
35
47
|
useLayoutEffect(() => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const target = linkRefs.current[targetTab];
|
|
39
|
-
if (!container || !target) return;
|
|
40
|
-
const cR = container.getBoundingClientRect();
|
|
41
|
-
const tR = target.getBoundingClientRect();
|
|
42
|
-
setBar((b) => ({ ...b, left: tR.left - cR.left, width: tR.width }));
|
|
43
|
-
}
|
|
44
|
-
window.addEventListener("resize", onResize);
|
|
45
|
-
return () => window.removeEventListener("resize", onResize);
|
|
48
|
+
window.addEventListener("resize", measure);
|
|
49
|
+
return () => window.removeEventListener("resize", measure);
|
|
46
50
|
}, [targetTab]);
|
|
47
51
|
if (visibleTabs.length === 0) return null;
|
|
48
52
|
return /* @__PURE__ */ jsxs(
|
|
@@ -58,8 +62,9 @@ function TabStrip() {
|
|
|
58
62
|
// intrinsic width (`shrink-0` on the <li>) and the strip clips
|
|
59
63
|
// whatever no longer fits rather than reflowing.
|
|
60
64
|
//
|
|
61
|
-
// `clip`, not `hidden`: the underbar below sits at
|
|
62
|
-
// deliberately outside this box
|
|
65
|
+
// `clip`, not `hidden`: the underbar below sits at a negative
|
|
66
|
+
// bottom offset, deliberately outside this box (whenever the strip
|
|
67
|
+
// is shorter than the topbar). Setting `overflow-x: hidden`
|
|
63
68
|
// makes CSS compute the still-`visible` overflow-y to `auto`,
|
|
64
69
|
// which would clip that bar away (and risk a stray scrollbar).
|
|
65
70
|
// `clip` is the one overflow value that leaves the other axis
|
|
@@ -109,7 +114,7 @@ function TabStrip() {
|
|
|
109
114
|
"aria-hidden": true,
|
|
110
115
|
style: {
|
|
111
116
|
position: "absolute",
|
|
112
|
-
bottom:
|
|
117
|
+
bottom: bar.bottom,
|
|
113
118
|
left: 0,
|
|
114
119
|
height: 3,
|
|
115
120
|
background: "var(--color-doc-template-ink)",
|
|
@@ -160,7 +160,7 @@ function Topbar({ searchOpen, onOpenSearch, onCloseSearch, query, setQuery }) {
|
|
|
160
160
|
const [tabsFit, setTabsFit] = useState(false);
|
|
161
161
|
const [tabsW, setTabsW] = useState(0);
|
|
162
162
|
const [pinLeft, setPinLeft] = useState(0);
|
|
163
|
-
const [
|
|
163
|
+
const [searchPinLeft, setSearchPinLeft] = useState(null);
|
|
164
164
|
useLayoutEffect(() => {
|
|
165
165
|
const tabsEl = tabsRef.current;
|
|
166
166
|
if (!tabsEl) return;
|
|
@@ -178,13 +178,13 @@ function Topbar({ searchOpen, onOpenSearch, onCloseSearch, query, setQuery }) {
|
|
|
178
178
|
const brandClear = brandMaxRight.current + 16 <= pin;
|
|
179
179
|
const actions = actionsRef.current?.getBoundingClientRect();
|
|
180
180
|
const actionsLeft = actions ? actions.left : window.innerWidth;
|
|
181
|
-
const pinnedSearchLeft = textRight
|
|
181
|
+
const pinnedSearchLeft = textRight;
|
|
182
182
|
const packedSearchLeft = actionsLeft - 8 - closedWidth;
|
|
183
183
|
const fits = (searchLeft) => w > 0 && brandClear && pin + w + 16 <= searchLeft;
|
|
184
|
-
const fullPin = textRight + 16 <= actionsLeft && fits(pinnedSearchLeft);
|
|
184
|
+
const fullPin = textRight + closedWidth + 16 <= actionsLeft && fits(pinnedSearchLeft);
|
|
185
185
|
setTabsW(w);
|
|
186
186
|
setPinLeft(pin);
|
|
187
|
-
|
|
187
|
+
setSearchPinLeft(fullPin ? pinnedSearchLeft : null);
|
|
188
188
|
setTabsFit(fullPin || fits(packedSearchLeft));
|
|
189
189
|
};
|
|
190
190
|
measure();
|
|
@@ -244,14 +244,17 @@ function Topbar({ searchOpen, onOpenSearch, onCloseSearch, query, setQuery }) {
|
|
|
244
244
|
placeSelf: "stretch",
|
|
245
245
|
boxShadow: "0 4px 14px rgb(0 0 0 / 0.06)",
|
|
246
246
|
transition: `left ${EXPAND_MS}ms ${EXPAND_EASE}, right ${EXPAND_MS}ms ${EXPAND_EASE}, background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease`
|
|
247
|
-
} :
|
|
248
|
-
// Closed,
|
|
249
|
-
// edge
|
|
247
|
+
} : searchPinLeft != null ? {
|
|
248
|
+
// Closed, sitting just outside the content column with
|
|
249
|
+
// its left edge on the column's right border (mirrors
|
|
250
|
+
// the tab strip pinned to the left edge). Left-anchored,
|
|
251
|
+
// so breakpoint width changes grow it away from the
|
|
252
|
+
// column and the shared border never moves.
|
|
250
253
|
// (gridArea/placeSelf: see the note above about
|
|
251
254
|
// fixed-positioned grid items.)
|
|
252
255
|
position: "fixed",
|
|
253
256
|
top: 6,
|
|
254
|
-
|
|
257
|
+
left: searchPinLeft,
|
|
255
258
|
width: closedWidth,
|
|
256
259
|
maxWidth: closedWidth,
|
|
257
260
|
height: 28,
|
package/package.json
CHANGED