Exclusivobeta

Code Block <mv-code-block>

Envolve qualquer <pre><code> simples ou já destacado com nome de arquivo, rótulo da linguagem, botão de copiar, números de linha, linhas destacadas e de diff, dobra e um alternador de quebra de linha, e copia o que o leitor realmente precisa: prompts do shell, saída dos comandos e marcadores de diff ficam de fora, e números de linha ou marcadores também nunca podem ser selecionados à mão.

CategoriaExibição de dados
TipoWeb Component (<mv-code-block>)
Statusbeta
Também instalacopy-button
Keywordsexclusive, light, code, snippet, pre, copy, clipboard, syntax, line-numbers, diff, docs, terminal

When to use

  • Docs, a blog post or a changelog show code snippets that readers copy into their editor or terminal
  • Install steps mix shell prompts and output, and only the commands should land in the clipboard
  • A snippet must point at specific lines or show what changed between two versions
  • A long file excerpt should fold to its first lines with a way to show the rest

Avoid when

  • Only a single value, key or command needs a copy button, without a code frame → use Copy Button instead
  • The code must be editable or runnable in the page; this block only displays it
  • A short inline keyboard shortcut or key name sits inside a sentence → use Kbd instead

Instalação

node scripts/add.mjs code-block --out ./src/marvelous

Agente de IA com o servidor MCP do Marvelous UI: install_components({ slugs: ["code-block"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Arquivos copiados (dependências incluídas): tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/motion.js, core/observe.js, components/code-block/code-block.js, components/code-block/code-block.css, components/copy-button/copy-button.js, components/copy-button/copy-button.css.

Uso

Início rápido, a menor marcação que funciona:

<mv-code-block filename="install.sh"><pre><code class="language-bash">$ npm install @acme/ui</code></pre></mv-code-block>

Marcação de referência, para usar como ponto de partida e personalizar com atributos, data-* e variáveis CSS:

<div id="mv-code-block-demo" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,340px),1fr));gap:1rem;width:100%;max-width:1040px;margin-inline:auto;align-items:start">
  <mv-code-block filename="src/lib/format-price.ts" line-numbers highlight="6-7" collapse="10">
<pre><code class="language-ts"><span class="tk-c">/**
 * Format a price in the shopper's own locale.
 * Amounts are stored in cents to avoid rounding drift.
 */</span>
<span class="tk-k">export function</span> <span class="tk-f">formatPrice</span>(cents: <span class="tk-k">number</span>, currency = <span class="tk-s">"USD"</span>, locale = <span class="tk-s">"en-US"</span>): <span class="tk-k">string</span> {
  <span class="tk-k">const</span> amount = cents / <span class="tk-n">100</span>;
  <span class="tk-k">return new</span> Intl.<span class="tk-f">NumberFormat</span>(locale, { style: <span class="tk-s">"currency"</span>, currency }).<span class="tk-f">format</span>(amount);
}

<span class="tk-k">export const</span> examples = [
  <span class="tk-f">formatPrice</span>(<span class="tk-n">129900</span>),                  <span class="tk-c">// "$1,299.00"</span>
  <span class="tk-f">formatPrice</span>(<span class="tk-n">4550</span>, <span class="tk-s">"EUR"</span>, <span class="tk-s">"de-DE"</span>),   <span class="tk-c">// "45,50 €"</span>
  <span class="tk-f">formatPrice</span>(<span class="tk-n">2400</span>, <span class="tk-s">"GBP"</span>, <span class="tk-s">"en-GB"</span>),   <span class="tk-c">// "£24.00"</span>
  <span class="tk-f">formatPrice</span>(<span class="tk-n">149900</span>, <span class="tk-s">"INR"</span>, <span class="tk-s">"hi-IN"</span>), <span class="tk-c">// "₹1,499.00"</span>
];
</code></pre>
  </mv-code-block>

  <div style="display:grid;gap:1rem">
    <mv-code-block>
<pre><code class="language-bash">$ npm install @acme/ui
added 42 packages in 3s
$ npx acme init --template dashboard \
    --currency USD
✔ Created acme.config.json</code></pre>
    </mv-code-block>

    <mv-code-block filename="checkout.js" language="diff-js">
<pre><code>const total = items.reduce((sum, item) =&gt; sum + item.price, 0);
-const label = "$" + total.toFixed(2);
+const label = new Intl.NumberFormat("en-US", {
+  style: "currency",
+  currency: "USD",
+}).format(total);</code></pre>
    </mv-code-block>

    <mv-code-block>
<pre><code>npm install @acme/ui</code></pre>
    </mv-code-block>
  </div>
</div>
<style>
  /* Stand-in for your own highlighter's theme: mv-code-block keeps its markup as is. */
  #mv-code-block-demo .tk-c { color: var(--mv-fg-subtle); font-style: italic; }
  #mv-code-block-demo .tk-k { color: var(--mv-accent); }
  #mv-code-block-demo .tk-f { color: var(--mv-info); }
  #mv-code-block-demo .tk-s { color: var(--mv-success); }
  #mv-code-block-demo .tk-n { color: var(--mv-warning); }
</style>

API

Attributes

NameTipoDefaultDescription
filenamestringFile name shown in the header (and used to name the copy button and the scroll region). Shown before upgrade too, with no layout shift.
languagestringLanguage label (e.g. ts, bash). Defaults to the language-* / lang-* class of the <code> or <pre>, as written by Markdown renderers and highlighters. Shell languages (bash, sh, zsh, console, powershell…) enable prompt handling; diff (a patch) or diff-<lang> (code with + / - line markers) enable diff lines. Not named lang on purpose: lang is the human-language attribute screen readers rely on.
highlightstringLines to highlight, e.g. "2,5-7" (numbers as displayed, so they follow line-numbers).
collapsenumberFolds the snippet to its first N lines with a "Show all N lines" button. Never folds when that would hide fewer than 3 lines.
copyauto | clean | raw | noneautoWhat the copy button copies. clean: drops shell prompts, command output (when prompts are present), removed diff lines and diff markers. raw: the exact source text. none: no copy button. auto: clean for shell languages and diff-<lang>, raw otherwise (a diff patch is copied as a patch).
line-numbersboolean | numberShows line numbers; a value sets the first number (e.g. line-numbers="42" for an excerpt).
data-wrapbooleanWrapped lines. Set by the wrap toggle; can be set initially. The toggle only appears when a line overflows (or while wrapped).
data-folded / data-numbers / data-bare / data-readybooleanSet by the component (for styling). data-bare: no file name and no language, so the copy button floats in the corner.

Properties

NameTipoDescription
textstringThe text the copy button copies (read-only).
wrapbooleanLine wrapping on or off.
expandedbooleanWhether a folded snippet is currently unfolded.
stringsobjectTranslatable texts: { copy: "Copy", copied: "Copied!", copyFailed: "Copy failed", wrap: "Wrap lines", showAll: "Show all {count} lines", showLess: "Show fewer lines", code: "Code" }. showAll may also be an object of plural forms ({ one, few, many, other }), picked with Intl.PluralRules; {count} is formatted with Intl.NumberFormat in the page's lang.

Methods

NameDescription
toggle(force?)Folds or unfolds the snippet (no argument: toggles).

Events

NameDescription
mv-toggleThe snippet was folded or unfolded; detail = { expanded }.
mv-copyBubbles from the inner copy button; detail = { text } (the cleaned text).
mv-copy-errorBubbles from the inner copy button when the clipboard refuses; detail = { error }.

Content structure

NameDescription
preA child <pre>, with or without a <code> inside, plain or highlighted by any highlighter (build time or runtime). Its markup is kept: tokens that span several lines are split per line, classes intact. If a highlighter rewrites the code later, the lines are rebuilt.

CSS classes

NameDescription
mv-code-block-bar / -title / -name / -lang / -actions / -wrap / -copyGenerated header parts.
mv-code-block-lineOne span per line; data-highlight, data-kind="add | del | meta | output" set as needed.
mv-code-block-markDiff marker or shell prompt: kept in the text, but aria-hidden and not selectable.
mv-code-block-fold / -fold-buttonFold footer and its button.

CSS variables

NameDefaultDescription
--mv-code-block-bgvar(--mv-bg-subtle)Block background.
--mv-code-block-bar-bgmix of --mv-bg-muted and the block backgroundHeader background.
--mv-code-block-highlightvar(--mv-accent)Highlighted line bar (tint at 11%).
--mv-code-block-addvar(--mv-success)Added lines.
--mv-code-block-delvar(--mv-danger)Removed lines.
--mv-code-block-paddingvar(--mv-space-4)Inline padding of lines and header.
--mv-code-block-radiusvar(--mv-radius-lg)Corner radius.
--mv-code-block-font-size0.8125remCode size.

Accessibility

Without JavaScript the block is a readable, styled <pre> (file name included). Line numbers are CSS generated content with an empty alternative (content: counter() / ""), so they are never selected, copied or read aloud. Prompts and diff markers stay in the text for highlighters but sit in aria-hidden, user-select: none spans; added and removed lines carry role="insertion" / "deletion" and highlighted lines role="mark", so the change is announced in the reader's own language, not by color alone (the + / - glyphs and an inline-start bar are also shown). The copy button is a real <button> described by the file name, and its result is announced once by a polite status. The wrap toggle is an aria-pressed button shown only when a line overflows; the scroller becomes focusable (a named group) only when it actually scrolls, so keyboard users can scroll it. The fold button has aria-expanded and aria-controls; folded lines use hidden="until-found", so find-in-page still reaches them and unfolds the snippet, and collapsing keeps the button in view. The language is never put in the lang attribute. Print shows every line, wrapped. Forced colors: system borders and Highlight bars. No motion beyond a chevron turn.

Esta página foi traduzida com IA. Informar um problema de tradução