diff --git a/data/onPostBuild/transpileMdxToMarkdown.test.ts b/data/onPostBuild/transpileMdxToMarkdown.test.ts index 86fcdd759b..fdfedc92a4 100644 --- a/data/onPostBuild/transpileMdxToMarkdown.test.ts +++ b/data/onPostBuild/transpileMdxToMarkdown.test.ts @@ -4,6 +4,7 @@ import { removeScriptTags, removeAnchorTags, removeJsxComments, + convertMethodSignatureToCode, convertImagePathsToGitHub, convertDocsLinksToMarkdown, convertJsxLinkProps, @@ -306,6 +307,50 @@ import Baz from 'qux'; }); }); + describe('convertMethodSignatureToCode', () => { + it('should convert simple MethodSignature to inline code', () => { + const input = 'rooms.get(name, options)'; + const output = convertMethodSignatureToCode(input); + expect(output).toBe('`rooms.get(name, options)`'); + }); + + it('should convert template literal MethodSignature to inline code', () => { + const input = '{`rooms.get(name, options)`}'; + const output = convertMethodSignatureToCode(input); + expect(output).toBe('`rooms.get(name, options)`'); + }); + + it('should handle MethodSignature with angle brackets in template literal', () => { + const input = '{`Map`}'; + const output = convertMethodSignatureToCode(input); + expect(output).toBe('`Map`'); + }); + + it('should handle multiple MethodSignatures', () => { + const input = `## Method A +methodA() + +## Method B +{\`methodB()\`}`; + const output = convertMethodSignatureToCode(input); + expect(output).toContain('`methodA()`'); + expect(output).toContain('`methodB()`'); + expect(output).not.toContain(''); + }); + + it('should preserve MethodSignature in code blocks', () => { + const input = '```jsx\npreserve this\n```'; + const output = convertMethodSignatureToCode(input); + expect(output).toContain('preserve this'); + }); + + it('should handle surrounding content', () => { + const input = 'Before\n\nmethod()\n\nAfter'; + const output = convertMethodSignatureToCode(input); + expect(output).toBe('Before\n\n`method()`\n\nAfter'); + }); + }); + describe('convertImagePathsToGitHub', () => { const githubBase = 'https://raw.githubusercontent.com/ably/docs/main/src'; diff --git a/data/onPostBuild/transpileMdxToMarkdown.ts b/data/onPostBuild/transpileMdxToMarkdown.ts index ffcacdc569..4c00e3c730 100644 --- a/data/onPostBuild/transpileMdxToMarkdown.ts +++ b/data/onPostBuild/transpileMdxToMarkdown.ts @@ -233,6 +233,22 @@ function removeJsxComments(content: string): string { return transformNonCodeBlocks(content, (text) => text.replace(/\{\/\*[\s\S]*?\*\/\}/g, '')); } +/** + * Convert MethodSignature components to inline code + * Handles both simple content and template literal syntax + * content → `content` + * {`content`} → `content` + */ +function convertMethodSignatureToCode(content: string): string { + return transformNonCodeBlocks(content, (text) => + text + // Template literal syntax: {`content`} + .replace(/\{`([^`]*)`\}<\/MethodSignature>/g, '`$1`') + // Simple syntax: content + .replace(/([^<{]+)<\/MethodSignature>/g, '`$1`'), + ); +} + /** * Convert image paths to GitHub raw URLs * Handles relative (../), absolute (/images/), and direct (images/) paths @@ -456,25 +472,28 @@ function transformMdxToMarkdown( // Stage 5: Remove JSX comments content = removeJsxComments(content); - // Stage 6: Strip hidden attribute from tables (makes them visible in markdown) + // Stage 6: Convert MethodSignature components to inline code + content = convertMethodSignatureToCode(content); + + // Stage 7: Strip hidden attribute from tables (makes them visible in markdown) content = stripHiddenFromTables(content); - // Stage 7: Convert image paths to GitHub URLs + // Stage 8: Convert image paths to GitHub URLs content = convertImagePathsToGitHub(content); - // Stage 8: Convert relative URLs to absolute URLs + // Stage 9: Convert relative URLs to absolute URLs content = convertRelativeUrls(content, siteUrl); - // Stage 9: Convert quoted /docs/ URLs to markdown links (for JSX props like link: '/docs/...') + // Stage 10: Convert quoted /docs/ URLs to markdown links (for JSX props like link: '/docs/...') content = convertJsxLinkProps(content, siteUrl); - // Stage 10: Convert /docs/ links to .md extension and remove ?lang= params + // Stage 11: Convert /docs/ links to .md extension and remove ?lang= params content = convertDocsLinksToMarkdown(content); - // Stage 11: Replace template variables + // Stage 12: Replace template variables content = replaceTemplateVariables(content); - // Stage 12: Prepend title as markdown heading + // Stage 13: Prepend title as markdown heading const finalContent = `# ${title}\n\n${intro ? `${intro}\n\n` : ''}${content}`; return { content: finalContent, title, intro }; @@ -592,6 +611,7 @@ export { removeScriptTags, removeAnchorTags, removeJsxComments, + convertMethodSignatureToCode, stripHiddenFromTables, convertImagePathsToGitHub, convertDocsLinksToMarkdown, diff --git a/src/components/Layout/MDXWrapper.tsx b/src/components/Layout/MDXWrapper.tsx index 492501d799..caf5c5468d 100644 --- a/src/components/Layout/MDXWrapper.tsx +++ b/src/components/Layout/MDXWrapper.tsx @@ -21,6 +21,7 @@ import { Table, NestedTableProvider } from './mdx/NestedTable'; import { Tiles } from './mdx/tiles'; import { PageHeader } from './mdx/PageHeader'; import Admonition from './mdx/Admonition'; +import { MethodSignature } from './mdx/MethodSignature'; import { Frontmatter, PageContextType } from './Layout'; import { ActivePage } from './utils/nav'; @@ -285,6 +286,7 @@ const MDXWrapper: React.FC = ({ children, pageContext, location th: Table.Head, td: Table.Cell, Tiles, + MethodSignature, }} > diff --git a/src/components/Layout/mdx/MethodSignature.tsx b/src/components/Layout/mdx/MethodSignature.tsx new file mode 100644 index 0000000000..e50cf13535 --- /dev/null +++ b/src/components/Layout/mdx/MethodSignature.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import cn from '@ably/ui/core/utils/cn'; + +interface MethodSignatureProps { + children: React.ReactNode; + className?: string; +} + +/** + * A component for displaying method signatures prominently in API reference docs. + * Uses orange styling consistent with NestedTable property names. + * Features an L-shaped connector line linking to the parent header. + * + * Note: Must be placed immediately after an h2/h3 heading with standard margins. + * The connector line positioning assumes this layout relationship. + * + * Usage in MDX: + * rooms.get(name, options) + * + * For signatures containing special characters like < > { }, use a template literal: + * {`rooms.get(name, options)`} + */ +export const MethodSignature: React.FC = ({ children, className }) => { + return ( + + {/* L-shaped connector line */} + + + {children} + + + ); +};
+ {children} +