# CodeView

> A whole source file to read and cite: one table row per line, numbers painted from an attribute so a copy takes only code, rows in chunks the browser skips until they near the screen, a band for the cited lines, and blame hunks with an age strip beside them.

```ts
import { CodeView } from "@sdxc/ui/app";
```

Without script `selected` and `#Ln` paint the cited lines, and each number links to `?L=n#Ln`;
mapping `@sdxc/ui/app/code-view` runs CodeViewSelection for ranges, the menu and `y`.
Set `--code-view-font-size`, `-line-height`, `-blame-width`, `-selected` and `--code-age-1`–`5`.

## Examples

```tsx
<CodeView path="app/routes.ts" language="ts" code={source} selected={parseLineRange(url.searchParams.get("L"))} permalink={`/blob/${sha}/app/routes.ts`} labels={labels}>
	<CodeView.Header meta={t("file.meta", codeStats(source))}>{actions}</CodeView.Header>
</CodeView>
```

```tsx
<CodeView path="app/routes.ts" language="ts" code={source} blame={hunks} labels={labels} />
```

## Props

| Prop | Type | Description |
| --- | --- | --- |
| `code` | `string` | The file's source; a single trailing newline is dropped. |
| `language?` | `string` | Language the code highlights as (`ts`, `css`); omitted, the code draws plain. |
| `path` | `string` | The file's path, which names the table for assistive technology. |
| `tokens?` | `readonly Token[]` | Runs already painted for `code`, which skip highlighting here. |
| `selected?` | `LineRange` | The lines the page's address cites as `?L=3-8`, painted on the server so the band shows without script. Read it with `parseLineRange(url.searchParams.get("L"))`. |
| `lineHref?` | `(line: number) => string` | The address each line number links to. @default lineLink(line), `?L=n#Ln` |
| `blame?` | `readonly BlameHunk[]` | Blame hunks; when set, each hunk draws its commit and age in a leading column. |
| `permalink?` | `string` | The address of this file at a fixed commit, which `y` and "Copy permalink" use. |
| `issueHref?` | `string` | Where "Reference in new issue" goes; the permalink arrives as its `body` parameter. |
| `labels` | `Labels` | Every string the view shows or announces, so it reads in any language. |
| `now?` | `RelativeTimeFormat.DateInput` | The moment blame ages count from. @default the current time |
| `locale?` | `string` | The locale blame ages are written in. @default the runtime's locale |
| `chunkSize?` | `number` | Lines per chunk. @default DEFAULT_CHUNK_SIZE |
| `children?` | `RemixNode` | A CodeView.Header drawn above the lines. |

Also accepts everything in `TagProps<"div">`.


### CodeView.Header

Renders the file's header: its facts (lines, size) on the start side in tabular figures, and its actions on the end side, wrapping under the facts on a narrow view.

| Prop | Type | Description |
| --- | --- | --- |
| `meta?` | `RemixNode` | The file's facts, such as "49 lines (42 loc) · 1.75 KB", built from codeStats. |
| `children?` | `RemixNode` | Actions at the header's end: Raw, Copy, Download, a Code \| Blame switch. |

Also accepts everything in `TagProps<"div">`.


### CodeView.AgeLegend

Renders the age strip's legend: the older label, one swatch per step in the strip's own colors, and the newer label.

| Prop | Type | Description |
| --- | --- | --- |
| `labels` | `{ older: string; newer: string }` | The legend's ends, such as `{ older: "Older", newer: "Newer" }`. |

Also accepts everything in `TagProps<"div">`.


## Also exported

- `codeStats`
