Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Tabbed Code Snippets Blog Block for React

A code window with a tab per file, numbered lines, marked keywords and a Copy button that really copies, beside the three posts the snippets come from.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

A code-notes block for React with Base UI, written for Gistline, a code-notes blog. A start-aligned header sits over a split behind a divider. At the end a code window drawn in the page's own theme: its title bar is the tab list, one tab per file (retry.ts, gaps.sql, lines.rs), with a Copy button at its end that copies the open file; under the bar numbered lines of mono code with keywords, strings and comments marked by weight and style, and a foot that says how many lines it has and which post it comes from. At the start the three posts the snippets belong to, as cards, the one in the window marked "Shown in the window". It's built from Tabs, CopyButton, Avatar, Badge and Guides. There is no highlighter library, so no extra weight.

FAQ

How do I add a snippet?

Add an entry to SNIPPETS: an id, a file name, a label, the post's title, dek, author, date and minutes, and lines, one array of marked runs per line, built with the helpers kw, fn, str, com and txt. A blank line is an empty array. The tab, the card, the line count and the text that Copy puts on the clipboard all come from it.

What does Copy copy?

The open file, as plain text: every run of a line joined, one line to a row, with no line numbers and no markup. It uses the browser's clipboard, so on a page that isn't served over HTTPS it can fail, and the button says so ("Couldn't copy") instead of pretending.

Is the code highlighted?

Lightly, and without colour: keywords are bold, comments italic, strings and names underlined, so it reads in every theme and in print. For real syntax highlighting, replace CodeLine's runs with your highlighter's output.

How do the tabs work?

Arrow keys move between the files and the open file is the panel. Every file is also drawn once more, unseen, in the same grid cell, so the window keeps its height whichever tab is open. A long line scrolls sideways in a region you can focus.

Do the post cards switch the tab?

No. They are links to the posts, and the one that matches the open file is marked in words. The tabs are the control.

What happens to the code in a right-to-left page?

Nothing: code always reads left to right, so the lines, the numbers and the window keep their direction while the cards and the header mirror.

  • Pro

    Scroll Panel Glossary Blog

    Topics and indexes

    A glossary in a fixed-height scroll panel: sticky letter headings, a part-of-speech tag per term, See also buttons that open a hover card and scroll to the term, and a posts link.

  • Pro

    Expandable Code Banner

    Disclosures and tabs

    An install notice for a CLI toolkit as a disclosure: a header with a version badge opens package-manager tabs and the command in a mono box with a Copy button.

  • Pro

    A film-criticism reading list with three underline tabs, Latest, Popular and Editor's picks, each drawing a different row: dated rows, ranked rows with read counts, and rows with an editor's note.

  • Pro

    A developer-tools blog behind a search field: a slash shortcut focuses it, typing keeps the posts whose title or summary holds the words and marks them, and six cells draw tiny tool windows as covers.

  • Pro

    A link roll in three ruled columns, Books, Tools and Papers: a monogram tile, an external link, the source domain in mono, one line on why, and a Copy button for the link.

  • Pro

    Copy Link Changelog

    Votes and sharing

    Three docs-host releases, each its own cell with an anchor and a Copy link button that puts that release's permalink on the clipboard and says so, with a :target ring on the one the address points at.