@jfrader/storybook-docs 0.8.0 → 0.9.0
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/index.css +7 -2
- package/dist/index.js +60 -21
- package/dist/styles.css +1 -1
- package/dist/toc.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -115,11 +115,13 @@
|
|
|
115
115
|
}
|
|
116
116
|
.toc-track {
|
|
117
117
|
display: block;
|
|
118
|
+
min-width: 0;
|
|
118
119
|
grid-column: 3;
|
|
119
120
|
grid-row: 2;
|
|
120
121
|
}
|
|
121
122
|
.toc {
|
|
122
123
|
display: block;
|
|
124
|
+
min-width: 0;
|
|
123
125
|
padding: 34px 18px 40px 6px;
|
|
124
126
|
font-size: 12.5px;
|
|
125
127
|
}
|
|
@@ -140,9 +142,12 @@
|
|
|
140
142
|
border-left: 1px solid var(--sd-border);
|
|
141
143
|
}
|
|
142
144
|
.toc-link {
|
|
143
|
-
display:
|
|
144
|
-
align-items: center;
|
|
145
|
+
display: block;
|
|
145
146
|
width: 100%;
|
|
147
|
+
min-width: 0;
|
|
148
|
+
overflow: hidden;
|
|
149
|
+
white-space: nowrap;
|
|
150
|
+
text-overflow: ellipsis;
|
|
146
151
|
min-block-size: 24px;
|
|
147
152
|
padding: 4px 8px;
|
|
148
153
|
font: inherit;
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { createRoot } from "react-dom/client";
|
|
|
5
5
|
import { site as site3, themeCss, theme as theme2 } from "virtual:storybook-docs/site";
|
|
6
6
|
|
|
7
7
|
// src/app.tsx
|
|
8
|
-
import { useEffect as useEffect8, useRef as useRef5, useState as useState9 } from "react";
|
|
8
|
+
import { useEffect as useEffect8, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState9 } from "react";
|
|
9
9
|
import { catalog as catalog3, groups as groups2 } from "virtual:storybook-docs/catalog";
|
|
10
10
|
import { pages, site as site2, theme } from "virtual:storybook-docs/site";
|
|
11
11
|
|
|
@@ -522,11 +522,12 @@ function LazySection({ children, placeholder = "\u2026" }) {
|
|
|
522
522
|
}
|
|
523
523
|
|
|
524
524
|
// src/toc.tsx
|
|
525
|
-
import { useCallback, useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
525
|
+
import { useCallback, useEffect as useEffect3, useLayoutEffect, useRef as useRef2, useState as useState3 } from "react";
|
|
526
526
|
|
|
527
527
|
// src/rail.ts
|
|
528
528
|
var RAIL_MEDIA = "(min-width: 1180px)";
|
|
529
529
|
var RAIL_GAP = 20;
|
|
530
|
+
var RAIL_SETTLE_MS = 120;
|
|
530
531
|
function followRail(rail, header) {
|
|
531
532
|
const track = rail.parentElement;
|
|
532
533
|
if (!track) return () => {
|
|
@@ -535,6 +536,8 @@ function followRail(rail, header) {
|
|
|
535
536
|
let lastY = window.scrollY;
|
|
536
537
|
let direction = "down";
|
|
537
538
|
let spacer = 0;
|
|
539
|
+
let scrolling = false;
|
|
540
|
+
let settleTimer;
|
|
538
541
|
const geometry = () => {
|
|
539
542
|
const top = header.offsetHeight + RAIL_GAP;
|
|
540
543
|
const viewportBottom = window.innerHeight - RAIL_GAP;
|
|
@@ -544,8 +547,8 @@ function followRail(rail, header) {
|
|
|
544
547
|
viewportBottom,
|
|
545
548
|
height,
|
|
546
549
|
fits: top + height <= viewportBottom,
|
|
547
|
-
trackTop: track.getBoundingClientRect().top + window.scrollY,
|
|
548
|
-
maxOffset: Math.max(0, track.clientHeight - height)
|
|
550
|
+
trackTop: track.getBoundingClientRect().top + window.scrollY + RAIL_GAP,
|
|
551
|
+
maxOffset: Math.max(0, track.clientHeight - height - RAIL_GAP)
|
|
549
552
|
};
|
|
550
553
|
};
|
|
551
554
|
const clear = () => {
|
|
@@ -558,17 +561,28 @@ function followRail(rail, header) {
|
|
|
558
561
|
return;
|
|
559
562
|
}
|
|
560
563
|
spacer = g.fits ? 0 : Math.min(spacer, g.maxOffset);
|
|
564
|
+
track.style.setProperty("--sd-rail-start", `${RAIL_GAP}px`);
|
|
561
565
|
track.style.setProperty("--sd-rail-offset", `${spacer}px`);
|
|
562
566
|
rail.style.position = "sticky";
|
|
563
|
-
|
|
567
|
+
const parkedTop = g.fits ? g.top : g.viewportBottom - g.height;
|
|
568
|
+
const armedTop = Number.parseFloat(rail.style.top);
|
|
569
|
+
const stableTop = scrolling && Number.isFinite(armedTop) ? Math.min(armedTop, parkedTop) : parkedTop;
|
|
570
|
+
rail.style.top = g.fits || direction === "down" ? `${stableTop}px` : "auto";
|
|
564
571
|
rail.style.bottom = g.fits || direction === "down" ? "auto" : `${window.innerHeight - g.top - g.height}px`;
|
|
565
572
|
};
|
|
566
573
|
const onScroll = () => {
|
|
567
574
|
const y = window.scrollY;
|
|
575
|
+
scrolling = true;
|
|
576
|
+
window.clearTimeout(settleTimer);
|
|
577
|
+
settleTimer = window.setTimeout(() => {
|
|
578
|
+
scrolling = false;
|
|
579
|
+
arm();
|
|
580
|
+
}, RAIL_SETTLE_MS);
|
|
568
581
|
const next = y > lastY ? "down" : y < lastY ? "up" : direction;
|
|
569
582
|
if (next !== direction && media.matches) {
|
|
570
583
|
const g = geometry();
|
|
571
|
-
|
|
584
|
+
const armedTop = Number.parseFloat(rail.style.top);
|
|
585
|
+
spacer = direction === "down" ? Math.min(Math.max(spacer, lastY + (Number.isFinite(armedTop) ? armedTop : g.viewportBottom - g.height) - g.trackTop), g.maxOffset) : Math.max(Math.min(spacer, lastY + g.top - g.trackTop), 0);
|
|
572
586
|
direction = next;
|
|
573
587
|
arm(g);
|
|
574
588
|
}
|
|
@@ -586,6 +600,7 @@ function followRail(rail, header) {
|
|
|
586
600
|
arm();
|
|
587
601
|
return () => {
|
|
588
602
|
observer.disconnect();
|
|
603
|
+
window.clearTimeout(settleTimer);
|
|
589
604
|
window.removeEventListener("scroll", onScroll);
|
|
590
605
|
window.removeEventListener("resize", relayout);
|
|
591
606
|
media.removeEventListener("change", relayout);
|
|
@@ -615,13 +630,13 @@ function storyLink(location, story) {
|
|
|
615
630
|
return `${base}${hashPath(location.hash)}?${new URLSearchParams({ [STORY_PARAM]: story })}`;
|
|
616
631
|
}
|
|
617
632
|
var slugify = (text) => text.normalize("NFKD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
618
|
-
function useRailFollow(ref, ready = true) {
|
|
619
|
-
|
|
633
|
+
function useRailFollow(ref, ready = true, pageKey) {
|
|
634
|
+
useLayoutEffect(() => {
|
|
620
635
|
const element = ref.current;
|
|
621
636
|
const header = element?.closest(".app")?.querySelector(".top");
|
|
622
|
-
if (!element || !header) return;
|
|
637
|
+
if (!ready || !element || !header) return;
|
|
623
638
|
return followRail(element, header);
|
|
624
|
-
}, [ready, ref]);
|
|
639
|
+
}, [ready, ref, pageKey]);
|
|
625
640
|
}
|
|
626
641
|
function scanPage(root, pageKey) {
|
|
627
642
|
const used = /* @__PURE__ */ new Set();
|
|
@@ -677,11 +692,14 @@ function scanPage(root, pageKey) {
|
|
|
677
692
|
var signature = (scan) => `${scan.pageKey}|${scan.sections.map((s) => `${s.id}(${s.subs.map((sub) => sub.id).join("+")}):${s.stories.map((st) => `${st.id}:${st.name}`).join(",")}`).join(";")}`;
|
|
678
693
|
var prefersReducedMotion = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
679
694
|
function scrollToElement(element) {
|
|
695
|
+
const hash = window.location.hash;
|
|
680
696
|
element.scrollIntoView({ behavior: prefersReducedMotion() ? "auto" : "smooth", block: "start" });
|
|
681
697
|
let ticks = SETTLE_TICKS;
|
|
682
698
|
let lastY = window.scrollY;
|
|
699
|
+
let timer;
|
|
700
|
+
let cancelled = false;
|
|
683
701
|
const settle = () => {
|
|
684
|
-
if (!element.isConnected || ticks === 0) return;
|
|
702
|
+
if (cancelled || window.location.hash !== hash || !element.isConnected || ticks === 0) return;
|
|
685
703
|
ticks -= 1;
|
|
686
704
|
const moving = window.scrollY !== lastY;
|
|
687
705
|
lastY = window.scrollY;
|
|
@@ -689,9 +707,13 @@ function scrollToElement(element) {
|
|
|
689
707
|
element.scrollIntoView({ behavior: "auto", block: "start" });
|
|
690
708
|
lastY = window.scrollY;
|
|
691
709
|
}
|
|
692
|
-
window.setTimeout(settle, SETTLE_TICK_MS);
|
|
710
|
+
timer = window.setTimeout(settle, SETTLE_TICK_MS);
|
|
711
|
+
};
|
|
712
|
+
timer = window.setTimeout(settle, SETTLE_TICK_MS);
|
|
713
|
+
return () => {
|
|
714
|
+
cancelled = true;
|
|
715
|
+
window.clearTimeout(timer);
|
|
693
716
|
};
|
|
694
|
-
window.setTimeout(settle, SETTLE_TICK_MS);
|
|
695
717
|
}
|
|
696
718
|
function useActiveIds(scan) {
|
|
697
719
|
const [active, setActive] = useState3({ section: null, story: null });
|
|
@@ -721,6 +743,12 @@ function PageRail({ pageKey }) {
|
|
|
721
743
|
pageKeyRef.current = pageKey;
|
|
722
744
|
const [target, setTarget] = useState3(() => storyFromHash(window.location.hash));
|
|
723
745
|
const flashed = useRef2(null);
|
|
746
|
+
const cancelScroll = useRef2(null);
|
|
747
|
+
const go = useCallback((element) => {
|
|
748
|
+
cancelScroll.current?.();
|
|
749
|
+
cancelScroll.current = scrollToElement(element);
|
|
750
|
+
}, []);
|
|
751
|
+
useEffect3(() => () => cancelScroll.current?.(), []);
|
|
724
752
|
useEffect3(() => {
|
|
725
753
|
const main = document.querySelector(".main");
|
|
726
754
|
if (!main) return;
|
|
@@ -752,17 +780,16 @@ function PageRail({ pageKey }) {
|
|
|
752
780
|
if (!target || !scan || scan.pageKey !== pageKey) return;
|
|
753
781
|
const match = scan.frames.find((frame) => frame.story === target) ?? scan.frames.find((frame) => frame.story.toLowerCase() === target.toLowerCase()) ?? scan.frames.find((frame) => frame.name === target) ?? scan.frames.find((frame) => frame.name.toLowerCase() === target.toLowerCase());
|
|
754
782
|
if (!match) return;
|
|
755
|
-
|
|
783
|
+
go(match.element);
|
|
756
784
|
flashed.current?.classList.remove("toc-flash");
|
|
757
785
|
match.element.classList.add("toc-flash");
|
|
758
786
|
flashed.current = match.element;
|
|
759
787
|
window.setTimeout(() => match.element.classList.remove("toc-flash"), FLASH_MS);
|
|
760
788
|
setTarget(null);
|
|
761
|
-
}, [target, scan, pageKey]);
|
|
789
|
+
}, [target, scan, pageKey, go]);
|
|
762
790
|
const railRef = useRef2(null);
|
|
763
791
|
useRailFollow(railRef, scan !== null);
|
|
764
792
|
const active = useActiveIds(scan);
|
|
765
|
-
const go = useCallback((element) => scrollToElement(element), []);
|
|
766
793
|
if (!scan) return null;
|
|
767
794
|
return /* @__PURE__ */ jsx5(Fragment, { children: scan.sections.length > 0 ? /* @__PURE__ */ jsx5("div", { className: "rail-track toc-track", children: /* @__PURE__ */ jsxs3("aside", { className: "toc", "aria-label": "On this page", ref: railRef, children: [
|
|
768
795
|
/* @__PURE__ */ jsx5("div", { className: "toc-title", children: "On this page" }),
|
|
@@ -772,17 +799,19 @@ function PageRail({ pageKey }) {
|
|
|
772
799
|
{
|
|
773
800
|
type: "button",
|
|
774
801
|
className: "toc-link",
|
|
802
|
+
title: section.title,
|
|
775
803
|
"aria-current": active.section === section.id ? "location" : void 0,
|
|
776
804
|
onClick: () => go(section.heading),
|
|
777
805
|
children: section.title
|
|
778
806
|
}
|
|
779
807
|
),
|
|
780
|
-
section.subs.length > 0 ? /* @__PURE__ */ jsx5("ul", { children: section.subs.map((sub) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5("button", { type: "button", className: "toc-link toc-sub", onClick: () => go(sub.element), children: sub.title }) }, sub.id)) }) : null,
|
|
808
|
+
section.subs.length > 0 ? /* @__PURE__ */ jsx5("ul", { children: section.subs.map((sub) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5("button", { type: "button", className: "toc-link toc-sub", title: sub.title, onClick: () => go(sub.element), children: sub.title }) }, sub.id)) }) : null,
|
|
781
809
|
section.stories.length > 0 ? /* @__PURE__ */ jsx5("ul", { children: section.stories.map((story) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(
|
|
782
810
|
"button",
|
|
783
811
|
{
|
|
784
812
|
type: "button",
|
|
785
813
|
className: "toc-link toc-story",
|
|
814
|
+
title: story.name,
|
|
786
815
|
"aria-current": active.story === story.id ? "location" : void 0,
|
|
787
816
|
onClick: () => go(story.element),
|
|
788
817
|
children: story.name
|
|
@@ -1885,9 +1914,20 @@ function DocsApp() {
|
|
|
1885
1914
|
const [mode, setMode] = useState9(theme.values?.[0] ?? "dark");
|
|
1886
1915
|
const [navOpen, setNavOpen] = useState9(false);
|
|
1887
1916
|
const navRef = useRef5(null);
|
|
1888
|
-
|
|
1917
|
+
const pageKey = route.kind === "component" ? `components/${route.slug}` : route.kind;
|
|
1889
1918
|
const headerRef = useRef5(null);
|
|
1890
1919
|
const mainRef = useRef5(null);
|
|
1920
|
+
const renderedPage = useRef5(pageKey);
|
|
1921
|
+
useLayoutEffect2(() => {
|
|
1922
|
+
if (renderedPage.current !== pageKey) {
|
|
1923
|
+
const reset = () => window.scrollTo({ top: 0, left: 0, behavior: "instant" });
|
|
1924
|
+
reset();
|
|
1925
|
+
const frame = requestAnimationFrame(reset);
|
|
1926
|
+
renderedPage.current = pageKey;
|
|
1927
|
+
return () => cancelAnimationFrame(frame);
|
|
1928
|
+
}
|
|
1929
|
+
}, [pageKey]);
|
|
1930
|
+
useRailFollow(navRef, true, pageKey);
|
|
1891
1931
|
useEffect8(() => {
|
|
1892
1932
|
const header = headerRef.current;
|
|
1893
1933
|
if (!header) return;
|
|
@@ -1907,7 +1947,6 @@ function DocsApp() {
|
|
|
1907
1947
|
const onHash = () => {
|
|
1908
1948
|
setRoute(parseRoute(window.location.hash));
|
|
1909
1949
|
setNavOpen(false);
|
|
1910
|
-
window.scrollTo(0, 0);
|
|
1911
1950
|
mainRef.current?.focus({ preventScroll: true });
|
|
1912
1951
|
};
|
|
1913
1952
|
window.addEventListener("hashchange", onHash);
|
|
@@ -2019,8 +2058,8 @@ function DocsApp() {
|
|
|
2019
2058
|
)) }, `${group}-${activeSlug ?? route.kind}`);
|
|
2020
2059
|
})
|
|
2021
2060
|
] }) }),
|
|
2022
|
-
/* @__PURE__ */ jsx16("main", { id: "main", className: "main", tabIndex: -1, ref: mainRef, children: route.kind === "component" ? /* @__PURE__ */ jsx16(ComponentPage, { entry: catalog3.find((entry) => entry.slug === route.slug) }) : route.kind === "color" ? /* @__PURE__ */ jsx16(ColorPage, {}) : route.kind === "typography" ? /* @__PURE__ */ jsx16(TypePage, {}) : route.kind === "spacing" ? /* @__PURE__ */ jsx16(SpacingPage, {}) : route.kind === "effects" ? /* @__PURE__ */ jsx16(EffectsPage, {}) : route.kind === "releases" ? /* @__PURE__ */ jsx16(ReleasesPage, {}) : /* @__PURE__ */ jsx16(OverviewPage, {}) }),
|
|
2023
|
-
route.kind !== "overview" ? /* @__PURE__ */ jsx16(PageRail, { pageKey
|
|
2061
|
+
/* @__PURE__ */ jsx16("main", { id: "main", className: "main", tabIndex: -1, ref: mainRef, children: route.kind === "component" ? /* @__PURE__ */ jsx16(ComponentPage, { entry: catalog3.find((entry) => entry.slug === route.slug) }, pageKey) : route.kind === "color" ? /* @__PURE__ */ jsx16(ColorPage, {}) : route.kind === "typography" ? /* @__PURE__ */ jsx16(TypePage, {}) : route.kind === "spacing" ? /* @__PURE__ */ jsx16(SpacingPage, {}) : route.kind === "effects" ? /* @__PURE__ */ jsx16(EffectsPage, {}) : route.kind === "releases" ? /* @__PURE__ */ jsx16(ReleasesPage, {}) : /* @__PURE__ */ jsx16(OverviewPage, {}) }),
|
|
2062
|
+
route.kind !== "overview" ? /* @__PURE__ */ jsx16(PageRail, { pageKey }, pageKey) : null
|
|
2024
2063
|
] });
|
|
2025
2064
|
}
|
|
2026
2065
|
|
package/dist/styles.css
CHANGED
package/dist/toc.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare function hashPath(hash: string): string;
|
|
|
6
6
|
/** The `?story=` deep-link target of a hash, if any. */
|
|
7
7
|
export declare function storyFromHash(hash: string): string | null;
|
|
8
8
|
export declare function storyLink(location: Location, story: string): string;
|
|
9
|
-
export declare function useRailFollow(ref: RefObject<HTMLElement | null>, ready?: boolean): void;
|
|
9
|
+
export declare function useRailFollow(ref: RefObject<HTMLElement | null>, ready?: boolean, pageKey?: string): void;
|
|
10
10
|
/** The "On this page" rail and the `?story=` deep-link landing. */
|
|
11
11
|
export declare function PageRail({ pageKey }: {
|
|
12
12
|
pageKey: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jfrader/storybook-docs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A documentation front for any design system that has Storybook: navigation, live examples and API tables are generated from the story files themselves.",
|
|
6
6
|
"exports": {
|