Code Block
components specs/components/code-block.kmd
Code-block widget — the multi-framework code-tabs surface that hosts per-format code samples behind a shared tab strip (HTML / Flutter / Compose / SwiftUI / Web Components), with a per-tab copy button and a transient "Copied" toast. The framework choice persists across the session so picking "Flutter" once shows Flutter in every code block.
Quando esta spec se aplica
Triggers primários
- Embed a multi-framework code sample in KDS
Todos os triggers
- Render a code sample on a Koder docs/design surface
- Show the same widget across multiple frameworks
- Add a copy-to-clipboard affordance to a code block
Corpo da especificação
Spec — Code Block
Facet Visual do Koder Design. The KDS realization of material.io's multi-framework code panels — the highest-value "designer crosses to developer" surface. Implemented in design-gen (
internal/kindsCodeTabs+assets/jstab switcher; shipped in tools/design-gen#044, copy button #028).
Anatomy
┌───────────────────────────────────────────────┐
│ [HTML] Flutter Compose SwiftUI Web [Copy] │ ← tab strip + copy
├───────────────────────────────────────────────┤
│ <button class="kd-btn filled">Save</button> │
│ …only the selected framework's panel shows… │ ← <pre><code>
└───────────────────────────────────────────────┘
- Tab strip: one tab per framework supplied; the active tab is
marked
aria-selected="true". Frameworks with no sample for a given block are omitted (no empty tabs). - Panels: one
<pre><code>per framework; only the selected one is visible (othershidden). Mono type role (--kds-font-mono). - Copy button: top-right; copies the visible panel's text.
R1 — Single logical widget, N syntaxes
A code-block tags N samples that express the same widget in different frameworks. Switching tabs swaps syntax only — never the widget being demonstrated. A block MAY carry a single framework (then the tab strip collapses to a label, not a control).
R2 — Shared, persisted framework selection
All code-blocks on a page (and across the session) share one framework
choice, persisted in localStorage["kds.framework"]. Picking a
framework in any block updates every other block on the page
immediately and restores on the next visit. Default when unset: the
first framework declared on the block (HTML where present).
R3 — Syntax-agnostic rendering
Panels render pre-escaped, server-highlighted code. No client-side
syntax-highlight dependency on the render path
(policies/headless-first.kmd — the headless build emits the same
HTML the user sees). Long lines scroll horizontally within the panel;
they do not wrap or expand the page.
R4 — Copy affordance + transient confirmation
Each block exposes a copy button that writes the visible panel's raw
text to the clipboard and shows a transient "Copied" toast for
~1.5 s, then reverts. The button keeps its label/icon between states
(no layout shift). On clipboard failure the toast reads the canonical
error per specs/errors/user-facing-messages.kmd — never a silent
no-op. Reuses the SDK copy primitive (policies/reuse-first.kmd).
R5 — Accessibility
- Tab strip is a
role="tablist"; tabs arerole="tab"witharia-controlspointing at their panel; panels arerole="tabpanel". - Arrow keys move between tabs; Enter/Space activates; the copy button
is reachable by Tab and announces its state change via
aria-live. - Color contrast of tab/active states meets the
themes/color-roles.kmdAA floor in both light and dark.
R6 — Degradation (no JS)
With JavaScript disabled, every framework panel is visible (stacked, each under its framework label) and the copy button is hidden — the content is never gated behind the switcher.
Out of scope
- Editable / runnable code (playground) — see the component prop playground surface, not this block.
- Diff rendering — a separate future surface.
Referências
specs/components/buttons.kmdspecs/interaction/states.kmdspecs/themes/color-roles.kmdspecs/fonts/typography.kmd