The Component Showcase

This article renders every content component the blog offers, so each one can be seen live and its pattern copied. It is not documentation — it is a visual index.

Typography

Body copy is a paragraph. It carries strong emphasis for the load-bearing words, italic emphasis for a lighter touch, and inline code for identifiers, file names and anything typed verbatim.

Heading level two

Heading level three

Heading level four

Headings nest from level two (##) downward; level one is reserved for the article title.

Anchor

Badge

InfoSuccessWarningDanger

Blockquote

Almost before we knew it, we had left the ground.

Support callout

Support this work

Enjoying my writing and feeling like supporting my work? You can show your appreciation by buying me a coffee (I really really really do like coffee), which gives me the energy to take on more ambitious articles and projects.

As a token of gratitude, your name will be featured on the little screen below. Thank you for reading!

Callouts

Details/Summary

Lists

  • First item
  • Second item
  • Third item
  1. First step
  2. Second step
  3. Third step
  • Parent item
    1. Nested first
    2. Nested second
  • Another parent
    • Nested arrow one
    • Nested arrow two

Card

A card title

Cards group related content on a raised surface. The body accepts any markdown, inline code, links and more.

Without a title, the card is body-only and has no separator.

Buttons

Variants
With an icon
Sizes
Icon only, square
Icon only, round
Disabled

Form components

Toggles

Slider

Slider250.00
Opacity65%
Stepped4
Disabled125

Select

Code Block

A fenced block with a title bar (copy button included) and highlighted lines:

greet.ts
console.log('hello world');
 
/**
 * Some comments
 */
function sayHi(name) {
  const message = `hi ${name}`;
  return message;
}

A changed line ends in // [!code ++] or // [!code --], and copying takes only the new code:

greet.ts1 added, 1 removed
function greet(name: string) {
  return 'Hello ' + name + '!'; 
  return `Hello ${name}!`; 
}

variant="info", "warning" and "danger" are for logs and output, titled after their level unless given a title:

Info
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
Warning
Warning: Each child in a list should have a unique "key" prop.
    Check the render method of `PostList`.
Error: TypeError
TypeError: Cannot read properties of undefined (reading 'map')
    at MessageList (components/message-list.tsx:18:22)
    at renderWithHooks (react-dom.development.js:16305:18)

A block longer than 24 lines folds to its first 16:

easing.ts
type Easing = (t: number) => number;
 
export const linear: Easing = (t) => t;
 
export const easeInQuad: Easing = (t) => t * t;
 
export const easeOutQuad: Easing = (t) => t * (2 - t);
 
export const easeInOutQuad: Easing = (t) =>
  t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
 
export const easeInCubic: Easing = (t) => t ** 3;
 
export const easeOutCubic: Easing = (t) => 1 - (1 - t) ** 3;
 
export const easeInOutCubic: Easing = (t) =>
  t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2;
 
export const easeOutBack: Easing = (t) => {
  const c1 = 1.70158;
  const c3 = c1 + 1;
  return 1 + c3 * (t - 1) ** 3 + c1 * (t - 1) ** 2;
};
 
export const easeOutElastic: Easing = (t) => {
  if (t === 0 || t === 1) return t;
  const c4 = (2 * Math.PI) / 3;
  return 2 ** (-10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
};
 
// Runs an easing over a duration, calling back with each eased value.
export function animate(duration: number, ease: Easing, onFrame: (value: number) => void) {
  const start = performance.now();
  const tick = (now: number) => {
    const t = Math.min((now - start) / duration, 1);
    onFrame(ease(t));
    if (t < 1) requestAnimationFrame(tick);
  };
  requestAnimationFrame(tick);
}

Sandpack Code Block

Loading live editor…

Math Equations

Inline math flows in a sentence — Euler's identity — while a display equation centres on its own line and scrolls if it runs wide:

Images

Monet's Meadow with Poplars

Before / After Image

This blog in its dark theme beside its light one.

Slideshow

Use the Left and Right arrow keys to change images, and Enter to enlarge one.

The crescent moon over the curve of the Earth, its atmosphere a thin blue line.
Cumulus clouds piled under a clear blue sky.
A painting of a ship in a storm, its sails torn under breaking waves.
Three images, one frame.

Autoplay

Use the Left and Right arrow keys to change images, and Enter to enlarge one, and Space to pause or play.

The same three, playing on their own.

Video

Tweet

A post on X, fetched at build and drawn in the site's own markup.

Adam Fuhrer@adamfuhrer

mona #plottertwitter

Charts

A figure that carries axes.

Frame time (ms)
Texture size (px)
An area reads as a quantity over a progression, and fills with a gradient by default.

Geometric diagrams

SVG, drawn from maths a test can read.

OCHp1p2g1g2PlanetAtmosphere
Ray angle9.0°
p1 and p2 are where the ray crosses the atmosphere, g1 and g2 the ground, and the bold stretch is the air it travels through. H is the point nearest the centre.

Leaders, for names that cannot sit beside their subject.

1st pass2nd passB(t)P0P1P2P3
t0.42
Each pass slides a point the fraction t along every segment of the one before, until one point is left, on the curve.

A loupe.

28%
Edge angle25.0°
A pixel is filled by the share of it the shape covers, hatched under the loupe.

A surface, in three dimensions.

xyz625 vertices
Frequency1.50
Turn0°
A flat grid, each point lifted by a wave of its distance from the centre.

Driven by time.

P0P1t = 0.73
Linear interpolation: the point sits the fraction t of the way from P0 to P1.

Rendered surfaces

A fragment shader, driven by its uniforms and by time.

Uniforms

Frequency1.50
Light135°
The same ripple, lit per pixel: each pixel finds where its ray meets the surface and shades it by the light, or by its normal.

Over an image.

Uniforms

Radius0.40
Cells32
A halftone: the image sampled once per cell and drawn as a dot, sized by the radius or by the cell's brightness.

Over a video.

Uniforms

Pixel size16px
Radius0.25
The halftone over a video: each cell takes one colour, and its dot grows as the cell darkens.

Tables

GFM pipes, mapped onto the shadcn primitive.

ApproachShips to the browserAuthoring
GFM pipesnothing, the plugin runs at builda row per line
<Table> composed by handnothing, still a Server ComponentJSX, for what pipes cannot say
TanStack Table31 kB, and 'use client'a column definition per table

Alignment comes from the delimiter row.

LeftCentreRight
--primary262.041.0
--border17 presets0.5

Past the measure, a table scrolls inside its own edge.

PresetHueLightnessLightDarkFloorTailwind
Blue259.8default4.067.213.79blue-500
Violet292.7+0.023.916.883.79violet-500
Teal182.5+0.053.846.443.79teal-500

Dividers


Footnotes

A reference marks a spot 1, and the list below resolves it.

  1. Footnotes are resolved by the FootnotesList component, which renders this list and links each entry back to its reference.

Liked this article? Share it with a friend on Bluesky or Twitter or support me to take on more ambitious projects to write about. Have a question, feedback or simply wish to contact me privately? Shoot me a DM and I'll do my best to get back to you.


Have a wonderful day

— Lény