@nswds/app 1.74.0 → 1.75.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.cjs CHANGED
@@ -58,7 +58,7 @@ var ProgressPrimitive = require('@radix-ui/react-progress');
58
58
  var tailwindVariants = require('tailwind-variants');
59
59
  var ResizablePrimitive = require('react-resizable-panels');
60
60
  var SliderPrimitive = require('@radix-ui/react-slider');
61
- var slugify = require('@sindresorhus/slugify');
61
+ var slugify$1 = require('@sindresorhus/slugify');
62
62
  var zustand = require('zustand');
63
63
  var middleware = require('zustand/middleware');
64
64
 
@@ -17465,16 +17465,31 @@ function FormatToggle({ format, setFormat }) {
17465
17465
 
17466
17466
  // package.json
17467
17467
  var package_default = {
17468
- version: "1.73.0"};
17468
+ version: "1.74.0"};
17469
+ function flattenText(nodes) {
17470
+ if (nodes == null || typeof nodes === "boolean") return "";
17471
+ if (typeof nodes === "string" || typeof nodes === "number") return String(nodes);
17472
+ if (Array.isArray(nodes)) return nodes.map(flattenText).join("");
17473
+ if (React5.isValidElement(nodes)) {
17474
+ const { children } = nodes.props;
17475
+ return flattenText(children);
17476
+ }
17477
+ return "";
17478
+ }
17479
+ function slugify(input) {
17480
+ return input.toLowerCase().trim().replace(/[\s\W]+/g, "-").replace(/^-+|-+$/g, "");
17481
+ }
17469
17482
  function Heading({
17470
17483
  className,
17471
17484
  trim = "normal",
17472
17485
  size = 1,
17473
17486
  level = 1,
17474
17487
  display = false,
17488
+ id: idProp,
17489
+ children,
17475
17490
  ...props
17476
17491
  }) {
17477
- const Element2 = `h${level}`;
17492
+ const Tag = `h${level}`;
17478
17493
  const headingSizeClasses = {
17479
17494
  1: "text-[calc(var(--heading-font-size-1)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-52)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
17480
17495
  2: "text-[calc(var(--heading-font-size-2)_*_var(--heading-font-size-adjust))] leading-[var(--line-height-44)] tracking-[calc(var(--heading-letter-spacing-2)_+_var(--heading-letter-spacing))]",
@@ -17506,10 +17521,17 @@ function Heading({
17506
17521
  "after:mt-[calc(var(--leading-trim-end,var(--default-leading-trim-end))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
17507
17522
  ]
17508
17523
  };
17524
+ const computedId = React5.useMemo(() => {
17525
+ if (idProp) return idProp;
17526
+ const text = flattenText(children);
17527
+ return text ? slugify(text) : void 0;
17528
+ }, [idProp, children]);
17509
17529
  return /* @__PURE__ */ jsxRuntime.jsx(
17510
- Element2,
17530
+ Tag,
17511
17531
  {
17512
17532
  ...props,
17533
+ id: computedId,
17534
+ "data-anchor": true,
17513
17535
  className: clsx12__default.default(
17514
17536
  className,
17515
17537
  trimClasses[trim],
@@ -17518,7 +17540,8 @@ function Heading({
17518
17540
  "[--leading-trim-end:var(--heading-leading-trim-end)] [--leading-trim-start:var(--heading-leading-trim-start)]",
17519
17541
  "text-primary-800 dark:text-white",
17520
17542
  sizeClass
17521
- )
17543
+ ),
17544
+ children
17522
17545
  }
17523
17546
  );
17524
17547
  }
@@ -29909,9 +29932,12 @@ function useActiveSectionObserver(tableOfContents) {
29909
29932
  return currentSection;
29910
29933
  }
29911
29934
  function TableOfContents({ tableOfContents }) {
29912
- const [mounted, setMounted] = React5.useState(false);
29913
- React5.useEffect(() => setMounted(true), []);
29914
- const currentSection = useActiveSectionObserver(mounted ? tableOfContents : []);
29935
+ const [ready, setReady] = React5.useState(false);
29936
+ React5.useEffect(() => {
29937
+ const raf = requestAnimationFrame(() => setReady(true));
29938
+ return () => cancelAnimationFrame(raf);
29939
+ }, []);
29940
+ const currentSection = useActiveSectionObserver(ready ? tableOfContents : []);
29915
29941
  const isActive = React5.useMemo(() => {
29916
29942
  const check = (section) => {
29917
29943
  if (section.id === currentSection) return true;
@@ -29919,8 +29945,8 @@ function TableOfContents({ tableOfContents }) {
29919
29945
  };
29920
29946
  return check;
29921
29947
  }, [currentSection]);
29922
- return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-labelledby": "on-this-page-title", className: "w-56", suppressHydrationWarning: true, children: !mounted ? (
29923
- // lightweight placeholder to avoid layout shift (optional)
29948
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-labelledby": "on-this-page-title", className: "w-56", suppressHydrationWarning: true, children: !ready ? (
29949
+ // SSR + initial client paint: deterministic skeleton
29924
29950
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-hidden": true, className: "mt-3 space-y-2", children: [
29925
29951
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-40 animate-pulse rounded bg-black/10 dark:bg-white/10" }),
29926
29952
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 w-32 animate-pulse rounded bg-black/10 dark:bg-white/10" }),
@@ -30610,7 +30636,7 @@ function domToSimple(node) {
30610
30636
  }
30611
30637
  throw new Error("Unsupported node type");
30612
30638
  }
30613
- function getHeadings(slugify$1 = slugify.slugifyWithCounter()) {
30639
+ function getHeadings(slugify2 = slugify$1.slugifyWithCounter()) {
30614
30640
  const content = document.querySelector("article");
30615
30641
  if (!content) {
30616
30642
  return [];
@@ -30621,7 +30647,7 @@ function getHeadings(slugify$1 = slugify.slugifyWithCounter()) {
30621
30647
  headings.forEach((el) => {
30622
30648
  const simplifiedNode = domToSimple(el);
30623
30649
  const title = getNodeText(simplifiedNode).trim();
30624
- const slugifiedTitle = slugify$1(title);
30650
+ const slugifiedTitle = slugify2(title);
30625
30651
  const id3 = el.id || slugifiedTitle;
30626
30652
  const level = parseInt(el.tagName[1]);
30627
30653
  const node = { level, id: id3, title, children: [] };
@@ -30644,14 +30670,27 @@ function getHeadings(slugify$1 = slugify.slugifyWithCounter()) {
30644
30670
  }
30645
30671
  function usePageHeadings() {
30646
30672
  const [headings, setHeadings] = React5.useState([]);
30647
- const pathname = navigation.usePathname();
30648
30673
  React5.useEffect(() => {
30649
- const timer = setTimeout(() => {
30650
- const result = getHeadings();
30651
- setHeadings(result);
30652
- }, 0);
30653
- return () => clearTimeout(timer);
30654
- }, [pathname]);
30674
+ const raf = requestAnimationFrame(() => {
30675
+ setHeadings(getHeadings());
30676
+ });
30677
+ const observer = new MutationObserver(() => {
30678
+ setHeadings(getHeadings());
30679
+ });
30680
+ const article = document.querySelector("article");
30681
+ if (article) {
30682
+ observer.observe(article, {
30683
+ childList: true,
30684
+ subtree: true,
30685
+ attributes: true,
30686
+ attributeFilter: ["id"]
30687
+ });
30688
+ }
30689
+ return () => {
30690
+ cancelAnimationFrame(raf);
30691
+ observer.disconnect();
30692
+ };
30693
+ }, []);
30655
30694
  return headings;
30656
30695
  }
30657
30696
  function createFormStore(opts) {