II Type

Star on GitHubFeedback
II TypeNative HTML and a hookot-calligram

Calligram

A paragraph that fills a shape, as Apollinaire's calligrams did: each line is as wide as the shape is at that height, so the outline is only implied. Or it falls as rain, or runs round a frame about one word.

Report an issue with Calligram

Example

Everything is type. A heading is type, and so is a button, a rule, a sign on a door, and nothing in the interface is a picture of something else. A page like this has a pulse in it, a breath, a line turning three words along. Type is a place you can stand and read, and this is the shape it leaves when it is set down in words.

It is raining letters, a soft fall under everything, and a line breaks three words along, and nobody in the room looks up

Held in this frame the room goes quiet, the street and the voices and the hum fall away one by one, and what is left in the middle is the one thing you came here to dolisten

Circle

Everything is type. A heading is type, and so is a button, a rule, a sign on a door, and nothing in the interface is a picture of something else. A page like this has a pulse in it, a breath, a line turning three words along. Type is a place you can stand and read, and this is the shape it leaves when it is set down in words.

Fermata

Everything is type. A heading is type, a button is type, and nothing here is a picture of something else.

Wave

Everything is type. A heading is type, and so is a button, a rule, a sign on a door, and nothing in the interface is a picture of something else. A page like this has a pulse in it, a breath, a line turning three words along. Type is a place you can stand and read, and this is the shape it leaves when it is set down in words.

Rain

It is raining letters, a soft fall under everything, and a line breaks three words along, and nobody in the room looks up

Mirror

Held in this frame the room goes quiet, the street and the voices and the hum fall away one by one, and what is left in the middle is the one thing you came here to dolisten

Install

Run it in a project that has the shadcn CLI set up. It brings the 0nlyType base along.

npx shadcn@latest add https://thedirectors.agency/ui/r/calligram.json

Usage

calligram-example.tsx
import { Calligram } from "@/components/ui/calligram"const text ="Everything is type. A heading is type, and so is a button, a rule, a sign on a door, and nothing in the interface is a picture of something else. A page like this has a pulse in it, a breath, a line turning three words along. Type is a place you can stand and read, and this is the shape it leaves when it is set down in words."const short = "Everything is type. A heading is type, a button is type, and nothing here is a picture of something else."const rain = "It is raining letters, a soft fall under everything, and a line breaks three words along, and nobody in the room looks up"const frame = "Held in this frame the room goes quiet, the street and the voices and the hum fall away one by one, and what is left in the middle is the one thing you came here to do"export default function Example() {return (<div className="grid grid-cols-[minmax(0,1fr)] justify-items-center gap-16"><Calligram fade>{text}</Calligram><div className="grid w-full max-w-[44rem] grid-cols-[minmax(0,1fr)] items-start gap-12 sm:grid-cols-2"><Calligram variant="rain" fade size="20rem" className="mx-auto">{rain}</Calligram><Calligram variant="mirror" centre="listen" size="20rem" className="mx-auto">{frame}</Calligram></div></div>)}

Contract

  • Underneath: native, plus a hook that lays the lines out with pretext.
  • Anatomy: <p class="ot-calligram" data-shape | data-variant="rain | mirror"> holding the text for readers (.ot-sr), .ot-calligram-lines (aria-hidden, one block per line, each carrying --t, how far it is from the shape's widest part) and, for fermata, .ot-calligram-dot. Rain fills the lines with .ot-calligram-streaks of one span per letter (--j, its place down the streak); mirror with one .ot-calligram-side per side (--x, --a its turn), then .ot-calligram-centre, which is read.
  • fill (the default): the paragraph fills shape.
  • A paragraph that fills a shape, as Apollinaire's calligrams did. Each line is as wide as the shape's chord at its height and is centred in it, spread to both sides by its gaps and a little by its letters, so the outline is only implied: nothing is drawn. circle is the 0 of 0nlyType, fermata a half-disc of text over one accent dot, wave widths that swell and narrow like a sound wave (eleven rows a swell).
  • The circle and the half-disc are filled exactly: the size of the type is found (it never exceeds twice the inherited size) so the last word lands in the last row, and the box has its own aspect ratio, so nothing moves when the lines arrive. size is the shape's width (default 34rem, never wider than its space). The wave takes the inherited size and its height follows its rows.
  • rain: after Apollinaire's "Il pleut" (1916), where the words run down the page in slanting streaks. The words fall in streaks, a letter to a drop (0.8em apart, upright, centred on the streak), each letter a sixth of an em further over than the one above, so every streak leans the same way, as rain does in wind. A word is never split unless it's longer than a streak; a space is an empty drop. The streaks stand 2.2em apart, as long as they need to be for all of them to fit the width, and each starts a few drops late by a fixed hash, so the tops are ragged and the feet fall where they fall. Read left to right, each top to bottom; right to left the streaks run from the right and lean the other way. With data-fade each streak darkens as it falls, the drop at its foot in ink. Its height follows its streaks.
  • mirror: after his "Cœur couronne et miroir" (1918), where the words make a mirror frame around his name. The paragraph is the frame of a square: a line to each side, clockwise from the top, each turned to face out (the right side reads downward, the foot upside down, the left side upward), each spread to its side's length by its gaps; when a ring is full the next begins a line inside it, so a long text spirals in until the words run out. The last line stays unspread, so the frame closes on a pause. What is left in the middle holds centre in the expression italic, as large as that room allows (at most six times the inherited size), because it is yours; it is real text, read after the paragraph. Right to left the frame runs counter-clockwise from the top right. The square's box has its own aspect ratio, so nothing moves when it's laid.
  • data-fade lets the colour follow the shape, ink at the widest and pencil at the narrowest. It is a still ornament in every variant: pointing shows nothing. It lays out again when its width changes or <html> changes face (it watches the pair, scheme, mode and key attributes, not class, which smooth scrolling toggles on every scroll). Before that it is a plain paragraph. Forced colours: the text is system text and the fermata's dot is CanvasText.

Props

Props of Calligram
PropTypeDefaultWhat it does
childrenstringThe paragraph, as plain text: pretext measures it.
variant"fill" | "rain" | "mirror""fill"fill: the paragraph fills `shape`. rain: after Apollinaire's "Il pleut", the words fall in leaning streaks of letters, a letter to a drop, each streak starting a little late; its height follows its streaks. mirror: after his "Cœur couronne et miroir", the paragraph is the frame of a square, a line to each side, clockwise from the top and turned to face out, ringing inward until the words run out, with `centre` large in the italic in the middle.
shape"circle" | "fermata" | "wave""circle"For fill. The circle is the 0 of 0nlyType, the fermata is an arc over an accent dot, the wave swells and narrows like a sound wave.
centrestringFor mirror: the word in the middle, in the expression italic, as large as the room inside the frame allows. It is read after the paragraph.
sizestring"34rem"The shape's diameter as a CSS length. It never grows wider than the space it's in.
fadebooleanfalseLet the colour follow the shape: ink at its centre, pencil at its edge. In rain each streak darkens as it falls; in mirror the frame fades as it rings inward.

Craft

Where its move comes from

Where its move comes from
ComponentReferenceMove
CalligramApollinaire's calligramsThe paragraph fills the shape; the outline is only implied
Rain calligramApollinaire, "Il pleut" (1916)The words fall in leaning streaks of letters
Mirror calligramApollinaire, "Cœur couronne et miroir" (1918); "Healthy habits →" corner notesThe paragraph is the frame; one italic word in the middle