# Markdown

> Renders GitHub-flavoured Markdown in Nasaq typography, with bidi-aware blocks, CodeBlock for code and no raw HTML.

Source: https://docs.nasaqui.com/components/markdown

## Install

```bash
npx shadcn@latest add https://docs.nasaqui.com/r/markdown.json
```

Turns a Markdown string into Nasaq UI: headings and paragraphs use the `Text` roles, tables use the `Table`
components, fenced code uses [CodeBlock](https://docs.nasaqui.com/components/code-block), inline code uses `InlineCode`, and links,
lists, blockquotes and rules follow the design tokens. It is built on `react-markdown` with `remark-gfm`
(tables, task lists, strikethrough, autolinks). It is safe for untrusted text: raw HTML is never rendered.

## When to use

- Model output, release notes, comments, help articles: any text a person or an AI wrote as Markdown.
- Chat bubbles (see [chat](https://docs.nasaqui.com/components/chat)).

## When not to use

- A short label or sentence: use [Text](https://docs.nasaqui.com/components/text).
- Trusted, hand-written page layout: compose components directly.
- Editing Markdown: this renders only.

## Import

```tsx
import { Markdown } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"
```

## Quick start

```tsx
import { Markdown } from "@fadymondy/nasaq/web";

export function Notes() {
  return <Markdown>{"## Release\n\n- Faster **search**\n- Run `pnpm build`"}</Markdown>;
}
```

## Anatomy

```
Markdown        data-slot="markdown"     <div> flex column, gap-3
├─ h1–h6        data-slot="text"         Text h1 / h2 / h3 roles, dir="auto"
├─ p            data-slot="text"         Text body, dir="auto"
├─ ul / ol / li                          dir="auto", logical padding
├─ blockquote                            border-s, dir="auto"
├─ table        data-slot="table"        Table, TableHeader, TableBody, TableRow, TableHead, TableCell
├─ pre          data-slot="code-block"   CodeBlock (always dir="ltr")
├─ code         data-slot="inline-code"  InlineCode
└─ a, hr, img, strong, task-list checkbox
```

## API

### `Markdown`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `string` | required | The Markdown source. |
| `components?` | `Components` (react-markdown) | none | Per-element overrides, merged over the defaults. |
| `remarkPlugins?` | `Options["remarkPlugins"]` | none | Added after `remark-gfm`. |
| `className?` | `string` | none | Merged onto the wrapper `<div>`. |

There is no option to enable raw HTML.

## Examples

### Mixed Arabic and English

```tsx
import { Markdown } from "@fadymondy/nasaq/web";

const source = `# ملاحظات الإصدار

هذه فقرة عربية تحتوي على \`pnpm build\` داخل الجملة.

This paragraph is English and stays left-to-right.

| الميزة | Status |
| :-- | --: |
| البحث | Done |`;

export function Notes() {
  return <Markdown>{source}</Markdown>;
}
```

### Override an element

```tsx
import { Markdown } from "@fadymondy/nasaq/web";

export function Plain({ text }: { text: string }) {
  return <Markdown components={{ h1: ({ children }) => <h2 className="text-h2">{children}</h2> }}>{text}</Markdown>;
}
```

## Accessibility

- Semantic elements are preserved: headings, lists, tables with `scope="col"` headers, `blockquote`.
- Wide tables scroll in a focusable named region (`Table`); code scrolls in a focusable region (`CodeBlock`).
- External links open in a new tab with `rel="noopener noreferrer"`.
- Task-list checkboxes are rendered `disabled`; they are display only.
- Images keep their Markdown alt text; write meaningful alt text in the source.

| Key | Action |
| --- | --- |
| `Tab` | Moves through links, scroll regions and copy buttons |
| Arrow keys | Scroll a focused table or code region |

## RTL & i18n

- Every block carries `dir="auto"`: the first strong character decides, so an Arabic paragraph between English ones flows right to left, and a bullet list follows its own text.
- The wrapper has no `dir`, so it inherits the page.
- Code, and inline code, are always left-to-right and bidi-isolated.
- GFM column alignment maps to `text-start` / `text-end` / `text-center`, not left/right, so it follows the page direction.
- No built-in strings apart from those in CodeBlock ("Copy code" / "نسخ الشيفرة").

## Styling & tokens

- Colours: `text-nq-fg-body` for prose, `text-foreground` for strong and links, `text-muted-foreground` for quotes, `border-border` and `border-nq-line-strong` for rules.
- Change one element with `components`; change spacing with `className` (`gap-*` on the wrapper).

## Do / Don't

- **Do** put untrusted text straight in `children`; it is safe by default.
- **Don't** expect `<div>` or `<script>` in the source to render: raw HTML is dropped.
- **Don't** wrap a Markdown block in a fixed `dir`; let `dir="auto"` decide per block.

## Related

- [CodeBlock](https://docs.nasaqui.com/components/code-block) · [Text](https://docs.nasaqui.com/components/text) · [Table](https://docs.nasaqui.com/components/table) · [Chat](https://docs.nasaqui.com/components/chat)

## Lab

https://docs.nasaqui.com/?path=/docs/components-typography-markdown--docs

## Code

### React

```tsx
import { Markdown } from "@fadymondy/nasaq/web";

export function Notes() {
  return <Markdown>{"## Release\n\n- Faster **search**\n- Run `pnpm build`"}</Markdown>;
}
```

### shadcn

```tsx
import { Markdown } from "@/components/ui/markdown";

export function Notes() {
  return <Markdown>{"## Release\n\n- Faster **search**\n- Run `pnpm build`"}</Markdown>;
}
```

### Vue

```vue
<script setup lang="ts">
import { NqMarkdown } from "@fadymondy/nasaq/vue";
</script>

<template>
  <NqMarkdown source="## Release

- Faster **search**
- Run `pnpm build`" />
</template>
```

### Blade

```blade
<x-nq::markdown :source='"## Release\n\n- Faster **search**\n- Run `pnpm build`"' />
```

### HTML + Alpine

```html
<div data-slot="markdown" class="flex min-w-0 flex-col gap-3 text-body text-nq-fg-body"><h2 data-slot="text" dir="auto" class="text-h2 text-foreground mt-2 text-start first:mt-0">Release</h2>
<ul dir="auto" class="list-disc space-y-1 ps-6 text-body text-nq-fg-body marker:text-muted-foreground">
<li dir="auto" class="text-start [&amp;.task-list-item]:list-none [&amp;.task-list-item]:-ms-6">Faster <strong class="font-semibold text-foreground">search</strong></li>
<li dir="auto" class="text-start [&amp;.task-list-item]:list-none [&amp;.task-list-item]:-ms-6">Run <code data-slot="inline-code" dir="ltr" class="rounded-[4px] border border-border bg-secondary px-1 py-0.5 font-mono text-[0.9em] text-foreground [unicode-bidi:isolate]">pnpm build</code></li>
</ul>
</div>
```
