@bug-on/m3-expressive 1.3.2 → 1.3.3

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/layout.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as class_variance_authority_types from 'class-variance-authority/types';
2
2
  import * as React$1 from 'react';
3
- import { HTMLAttributes, ReactNode } from 'react';
3
+ import React__default, { HTMLAttributes, ReactNode } from 'react';
4
4
  import { HTMLMotionProps } from 'motion/react';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import { b as ScrollAreaProps } from './scroll-area-CVS6HyLl.mjs';
@@ -861,6 +861,12 @@ interface ToCItem {
861
861
  id: string;
862
862
  /** Human-readable label shown in the ToC. */
863
863
  label: string;
864
+ /**
865
+ * Heading level depth (1 for h2, 2 for h3, etc.).
866
+ * Indents lower-level items visually.
867
+ * @default 1
868
+ */
869
+ depth?: number;
864
870
  }
865
871
  /**
866
872
  * Props for the `TableOfContents` component.
@@ -881,6 +887,11 @@ interface TableOfContentsProps {
881
887
  * @default { type: "hover" }
882
888
  */
883
889
  scrollAreaProps?: Omit<ScrollAreaProps, "children">;
890
+ /**
891
+ * Optional ref to the scroll container element (e.g. ScrollArea viewport).
892
+ * If provided, IntersectionObserver will use this container as its root.
893
+ */
894
+ scrollContainerRef?: React__default.RefObject<HTMLElement | null | undefined>;
884
895
  }
885
896
  /**
886
897
  * Table of Contents sidebar component.
@@ -897,9 +908,9 @@ interface TableOfContentsProps {
897
908
  * @example
898
909
  * ```tsx
899
910
  * const toc: ToCItem[] = [
900
- * { id: "overview", label: "Overview" },
901
- * { id: "props", label: "Props" },
902
- * { id: "examples", label: "Examples" },
911
+ * { id: "overview", label: "Overview", depth: 1 },
912
+ * { id: "props", label: "Props", depth: 2 },
913
+ * { id: "examples", label: "Examples", depth: 1 },
903
914
  * ];
904
915
  *
905
916
  * <TableOfContents items={toc} />
@@ -907,7 +918,7 @@ interface TableOfContentsProps {
907
918
  *
908
919
  * @see https://m3.material.io/foundations/content-design/navigation
909
920
  */
910
- declare function TableOfContents({ items, className, scrollAreaProps, }: TableOfContentsProps): react_jsx_runtime.JSX.Element;
921
+ declare function TableOfContents({ items, className, scrollAreaProps, scrollContainerRef, }: TableOfContentsProps): react_jsx_runtime.JSX.Element;
911
922
 
912
923
  /**
913
924
  * TypeScaleTokens - MD3 Expressive Typography Physical Tokens
package/dist/layout.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as class_variance_authority_types from 'class-variance-authority/types';
2
2
  import * as React$1 from 'react';
3
- import { HTMLAttributes, ReactNode } from 'react';
3
+ import React__default, { HTMLAttributes, ReactNode } from 'react';
4
4
  import { HTMLMotionProps } from 'motion/react';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
6
  import { b as ScrollAreaProps } from './scroll-area-CVS6HyLl.js';
@@ -861,6 +861,12 @@ interface ToCItem {
861
861
  id: string;
862
862
  /** Human-readable label shown in the ToC. */
863
863
  label: string;
864
+ /**
865
+ * Heading level depth (1 for h2, 2 for h3, etc.).
866
+ * Indents lower-level items visually.
867
+ * @default 1
868
+ */
869
+ depth?: number;
864
870
  }
865
871
  /**
866
872
  * Props for the `TableOfContents` component.
@@ -881,6 +887,11 @@ interface TableOfContentsProps {
881
887
  * @default { type: "hover" }
882
888
  */
883
889
  scrollAreaProps?: Omit<ScrollAreaProps, "children">;
890
+ /**
891
+ * Optional ref to the scroll container element (e.g. ScrollArea viewport).
892
+ * If provided, IntersectionObserver will use this container as its root.
893
+ */
894
+ scrollContainerRef?: React__default.RefObject<HTMLElement | null | undefined>;
884
895
  }
885
896
  /**
886
897
  * Table of Contents sidebar component.
@@ -897,9 +908,9 @@ interface TableOfContentsProps {
897
908
  * @example
898
909
  * ```tsx
899
910
  * const toc: ToCItem[] = [
900
- * { id: "overview", label: "Overview" },
901
- * { id: "props", label: "Props" },
902
- * { id: "examples", label: "Examples" },
911
+ * { id: "overview", label: "Overview", depth: 1 },
912
+ * { id: "props", label: "Props", depth: 2 },
913
+ * { id: "examples", label: "Examples", depth: 1 },
903
914
  * ];
904
915
  *
905
916
  * <TableOfContents items={toc} />
@@ -907,7 +918,7 @@ interface TableOfContentsProps {
907
918
  *
908
919
  * @see https://m3.material.io/foundations/content-design/navigation
909
920
  */
910
- declare function TableOfContents({ items, className, scrollAreaProps, }: TableOfContentsProps): react_jsx_runtime.JSX.Element;
921
+ declare function TableOfContents({ items, className, scrollAreaProps, scrollContainerRef, }: TableOfContentsProps): react_jsx_runtime.JSX.Element;
911
922
 
912
923
  /**
913
924
  * TypeScaleTokens - MD3 Expressive Typography Physical Tokens
package/dist/layout.js CHANGED
@@ -5883,12 +5883,15 @@ Text.displayName = "Text";
5883
5883
  function TableOfContents({
5884
5884
  items,
5885
5885
  className,
5886
- scrollAreaProps
5886
+ scrollAreaProps,
5887
+ scrollContainerRef
5887
5888
  }) {
5888
5889
  const [activeId, setActiveId] = React23.useState("");
5889
5890
  const itemIds = React23.useMemo(() => items.map((i) => i.id), [items]);
5890
5891
  React23.useEffect(() => {
5892
+ var _a;
5891
5893
  if (typeof IntersectionObserver === "undefined") return;
5894
+ const root = (_a = scrollContainerRef == null ? void 0 : scrollContainerRef.current) != null ? _a : null;
5892
5895
  const observer = new IntersectionObserver(
5893
5896
  (entries) => {
5894
5897
  for (const entry of entries) {
@@ -5896,19 +5899,20 @@ function TableOfContents({
5896
5899
  }
5897
5900
  },
5898
5901
  // rootMargin: top offset ~100px (fixed header), bottom -80% (early switch)
5899
- { rootMargin: "-100px 0% -80% 0%" }
5902
+ { root, rootMargin: "-100px 0% -80% 0%" }
5900
5903
  );
5901
5904
  for (const id of itemIds) {
5902
5905
  const el = document.getElementById(id);
5903
5906
  if (el) observer.observe(el);
5904
5907
  }
5905
5908
  return () => observer.disconnect();
5906
- }, [itemIds]);
5909
+ }, [itemIds, scrollContainerRef]);
5907
5910
  const handleClick = React23.useCallback(
5908
5911
  (e, id) => {
5909
- var _a;
5910
5912
  e.preventDefault();
5911
- (_a = document.getElementById(id)) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "start" });
5913
+ const target = document.getElementById(id);
5914
+ if (!target) return;
5915
+ target.scrollIntoView({ behavior: "smooth", block: "start" });
5912
5916
  },
5913
5917
  []
5914
5918
  );
@@ -5925,19 +5929,35 @@ function TableOfContents({
5925
5929
  type: "hover"
5926
5930
  }, scrollAreaProps), {
5927
5931
  className: cn("flex-1 min-h-0", scrollAreaProps == null ? void 0 : scrollAreaProps.className),
5928
- children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-4 pr-4", children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
5929
- "a",
5930
- {
5931
- href: `#${item.id}`,
5932
- onClick: (e) => handleClick(e, item.id),
5933
- "aria-current": activeId === item.id ? "true" : void 0,
5934
- className: cn(
5935
- "text-sm transition-colors hover:text-m3-primary block",
5936
- activeId === item.id ? "text-m3-primary font-bold" : "text-m3-on-surface-variant font-medium"
5937
- ),
5938
- children: item.label
5939
- }
5940
- ) }, item.id)) })
5932
+ children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-2 pr-4", children: items.map((item) => {
5933
+ var _a;
5934
+ const depth = (_a = item.depth) != null ? _a : 1;
5935
+ const isSubItem = depth > 1;
5936
+ return /* @__PURE__ */ jsxRuntime.jsx(
5937
+ "li",
5938
+ {
5939
+ className: cn(
5940
+ isSubItem && "pl-3.5 border-l border-m3-outline-variant/40 ml-1"
5941
+ ),
5942
+ children: /* @__PURE__ */ jsxRuntime.jsx(
5943
+ "a",
5944
+ {
5945
+ href: `#${item.id}`,
5946
+ onClick: (e) => handleClick(e, item.id),
5947
+ "aria-current": activeId === item.id ? "true" : void 0,
5948
+ className: cn(
5949
+ "transition-colors hover:text-m3-primary block truncate",
5950
+ isSubItem ? "text-xs py-0.5 leading-relaxed" : "text-sm py-1 font-medium leading-snug",
5951
+ activeId === item.id ? "text-m3-primary font-bold" : "text-m3-on-surface-variant"
5952
+ ),
5953
+ title: item.label,
5954
+ children: item.label
5955
+ }
5956
+ )
5957
+ },
5958
+ item.id
5959
+ );
5960
+ }) })
5941
5961
  })
5942
5962
  )
5943
5963
  ]