diff --git a/renderers/react/src/v0_9/catalog/basic/components/Text.tsx b/renderers/react/src/v0_9/catalog/basic/components/Text.tsx index 508c24687..18dd39d87 100644 --- a/renderers/react/src/v0_9/catalog/basic/components/Text.tsx +++ b/renderers/react/src/v0_9/catalog/basic/components/Text.tsx @@ -22,54 +22,46 @@ import {useMarkdown} from '../hooks/useMarkdown'; // Import CSS Module import styles from './Text.module.css'; -/** - * Wraps the plain text with appropriate Markdown syntax based on the requested variant. - * - * @param text The plain text to be wrapped. - * @param variant The typography variant (e.g., 'h1', 'caption'). - * @returns The text wrapped in Markdown syntax. - */ -const handleVariant = (text: string, variant?: string): string => { - switch (variant) { - case 'h1': - return `# ${text}`; - case 'h2': - return `## ${text}`; - case 'h3': - return `### ${text}`; - case 'h4': - return `#### ${text}`; - case 'h5': - return `##### ${text}`; - case 'caption': - return `*${text}*`; - default: - return text; - } -}; +const NON_MARKDOWN_VARIANTS = new Set(['h1', 'h2', 'h3', 'h4', 'h5', 'caption']); export const Text = createComponentImplementation(TextApi, ({props}) => { useBasicCatalogStyles(); const text = typeof props.text === 'string' ? props.text : String(props.text ?? ''); - const markdownText = handleVariant(text, props.variant); - const renderedHtml = useMarkdown(markdownText); + const variant = props.variant; + const isKnownVariant = variant !== undefined && NON_MARKDOWN_VARIANTS.has(variant); + + const renderedHtml = useMarkdown(text); const style: React.CSSProperties = { ...getBaseLeafStyle(), ...getWeightStyle(props.weight), }; - const isCaption = props.variant === 'caption'; - const classes = [styles.a2uiText, isCaption ? styles.a2uiCaption : props.variant || 'body']; + const isCaption = variant === 'caption'; + const classes = [styles.a2uiText, isCaption ? styles.a2uiCaption : variant || 'body']; + + if (isKnownVariant) { + const HeadingTag = isCaption ? 'em' : (variant as 'h1' | 'h2' | 'h3' | 'h4' | 'h5'); + if (isCaption) { + return ( + + {text} + + ); + } + return ( +
+ {text} +
+ ); + } + if (renderedHtml === null) { classes.push('no-markdown-renderer'); } const contentProps = renderedHtml !== null ? {dangerouslySetInnerHTML: {__html: renderedHtml}} - : {children: markdownText}; + : {children: text}; - if (isCaption) { - return ; - } return
; }); diff --git a/renderers/react/tests/v0_9/catalog-components.test.tsx b/renderers/react/tests/v0_9/catalog-components.test.tsx index 59afa8bcc..f2cc1d47b 100644 --- a/renderers/react/tests/v0_9/catalog-components.test.tsx +++ b/renderers/react/tests/v0_9/catalog-components.test.tsx @@ -68,7 +68,7 @@ describe('Basic Catalog Components', () => { const {view} = renderA2uiComponent(Text, 't1', {text: 'Title', variant: 'h1'}); const h1 = view.container.querySelector('div.h1'); expect(h1).not.toBeNull(); - expect(h1?.textContent).toBe('# Title'); + expect(h1?.textContent).toBe('Title'); }); }); diff --git a/renderers/react/tests/v0_9/integration-scenarios.test.tsx b/renderers/react/tests/v0_9/integration-scenarios.test.tsx index aeae5d184..98c650898 100644 --- a/renderers/react/tests/v0_9/integration-scenarios.test.tsx +++ b/renderers/react/tests/v0_9/integration-scenarios.test.tsx @@ -38,7 +38,7 @@ describe('Gallery Integration Tests', () => { , ); - expect(screen.getByText('### Markdown Rendering')).toBeInTheDocument(); + expect(screen.getByText('Markdown Rendering')).toBeInTheDocument(); }); it('renders Task Card -> content visibility', async () => { @@ -54,8 +54,8 @@ describe('Gallery Integration Tests', () => { , ); - expect(screen.getByText('### Review pull request')).toBeInTheDocument(); - expect(screen.getByText('*Backend*')).toBeInTheDocument(); + expect(screen.getByText('Review pull request')).toBeInTheDocument(); + expect(screen.getByText('Backend')).toBeInTheDocument(); }); it('handles Login form -> input updates data model', async () => {