radiant-docs 0.1.42 → 0.1.43

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "radiant-docs",
3
- "version": "0.1.42",
3
+ "version": "0.1.43",
4
4
  "description": "CLI tool for previewing Radiant documentation locally",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,6 +14,7 @@ import remarkDemoteH1 from "./src/lib/mdx/remark-demote-h1";
14
14
  import remarkResolveInternalLinks from "./src/lib/mdx/remark-resolve-internal-links";
15
15
  import remarkStandaloneImageComponent from "./src/lib/mdx/remark-standalone-image-component";
16
16
  import rehypeExternalLinks from "./src/lib/mdx/rehype-external-links";
17
+ import rehypePrefixPreviewHeadingIds from "./src/lib/mdx/rehype-prefix-preview-heading-ids";
17
18
  import remarkGfm from "remark-gfm";
18
19
  import rehypeSlug from "rehype-slug";
19
20
  import rehypeAutolinkHeadings from "rehype-autolink-headings";
@@ -344,6 +345,7 @@ export default defineConfig({
344
345
  ],
345
346
  rehypePlugins: [
346
347
  rehypeSlug,
348
+ rehypePrefixPreviewHeadingIds,
347
349
  rehypeExternalLinks,
348
350
  [
349
351
  rehypeAutolinkHeadings,
@@ -19,6 +19,7 @@ import ComponentPreview from "./user/ComponentPreview.astro";
19
19
  import ComponentPreviewBlock from "./user/ComponentPreviewBlock.astro";
20
20
  import type { MdxRoute, Route } from "../lib/routes";
21
21
  import PagePagination from "./PagePagination.astro";
22
+ import { PREVIEW_HEADING_ID_PREFIX } from "../lib/mdx/rehype-prefix-preview-heading-ids";
22
23
 
23
24
  interface Props {
24
25
  entry: any;
@@ -56,7 +57,11 @@ const description =
56
57
  ? entry.data.description.trim()
57
58
  : undefined;
58
59
 
59
- const tocHeadings = headings.filter(({ depth }) => depth === 2 || depth === 3);
60
+ const tocHeadings = headings.filter(
61
+ ({ depth, slug }) =>
62
+ (depth === 2 || depth === 3) &&
63
+ !slug.startsWith(PREVIEW_HEADING_ID_PREFIX),
64
+ );
60
65
  ---
61
66
 
62
67
  <Layout pageTitle={title} pageDescription={description}>
@@ -136,6 +136,16 @@ const isInitiallyExpanded = shouldShowAllCode || totalLineCount <= visibleLines;
136
136
  margin-bottom: 0.5714286em;
137
137
  }
138
138
 
139
+ .rd-component-preview
140
+ :global(.prose-rules > [data-rd-preview-heading="true"]:first-child) {
141
+ margin-top: 0;
142
+ }
143
+
144
+ .rd-component-preview
145
+ :global(.prose-rules > [data-rd-preview-heading="true"]:last-child) {
146
+ margin-bottom: 0;
147
+ }
148
+
139
149
  .rd-component-preview__code :global(.group\/prose-code) {
140
150
  margin-top: 0 !important;
141
151
  margin-bottom: 0 !important;
@@ -0,0 +1,52 @@
1
+ import type { Root } from "hast";
2
+ import type { Plugin } from "unified";
3
+ import { visit } from "unist-util-visit";
4
+
5
+ export const PREVIEW_HEADING_ID_PREFIX = "rd-preview-";
6
+
7
+ type ElementNode = {
8
+ type: "element";
9
+ tagName?: string;
10
+ properties?: Record<string, unknown>;
11
+ };
12
+
13
+ function isHeadingTagName(tagName: string | undefined): boolean {
14
+ return typeof tagName === "string" && /^h[1-6]$/.test(tagName);
15
+ }
16
+
17
+ function isPreviewHeading(properties: Record<string, unknown>): boolean {
18
+ return (
19
+ properties["data-rd-preview-heading"] === "true" ||
20
+ properties.dataRdPreviewHeading === "true" ||
21
+ properties["data-rd-preview-heading"] === true ||
22
+ properties.dataRdPreviewHeading === true
23
+ );
24
+ }
25
+
26
+ function readStringId(value: unknown): string | null {
27
+ return typeof value === "string" && value.trim().length > 0 ? value : null;
28
+ }
29
+
30
+ const rehypePrefixPreviewHeadingIds: Plugin<[], Root> = () => {
31
+ return (tree) => {
32
+ let fallbackIndex = 0;
33
+
34
+ visit(tree, "element", (node: ElementNode) => {
35
+ if (!isHeadingTagName(node.tagName)) return;
36
+
37
+ const properties = node.properties ?? {};
38
+ if (!isPreviewHeading(properties)) return;
39
+
40
+ const currentId = readStringId(properties.id);
41
+ fallbackIndex += 1;
42
+ const baseId = currentId ?? `heading-${fallbackIndex}`;
43
+
44
+ properties.id = baseId.startsWith(PREVIEW_HEADING_ID_PREFIX)
45
+ ? baseId
46
+ : `${PREVIEW_HEADING_ID_PREFIX}${baseId}`;
47
+ node.properties = properties;
48
+ });
49
+ };
50
+ };
51
+
52
+ export default rehypePrefixPreviewHeadingIds;
@@ -61,6 +61,10 @@ type HeadingNode = {
61
61
  type: "heading";
62
62
  depth?: number;
63
63
  children?: unknown[];
64
+ data?: {
65
+ hProperties?: Record<string, unknown>;
66
+ [key: string]: unknown;
67
+ };
64
68
  };
65
69
 
66
70
  type NodeWithChildren = {
@@ -224,14 +228,16 @@ function transformPreviewNode(node: unknown): unknown {
224
228
  if (headingNode.type === "heading") {
225
229
  const depth = normalizePreviewHeadingDepth(headingNode.depth);
226
230
  return {
227
- type: "mdxJsxFlowElement",
228
- name: "div",
229
- attributes: [
230
- createAttribute("data-rd-preview-heading", "true"),
231
- createAttribute("data-rd-preview-heading-level", String(depth)),
232
- createAttribute("role", "heading"),
233
- createAttribute("aria-level", String(depth)),
234
- ],
231
+ ...headingNode,
232
+ depth,
233
+ data: {
234
+ ...(headingNode.data ?? {}),
235
+ hProperties: {
236
+ ...(headingNode.data?.hProperties ?? {}),
237
+ "data-rd-preview-heading": "true",
238
+ "data-rd-preview-heading-level": String(depth),
239
+ },
240
+ },
235
241
  children: transformPreviewChildren(headingNode.children),
236
242
  };
237
243
  }