> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# CodeSnippet

A block of code to be read and copied, never edited — reach for `InlineCodeSnippet` when the code belongs inside a sentence, and a real editor when the value is meant to change. Everything beyond the code is composed: a `CodeSnippetHeader` carrying a title or tabs, `CodeSnippetActions` for copy, wrap and fullscreen, `CodeSnippetLineNumbers`, and per-line colour, prefixes and folds — and highlighting happens only inside a `CodeSnippetAdapterProvider`. The snippet sits inside a `display: contents` wrapper that keeps it mounted across fullscreen, so space snippets with their own `className` (for example `mt-16`) or a `gap` on the parent — not `space-*`, `divide-*` or child selectors on the parent.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/CodeSnippet) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/data-display-codesnippet-codesnippet--overview)

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const Default = () => (
  <CodeSnippetRoot code={bashCode} language='text'>
    <CodeSnippetContent>
      <CodeSnippetCode />
    </CodeSnippetContent>
  </CodeSnippetRoot>
);
```

## Usage

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';
```

## Examples

### CodeSnippet

#### With line numbers

`CodeSnippetLineNumbers` is a sibling of the code inside `CodeSnippetContent`, so the
gutter is something you compose in rather than a prop you switch on.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const WithLineNumbers = () => (
  <CodeSnippetRoot code={sampleCode} language='text'>
    <CodeSnippetContent>
      <CodeSnippetLineNumbers />
      <CodeSnippetCode />
    </CodeSnippetContent>
  </CodeSnippetRoot>
);
```

#### Sizes

The three sizes. `sm` is the default at 12px; `md` and `lg` step the code to 14 and
16px for a block meant to be read from further away.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';
import { VStack } from '@wallarm-org/design-system/Stack';

export const Sizes = () => (
  <VStack gap={16}>
    <VStack align='start' gap={4}>
      <CodeSnippetRoot code={bashCode} language='text' size='sm'>
        <CodeSnippetContent>
          <CodeSnippetCode />
        </CodeSnippetContent>
      </CodeSnippetRoot>
    </VStack>
    <VStack align='start' gap={4}>
      <CodeSnippetRoot code={bashCode} language='text' size='md'>
        <CodeSnippetContent>
          <CodeSnippetCode />
        </CodeSnippetContent>
      </CodeSnippetRoot>
    </VStack>
    <VStack align='start' gap={4}>
      <CodeSnippetRoot code={bashCode} language='text' size='lg'>
        <CodeSnippetContent>
          <CodeSnippetCode />
        </CodeSnippetContent>
      </CodeSnippetRoot>
    </VStack>
  </VStack>
);
```

#### Line annotations

`lines`, keyed by line number, tints a line and hangs a prefix off it — here a
tooltipped icon on each of the three headers worth calling out.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';
import { Info, Skull, TriangleAlert } from '@wallarm-org/design-system/icons';
import { Tooltip, TooltipContent, TooltipTrigger } from '@wallarm-org/design-system/Tooltip';

export const LineAnnotations = () => {
  const httpCode = `Host: inventory.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Cache-Control: no-cache`;

  return (
    <CodeSnippetRoot
      code={httpCode}
      language='text'
      lines={{
        3: {
          color: 'danger',
          prefix: (
            <Tooltip>
              <TooltipTrigger>
                <Skull />
              </TooltipTrigger>
              <TooltipContent>Tooltip</TooltipContent>
            </Tooltip>
          ),
        },
        5: {
          color: 'warning',
          prefix: (
            <Tooltip>
              <TooltipTrigger>
                <TriangleAlert />
              </TooltipTrigger>
              <TooltipContent>Tooltip</TooltipContent>
            </Tooltip>
          ),
        },
        7: {
          color: 'info',
          prefix: (
            <Tooltip>
              <TooltipTrigger>
                <Info />
              </TooltipTrigger>
              <TooltipContent>Tooltip</TooltipContent>
            </Tooltip>
          ),
        },
      }}
    >
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  );
};
```

#### Line colors

The seven line colours are semantic, so choose by what the line means — `danger` for
the attack, `info` for the aside — not by which tint reads best.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';
import { Info } from '@wallarm-org/design-system/icons';

export const LineColors = () => {
  const colorsCode = `Line 1: Default (no color)
Line 2: Danger color
Line 3: Warning color
Line 4: Info color
Line 5: Success color
Line 6: Brand color
Line 7: AI color
Line 8: Neutral color`;

  return (
    <CodeSnippetRoot
      code={colorsCode}
      language='text'
      lines={{
        2: { color: 'danger' },
        3: { color: 'warning' },
        4: { color: 'info' },
        5: { color: 'success' },
        6: { color: 'brand' },
        7: { color: 'ai' },
        8: { color: 'neutral' },
      }}
    >
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  );
};
```

#### Line ranges

`ranges` narrows the emphasis to character offsets inside the line — start inclusive,
end exclusive — and once a line has them only the range is coloured, though the
line's own background stays.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const LineRanges = () => {
  const httpCode = `GET /api/v2/users HTTP/1.1
Host: inventory.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
X-Forwarded-For: 192.168.1.100
Cache-Control: no-cache`;

  return (
    <CodeSnippetRoot
      code={httpCode}
      language='text'
      lines={{
        4: {
          color: 'danger',
          ranges: [{ start: 8, end: 24 }],
        },
        7: {
          color: 'info',
          ranges: [{ start: 17, end: 30 }],
        },
      }}
    >
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  );
};
```

#### Text styles

`textStyle` overrides the weight or slant a colour would have chosen, with `className`
and `style` left for the cases the three named styles do not cover.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const TextStyles = () => {
  const stylesCode = `Line 1: Default (regular)
Line 2: Medium weight
Line 3: Italic style
Line 4: Danger with italic override
Line 5: Neutral (default italic)
Line 6: Custom className
Line 7: Custom inline style`;

  return (
    <CodeSnippetRoot
      code={stylesCode}
      language='text'
      lines={{
        2: { textStyle: 'medium' },
        3: { textStyle: 'italic' },
        4: { color: 'danger', textStyle: 'italic' },
        5: { color: 'neutral' },
        6: { className: 'underline' },
        7: { style: { textDecoration: 'line-through' } },
      }}
    >
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  );
};
```

#### Line with prefix

A `+` and `-` prefix over `success` and `danger` lines gives you a diff without a diff
component.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const LineWithPrefix = () => {
  const diffCode = `const greeting = "Hello";
console.log("old message");
console.log("new message");
console.log("another new line");

export default greeting;`;

  return (
    <CodeSnippetRoot
      code={diffCode}
      language='text'
      lines={{
        2: { color: 'danger', prefix: '-' },
        3: { color: 'success', prefix: '+' },
        4: { color: 'success', prefix: '+' },
      }}
    >
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  );
};
```

#### Line wrapping

`wrapLines` against the same code unwrapped, in three pairs — what to check is that
prefixes, colour sticks and fold toggles stay on the first visual row of a wrapped line.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot, getHttpFolds } from '@wallarm-org/design-system/CodeSnippet';
import { VStack } from '@wallarm-org/design-system/Stack';

export const LineWrapping = () => {
  const longCode = `const veryLongVariableName = "This is a very long string that will demonstrate line wrapping behavior when the content exceeds the container width";
console.log(veryLongVariableName);`;
  const httpCode = `GET /api/v2/users?page=1&limit=20&filter=active&sort=name&order=asc&include=profile,settings HTTP/1.1
Host: api.wallarm.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0
Content-Type: application/json
Accept: application/json
{
  "filter": { "status": "active", "role": "admin" }
}`;
  return (
    <VStack gap={16}>
      <VStack align='start' gap={4}>
        <div style={{ maxWidth: '600px' }}>
          <CodeSnippetRoot code={longCode} language='text'>
            <CodeSnippetContent>
              <CodeSnippetLineNumbers />
              <CodeSnippetCode />
            </CodeSnippetContent>
          </CodeSnippetRoot>
        </div>
      </VStack>
      <VStack align='start' gap={4}>
        <div style={{ maxWidth: '600px' }}>
          <CodeSnippetRoot code={longCode} language='text' wrapLines>
            <CodeSnippetContent>
              <CodeSnippetLineNumbers />
              <CodeSnippetCode />
            </CodeSnippetContent>
          </CodeSnippetRoot>
        </div>
      </VStack>
      <VStack align='start' gap={4}>
        <div style={{ maxWidth: '600px' }}>
          <CodeSnippetRoot
            code={longCode}
            language='text'
            lines={{
              1: { color: 'danger', prefix: '-' },
              2: { color: 'success', prefix: '+' },
            }}
          >
            <CodeSnippetContent>
              <CodeSnippetLineNumbers />
              <CodeSnippetCode />
            </CodeSnippetContent>
          </CodeSnippetRoot>
        </div>
      </VStack>
      <VStack align='start' gap={4}>
        <div style={{ maxWidth: '600px' }}>
          <CodeSnippetRoot
            code={longCode}
            language='text'
            wrapLines
            lines={{
              1: { color: 'danger', prefix: '-' },
              2: { color: 'success', prefix: '+' },
            }}
          >
            <CodeSnippetContent>
              <CodeSnippetLineNumbers />
              <CodeSnippetCode />
            </CodeSnippetContent>
          </CodeSnippetRoot>
        </div>
      </VStack>
      <VStack align='start' gap={4}>
        <div style={{ maxWidth: '600px' }}>
          <CodeSnippetRoot
            code={httpCode}
            language='text'
            folds={getHttpFolds(httpCode, { headers: { defaultCollapsed: true } })}
          >
            <CodeSnippetContent>
              <CodeSnippetLineNumbers />
              <CodeSnippetCode />
            </CodeSnippetContent>
          </CodeSnippetRoot>
        </div>
      </VStack>
      <VStack align='start' gap={4}>
        <div style={{ maxWidth: '600px' }}>
          <CodeSnippetRoot
            code={httpCode}
            language='text'
            wrapLines
            folds={getHttpFolds(httpCode, { headers: { defaultCollapsed: true } })}
          >
            <CodeSnippetContent>
              <CodeSnippetLineNumbers />
              <CodeSnippetCode />
            </CodeSnippetContent>
          </CodeSnippetRoot>
        </div>
      </VStack>
    </VStack>
  );
};
```

#### With both scrolls

Given a fixed height inside a narrow column, the block scrolls in both directions
rather than pushing its container around.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';
import { Skull, TriangleAlert } from '@wallarm-org/design-system/icons';

export const WithBothScrolls = () => (
  <div style={{ maxWidth: '500px', maxHeight: '300px', background: 'white' }}>
    <CodeSnippetRoot
      code={longScrollCode}
      language='text'
      lines={{
        2: { color: 'warning', prefix: <TriangleAlert /> },
        3: { color: 'info' },
        13: { color: 'danger', prefix: <Skull /> },
        20: { color: 'success', prefix: '+' },
      }}
      style={{ height: '280px' }}
    >
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  </div>
);
```

#### Custom starting line

`startingLineNumber` renumbers the gutter, for a fragment lifted out of a longer file.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const CustomStartingLine = () => (
  <CodeSnippetRoot code={sampleCode} language='text' startingLineNumber={97}>
    <CodeSnippetContent>
      <CodeSnippetLineNumbers />
      <CodeSnippetCode />
    </CodeSnippetContent>
  </CodeSnippetRoot>
);
```

#### JSON with shiki

Shiki, supplied through `CodeSnippetAdapterProvider`, uses VS Code-style grammars.
The adapter lazily initializes its supported languages and github-light theme with
the Oniguruma WASM engine on the first highlight call.

```tsx
import { loadShikiAdapter, CodeSnippetAdapterProvider, CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const JSONWithShiki = () => (
  <CodeSnippetAdapterProvider adapter={loadShikiAdapter}>
    <CodeSnippetRoot code={jsonCode} language='json'>
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  </CodeSnippetAdapterProvider>
);
```

#### Typescript with prism

TypeScript highlighted with Prism. Its loader emits only the Prism adapter's
dependencies; unused Shiki and highlight.js loaders are discarded by the consumer.

```tsx
import { loadPrismAdapter, CodeSnippetAdapterProvider, CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const TypescriptWithPrism = () => (
  <CodeSnippetAdapterProvider adapter={loadPrismAdapter}>
    <CodeSnippetRoot code={typescriptCode} language='typescript'>
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  </CodeSnippetAdapterProvider>
);
```

#### Bash with prism

A multi-line `curl` under Prism, where the continuation backslashes and the quoted JSON
body are the parts a highlighter usually gets wrong.

```tsx
import { loadPrismAdapter, CodeSnippetAdapterProvider, CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const BashWithPrism = () => (
  <CodeSnippetAdapterProvider adapter={loadPrismAdapter}>
    <CodeSnippetRoot code={curlCode} language='bash'>
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  </CodeSnippetAdapterProvider>
);
```

#### HTML with highlight js

HTML highlighted with highlight.js. The adapter loads the library lazily and
exposes the languages listed by its getSupportedLanguages() method.

```tsx
import { loadHighlightJsAdapter, CodeSnippetAdapterProvider, CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const HTMLWithHighlightJs = () => (
  <CodeSnippetAdapterProvider adapter={loadHighlightJsAdapter}>
    <CodeSnippetRoot code={htmlCode} language='html'>
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  </CodeSnippetAdapterProvider>
);
```

#### HTTP request with prism

`language='http'` is a grammar in its own right — method, path and version on the first
line, then header names told apart from their values.

```tsx
import { loadPrismAdapter, CodeSnippetAdapterProvider, CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const HTTPRequestWithPrism = () => (
  <CodeSnippetAdapterProvider adapter={loadPrismAdapter}>
    <CodeSnippetRoot code={httpRequestCode} language='http'>
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  </CodeSnippetAdapterProvider>
);
```

#### HTTP response with shiki

The response side, where the JSON body after the headers is highlighted as JSON rather
than as more header text.

```tsx
import { loadShikiAdapter, CodeSnippetAdapterProvider, CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot } from '@wallarm-org/design-system/CodeSnippet';

export const HTTPResponseWithShiki = () => (
  <CodeSnippetAdapterProvider adapter={loadShikiAdapter}>
    <CodeSnippetRoot code={httpResponseCode} language='http'>
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  </CodeSnippetAdapterProvider>
);
```

#### With header

`CodeSnippetHeader` with a `CodeSnippetTitle` names the file the code came from, as a
bar above the block rather than a caption on it.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetHeader, CodeSnippetRoot, CodeSnippetTitle } from '@wallarm-org/design-system/CodeSnippet';

export const WithHeader = () => (
  <CodeSnippetRoot code={bashCode} language='text'>
    <CodeSnippetHeader>
      <CodeSnippetTitle>install.sh</CodeSnippetTitle>
    </CodeSnippetHeader>
    <CodeSnippetContent>
      <CodeSnippetCode />
    </CodeSnippetContent>
  </CodeSnippetRoot>
);
```

#### With tabs and actions

Tabs in the header swap the `code` the block is given, which is how one command per
package manager is built; the actions sit at the far end of the same bar.

```tsx
import { useState } from 'react';
import { CodeSnippetActions, CodeSnippetCode, CodeSnippetContent, CodeSnippetCopyButton, CodeSnippetFullscreenButton, CodeSnippetHeader, CodeSnippetRoot, CodeSnippetTab, CodeSnippetTabs, CodeSnippetWrapButton } from '@wallarm-org/design-system/CodeSnippet';

export const WithTabsAndActions = () => {
  const [tab, setTab] = useState('npm');
  const code = packageManagerCodes[tab] ?? '';

  return (
    <div style={{ width: '320px' }}>
      <CodeSnippetRoot code={code} language='text'>
        <CodeSnippetHeader>
          <CodeSnippetTabs value={tab} onValueChange={setTab}>
            <CodeSnippetTab value='npm'>npm</CodeSnippetTab>
            <CodeSnippetTab value='pnpm'>pnpm</CodeSnippetTab>
            <CodeSnippetTab value='yarn'>yarn</CodeSnippetTab>
            <CodeSnippetTab value='bun'>bun</CodeSnippetTab>
          </CodeSnippetTabs>
          <CodeSnippetActions>
            <CodeSnippetFullscreenButton />
            <CodeSnippetWrapButton />
            <CodeSnippetCopyButton />
          </CodeSnippetActions>
        </CodeSnippetHeader>
        <CodeSnippetContent>
          <CodeSnippetCode />
        </CodeSnippetContent>
      </CodeSnippetRoot>
    </div>
  );
};
```

#### With floating actions

With no header to hold them, `CodeSnippetActions` floats over the top-right of the code
— the shape for a block whose only affordance is copy.

```tsx
import { CodeSnippetActions, CodeSnippetCode, CodeSnippetContent, CodeSnippetCopyButton, CodeSnippetLineNumbers, CodeSnippetRoot, CodeSnippetWrapButton } from '@wallarm-org/design-system/CodeSnippet';

export const WithFloatingActions = () => (
  <div style={{ width: '320px' }}>
    <CodeSnippetRoot code={sampleCode} language='text'>
      <CodeSnippetActions>
        <CodeSnippetWrapButton />
        <CodeSnippetCopyButton />
      </CodeSnippetActions>
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  </div>
);
```

#### Show more

`maxLines` clips the block and adds the control itself — but only when it would hide at
least three lines, so the middle snippet stays open; the third passes props to the real
button by rendering `CodeSnippetShowMoreButton` in place of the automatic one.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetRoot, CodeSnippetShowMoreButton } from '@wallarm-org/design-system/CodeSnippet';

export const ShowMore = () => (
  <div style={{ display: 'flex', flexDirection: 'column', gap: '24px', width: '500px' }}>
    <div>
      <CodeSnippetRoot
        code={showMoreCode}
        language='text'
        maxLines={7}
        data-testid='show-more-clipped'
      >
        <CodeSnippetContent>
          <CodeSnippetCode />
        </CodeSnippetContent>
      </CodeSnippetRoot>
    </div>
    <div>
      <CodeSnippetRoot
        code={showMoreThresholdCode}
        language='text'
        maxLines={7}
        data-testid='show-more-threshold'
      >
        <CodeSnippetContent>
          <CodeSnippetCode />
        </CodeSnippetContent>
      </CodeSnippetRoot>
    </div>
    <div>
      <CodeSnippetRoot code={showMoreCode} language='text' maxLines={7}>
        <CodeSnippetContent>
          <CodeSnippetCode />
        </CodeSnippetContent>
        <CodeSnippetShowMoreButton data-analytics-id='CODE_SHOW_MORE' />
      </CodeSnippetRoot>
    </div>
  </div>
);
```

#### HTTP request with folding

`getHttpFolds` reads an HTTP message and returns its fold regions, so the reader opens
the headers or the body rather than scrolling past both.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot, getHttpFolds } from '@wallarm-org/design-system/CodeSnippet';

export const HTTPRequestWithFolding = () => (
  <CodeSnippetRoot
    code={foldableRequestCode}
    language='text'
    folds={getHttpFolds(foldableRequestCode)}
  >
    <CodeSnippetContent>
      <CodeSnippetLineNumbers />
      <CodeSnippetCode />
    </CodeSnippetContent>
  </CodeSnippetRoot>
);
```

#### HTTP response with folding

The same helper on a response, where the body is usually the half worth folding away.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot, getHttpFolds } from '@wallarm-org/design-system/CodeSnippet';

export const HTTPResponseWithFolding = () => (
  <CodeSnippetRoot
    code={foldableResponseCode}
    language='text'
    folds={getHttpFolds(foldableResponseCode)}
  >
    <CodeSnippetContent>
      <CodeSnippetLineNumbers />
      <CodeSnippetCode />
    </CodeSnippetContent>
  </CodeSnippetRoot>
);
```

#### With folding expanded

Folds over coloured lines: a collapsed fold takes its colours and prefixes with it, and
hands them back on expand.

```tsx
import { CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot, getHttpFolds } from '@wallarm-org/design-system/CodeSnippet';

export const WithFoldingExpanded = () => (
  <CodeSnippetRoot
    code={foldableRequestCode}
    language='text'
    folds={getHttpFolds(foldableRequestCode)}
    lines={{
      3: { color: 'warning' },
      4: { color: 'danger', ranges: [{ start: 14, end: 42, color: 'danger' }] },
      10: { color: 'info' },
      11: { color: 'info' },
    }}
  >
    <CodeSnippetContent>
      <CodeSnippetLineNumbers />
      <CodeSnippetCode />
    </CodeSnippetContent>
  </CodeSnippetRoot>
);
```

#### With folding and show more

Folds, `maxLines` and `startingLineNumber` together — fold line numbers are absolute, so
`getHttpFolds` has to be given the same offset the gutter uses.

```tsx
import { loadShikiAdapter, CodeSnippetAdapterProvider, CodeSnippetCode, CodeSnippetContent, CodeSnippetLineNumbers, CodeSnippetRoot, getHttpFolds } from '@wallarm-org/design-system/CodeSnippet';

export const WithFoldingAndShowMore = () => (
  <CodeSnippetAdapterProvider adapter={loadShikiAdapter}>
    <CodeSnippetRoot
      code={foldableResponseCode}
      language='http'
      startingLineNumber={100}
      maxLines={6}
      folds={getHttpFolds(foldableResponseCode, { startingLineNumber: 100 })}
    >
      <CodeSnippetContent>
        <CodeSnippetLineNumbers />
        <CodeSnippetCode />
      </CodeSnippetContent>
    </CodeSnippetRoot>
  </CodeSnippetAdapterProvider>
);
```

#### Fullscreen inside drawer

Fullscreen opened from a modal `Drawer` stacks above it as a nested layer: its buttons stay
clickable, and Escape or a backdrop click leaves fullscreen while the drawer stays open.

```tsx
import { Button } from '@wallarm-org/design-system/Button';
import { CodeSnippetActions, CodeSnippetCode, CodeSnippetContent, CodeSnippetCopyButton, CodeSnippetFullscreenButton, CodeSnippetHeader, CodeSnippetRoot, CodeSnippetTitle } from '@wallarm-org/design-system/CodeSnippet';
import { Drawer, DrawerBody, DrawerContent, DrawerHeader, DrawerTitle, DrawerTrigger } from '@wallarm-org/design-system/Drawer';

export const FullscreenInsideDrawer = () => (
  <Drawer>
    <DrawerTrigger asChild>
      <Button variant='outline' color='neutral'>
        Open Drawer
      </Button>
    </DrawerTrigger>
    <DrawerContent>
      <DrawerHeader>
        <DrawerTitle>Request</DrawerTitle>
      </DrawerHeader>
      <DrawerBody>
        <CodeSnippetRoot code={jsonCode} language='json'>
          <CodeSnippetHeader>
            <CodeSnippetTitle>package.json</CodeSnippetTitle>
            <CodeSnippetActions>
              <CodeSnippetFullscreenButton />
              <CodeSnippetCopyButton />
            </CodeSnippetActions>
          </CodeSnippetHeader>
          <CodeSnippetContent>
            <CodeSnippetCode />
          </CodeSnippetContent>
        </CodeSnippetRoot>
      </DrawerBody>
    </DrawerContent>
  </Drawer>
);
```

### InlineCodeSnippet

#### Default

One snippet in three sentence sizes: `size='inherit'`, the default, scales the type
and the padding with whatever it sits in, and hovering offers the copy.

```tsx
import { InlineCodeSnippet } from '@wallarm-org/design-system/CodeSnippet';
import { VStack } from '@wallarm-org/design-system/Stack';

export const Default = () => (
  <VStack align='start'>
    <p className='text-xs text-text-primary'>
      Small text: Run{' '}
      <InlineCodeSnippet code='npm install @wads/ui' data-testid='inline-code-copyable' /> to
      install dependencies.
    </p>
    <p className='text-sm text-text-primary'>
      Medium text: Run <InlineCodeSnippet code='npm install @wads/ui' /> to install dependencies.
    </p>
    <p className='text-base text-text-primary'>
      Large text: Run <InlineCodeSnippet code='npm install @wads/ui' /> to install dependencies.
    </p>
  </VStack>
);
```

#### Sizes

The three fixed sizes, each beside the text size it pairs with — set one when the
snippet must hold its size regardless of its surroundings.

```tsx
import { InlineCodeSnippet } from '@wallarm-org/design-system/CodeSnippet';
import { VStack } from '@wallarm-org/design-system/Stack';

export const Sizes = () => (
  <VStack align='start' gap={16}>
    <VStack align='start' gap={4}>
      <div className='text-xs text-text-primary'>
        To start creating an interface, run{' '}
        <InlineCodeSnippet code='npm install @wads/ui' size='sm' /> and then apply the following...
      </div>
    </VStack>
    <VStack align='start' gap={4}>
      <div className='text-sm text-text-primary'>
        To start creating an interface, run{' '}
        <InlineCodeSnippet code='npm install @wads/ui' size='md' /> and then apply the following...
      </div>
    </VStack>
    <VStack align='start' gap={4}>
      <div className='text-base text-text-primary'>
        To start creating an interface, run{' '}
        <InlineCodeSnippet code='npm install @wads/ui' size='lg' /> and then apply the following...
      </div>
    </VStack>
  </VStack>
);
```

#### Non copyable

`copyable={false}` takes the tooltip and the pointer cursor away with the copy, for a
snippet that is only being named rather than reused.

```tsx
import { InlineCodeSnippet } from '@wallarm-org/design-system/CodeSnippet';

export const NonCopyable = () => (
  <p className='text-sm text-text-primary'>
    This code is not copyable:{' '}
    <InlineCodeSnippet
      code='npm install @wads/ui'
      copyable={false}
      data-testid='inline-code-non-copyable'
    />
  </p>
);
```

#### Various content

Commands, JSON, SQL and a quoted message all render in one colour — inline code gets
the mono treatment and nothing else.

```tsx
import { InlineCodeSnippet } from '@wallarm-org/design-system/CodeSnippet';
import { VStack } from '@wallarm-org/design-system/Stack';

export const VariousContent = () => (
  <VStack align='start'>
    <InlineCodeSnippet code='npm install' />
    <InlineCodeSnippet code='curl -X POST https://api.wallarm.com' />
    <InlineCodeSnippet code='{"status": "ok"}' />
    <InlineCodeSnippet code='SELECT * FROM users WHERE id = 1' />
    <InlineCodeSnippet code="git commit -m 'feat: add feature'" />
  </VStack>
);
```

## Props

### CodeSnippetActions

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### CodeSnippetAdapterProvider

| Prop       | Type                      | Default | Description                                                                                                                                                                                   |
| ---------- | ------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| adapter \* | `AdapterInput<TLanguage>` |         | Syntax adapter or a loader function that returns a Promise of the adapter. Using a loader function enables code splitting - the adapter bundle will only be loaded when the component mounts. |

### CodeSnippetCode

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### CodeSnippetContent

| Prop           | Type                                                 | Default | Description                                      |
| -------------- | ---------------------------------------------------- | ------- | ------------------------------------------------ |
| defaultChecked | `boolean \| undefined`                               |         |                                                  |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |                                                  |
| autoFocus      | `boolean \| undefined`                               |         |                                                  |
| id             | `string \| undefined`                                |         |                                                  |
| tabIndex       | `number \| undefined`                                |         |                                                  |
| title          | `string \| undefined`                                |         |                                                  |
| rel            | `string \| undefined`                                |         |                                                  |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |                                                  |
| nativeScroll   | `boolean \| undefined`                               | `false` | Use native browser scroll instead of ScrollArea. |

### CodeSnippetCopyButton

| Prop           | Type                                                                       | Default | Description |
| -------------- | -------------------------------------------------------------------------- | ------- | ----------- |
| title          | `string \| undefined`                                                      |         |             |
| defaultChecked | `boolean \| undefined`                                                     |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined`                       |         |             |
| autoFocus      | `boolean \| undefined`                                                     |         |             |
| id             | `string \| undefined`                                                      |         |             |
| tabIndex       | `number \| undefined`                                                      |         |             |
| rel            | `string \| undefined`                                                      |         |             |
| color          | `string \| undefined`                                                      |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`                              |         |             |
| type           | `"button" \| "submit" \| "reset" \| undefined`                             |         |             |
| disabled       | `boolean \| undefined`                                                     |         |             |
| name           | `string \| undefined`                                                      |         |             |
| value          | `string \| number \| readonly string[] \| undefined`                       |         |             |
| asChild        | `boolean \| undefined`                                                     |         |             |
| size           | `{ small: string; medium: string; large: string; 'inline-edit': string; }` |         |             |
| data-testid    | `string \| undefined`                                                      |         |             |
| variant        | `{ primary: string; outline: string; ghost: string; secondary: string; }`  |         |             |
| loading        | `{ true: string; }`                                                        |         |             |
| as             | `C \| undefined`                                                           |         |             |
| fullWidth      | `{ true: string; false: string; }`                                         |         |             |

### CodeSnippetFullscreenButton

| Prop           | Type                                                                       | Default | Description |
| -------------- | -------------------------------------------------------------------------- | ------- | ----------- |
| title          | `string \| undefined`                                                      |         |             |
| defaultChecked | `boolean \| undefined`                                                     |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined`                       |         |             |
| autoFocus      | `boolean \| undefined`                                                     |         |             |
| id             | `string \| undefined`                                                      |         |             |
| tabIndex       | `number \| undefined`                                                      |         |             |
| rel            | `string \| undefined`                                                      |         |             |
| color          | `string \| undefined`                                                      |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`                              |         |             |
| type           | `"button" \| "submit" \| "reset" \| undefined`                             |         |             |
| disabled       | `boolean \| undefined`                                                     |         |             |
| name           | `string \| undefined`                                                      |         |             |
| value          | `string \| number \| readonly string[] \| undefined`                       |         |             |
| asChild        | `boolean \| undefined`                                                     |         |             |
| size           | `{ small: string; medium: string; large: string; 'inline-edit': string; }` |         |             |
| data-testid    | `string \| undefined`                                                      |         |             |
| variant        | `{ primary: string; outline: string; ghost: string; secondary: string; }`  |         |             |
| loading        | `{ true: string; }`                                                        |         |             |
| as             | `C \| undefined`                                                           |         |             |
| fullWidth      | `{ true: string; false: string; }`                                         |         |             |

### CodeSnippetHeader

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### CodeSnippetLineNumbers

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### CodeSnippetRoot

| Prop               | Type                                                 | Default              | Description                                                                                                                                                       |
| ------------------ | ---------------------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| title              | `string \| undefined`                                |                      |                                                                                                                                                                   |
| defaultChecked     | `boolean \| undefined`                               |                      |                                                                                                                                                                   |
| defaultValue       | `string \| number \| readonly string[] \| undefined` |                      |                                                                                                                                                                   |
| autoFocus          | `boolean \| undefined`                               |                      |                                                                                                                                                                   |
| id                 | `string \| undefined`                                |                      |                                                                                                                                                                   |
| tabIndex           | `number \| undefined`                                |                      |                                                                                                                                                                   |
| rel                | `string \| undefined`                                |                      |                                                                                                                                                                   |
| onCopy             | `ClipboardEventHandler<T> \| undefined`              |                      |                                                                                                                                                                   |
| onChange           | `ChangeEventHandler<T, Element> \| undefined`        |                      |                                                                                                                                                                   |
| size               | `{ sm: string; md: string; lg: string; }`            | `sm`                 |                                                                                                                                                                   |
| data-testid        | `string \| undefined`                                |                      |                                                                                                                                                                   |
| code \*            | `string`                                             |                      | The code string to display                                                                                                                                        |
| language           | `TLanguage \| undefined`                             | `text' as TLanguage` | Programming language for syntax highlighting                                                                                                                      |
| lines              | `Record<number, LineConfig> \| undefined`            | `EMPTY_LINES`        | Per-line configuration (color, prefix) keyed by line number                                                                                                       |
| startingLineNumber | `number \| undefined`                                | `1`                  | Starting line number (default: 1)                                                                                                                                 |
| wrapLines          | `boolean \| undefined`                               |                      | Enable line wrapping                                                                                                                                              |
| maxLines           | `number \| undefined`                                | `0`                  | Max lines before collapsing. Root auto-renders the default show-more button unless a direct `CodeSnippetShowMoreButton` child is provided for button-level props. |
| folds              | `FoldRegion[] \| undefined`                          |                      | Foldable regions that can be collapsed/expanded                                                                                                                   |

### CodeSnippetShowMoreButton

| Prop           | Type                                                                       | Default | Description |
| -------------- | -------------------------------------------------------------------------- | ------- | ----------- |
| title          | `string \| undefined`                                                      |         |             |
| defaultChecked | `boolean \| undefined`                                                     |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined`                       |         |             |
| autoFocus      | `boolean \| undefined`                                                     |         |             |
| id             | `string \| undefined`                                                      |         |             |
| tabIndex       | `number \| undefined`                                                      |         |             |
| rel            | `string \| undefined`                                                      |         |             |
| color          | `string \| undefined`                                                      |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`                              |         |             |
| type           | `"button" \| "submit" \| "reset" \| undefined`                             |         |             |
| disabled       | `boolean \| undefined`                                                     |         |             |
| name           | `string \| undefined`                                                      |         |             |
| value          | `string \| number \| readonly string[] \| undefined`                       |         |             |
| asChild        | `boolean \| undefined`                                                     |         |             |
| size           | `{ small: string; medium: string; large: string; 'inline-edit': string; }` |         |             |
| data-testid    | `string \| undefined`                                                      |         |             |
| variant        | `{ primary: string; outline: string; ghost: string; secondary: string; }`  |         |             |
| loading        | `{ true: string; }`                                                        |         |             |
| as             | `C \| undefined`                                                           |         |             |
| fullWidth      | `{ true: string; false: string; }`                                         |         |             |

### CodeSnippetTab

| Prop           | Type                                                                 | Default | Description |
| -------------- | -------------------------------------------------------------------- | ------- | ----------- |
| value \*       | `string`                                                             |         |             |
| asChild        | `boolean \| undefined`                                               |         |             |
| onFocus        | `((e: FocusEvent<HTMLButtonElement, Element>) => void) \| undefined` |         |             |
| title          | `string \| undefined`                                                |         |             |
| defaultChecked | `boolean \| undefined`                                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined`                 |         |             |
| autoFocus      | `boolean \| undefined`                                               |         |             |
| id             | `string \| undefined`                                                |         |             |
| tabIndex       | `number \| undefined`                                                |         |             |
| rel            | `string \| undefined`                                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`                        |         |             |
| type           | `"button" \| "submit" \| "reset" \| undefined`                       |         |             |
| disabled       | `boolean \| undefined`                                               |         |             |
| name           | `string \| undefined`                                                |         |             |
| data-testid    | `string \| undefined`                                                |         |             |

### CodeSnippetTabs

| Prop          | Type                                     | Default | Description |
| ------------- | ---------------------------------------- | ------- | ----------- |
| value         | `string \| undefined`                    |         |             |
| defaultValue  | `string \| undefined`                    |         |             |
| onValueChange | `((value: string) => void) \| undefined` |         |             |

### CodeSnippetTitle

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### CodeSnippetWrapButton

| Prop           | Type                                                                                         | Default | Description |
| -------------- | -------------------------------------------------------------------------------------------- | ------- | ----------- |
| title          | `string \| undefined`                                                                        |         |             |
| defaultChecked | `boolean \| undefined`                                                                       |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined`                                         |         |             |
| autoFocus      | `boolean \| undefined`                                                                       |         |             |
| id             | `string \| undefined`                                                                        |         |             |
| tabIndex       | `number \| undefined`                                                                        |         |             |
| rel            | `string \| undefined`                                                                        |         |             |
| color          | `string \| undefined`                                                                        |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`                                                |         |             |
| onToggle       | `((active: boolean, event: MouseEvent<HTMLButtonElement, MouseEvent>) => void) \| undefined` |         |             |
| type           | `"button" \| "submit" \| "reset" \| undefined`                                               |         |             |
| disabled       | `boolean \| undefined`                                                                       |         |             |
| name           | `string \| undefined`                                                                        |         |             |
| value          | `string \| number \| readonly string[] \| undefined`                                         |         |             |
| asChild        | `boolean \| undefined`                                                                       |         |             |
| size           | `{ small: string; medium: string; large: string; 'inline-edit': string; }`                   |         |             |
| data-testid    | `string \| undefined`                                                                        |         |             |
| variant        | `{ outline: string; ghost: string; }`                                                        |         |             |
| loading        | `{ true: string; }`                                                                          |         |             |
| as             | `C \| undefined`                                                                             |         |             |
| fullWidth      | `{ true: string; false: string; }`                                                           |         |             |
| active         | `{ true: string; false: string; }`                                                           |         |             |

### InlineCodeSnippet

| Prop           | Type                                                 | Default   | Description                                                                                                                              |
| -------------- | ---------------------------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| code \*        | `string`                                             |           | The code content to display                                                                                                              |
| size           | `"inherit" \| "sm" \| "md" \| "lg" \| undefined`     | `inherit` | Size variant                                                                                                                             |
| asChild        | `boolean \| undefined`                               | `false`   | Render as the React element passed via `children` instead of the default `<code>`. The `code` prop becomes the cloned element's content. |
| copyable       | `boolean \| undefined`                               | `true`    | Enable click to copy functionality (default: true)                                                                                       |
| title          | `string \| undefined`                                |           |                                                                                                                                          |
| defaultChecked | `boolean \| undefined`                               |           |                                                                                                                                          |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |           |                                                                                                                                          |
| autoFocus      | `boolean \| undefined`                               |           |                                                                                                                                          |
| id             | `string \| undefined`                                |           |                                                                                                                                          |
| tabIndex       | `number \| undefined`                                |           |                                                                                                                                          |
| rel            | `string \| undefined`                                |           |                                                                                                                                          |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |           |                                                                                                                                          |
