# Markdown

## Introduction

Markdown is a component that renders markdown-formatted text as styled React components. It supports GitHub Flavored Markdown (GFM) including bold, italic, strikethrough, links, code blocks, tables, task lists, blockquotes, and lists. Additionally, it provides custom features like accent color highlighting using `||text||` syntax, configurable typography levels, and text alignment options. Markdown is ideal for displaying user-generated content, documentation, comments, and any dynamic text that requires rich formatting.

```tsx
<Markdown
  content="This is markdown with **bold text** and *italic text* and ||accent color||"
/>
```

| Field             | Description | Default |
| ----------------- | ----------- | ------- |
| content           | —           | —       |
| defaultLevel      | —           | —       |
| defaultLinkAction | —           | —       |
| accentColor       | —           | —       |
| textAlign         | —           | —       |

> ⚠️ **Usage Warning** ⚠️
>
> Consider these guidelines when using Markdown:
>
> - **Security**: Always sanitize user-generated markdown content to prevent XSS attacks
> - **Performance**: For very long documents, consider lazy loading or pagination
> - **Styling consistency**: Use `defaultLevel` to match your app's typography system
> - **Links**: Use `defaultLinkAction` to control how links open (new tab vs same tab)

## Usage

```tsx
import { Markdown } from '@ceed/ads';

function ArticleContent({ content }) {
  return (
    <Markdown
      content={content}
      defaultLevel="body-md"
      defaultLinkAction="_blank"
    />
  );
}
```

## Examples

### Playground

Interactive example with basic markdown formatting.

```tsx
<Markdown
  content="This is markdown with **bold text** and *italic text* and ||accent color||"
/>
```

### Default Level

Control the base typography level for the content.

```tsx
<Stack spacing={2}>
  <Markdown {...args} defaultLevel="title-lg" />
  <Markdown {...args} defaultLevel="title-md" />
  <Markdown {...args} defaultLevel="title-sm" />
  <Markdown {...args} defaultLevel="body-lg" />
  <Markdown {...args} defaultLevel="body-md" />
  <Markdown {...args} defaultLevel="body-sm" />
  <Markdown {...args} defaultLevel="body-xs" />
</Stack>
```

### Text Alignment

Align text to left, center, or right.

```tsx
<Markdown
  content="Hi I'm **markdown**"
  textAlign="center"
/>
```

### Colors

Apply different color themes to the markdown content.

```tsx
<div>
  <Markdown {...args} color="primary" />
  <Markdown {...args} color="danger" />
  <Markdown {...args} color="neutral" />
  <Markdown {...args} color="success" />
  <Markdown {...args} color="warning" />
</div>
```

### Text Color

Use specific text colors from the theme palette.

```tsx
<Stack>
  <Markdown {...args} textColor="common.black" />
  <Markdown {...args} textColor="danger.400" />
  <Markdown {...args} textColor="primary.500" />
</Stack>
```

### Accent Color

Highlight text with custom accent color using `||text||` syntax.

```tsx
<Stack spacing={2}>
  <Markdown {...args} />
  <Markdown {...args} fontWeight={600} />
</Stack>
```

### Bold Font Weight

Customize the weight of bold text.

```tsx
<Stack spacing={2}>
  <Typography fontWeight="normal">Normal:</Typography>
  <Markdown {...args} />

  <Typography fontWeight="sm">SM:</Typography>
  <Markdown {...args} boldFontWeight="sm" />
  <Typography fontWeight="md">MD:</Typography>
  <Markdown {...args} boldFontWeight="md" />
  <Typography fontWeight="lg">LG:</Typography>
  <Markdown {...args} boldFontWeight="lg" />
  <Typography fontWeight="xl">XL:</Typography>
  <Markdown {...args} boldFontWeight="xl" />
</Stack>
```

### Strikethrough

GFM strikethrough support using `~text~` syntax.

```tsx
<Markdown content="I am markdown with ~strikethrough~" />
```

### Tables

Full GFM table support with alignment options.

```tsx
<Markdown
  content={"\n| Feature | Status | Notes |\n|---------|--------|-------|\n| Tables | ✅ Supported | GFM tables work |\n| Alignment | ✅ Supported | Left, center, right |\n| Headers | ✅ Supported | Bold headers |\n\n| Left | Center | Right |\n|:-----|:------:|------:|\n| L1 | C1 | R1 |\n| L2 | C2 | R2 |\n"}
/>
```

### Code Blocks

Inline code and fenced code blocks with syntax highlighting.

````tsx
<Markdown
  content={"\nHere is some `inline code` in a sentence.\n\n```javascript\n// Code block with syntax highlighting\nfunction hello() {\n  console.log('Hello, World!');\n}\n```\n\n```typescript\ninterface User {\n  name: string;\n  age: number;\n}\n```\n"}
/>
````

### Task Lists

Interactive task list checkboxes.

```tsx
<Markdown
  content={"\n## Task List\n\n- [x] Completed task\n- [x] Another completed task\n- [ ] Incomplete task\n- [ ] Another incomplete task\n\n### Nested Tasks\n\n- Parent item\n  - [x] Child completed\n  - [ ] Child incomplete\n"}
/>
```

### Blockquotes

Styled blockquotes for quoted content.

```tsx
<Markdown
  content={"\n> This is a blockquote.\n> It can span multiple lines.\n\n> **Note:** Blockquotes can contain **bold** and *italic* text.\n\n> Nested content:\n> - List item 1\n> - List item 2\n"}
/>
```

### Lists

Ordered and unordered lists with nesting support.

```tsx
<Markdown
  content={"\n## Unordered List\n\n- First item\n- Second item\n- Third item\n  - Nested item 1\n  - Nested item 2\n\n## Ordered List\n\n1. First item\n2. Second item\n3. Third item\n   1. Nested item 1\n   2. Nested item 2\n"}
/>
```

### GFM Complete

Full demonstration of all GFM features.

````tsx
<Markdown
  content={"\n# GFM Complete Example\n\nThis example demonstrates all **GitHub Flavored Markdown** features.\n\n## Text Formatting\n\n- **Bold text** using `**text**`\n- *Italic text* using `*text*`\n- ~Strikethrough~ using `~text~`\n- `Inline code` using backticks\n- ||Accent color|| using `||text||`\n\n## Links and Images\n\n[Visit GitHub](https://github.com)\n\n## Blockquotes\n\n> This is a blockquote with **bold** and *italic* text.\n>\n> Multiple paragraphs are supported.\n\n## Code Blocks\n\n```typescript\nconst greeting: string = 'Hello, GFM!';\nconsole.log(greeting);\n```\n\n## Tables\n\n| Syntax | Description | Example |\n|--------|-------------|---------|\n| Bold | Makes text bold | **bold** |\n| Italic | Makes text italic | *italic* |\n| Code | Inline code | `code` |\n\n## Lists\n\n### Unordered\n- Item 1\n- Item 2\n- Item 3\n\n### Ordered\n1. First\n2. Second\n3. Third\n\n### Task List\n- [x] Completed task\n- [ ] Pending task\n\n---\n\n*End of GFM demonstration*\n"}
/>
````

## When to Use

### ✅ Good Use Cases

- **Documentation**: Rendering help docs, READMEs, or guides
- **User-generated content**: Comments, posts, or descriptions with formatting
- **Dynamic content**: Content from CMS or databases stored as markdown
- **Release notes**: Changelogs and update information
- **Email templates**: Preview email content written in markdown
- **Chat/messaging**: Rich text messages with formatting
- **Knowledge bases**: FAQ answers and support articles

### ❌ When Not to Use

- **Simple text**: Use Typography for plain text without formatting
- **Complex layouts**: Use proper components instead of markdown tables for data
- **Interactive content**: Don't rely on markdown for forms or inputs
- **Critical UI text**: Use Typography for button labels, form labels, etc.
- **Structured data**: Use DataTable or custom components for tabular data

## Common Use Cases

### Article/Blog Content

```tsx
function ArticlePage({ article }) {
  return (
    <Box sx={{ maxWidth: 700, mx: 'auto', py: 4 }}>
      <Typography level="h1" sx={{ mb: 2 }}>
        {article.title}
      </Typography>
      <Stack direction="row" gap={2} sx={{ mb: 3 }}>
        <Typography level="body-sm" color="neutral">
          By {article.author}
        </Typography>
        <Typography level="body-sm" color="neutral">
          {article.date}
        </Typography>
      </Stack>
      <Divider sx={{ mb: 3 }} />
      <Markdown
        content={article.body}
        defaultLevel="body-md"
        defaultLinkAction="_blank"
      />
    </Box>
  );
}
```

### Comment with Formatting

```tsx
function Comment({ comment }) {
  return (
    <Card variant="outlined">
      <CardContent>
        <Stack direction="row" gap={2} alignItems="center" sx={{ mb: 2 }}>
          <Avatar src={comment.author.avatar} size="sm" />
          <Box>
            <Typography level="title-sm">{comment.author.name}</Typography>
            <Typography level="body-xs" color="neutral">
              {comment.createdAt}
            </Typography>
          </Box>
        </Stack>
        <Markdown
          content={comment.body}
          defaultLevel="body-sm"
        />
      </CardContent>
    </Card>
  );
}
```

### Release Notes

```tsx
function ReleaseNotes({ version, notes }) {
  return (
    <Box>
      <Typography level="h2" sx={{ mb: 2 }}>
        Version {version}
      </Typography>
      <Markdown
        content={notes}
        defaultLevel="body-md"
        accentColor="success.500"
      />
    </Box>
  );
}

// Usage with markdown content
const releaseNotes = `
## What's New

- **New Feature**: Added ||dark mode support||
- **Improvement**: Faster load times
- **Bug Fix**: Fixed login issue on mobile

### Breaking Changes

~Old API endpoints are deprecated~. Please migrate to the new v2 endpoints.

### Migration Guide

1. Update your API calls
2. Test thoroughly
3. Deploy changes
`;
```

### Help Documentation

```tsx
function HelpArticle({ title, content }) {
  return (
    <Container maxWidth="laptop">
      <Typography level="h1" sx={{ mb: 3 }}>
        {title}
      </Typography>
      <Markdown
        content={content}
        defaultLevel="body-md"
        defaultLinkAction="_blank"
      />
    </Container>
  );
}

// Example help content
const helpContent = `
## Getting Started

Welcome to our platform! Here's how to get started:

### Step 1: Create an Account

Visit the [signup page](/signup) and fill in your details.

> **Tip:** Use a strong password with at least 12 characters.

### Step 2: Verify Your Email

Check your inbox for a verification email and click the link.

### Step 3: Complete Your Profile

Add your profile information:

- [ ] Upload a profile picture
- [ ] Add your bio
- [ ] Set your preferences

### Need Help?

Contact us at [support@example.com](mailto:support@example.com).
`;
```

### Task Description with Checklist

```tsx
function TaskDetails({ task }) {
  return (
    <Card>
      <CardContent>
        <Typography level="title-lg" sx={{ mb: 2 }}>
          {task.title}
        </Typography>
        <Markdown
          content={task.description}
          defaultLevel="body-sm"
        />
      </CardContent>
    </Card>
  );
}

// Task with checklist
const taskDescription = `
## Requirements

Complete the following items:

- [x] Design mockups
- [x] Backend API
- [ ] Frontend implementation
- [ ] Unit tests
- [ ] Documentation

### Notes

Make sure to follow the ||coding standards|| and add proper error handling.
`;
```

### Notification Content

```tsx
function NotificationDetail({ notification }) {
  return (
    <Alert
      color={notification.type}
      sx={{ mb: 2 }}
    >
      <Markdown
        content={notification.message}
        defaultLevel="body-sm"
        accentColor={notification.type === 'success' ? 'success.600' : 'danger.600'}
      />
    </Alert>
  );
}

// Notification with formatting
const notification = {
  type: 'success',
  message: 'Your order **#12345** has been ||shipped||! Track it [here](/tracking).',
};
```

### Email Preview

```tsx
function EmailPreview({ subject, body }) {
  return (
    <Card variant="outlined">
      <CardContent>
        <Typography level="title-md" sx={{ mb: 2 }}>
          {subject}
        </Typography>
        <Divider sx={{ mb: 2 }} />
        <Markdown
          content={body}
          defaultLevel="body-md"
          defaultLinkAction="_blank"
        />
      </CardContent>
    </Card>
  );
}
```

### API Documentation

```tsx
function APIDocumentation({ endpoint }) {
  return (
    <Box>
      <Typography level="h2">{endpoint.name}</Typography>
      <Chip color="primary" sx={{ mb: 2 }}>
        {endpoint.method}
      </Chip>
      <Markdown
        content={endpoint.description}
        defaultLevel="body-md"
      />
    </Box>
  );
}

const endpointDoc = `
### Request

\`\`\`bash
curl -X POST https://api.example.com/users \\
  -H "Authorization: Bearer token" \\
  -d '{"name": "John"}'
\`\`\`

### Response

| Field | Type | Description |
|-------|------|-------------|
| id | string | User ID |
| name | string | User name |
| createdAt | string | ISO timestamp |

### Example Response

\`\`\`json
{
  "id": "user_123",
  "name": "John",
  "createdAt": "2024-01-01T00:00:00Z"
}
\`\`\`
`;
```

## Props and Customization

### Key Props

| Prop                | Type                                                           | Default        | Description                               |
| ------------------- | -------------------------------------------------------------- | -------------- | ----------------------------------------- |
| `content`           | `string`                                                       | -              | Markdown content to render                |
| `defaultLevel`      | `TypographyLevel`                                              | `'body-md'`    | Base typography level                     |
| `defaultLinkAction` | `'_self' \| '_blank' \| '_parent' \| '_top'`                   | `'_self'`      | Link target behavior                      |
| `color`             | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | -              | Color theme                               |
| `textColor`         | `string`                                                       | -              | Specific text color (e.g., 'primary.500') |
| `accentColor`       | `string`                                                       | `'danger.500'` | Color for `\|\|text\|\|` syntax           |
| `textAlign`         | `'left' \| 'center' \| 'right'`                                | `'left'`       | Text alignment                            |
| `fontWeight`        | `number \| string`                                             | -              | Base font weight                          |
| `boldFontWeight`    | `'sm' \| 'md' \| 'lg' \| 'xl'`                                 | -              | Bold text font weight                     |

### Supported Markdown Syntax

````markdown
## Text Formatting

**Bold text** using `**text**`
*Italic text* using `*text*`
~Strikethrough~ using `~text~`
`Inline code` using backticks
||Accent color|| using `||text||`

## Headings

# Heading 1
## Heading 2
### Heading 3

## Links

[Link text](https://example.com)
https://auto-linked-url.com

## Lists

### Unordered
- Item 1
- Item 2
  - Nested item

### Ordered
1. First
2. Second
3. Third

### Task List
- [x] Completed
- [ ] Pending

## Blockquotes

> Quoted text
> Multiple lines

## Code Blocks

```javascript
const code = 'highlighted';
````

## Tables

| Header 1 | Header 2 |
| -------- | -------- |
| Cell 1   | Cell 2   |

## Horizontal Rule

***

````

### Typography Levels

```tsx
// Title levels
<Markdown content="..." defaultLevel="title-lg" />
<Markdown content="..." defaultLevel="title-md" />
<Markdown content="..." defaultLevel="title-sm" />

// Body levels
<Markdown content="..." defaultLevel="body-lg" />
<Markdown content="..." defaultLevel="body-md" />  // default
<Markdown content="..." defaultLevel="body-sm" />
<Markdown content="..." defaultLevel="body-xs" />
````

### Color Options

```tsx
// Theme colors
<Markdown content="..." color="primary" />
<Markdown content="..." color="neutral" />
<Markdown content="..." color="success" />
<Markdown content="..." color="warning" />
<Markdown content="..." color="danger" />

// Specific text colors
<Markdown content="..." textColor="primary.500" />
<Markdown content="..." textColor="common.black" />
```

### Link Behavior

```tsx
// Open in same tab (default)
<Markdown content="[Link](url)" defaultLinkAction="_self" />

// Open in new tab
<Markdown content="[Link](url)" defaultLinkAction="_blank" />
```

### Accent Color Highlighting

```tsx
// Custom accent color for ||text|| syntax
<Markdown
  content="This is ||highlighted|| text"
  accentColor="success.500"
/>

// Default accent color is danger.500
<Markdown content="This is ||highlighted|| text" />
```

## Accessibility

Markdown renders semantic HTML elements with proper accessibility:

### Semantic Structure

- Headings render as `<h1>` through `<h6>`
- Lists render as `<ul>`, `<ol>`, and `<li>`
- Links render as `<a>` with proper attributes
- Code blocks have appropriate `<pre>` and `<code>` tags
- Tables use semantic `<table>`, `<thead>`, `<tbody>` structure

### Link Accessibility

```tsx
// Links opening in new tabs should have proper attributes
// The component handles rel="noopener noreferrer" automatically
<Markdown
  content="[External link](https://example.com)"
  defaultLinkAction="_blank"
/>
```

### Screen Reader Considerations

- Task list items announce their checked state
- Blockquotes are properly indicated
- Tables have proper header associations

### Color Contrast

```tsx
// Ensure sufficient contrast with text colors
<Markdown
  content="..."
  textColor="neutral.800"  // Good contrast
/>
```

## Best Practices

### ✅ Do

1. **Sanitize user content**: Always sanitize markdown from untrusted sources

```tsx
// ✅ Good: Sanitize before rendering
import sanitize from 'sanitize-html';

<Markdown content={sanitize(userContent)} />
```

2. **Match typography to context**: Use appropriate levels for the content type

```tsx
// ✅ Good: Match level to context
<Markdown content={articleBody} defaultLevel="body-md" />
<Markdown content={footnote} defaultLevel="body-xs" />
```

3. **Configure link behavior appropriately**: External links should open in new tabs

```tsx
// ✅ Good: External links in new tab
<Markdown
  content={externalContent}
  defaultLinkAction="_blank"
/>
```

4. **Use accent colors meaningfully**: Highlight important information

```tsx
// ✅ Good: Highlight key information
<Markdown
  content="Your balance is ||$1,234.56||"
  accentColor="success.500"
/>
```

### ❌ Don't

1. **Don't use for complex layouts**: Use proper components instead

```tsx
// ❌ Bad: Complex tables in markdown
<Markdown content={complexDataTable} />

// ✅ Good: Use DataTable component
<DataTable columns={columns} rows={rows} />
```

2. **Don't ignore security**: Never render untrusted content directly

```tsx
// ❌ Bad: Rendering untrusted content
<Markdown content={userInput} />

// ✅ Good: Sanitize first
<Markdown content={sanitizeMarkdown(userInput)} />
```

3. **Don't use for UI labels**: Use Typography for interface text

```tsx
// ❌ Bad: Markdown for button labels
<Markdown content="**Submit**" />

// ✅ Good: Typography for UI
<Typography fontWeight="lg">Submit</Typography>
```

4. **Don't mix markdown with complex interactivity**: Keep it content-focused

```tsx
// ❌ Bad: Trying to add interactive elements via markdown
<Markdown content="Click [here](javascript:void(0))" />

// ✅ Good: Use proper components for interactivity
<Box>
  <Markdown content="Complete the form below:" />
  <Button onClick={handleSubmit}>Submit</Button>
</Box>
```

## Performance Considerations

### Memoize Content

For frequently re-rendering parents, memoize the Markdown component:

```tsx
const MemoizedMarkdown = memo(({ content, ...props }) => (
  <Markdown content={content} {...props} />
));

function ParentComponent({ content }) {
  return (
    <Box>
      <MemoizedMarkdown content={content} defaultLevel="body-md" />
    </Box>
  );
}
```

### Lazy Load Long Content

For very long documents, consider lazy loading:

```tsx
function LazyMarkdown({ content }) {
  const [isVisible, setIsVisible] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setIsVisible(true);
          observer.disconnect();
        }
      },
      { threshold: 0.1 }
    );

    if (ref.current) {
      observer.observe(ref.current);
    }

    return () => observer.disconnect();
  }, []);

  return (
    <Box ref={ref}>
      {isVisible ? (
        <Markdown content={content} />
      ) : (
        <Skeleton variant="rectangular" height={200} />
      )}
    </Box>
  );
}
```

### Split Large Documents

For very large documents, split into sections:

```tsx
function LargeDocument({ sections }) {
  return (
    <Stack gap={4}>
      {sections.map((section, index) => (
        <Box key={index}>
          <Markdown content={section} defaultLevel="body-md" />
          {index < sections.length - 1 && <Divider />}
        </Box>
      ))}
    </Stack>
  );
}
```

### Avoid Unnecessary Re-parsing

Keep content stable when possible:

```tsx
// ❌ Bad: Creating new string on each render
<Markdown content={`Hello, ${name}!`} />

// ✅ Good: Memoize dynamic content
const content = useMemo(() => `Hello, ${name}!`, [name]);
<Markdown content={content} />
```

Markdown provides a powerful way to render formatted text content in your application. Use it for documentation, user-generated content, and any scenario requiring rich text display. Always sanitize untrusted content, match typography levels to your context, and consider performance for large documents.
