@jfrader/storybook-docs 0.7.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 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: flex;
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 { Children, 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
- rail.style.top = g.fits ? `${g.top}px` : direction === "down" ? `${g.viewportBottom - g.height}px` : "auto";
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
- spacer = direction === "down" ? Math.min(Math.max(spacer, lastY + g.viewportBottom - g.height - g.trackTop), g.maxOffset) : Math.max(Math.min(spacer, lastY + g.top - g.trackTop), 0);
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
- useEffect3(() => {
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
- scrollToElement(match.element);
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
@@ -1857,21 +1886,14 @@ function SearchBox() {
1857
1886
  import { releases as releases2 } from "virtual:storybook-docs/releases";
1858
1887
  import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
1859
1888
  var routeHref = (path) => `#${hrefFor(path)}`;
1860
- var NAV_GROUP_WINDOW = 12;
1861
- function NavGroup({ id, title, active, activeIndex = -1, children }) {
1862
- const [open, setOpen] = useState9(false);
1863
- const [showAll, setShowAll] = useState9(false);
1864
- const expanded = active || open;
1865
- const links = Children.toArray(children);
1866
- const capped = active && links.length > NAV_GROUP_WINDOW;
1867
- const start2 = Math.min(Math.max(activeIndex - NAV_GROUP_WINDOW / 2, 0), Math.max(0, links.length - NAV_GROUP_WINDOW));
1868
- const visibleLinks = capped && !showAll ? links.slice(start2, start2 + NAV_GROUP_WINDOW) : links;
1889
+ function NavGroup({ id, title, active, children }) {
1890
+ const [open, setOpen] = useState9(active);
1869
1891
  return /* @__PURE__ */ jsxs13("div", { role: "group", "aria-labelledby": id, children: [
1870
- /* @__PURE__ */ jsx16("button", { type: "button", className: "grp", id, "aria-expanded": expanded, "aria-controls": `${id}-links`, disabled: active, onClick: () => setOpen(!open), children: title }),
1871
- /* @__PURE__ */ jsxs13("div", { id: `${id}-links`, hidden: !expanded, children: [
1872
- /* @__PURE__ */ jsx16("div", { id: `${id}-window`, children: visibleLinks }),
1873
- capped ? /* @__PURE__ */ jsx16("button", { type: "button", className: "nav-more", "aria-expanded": showAll, "aria-controls": `${id}-window`, onClick: () => setShowAll(!showAll), children: showAll ? "Show less" : `Show all ${links.length}` }) : null
1874
- ] })
1892
+ /* @__PURE__ */ jsxs13("button", { type: "button", className: "grp", id, "aria-expanded": open, "aria-controls": `${id}-links`, onClick: () => setOpen(!open), children: [
1893
+ /* @__PURE__ */ jsx16("span", { children: title }),
1894
+ /* @__PURE__ */ jsx16("svg", { className: "grp-chevron", width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: /* @__PURE__ */ jsx16("path", { d: "m6 4 4 4-4 4" }) })
1895
+ ] }),
1896
+ /* @__PURE__ */ jsx16("div", { id: `${id}-links`, hidden: !open, children })
1875
1897
  ] });
1876
1898
  }
1877
1899
  function parseRoute(hash) {
@@ -1892,9 +1914,20 @@ function DocsApp() {
1892
1914
  const [mode, setMode] = useState9(theme.values?.[0] ?? "dark");
1893
1915
  const [navOpen, setNavOpen] = useState9(false);
1894
1916
  const navRef = useRef5(null);
1895
- useRailFollow(navRef);
1917
+ const pageKey = route.kind === "component" ? `components/${route.slug}` : route.kind;
1896
1918
  const headerRef = useRef5(null);
1897
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);
1898
1931
  useEffect8(() => {
1899
1932
  const header = headerRef.current;
1900
1933
  if (!header) return;
@@ -1914,7 +1947,6 @@ function DocsApp() {
1914
1947
  const onHash = () => {
1915
1948
  setRoute(parseRoute(window.location.hash));
1916
1949
  setNavOpen(false);
1917
- window.scrollTo(0, 0);
1918
1950
  mainRef.current?.focus({ preventScroll: true });
1919
1951
  };
1920
1952
  window.addEventListener("hashchange", onHash);
@@ -1999,7 +2031,7 @@ function DocsApp() {
1999
2031
  ]
2000
2032
  }
2001
2033
  ) : null,
2002
- foundations.length > 0 ? /* @__PURE__ */ jsx16(NavGroup, { id: "nav-grp-foundations", title: "Foundations", active: foundations.some((item) => route.kind === item.kind), children: foundations.map((item) => /* @__PURE__ */ jsx16(
2034
+ foundations.length > 0 ? /* @__PURE__ */ jsx16(NavGroup, { id: "nav-grp-foundations", title: "Design tokens", active: foundations.some((item) => route.kind === item.kind), children: foundations.map((item) => /* @__PURE__ */ jsx16(
2003
2035
  "a",
2004
2036
  {
2005
2037
  href: item.href,
@@ -2011,8 +2043,8 @@ function DocsApp() {
2011
2043
  )) }, `foundations-${activeSlug ?? route.kind}`) : null,
2012
2044
  groups2.map((group, index) => {
2013
2045
  const entries = catalog3.filter((entry) => entry.group === group);
2014
- const activeIndex = entries.findIndex((entry) => entry.slug === activeSlug);
2015
- return /* @__PURE__ */ jsx16(NavGroup, { id: `nav-grp-${index}`, title: group, active: activeIndex !== -1, activeIndex, children: entries.map((entry) => /* @__PURE__ */ jsx16(
2046
+ const active = entries.some((entry) => entry.slug === activeSlug);
2047
+ return /* @__PURE__ */ jsx16(NavGroup, { id: `nav-grp-${index}`, title: group, active, children: entries.map((entry) => /* @__PURE__ */ jsx16(
2016
2048
  "a",
2017
2049
  {
2018
2050
  href: routeHref(`/components/${entry.slug}`),
@@ -2026,8 +2058,8 @@ function DocsApp() {
2026
2058
  )) }, `${group}-${activeSlug ?? route.kind}`);
2027
2059
  })
2028
2060
  ] }) }),
2029
- /* @__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, {}) }),
2030
- route.kind !== "overview" ? /* @__PURE__ */ jsx16(PageRail, { pageKey: activeSlug ?? route.kind }) : null
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
2031
2063
  ] });
2032
2064
  }
2033
2065
 
package/dist/styles.css CHANGED
@@ -194,7 +194,7 @@ body {
194
194
  .rail-track::before {
195
195
  content: '';
196
196
  display: block;
197
- height: var(--sd-rail-offset, 0px);
197
+ height: calc(var(--sd-rail-start, 0px) + var(--sd-rail-offset, 0px));
198
198
  }
199
199
  }
200
200
  .nav {
@@ -202,8 +202,7 @@ body {
202
202
  background: var(--sd-surface);
203
203
  padding: 14px 12px 12px;
204
204
  }
205
- .nav a,
206
- .nav-more {
205
+ .nav a {
207
206
  display: flex;
208
207
  align-items: center;
209
208
  box-sizing: border-box;
@@ -214,16 +213,7 @@ body {
214
213
  font-size: 13.5px;
215
214
  text-decoration: none;
216
215
  }
217
- .nav-more {
218
- width: 100%;
219
- background: none;
220
- border: 0;
221
- font-family: inherit;
222
- cursor: pointer;
223
- text-align: left;
224
- }
225
- .nav a:hover,
226
- .nav-more:hover {
216
+ .nav a:hover {
227
217
  background: var(--sd-surface-hover);
228
218
  color: var(--sd-text);
229
219
  }
@@ -234,23 +224,46 @@ body {
234
224
  }
235
225
  .grp {
236
226
  margin: 3px 0 2px;
237
- padding: 0 10px;
227
+ padding: 8px 10px;
238
228
  font-size: 10.5px;
239
229
  letter-spacing: 0.09em;
240
230
  text-transform: uppercase;
241
231
  color: var(--sd-text-muted);
242
232
  font-weight: 700;
243
- display: block;
233
+ display: flex;
234
+ align-items: center;
235
+ justify-content: space-between;
236
+ gap: 8px;
244
237
  width: 100%;
245
238
  text-align: left;
246
239
  font-family: inherit;
247
240
  background: none;
248
241
  border: 0;
242
+ border-radius: 8px;
249
243
  cursor: pointer;
250
- min-height: 28px;
244
+ min-height: 36px;
245
+ }
246
+ .grp[aria-expanded="true"] {
247
+ background: var(--sd-surface-raised);
248
+ color: var(--sd-text);
249
+ }
250
+ .grp:hover {
251
+ background: var(--sd-surface-hover);
252
+ color: var(--sd-text);
253
+ }
254
+ .grp-chevron {
255
+ flex-shrink: 0;
256
+ transition: transform 150ms ease;
257
+ }
258
+ .grp[aria-expanded="true"] .grp-chevron {
259
+ transform: rotate(90deg);
260
+ }
261
+ @media (prefers-reduced-motion: reduce) {
262
+ .grp-chevron {
263
+ transition: none;
264
+ }
251
265
  }
252
- .grp:focus-visible,
253
- .nav-more:focus-visible {
266
+ .grp:focus-visible {
254
267
  outline: 2px solid var(--sd-focus-ring);
255
268
  outline-offset: 2px;
256
269
  }
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.7.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": {