@dreamlake/dockit 0.2.8 → 0.2.10

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.
@@ -153,6 +153,44 @@ function Topbar({ searchOpen, onOpenSearch, onCloseSearch, query, setQuery }) {
153
153
  });
154
154
  const iconButtonMode = isBelowLg && !searchOpen;
155
155
  const closedWidth = isXlUp ? CLOSED_WIDTH_XL : isLgUp ? CLOSED_WIDTH_LG : CLOSED_WIDTH_MD;
156
+ const brandRef = useRef(null);
157
+ const brandMaxRight = useRef(0);
158
+ const tabsRef = useRef(null);
159
+ const actionsRef = useRef(null);
160
+ const [tabsFit, setTabsFit] = useState(false);
161
+ const [tabsW, setTabsW] = useState(0);
162
+ const [pinLeft, setPinLeft] = useState(0);
163
+ useLayoutEffect(() => {
164
+ const tabsEl = tabsRef.current;
165
+ if (!tabsEl) return;
166
+ const content = document.querySelector("main.doc-content");
167
+ const measure = () => {
168
+ const w = tabsEl.getBoundingClientRect().width;
169
+ const rect = content?.getBoundingClientRect();
170
+ const textLeft = rect ? rect.left + parseFloat(getComputedStyle(content).paddingLeft) : Math.max(SEARCH_GUTTER, (window.innerWidth - SEARCH_MAX_W) / 2);
171
+ const pin = textLeft - 10;
172
+ const brand = brandRef.current?.getBoundingClientRect();
173
+ if (brand) brandMaxRight.current = Math.max(brandMaxRight.current, brand.right);
174
+ const brandClear = brandMaxRight.current + 16 <= pin;
175
+ const actions = actionsRef.current?.getBoundingClientRect();
176
+ const searchLeft = (actions ? actions.left : window.innerWidth) - 8 - closedWidth;
177
+ setTabsW(w);
178
+ setPinLeft(pin);
179
+ setTabsFit(w > 0 && brandClear && pin + w + 16 <= searchLeft);
180
+ };
181
+ measure();
182
+ const ro = new ResizeObserver(measure);
183
+ ro.observe(tabsEl);
184
+ if (content) ro.observe(content);
185
+ if (brandRef.current) ro.observe(brandRef.current);
186
+ if (actionsRef.current) ro.observe(actionsRef.current);
187
+ window.addEventListener("resize", measure);
188
+ return () => {
189
+ ro.disconnect();
190
+ window.removeEventListener("resize", measure);
191
+ };
192
+ }, [closedWidth]);
193
+ const edgePinned = isLgUp && !iconButtonMode && tabsFit;
156
194
  const searchStyle = iconButtonMode ? {
157
195
  // In-flow grid item — sits at the end of column 2 next to TabStrip.
158
196
  // Square footprint, icon-only, click opens the palette directly.
@@ -230,6 +268,7 @@ function Topbar({ searchOpen, onOpenSearch, onCloseSearch, query, setQuery }) {
230
268
  /* @__PURE__ */ jsxs(
231
269
  "a",
232
270
  {
271
+ ref: brandRef,
233
272
  href: "/",
234
273
  className: "flex items-center gap-2.5 pl-[14px] md:pl-[18px] no-underline text-doc-template-ink hover:opacity-80 min-w-[72px] shrink-0",
235
274
  style: {
@@ -328,10 +367,19 @@ function Topbar({ searchOpen, onOpenSearch, onCloseSearch, query, setQuery }) {
328
367
  "aria-label": "Breadcrumb",
329
368
  className: "hidden md:flex items-center gap-1.5 text-doc-template-muted uppercase pointer-events-none overflow-hidden",
330
369
  style: {
331
- gridColumn: 2,
332
- gridRow: 1,
333
- justifySelf: "start",
334
- marginLeft: 8,
370
+ // With the tab strip pinned to the content column's left
371
+ // edge, the breadcrumb moves out of the grid too and starts
372
+ // just right of the strip — otherwise it would fade in
373
+ // underneath the tabs. (gridArea/placeSelf: see the note on
374
+ // `searchStyle` about fixed-positioned grid items.)
375
+ ...edgePinned ? {
376
+ position: "fixed",
377
+ top: 0,
378
+ height: 40,
379
+ left: pinLeft + tabsW + 24,
380
+ gridArea: "auto",
381
+ placeSelf: "stretch"
382
+ } : { gridColumn: 2, gridRow: 1, justifySelf: "start", marginLeft: 8 },
335
383
  fontFamily: "var(--font-doc-template-mono)",
336
384
  fontSize: 10,
337
385
  fontWeight: 500,
@@ -367,7 +415,18 @@ function Topbar({ searchOpen, onOpenSearch, onCloseSearch, query, setQuery }) {
367
415
  minWidth: 0
368
416
  },
369
417
  children: [
370
- /* @__PURE__ */ jsx("div", { className: "flex items-stretch", style: palFade(searchOpen), children: /* @__PURE__ */ jsx(TabStrip, {}) }),
418
+ /* @__PURE__ */ jsx(
419
+ "div",
420
+ {
421
+ ref: tabsRef,
422
+ className: "flex items-stretch",
423
+ style: {
424
+ ...palFade(searchOpen),
425
+ ...edgePinned ? { position: "fixed", top: 0, left: pinLeft, height: 40 } : {}
426
+ },
427
+ children: /* @__PURE__ */ jsx(TabStrip, {})
428
+ }
429
+ ),
371
430
  /* @__PURE__ */ jsxs(
372
431
  "label",
373
432
  {
@@ -456,6 +515,7 @@ function Topbar({ searchOpen, onOpenSearch, onCloseSearch, query, setQuery }) {
456
515
  /* @__PURE__ */ jsx(
457
516
  "div",
458
517
  {
518
+ ref: actionsRef,
459
519
  className: "flex items-stretch gap-2.5 md:gap-3.5 pr-[14px] md:pr-[22px]",
460
520
  style: { gridColumn: 3, gridRow: 1, justifySelf: "end", ...palFade(searchOpen) },
461
521
  children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3.5", children: [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dreamlake/dockit",
3
- "version": "0.2.8",
4
- "description": "The DreamLake documentation shell \u2014 Vike + React + Tailwind v4 + MDX docs framework with sidebar, TOC, search, and theming",
3
+ "version": "0.2.10",
4
+ "description": "The DreamLake documentation shell — Vike + React + Tailwind v4 + MDX docs framework with sidebar, TOC, search, and theming",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "files": [
@@ -37,10 +37,6 @@
37
37
  },
38
38
  "./styles.css": "./dist/styles.css"
39
39
  },
40
- "scripts": {
41
- "build": "vite build",
42
- "typecheck": "tsc --noEmit"
43
- },
44
40
  "peerDependencies": {
45
41
  "@mdx-js/react": ">=3.0.0",
46
42
  "react": ">=19.0.0",
@@ -79,5 +75,9 @@
79
75
  "vite": "^7.0.0",
80
76
  "vite-plugin-dts": "^4.3.0",
81
77
  "tailwindcss": "^4.0.0"
78
+ },
79
+ "scripts": {
80
+ "build": "vite build",
81
+ "typecheck": "tsc --noEmit"
82
82
  }
83
- }
83
+ }
File without changes
File without changes