radiant-docs 0.1.19 → 0.1.20

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.19",
3
+ "version": "0.1.20",
4
4
  "description": "CLI tool for previewing Radiant documentation locally",
5
5
  "type": "module",
6
6
  "bin": {
@@ -340,61 +340,60 @@ const renderedCodeLinesHtml = normalizedTokenLines
340
340
  </div>
341
341
  </div>
342
342
  </div>
343
- </div>
344
-
345
- <script is:inline>
346
- (() => {
347
- const script = document.currentScript;
348
- if (!(script instanceof HTMLScriptElement)) return;
349
-
350
- const root = script.previousElementSibling;
351
- if (!(root instanceof HTMLElement)) return;
352
-
353
- const copyButtons = root.querySelectorAll("[data-rd-copy-trigger='true']");
354
- if (copyButtons.length === 0) return;
355
-
356
- const setCopiedState = (button, copied) => {
357
- const copyIcon = button.querySelector("[data-rd-copy-icon]");
358
- const checkIcon = button.querySelector("[data-rd-copy-check]");
343
+ <script is:inline>
344
+ (() => {
345
+ const script = document.currentScript;
346
+ if (!(script instanceof HTMLScriptElement)) return;
359
347
 
360
- if (!copyIcon || !checkIcon) return;
348
+ const root = script.closest("[data-rd-code-block-root='true']");
349
+ if (!(root instanceof HTMLElement)) return;
361
350
 
362
- if (copied) {
363
- copyIcon.classList.add("scale-50", "opacity-0", "-rotate-6");
364
- copyIcon.classList.remove("scale-100", "opacity-100", "rotate-0");
351
+ const copyButtons = root.querySelectorAll("[data-rd-copy-trigger='true']");
352
+ if (copyButtons.length === 0) return;
365
353
 
366
- checkIcon.classList.remove("scale-50", "opacity-0", "rotate-6");
367
- checkIcon.classList.add("scale-110", "opacity-100", "rotate-0");
368
- return;
369
- }
370
-
371
- copyIcon.classList.remove("scale-50", "opacity-0", "-rotate-6");
372
- copyIcon.classList.add("scale-100", "opacity-100", "rotate-0");
354
+ const setCopiedState = (button, copied) => {
355
+ const copyIcon = button.querySelector("[data-rd-copy-icon]");
356
+ const checkIcon = button.querySelector("[data-rd-copy-check]");
373
357
 
374
- checkIcon.classList.remove("scale-110", "opacity-100", "rotate-0");
375
- checkIcon.classList.add("scale-50", "opacity-0", "rotate-6");
376
- };
358
+ if (!copyIcon || !checkIcon) return;
377
359
 
378
- copyButtons.forEach((button) => {
379
- let timeoutId = null;
380
- button.addEventListener("click", async () => {
381
- const encodedCopyValue =
382
- button.getAttribute("data-rd-copy-content") ?? "";
383
- const copyValue = decodeURIComponent(encodedCopyValue);
360
+ if (copied) {
361
+ copyIcon.classList.add("scale-50", "opacity-0", "-rotate-6");
362
+ copyIcon.classList.remove("scale-100", "opacity-100", "rotate-0");
384
363
 
385
- try {
386
- await navigator.clipboard.writeText(copyValue);
387
- setCopiedState(button, true);
364
+ checkIcon.classList.remove("scale-50", "opacity-0", "rotate-6");
365
+ checkIcon.classList.add("scale-110", "opacity-100", "rotate-0");
366
+ return;
367
+ }
388
368
 
389
- if (timeoutId) window.clearTimeout(timeoutId);
390
- timeoutId = window.setTimeout(() => {
369
+ copyIcon.classList.remove("scale-50", "opacity-0", "-rotate-6");
370
+ copyIcon.classList.add("scale-100", "opacity-100", "rotate-0");
371
+
372
+ checkIcon.classList.remove("scale-110", "opacity-100", "rotate-0");
373
+ checkIcon.classList.add("scale-50", "opacity-0", "rotate-6");
374
+ };
375
+
376
+ copyButtons.forEach((button) => {
377
+ let timeoutId = null;
378
+ button.addEventListener("click", async () => {
379
+ const encodedCopyValue =
380
+ button.getAttribute("data-rd-copy-content") ?? "";
381
+ const copyValue = decodeURIComponent(encodedCopyValue);
382
+
383
+ try {
384
+ await navigator.clipboard.writeText(copyValue);
385
+ setCopiedState(button, true);
386
+
387
+ if (timeoutId) window.clearTimeout(timeoutId);
388
+ timeoutId = window.setTimeout(() => {
389
+ setCopiedState(button, false);
390
+ timeoutId = null;
391
+ }, 1200);
392
+ } catch {
391
393
  setCopiedState(button, false);
392
- timeoutId = null;
393
- }, 1200);
394
- } catch {
395
- setCopiedState(button, false);
396
- }
394
+ }
395
+ });
397
396
  });
398
- });
399
- })();
400
- </script>
397
+ })();
398
+ </script>
399
+ </div>
@@ -134,19 +134,19 @@ const isInitiallyExpanded = shouldShowAllCode || totalLineCount <= visibleLines;
134
134
  margin-bottom: 0.5714286em;
135
135
  }
136
136
 
137
- .rd-component-preview :global(.group\/prose-code) {
137
+ .rd-component-preview__code :global(.group\/prose-code) {
138
138
  margin-top: 0 !important;
139
139
  margin-bottom: 0 !important;
140
140
  }
141
141
 
142
- .rd-component-preview :global(.group\/prose-code > div) {
142
+ .rd-component-preview__code :global(.group\/prose-code > div) {
143
143
  background-color: var(--color-neutral-50) !important;
144
144
  border-top-left-radius: 0 !important;
145
145
  border-top-right-radius: 0 !important;
146
146
  }
147
147
 
148
- .rd-component-preview :global(.group\/prose-code pre),
149
- .rd-component-preview :global(.group\/prose-code code) {
148
+ .rd-component-preview__code :global(.group\/prose-code pre),
149
+ .rd-component-preview__code :global(.group\/prose-code code) {
150
150
  background-color: var(--color-neutral-50) !important;
151
151
  }
152
152
 
@@ -275,6 +275,8 @@ function parseComponentPreviewChildren(rawCode: string): unknown[] {
275
275
  mdastExtensions: [gfmFromMarkdown(), mdxFromMarkdown()],
276
276
  }) as Root;
277
277
 
278
+ transformCodeBlockNodes(parsedTree);
279
+
278
280
  return transformPreviewChildren(
279
281
  Array.isArray(parsedTree.children) ? parsedTree.children : [],
280
282
  );
@@ -322,135 +324,139 @@ function buildDefaultCodeGroupFileName(
322
324
  return `file-name-${codeIndexInGroup + 1}.${extension}`;
323
325
  }
324
326
 
325
- export const remarkCodeBlockComponent: Plugin<[], Root> = () => {
326
- return (tree) => {
327
- visitParents(tree, "code", (node, ancestors) => {
328
- const codeNode = node as CodeNode;
329
- const parent = ancestors[ancestors.length - 1] as ParentNode | undefined;
330
- const siblings = parent?.children;
331
- if (!siblings) return;
327
+ function transformCodeBlockNodes(tree: Root): void {
328
+ visitParents(tree, "code", (node, ancestors) => {
329
+ const codeNode = node as CodeNode;
330
+ const parent = ancestors[ancestors.length - 1] as ParentNode | undefined;
331
+ const siblings = parent?.children;
332
+ if (!siblings) return;
333
+
334
+ const currentIndex = siblings.indexOf(node);
335
+ if (currentIndex < 0) return;
336
+
337
+ const nearestMdxFlowElementName = getNearestMdxJsxFlowElementName(
338
+ ancestors,
339
+ );
340
+ const isInsideCodeGroup = nearestMdxFlowElementName === "CodeGroup";
341
+ const isInsideComponentPreview =
342
+ nearestMdxFlowElementName === COMPONENT_PREVIEW_NAME;
343
+ const componentPreviewNode = isInsideComponentPreview
344
+ ? getNearestMdxJsxFlowElement(ancestors, COMPONENT_PREVIEW_NAME)
345
+ : null;
346
+ const isInsideInlineMdx = isInsideMdxJsxTextElement(ancestors);
347
+ if (isInsideInlineMdx) return;
348
+
349
+ const meta = readMetaString(codeNode.meta);
350
+ const parsedMeta = parseParsedCodeMeta(meta);
351
+ const language =
352
+ typeof codeNode.lang === "string" && codeNode.lang.trim().length > 0
353
+ ? codeNode.lang.trim()
354
+ : "plaintext";
355
+ const normalizedLanguage = language.trim().toLowerCase();
356
+ const rawCode = typeof codeNode.value === "string" ? codeNode.value : "";
357
+ const codeIndexInGroup = isInsideCodeGroup
358
+ ? siblings
359
+ .slice(0, currentIndex)
360
+ .filter(
361
+ (sibling) => (sibling as { type?: string }).type === "code",
362
+ ).length
363
+ : 0;
364
+ const fileName =
365
+ parsedMeta.filename.length > 0
366
+ ? parsedMeta.filename
367
+ : isInsideCodeGroup
368
+ ? buildDefaultCodeGroupFileName(language, codeIndexInGroup)
369
+ : "";
370
+ const showFilename = isInsideCodeGroup || fileName.length > 0;
371
+
372
+ const attributes: MdxJsxAttributeNode[] = [
373
+ createAttribute("language", language),
374
+ createAttribute("raw", rawCode),
375
+ createAttribute("showFilename", showFilename ? "true" : "false"),
376
+ createAttribute(
377
+ "showLineNumbers",
378
+ parsedMeta.showLineNumbers ? "true" : "false",
379
+ ),
380
+ ];
381
+
382
+ if (parsedMeta.hideLanguageIcon) {
383
+ attributes.push(createAttribute("hideLanguageIcon", "true"));
384
+ }
332
385
 
333
- const currentIndex = siblings.indexOf(node);
334
- if (currentIndex < 0) return;
386
+ if (showFilename) {
387
+ attributes.push(createAttribute("filename", fileName));
388
+ }
335
389
 
336
- const nearestMdxFlowElementName = getNearestMdxJsxFlowElementName(
337
- ancestors,
338
- );
339
- const isInsideCodeGroup = nearestMdxFlowElementName === "CodeGroup";
340
- const isInsideComponentPreview =
341
- nearestMdxFlowElementName === COMPONENT_PREVIEW_NAME;
342
- const componentPreviewNode = isInsideComponentPreview
343
- ? getNearestMdxJsxFlowElement(ancestors, COMPONENT_PREVIEW_NAME)
344
- : null;
345
- const isInsideInlineMdx = isInsideMdxJsxTextElement(ancestors);
346
- if (isInsideInlineMdx) return;
347
-
348
- const meta = readMetaString(codeNode.meta);
349
- const parsedMeta = parseParsedCodeMeta(meta);
350
- const language =
351
- typeof codeNode.lang === "string" && codeNode.lang.trim().length > 0
352
- ? codeNode.lang.trim()
353
- : "plaintext";
354
- const normalizedLanguage = language.trim().toLowerCase();
355
- const rawCode = typeof codeNode.value === "string" ? codeNode.value : "";
356
- const codeIndexInGroup = isInsideCodeGroup
357
- ? siblings
358
- .slice(0, currentIndex)
359
- .filter(
360
- (sibling) => (sibling as { type?: string }).type === "code",
361
- ).length
362
- : 0;
363
- const fileName =
364
- parsedMeta.filename.length > 0
365
- ? parsedMeta.filename
366
- : isInsideCodeGroup
367
- ? buildDefaultCodeGroupFileName(language, codeIndexInGroup)
368
- : "";
369
- const showFilename = isInsideCodeGroup || fileName.length > 0;
370
-
371
- const attributes: MdxJsxAttributeNode[] = [
372
- createAttribute("language", language),
373
- createAttribute("raw", rawCode),
374
- createAttribute("showFilename", showFilename ? "true" : "false"),
375
- createAttribute(
376
- "showLineNumbers",
377
- parsedMeta.showLineNumbers ? "true" : "false",
378
- ),
379
- ];
380
-
381
- if (parsedMeta.hideLanguageIcon) {
382
- attributes.push(createAttribute("hideLanguageIcon", "true"));
383
- }
390
+ if (isInsideCodeGroup) {
391
+ attributes.push(createAttribute("inCodeGroup", "true"));
392
+ }
384
393
 
385
- if (showFilename) {
386
- attributes.push(createAttribute("filename", fileName));
387
- }
394
+ if (parsedMeta.highlightedLines.length > 0) {
395
+ attributes.push(
396
+ createAttribute("highlightedLines", parsedMeta.highlightedLines),
397
+ );
398
+ }
388
399
 
389
- if (isInsideCodeGroup) {
390
- attributes.push(createAttribute("inCodeGroup", "true"));
391
- }
400
+ if (parsedMeta.collapsedLines.length > 0) {
401
+ attributes.push(
402
+ createAttribute("collapsedLines", parsedMeta.collapsedLines),
403
+ );
404
+ }
392
405
 
393
- if (parsedMeta.highlightedLines.length > 0) {
394
- attributes.push(
395
- createAttribute("highlightedLines", parsedMeta.highlightedLines),
406
+ if (isInsideComponentPreview) {
407
+ if (!COMPONENT_PREVIEW_LANGUAGES.has(normalizedLanguage)) {
408
+ throw new Error(
409
+ `[USER_ERROR]: <${COMPONENT_PREVIEW_NAME}>: Fenced code blocks must use jsx, tsx, or mdx language (received "${language}")`,
396
410
  );
397
411
  }
398
412
 
399
- if (parsedMeta.collapsedLines.length > 0) {
400
- attributes.push(
401
- createAttribute("collapsedLines", parsedMeta.collapsedLines),
413
+ let previewChildren: unknown[] = [];
414
+ try {
415
+ previewChildren = parseComponentPreviewChildren(rawCode);
416
+ } catch (error) {
417
+ const reason =
418
+ error instanceof Error && error.message.trim().length > 0
419
+ ? ` -> ${error.message}`
420
+ : "";
421
+ throw new Error(
422
+ `[USER_ERROR]: <${COMPONENT_PREVIEW_NAME}>: Failed to parse fenced code block as MDX content${reason}`,
402
423
  );
403
424
  }
404
425
 
405
- if (isInsideComponentPreview) {
406
- if (!COMPONENT_PREVIEW_LANGUAGES.has(normalizedLanguage)) {
407
- throw new Error(
408
- `[USER_ERROR]: <${COMPONENT_PREVIEW_NAME}>: Fenced code blocks must use jsx, tsx, or mdx language (received "${language}")`,
409
- );
410
- }
411
-
412
- let previewChildren: unknown[] = [];
413
- try {
414
- previewChildren = parseComponentPreviewChildren(rawCode);
415
- } catch (error) {
416
- const reason =
417
- error instanceof Error && error.message.trim().length > 0
418
- ? ` -> ${error.message}`
419
- : "";
420
- throw new Error(
421
- `[USER_ERROR]: <${COMPONENT_PREVIEW_NAME}>: Failed to parse fenced code block as MDX content${reason}`,
422
- );
423
- }
424
-
425
- const previewAttributes = attributes.filter(
426
- (attribute) => attribute.name !== "inCodeGroup",
427
- );
428
- const showAllCode = readBooleanAttribute(
429
- componentPreviewNode?.attributes,
430
- "showAllCode",
431
- );
432
- if (showAllCode) {
433
- previewAttributes.push(createAttribute("showAllCode", "true"));
434
- }
435
- const previewNode: MdxJsxFlowElementNode = {
436
- type: "mdxJsxFlowElement",
437
- name: COMPONENT_PREVIEW_BLOCK_NAME,
438
- attributes: previewAttributes,
439
- children: previewChildren,
440
- };
441
- siblings[currentIndex] = previewNode;
442
- return;
426
+ const previewAttributes = attributes.filter(
427
+ (attribute) => attribute.name !== "inCodeGroup",
428
+ );
429
+ const showAllCode = readBooleanAttribute(
430
+ componentPreviewNode?.attributes,
431
+ "showAllCode",
432
+ );
433
+ if (showAllCode) {
434
+ previewAttributes.push(createAttribute("showAllCode", "true"));
443
435
  }
444
-
445
- const replacementNode: MdxJsxFlowElementNode = {
436
+ const previewNode: MdxJsxFlowElementNode = {
446
437
  type: "mdxJsxFlowElement",
447
- name: INTERNAL_CODE_BLOCK_NAME,
448
- attributes,
449
- children: [],
438
+ name: COMPONENT_PREVIEW_BLOCK_NAME,
439
+ attributes: previewAttributes,
440
+ children: previewChildren,
450
441
  };
442
+ siblings[currentIndex] = previewNode;
443
+ return;
444
+ }
451
445
 
452
- siblings[currentIndex] = replacementNode;
453
- });
446
+ const replacementNode: MdxJsxFlowElementNode = {
447
+ type: "mdxJsxFlowElement",
448
+ name: INTERNAL_CODE_BLOCK_NAME,
449
+ attributes,
450
+ children: [],
451
+ };
452
+
453
+ siblings[currentIndex] = replacementNode;
454
+ });
455
+ }
456
+
457
+ export const remarkCodeBlockComponent: Plugin<[], Root> = () => {
458
+ return (tree) => {
459
+ transformCodeBlockNodes(tree);
454
460
  };
455
461
  };
456
462