Thanks to visit codestin.com
Credit goes to docs.tangly.dev

Tangly v0.2 ships richer code blocks, page chrome, and more — see what's new

Code

CodeGroup, PackageManager, Snippet, FileTree, Kbd, CopyPrompt. Components for code, files, and keys.

~ 1 min read

ComponentUse for
<CodeGroup>Tab multiple code blocks; auto-syncs on known label families
<PackageManager>npm/yarn/pnpm/bun installs and scripts
<Snippet>Reuse content across pages
<FileTree>Render a directory tree from a Markdown list
<Kbd>Keyboard chord, with auto Cmd→Ctrl on non-Mac
<CopyPrompt>One-click “hand these instructions to my coding agent” button

CodeGroup

Wraps two or more code blocks and renders them as tabs. Each child’s data-filename (from the title="..." fence attribute) or language hint becomes the tab label.

PropTypeDefaultDescription
namestringSync key. Same name on multiple blocks → matched tabs across the page and across navigations (persisted in localStorage). When empty, the runtime auto-derives a name if the labels match a known family (npm/yarn/pnpm/bun, pip/uv/poetry, macOS/Linux/Windows, python/typescript, …).

Multiple languages

mdx
<CodeGroup>
  ```ts title="fetch.ts"
  await fetch("https://api.example.com/v1/users")
  ```
  ```py title="fetch.py"
  requests.get("https://api.example.com/v1/users")
  ```
  ```sh title="curl"
  curl https://api.example.com/v1/users
  ```
</CodeGroup>
fetch.ts
ts
await fetch("https://api.example.com/v1/users")
fetch.py
py
requests.get("https://api.example.com/v1/users")
curl
sh
curl https://api.example.com/v1/users

Synced across blocks

Pick TypeScript on the first block, the second block flips to TypeScript too.

mdx
<CodeGroup name="lang">
  ```ts
  console.log("hello")
  ```
  ```py
  print("hello")
  ```
</CodeGroup>

<CodeGroup name="lang">
  ```ts
  console.log("done")
  ```
  ```py
  print("done")
  ```
</CodeGroup>

Auto-sync (no name)

When labels match a known family, sync happens automatically. Pick bun once, every install block on the page flips. Works across pages too.

mdx
<CodeGroup>
  ```bash bun
  bun add tangly
  ```
  ```bash npm
  npm install tangly
  ```
  ```bash pnpm
  pnpm add tangly
  ```
  ```bash yarn
  yarn add tangly
  ```
</CodeGroup>

Recognized families: auto:pkg-js, auto:pkg-py, auto:pkg-rust, auto:os, auto:shell, auto:runtime-js, auto:lang, auto:editor. Full list in code-sync.ts.

Tab label resolution

Per child, in priority order:

  1. data-filename (from code-fence title="...")
  2. data-language (the language token after the opening fence)
  3. "Tab N" fallback

PackageManager

<PackageManager> renders an install or run command across npm, yarn, pnpm, and bun. Tabs auto-sync as auto:pkg-js so a single pick on any install block (raw <CodeGroup> or <PackageManager>) propagates everywhere.

PropTypeDefaultDescription
namestringPackage name to install. Required unless command is set.
mode"dev" | "prod""prod""dev" installs as devDependency.
commandstringRun a script instead of installing. e.g. "run build".
syncNamestring""Empty default → joins the auto:pkg-js pool. Override only to break the link.

Install

mdx
<PackageManager name="tangly" />
npm install tangly
yarn add tangly
pnpm add tangly
bun add tangly

Install as dev dependency

mdx
<PackageManager name="@tanglydocs/schema" mode="dev" />
npm install --save-dev @tanglydocs/schema
yarn add --dev @tanglydocs/schema
pnpm add --save-dev @tanglydocs/schema
bun add --dev @tanglydocs/schema

Run a script

mdx
<PackageManager command="run build" />
npm run build
yarn run build
pnpm run build
bun run build

Independent block

To break sync for a specific block, give it a unique syncName:

mdx
<PackageManager name="@tanglydocs/cli" syncName="cli-only" />

Snippet

Reusable inline content. Phase-1 placeholder, accepts inline children for now; the file-resolved form (file="snippets/x.mdx") lands in Phase 2.

PropTypeDefaultDescription
filestringPath under snippets/. Phase-2; ignored today.
mdx
<Snippet file="snippets/install.mdx">
  Inline fallback content. Renders as-is until file resolution lands.
</Snippet>

For most reuse cases today, embedded blocks cover the same need.

FileTree

Turns a nested Markdown list into a styled directory tree. Indentation drives nesting. Files pick icons from their extension. **bold** highlights a row. Trailing text becomes a comment. ... is a placeholder.

PropTypeDefaultDescription
variant"default" | "terminal" | "ascii""default"Visual style. See below
chromebooleanfalseOnly on terminal; draws three macOS-style window dots

Default

  • Directorysrc
    • Directorycomponents
      • Button.tsx
      • Card.tsx the file you’ll edit
      • Note.astro
    • Directorystyles
      • globals.css
  • package.json dependencies
  • tangly.config.ts
mdx
<FileTree>
- src
  - components
    - Button.tsx
    - **Card.tsx** the file you'll edit
    - Note.astro
  - styles
    - globals.css
  - ...
- package.json dependencies
- tangly.config.ts
</FileTree>

Terminal variant

Drops the icons, swaps in literal ├──/└── connectors, ships a dark background that ignores theme. Like running tree in a shell. Add chrome for the macOS window header.

  • Directorymy-docs/
    • docs.json
    • introduction.mdx
    • Directoryguides/
      • deploying.mdx
      • themes.mdx
  • package.json
mdx
<FileTree variant="terminal" chrome>
- my-docs/
  - docs.json
  - introduction.mdx
  - guides/
    - **deploying.mdx**
- package.json
</FileTree>

ASCII variant

Minimal: no card, no background, no icons. Use when a tree sits inside another component (Card, Step, Accordion) and the boxed look would be too heavy.

  • Directorypackages/
    • Directorytheme-ui/
      • Directorycomponents/
        • FileTree.astro
        • rehype-file-tree.ts
  • Directorydocs/
mdx
<FileTree variant="ascii">
- packages/
  - theme-ui/
    - components/
      - **FileTree.astro**
- docs/
</FileTree>

Authoring syntax

Five things to know:

  1. Directories. A line ending in / is a directory; so is any line with nested children. Directories are collapsible (<details open>); readers can fold them shut.
  2. Highlighting. Wrap a row in **bold** to highlight it.
  3. Comments. Anything after the filename becomes a muted comment. Inline Markdown works.
  4. Placeholders. A row containing only ... (or ) draws a dimmed placeholder row.
  5. Custom icons. Prefix a row with <Icon icon="..." /> to override the auto-detected file icon.
mdx
<FileTree>
- <Icon icon="cog" /> config
- <Icon icon="database" /> data
</FileTree>

Kbd

Renders styled keycap(s). Either pass children for a single key, or keys="..." for a chord. + and whitespace separate keys, and Cmd / swap to Ctrl on non-Mac platforms.

PropTypeDefaultDescription
keysstringChord string. e.g. "Cmd+K", "Shift Tab".

Single key

mdx
Press <Kbd>Tab</Kbd> to autocomplete.

Press Tab to autocomplete.

Chord (auto Cmd→Ctrl)

mdx
Open the command palette with <Kbd keys="Cmd+K" />.

Open the command palette with Cmd+K.

On Linux and Windows the same chord renders as Ctrl + K.

Manual chord

mdx
<Kbd>Shift</Kbd>+<Kbd>Tab</Kbd>

Shift+Tab

CopyPrompt

A button that copies a ready-to-paste prompt for a coding agent.

The pattern it exists for: instead of pasting a wall of setup instructions at the reader, paste one line that points their agent at a URL it can fetch. The instructions then live at that URL and can change without anyone re-copying.

PropTypeDefaultDescription
hrefstringURL of the instructions the agent should fetch. Relative is fine.
textstringFull prompt text. Wins over href when both are given.
subjectstringWhat the instructions set up, e.g. "squirrelscan". Used in the generated sentence.
labelstring"Copy prompt"Button label.
iconsstring[][]Small vendor marks shown before the label. Image URLs.
titlestringNative tooltip.

One of href or text is required; the build fails if both are missing.

From a URL

mdx
<CopyPrompt href="/agent-setup/prompt.md" subject="my-tool" />

Copies: Fetch and follow the setup instructions for my-tool at https://your-site.dev/agent-setup/prompt.md

A relative href picks up the site’s configured base at build, then resolves against the current document in the browser at click time. The agent receiving the prompt has no page context, so it needs an absolute URL.

Custom text

mdx
<CopyPrompt text="Install the CLI with `brew install my-tool`, then run `my-tool init`." />

With vendor marks

mdx
<CopyPrompt
  href="/agent-setup/prompt.md"
  subject="my-tool"
  label="Set up my agent"
  icons={["/logo/agents/claude-code.png", "/logo/agents/codex.png"]}
/>

Code block chrome

Code blocks render with a caption bar carrying the filename, the language label, and the Copy button. Set styling.codeblocks in docs.json to change that site-wide:

docs.json
json
{
  "styling": {
    "codeblocks": {
      "chrome": "bare",
      "copyButton": "hover"
    }
  }
}
KeyValuesDefaultDescription
chrome"bar" | "bare""bar"bare drops the caption and floats the Copy button over the top-right of the block.
copyButtontrue | false | "always" | "hover"truefalse removes the button. "hover" (bare chrome only) reveals it on hover or keyboard focus; touch devices always see it.

A single fence overrides chrome either way with a bare or bar meta flag:

mdx
```ts bare
const x = 1;
```

Source

Last updated Edit this page

Type to search…

↑↓ navigate open esc close