@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.d.cts CHANGED
@@ -1192,19 +1192,20 @@ declare function Header({ children, sitename, navigation, version, hide, }: {
1192
1192
  };
1193
1193
  }): react_jsx_runtime.JSX.Element;
1194
1194
 
1195
- type BaseProps$1 = React.ComponentPropsWithoutRef<'h1'>;
1195
+ type BaseProps$1 = React__default.ComponentPropsWithoutRef<'h1'>;
1196
+ type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
1196
1197
  type HeadingProps = ({
1197
1198
  display?: false;
1198
1199
  size?: 1 | 2 | 3 | 4 | 5 | 6;
1199
1200
  trim?: 'normal' | 'start' | 'end' | 'both';
1200
- level?: 1 | 2 | 3 | 4 | 5 | 6;
1201
+ level?: HeadingLevel;
1201
1202
  } & BaseProps$1) | ({
1202
1203
  display: true;
1203
1204
  size?: 1 | 2 | 3 | 4;
1204
- level?: 1 | 2 | 3 | 4 | 5 | 6;
1205
+ level?: HeadingLevel;
1205
1206
  trim?: 'normal' | 'start' | 'end' | 'both';
1206
1207
  } & BaseProps$1);
1207
- declare function Heading({ className, trim, size, level, display, ...props }: HeadingProps): react_jsx_runtime.JSX.Element;
1208
+ declare function Heading({ className, trim, size, level, display, id: idProp, children, ...props }: HeadingProps): react_jsx_runtime.JSX.Element;
1208
1209
 
1209
1210
  declare const heroBannerVariants: (props?: ({
1210
1211
  variant?: "white" | "primary-800" | "grey-150" | "accent-800" | "primary-200" | null | undefined;
package/dist/index.d.ts CHANGED
@@ -1192,19 +1192,20 @@ declare function Header({ children, sitename, navigation, version, hide, }: {
1192
1192
  };
1193
1193
  }): react_jsx_runtime.JSX.Element;
1194
1194
 
1195
- type BaseProps$1 = React.ComponentPropsWithoutRef<'h1'>;
1195
+ type BaseProps$1 = React__default.ComponentPropsWithoutRef<'h1'>;
1196
+ type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
1196
1197
  type HeadingProps = ({
1197
1198
  display?: false;
1198
1199
  size?: 1 | 2 | 3 | 4 | 5 | 6;
1199
1200
  trim?: 'normal' | 'start' | 'end' | 'both';
1200
- level?: 1 | 2 | 3 | 4 | 5 | 6;
1201
+ level?: HeadingLevel;
1201
1202
  } & BaseProps$1) | ({
1202
1203
  display: true;
1203
1204
  size?: 1 | 2 | 3 | 4;
1204
- level?: 1 | 2 | 3 | 4 | 5 | 6;
1205
+ level?: HeadingLevel;
1205
1206
  trim?: 'normal' | 'start' | 'end' | 'both';
1206
1207
  } & BaseProps$1);
1207
- declare function Heading({ className, trim, size, level, display, ...props }: HeadingProps): react_jsx_runtime.JSX.Element;
1208
+ declare function Heading({ className, trim, size, level, display, id: idProp, children, ...props }: HeadingProps): react_jsx_runtime.JSX.Element;
1208
1209
 
1209
1210
  declare const heroBannerVariants: (props?: ({
1210
1211
  variant?: "white" | "primary-800" | "grey-150" | "accent-800" | "primary-200" | null | undefined;
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { twMerge } from 'tailwind-merge';
5
5
  import { cva } from 'class-variance-authority';
6
6
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
7
7
  import * as React5 from 'react';
8
- import React5__default, { forwardRef, useEffect, createContext, useState, useContext, useMemo, useRef, useInsertionEffect, useLayoutEffect, Fragment as Fragment$1, createElement, useCallback, Suspense, useId, Component } from 'react';
8
+ import React5__default, { forwardRef, useEffect, createContext, useState, useContext, useMemo, useRef, useInsertionEffect, useLayoutEffect, Fragment as Fragment$1, createElement, useCallback, Suspense, useId, isValidElement, Component } from 'react';
9
9
  import * as Headless4 from '@headlessui/react';
10
10
  import { PopoverGroup, Popover as Popover$1, PopoverButton, PopoverPanel, Dialog as Dialog$1, DialogPanel } from '@headlessui/react';
11
11
  import Link12 from 'next/link';
@@ -17412,16 +17412,31 @@ function FormatToggle({ format, setFormat }) {
17412
17412
 
17413
17413
  // package.json
17414
17414
  var package_default = {
17415
- version: "1.73.0"};
17415
+ version: "1.74.0"};
17416
+ function flattenText(nodes) {
17417
+ if (nodes == null || typeof nodes === "boolean") return "";
17418
+ if (typeof nodes === "string" || typeof nodes === "number") return String(nodes);
17419
+ if (Array.isArray(nodes)) return nodes.map(flattenText).join("");
17420
+ if (isValidElement(nodes)) {
17421
+ const { children } = nodes.props;
17422
+ return flattenText(children);
17423
+ }
17424
+ return "";
17425
+ }
17426
+ function slugify(input) {
17427
+ return input.toLowerCase().trim().replace(/[\s\W]+/g, "-").replace(/^-+|-+$/g, "");
17428
+ }
17416
17429
  function Heading({
17417
17430
  className,
17418
17431
  trim = "normal",
17419
17432
  size = 1,
17420
17433
  level = 1,
17421
17434
  display = false,
17435
+ id: idProp,
17436
+ children,
17422
17437
  ...props
17423
17438
  }) {
17424
- const Element2 = `h${level}`;
17439
+ const Tag = `h${level}`;
17425
17440
  const headingSizeClasses = {
17426
17441
  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))]",
17427
17442
  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))]",
@@ -17453,10 +17468,17 @@ function Heading({
17453
17468
  "after:mt-[calc(var(--leading-trim-end,var(--default-leading-trim-end))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
17454
17469
  ]
17455
17470
  };
17471
+ const computedId = useMemo(() => {
17472
+ if (idProp) return idProp;
17473
+ const text = flattenText(children);
17474
+ return text ? slugify(text) : void 0;
17475
+ }, [idProp, children]);
17456
17476
  return /* @__PURE__ */ jsx(
17457
- Element2,
17477
+ Tag,
17458
17478
  {
17459
17479
  ...props,
17480
+ id: computedId,
17481
+ "data-anchor": true,
17460
17482
  className: clsx12(
17461
17483
  className,
17462
17484
  trimClasses[trim],
@@ -17465,7 +17487,8 @@ function Heading({
17465
17487
  "[--leading-trim-end:var(--heading-leading-trim-end)] [--leading-trim-start:var(--heading-leading-trim-start)]",
17466
17488
  "text-primary-800 dark:text-white",
17467
17489
  sizeClass
17468
- )
17490
+ ),
17491
+ children
17469
17492
  }
17470
17493
  );
17471
17494
  }
@@ -29856,9 +29879,12 @@ function useActiveSectionObserver(tableOfContents) {
29856
29879
  return currentSection;
29857
29880
  }
29858
29881
  function TableOfContents({ tableOfContents }) {
29859
- const [mounted, setMounted] = useState(false);
29860
- useEffect(() => setMounted(true), []);
29861
- const currentSection = useActiveSectionObserver(mounted ? tableOfContents : []);
29882
+ const [ready, setReady] = useState(false);
29883
+ useEffect(() => {
29884
+ const raf = requestAnimationFrame(() => setReady(true));
29885
+ return () => cancelAnimationFrame(raf);
29886
+ }, []);
29887
+ const currentSection = useActiveSectionObserver(ready ? tableOfContents : []);
29862
29888
  const isActive = useMemo(() => {
29863
29889
  const check = (section) => {
29864
29890
  if (section.id === currentSection) return true;
@@ -29866,8 +29892,8 @@ function TableOfContents({ tableOfContents }) {
29866
29892
  };
29867
29893
  return check;
29868
29894
  }, [currentSection]);
29869
- return /* @__PURE__ */ jsx("nav", { "aria-labelledby": "on-this-page-title", className: "w-56", suppressHydrationWarning: true, children: !mounted ? (
29870
- // lightweight placeholder to avoid layout shift (optional)
29895
+ return /* @__PURE__ */ jsx("nav", { "aria-labelledby": "on-this-page-title", className: "w-56", suppressHydrationWarning: true, children: !ready ? (
29896
+ // SSR + initial client paint: deterministic skeleton
29871
29897
  /* @__PURE__ */ jsxs("div", { "aria-hidden": true, className: "mt-3 space-y-2", children: [
29872
29898
  /* @__PURE__ */ jsx("div", { className: "h-4 w-40 animate-pulse rounded bg-black/10 dark:bg-white/10" }),
29873
29899
  /* @__PURE__ */ jsx("div", { className: "h-3 w-32 animate-pulse rounded bg-black/10 dark:bg-white/10" }),
@@ -30557,7 +30583,7 @@ function domToSimple(node) {
30557
30583
  }
30558
30584
  throw new Error("Unsupported node type");
30559
30585
  }
30560
- function getHeadings(slugify = slugifyWithCounter()) {
30586
+ function getHeadings(slugify2 = slugifyWithCounter()) {
30561
30587
  const content = document.querySelector("article");
30562
30588
  if (!content) {
30563
30589
  return [];
@@ -30568,7 +30594,7 @@ function getHeadings(slugify = slugifyWithCounter()) {
30568
30594
  headings.forEach((el) => {
30569
30595
  const simplifiedNode = domToSimple(el);
30570
30596
  const title = getNodeText(simplifiedNode).trim();
30571
- const slugifiedTitle = slugify(title);
30597
+ const slugifiedTitle = slugify2(title);
30572
30598
  const id3 = el.id || slugifiedTitle;
30573
30599
  const level = parseInt(el.tagName[1]);
30574
30600
  const node = { level, id: id3, title, children: [] };
@@ -30591,14 +30617,27 @@ function getHeadings(slugify = slugifyWithCounter()) {
30591
30617
  }
30592
30618
  function usePageHeadings() {
30593
30619
  const [headings, setHeadings] = useState([]);
30594
- const pathname = usePathname();
30595
30620
  useEffect(() => {
30596
- const timer = setTimeout(() => {
30597
- const result = getHeadings();
30598
- setHeadings(result);
30599
- }, 0);
30600
- return () => clearTimeout(timer);
30601
- }, [pathname]);
30621
+ const raf = requestAnimationFrame(() => {
30622
+ setHeadings(getHeadings());
30623
+ });
30624
+ const observer = new MutationObserver(() => {
30625
+ setHeadings(getHeadings());
30626
+ });
30627
+ const article = document.querySelector("article");
30628
+ if (article) {
30629
+ observer.observe(article, {
30630
+ childList: true,
30631
+ subtree: true,
30632
+ attributes: true,
30633
+ attributeFilter: ["id"]
30634
+ });
30635
+ }
30636
+ return () => {
30637
+ cancelAnimationFrame(raf);
30638
+ observer.disconnect();
30639
+ };
30640
+ }, []);
30602
30641
  return headings;
30603
30642
  }
30604
30643
  function createFormStore(opts) {