II Type

Star on GitHubFeedback
II TypeNative HTML and a hookot-sign

Sign

An icon made of its own word with Pretext: ruled in middle-dot leaders, laid along its strokes, or filling its silhouette row by row. Pointed at, it says itself.

Report an issue with Sign

Example

···································search
Dots
search·····························································
Words
searchsearchsearchsearchsearchsearchsearchsearchsearchsearchsearchsea
Fill
Dots···················search
Dots, said···················search
Wordssearch·····································
Words, saidsearch·····································
Fillsearchsearchsearchsearchsearchsearchsearchsearchsearchsearchsearchsea
Fill, saidsearchsearchsearchsearchsearchsearchsearchsearchsearchsearchsearchsea
Italicmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailma
Italic, saidmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailmailma
At 24·············close
At 24, said·············close

Signs

Each sign is its own item in each variant: install only the ones you use, and each brings this primitive along. Point at one to hear it; press it for its install line.

Variant
Size
Face

246 signs, each in three variants

npx shadcn@latest add https://thedirectors.agency/ui/r/sign-search-words.json
  • reject file-x
  • find file-search
  • folder folder
  • open folder-open
  • create folder-plus
  • files files
  • attach paperclip
  • clip clipboard
  • play play
  • pause pause
  • stop stop
  • repeat repeat
  • shuffle shuffle
  • loud volume
  • soft volume-low
  • music music
  • speak mic
  • photo camera
  • video video
  • image image
  • film film
  • listen headphones
  • show tv
  • disc disc
  • sound speaker
  • cast cast
  • skip skip-forward
  • replay skip-back
  • inbox inbox
  • comment message-square
  • chat message-circle
  • call phone
  • notify bell
  • snooze bell-off
  • ring bell-ring
  • mention at-sign
  • feed rss
  • alert circle-alert
  • warning triangle-alert
  • danger octagon-alert
  • info info
  • help circle-help
  • protect shield
  • safe shield-check
  • flash zap
  • fire flame
  • pulse activity
  • success circle-check
  • error circle-x
  • block ban
  • flag flag
  • support life-buoy
  • edit pencil
  • cut scissors
  • type type
  • bold bold
  • underline underline
  • left align-left
  • centre align-center
  • right align-right
  • justify align-justify
  • list list
  • code code
  • erase eraser
  • person user
  • team users
  • happy smile
  • sad frown
  • okay meh
  • award award
  • trophy trophy
  • crown crown
  • medal medal
  • contact contact
  • time clock
  • date calendar
  • event calendar-plus
  • booked calendar-check
  • cancel calendar-x
  • timer timer
  • reset timer-reset
  • wait hourglass
  • history history
  • alarm alarm-clock
  • watch watch
  • cart shopping-cart
  • bag shopping-bag
  • basket shopping-basket
  • card credit-card
  • euro euro
  • wallet wallet
  • tag tag
  • gift gift
  • coins coins
  • sale percent
  • sum calculator
  • cash banknote
  • shop store
  • desktop monitor
  • laptop laptop
  • mobile smartphone
  • tablet tablet
  • drive hard-drive
  • server server
  • chip cpu
  • data database
  • print printer
  • keys keyboard
  • mouse mouse
  • wifi wifi
  • battery battery
  • low battery-low
  • tune sliders
  • repair wrench
  • build hammer
  • key key
  • package package
  • box box
  • layers layers
  • grid grid
  • tiles layout-grid
  • columns columns
  • table table
  • board kanban
  • chart chart
  • pie chart-pie
  • rise trending-up
  • fall trending-down
  • book book
  • read book-open
  • library library
  • news newspaper
  • notes notebook
  • note sticky-note
  • work briefcase
  • coffee coffee
  • wine wine
  • beer beer
  • pizza pizza
  • apple apple
  • idea lightbulb
  • write feather
  • magnet magnet
  • target target
  • aim crosshair
  • world globe
  • map map
  • ticket ticket
  • shirt shirt
  • sleep bed
  • bath bath
  • paint brush
  • crop crop
  • frame frame
  • lens aperture
  • day sun
  • night moon
  • cloud cloud
  • rain cloud-rain
  • storm cloud-lightning
  • fog cloud-fog
  • wind wind
  • drop droplet
  • sea waves
  • leaf leaf
  • pine tree-pine
  • flower flower
  • grow sprout
  • peak mountain
  • camp tent
  • car car
  • bus bus
  • fly plane
  • train train
  • ship ship
  • fuel fuel
  • office building
  • bank landmark
  • castle castle
  • door door-open
  • lamp lamp
  • sofa sofa
  • dog dog
  • cat cat
  • bird bird
  • fish fish
  • bug bug
  • dice dice
  • drum drum
  • piano piano
  • always infinity
  • walk footprints
  • bot bot
  • ghost ghost
  • dose pill
  • health heart-pulse
  • baby baby
  • gem gem

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/sign.json

Usage

This example also uses Button.

npx shadcn@latest add https://thedirectors.agency/ui/r/button.json
sign-example.tsx
import { Button } from "@/components/ui/button"import { SignSearchDots } from "@/components/ui/sign-search-dots"import { SignSearchWords } from "@/components/ui/sign-search-words"import { SignSearchFill } from "@/components/ui/sign-search-fill"import { SignHomeDots } from "@/components/ui/sign-home-dots"import { SignMailDots } from "@/components/ui/sign-mail-dots"import { SignArrowRightDots } from "@/components/ui/sign-arrow-right-dots"import { SignMailFill } from "@/components/ui/sign-mail-fill"import { SignCloseDots } from "@/components/ui/sign-close-dots"export default function Example() {return (<div className="grid justify-items-center gap-16"><div className="grid grid-cols-[minmax(0,1fr)] justify-items-center gap-x-20 gap-y-14 sm:grid-cols-3"><figure className="grid justify-items-center gap-6"><SignSearchDots size={168} /><figcaption className="ot-label">Dots</figcaption></figure><figure className="grid justify-items-center gap-6"><SignSearchWords size={168} /><figcaption className="ot-label">Words</figcaption></figure><figure className="grid justify-items-center gap-6"><SignSearchFill size={168} /><figcaption className="ot-label">Fill</figcaption></figure></div><div className="flex flex-wrap justify-center gap-x-8 gap-y-4"><Button variant="quiet" className="gap-2.5"><SignHomeDots label="" />Home</Button><Button variant="quiet" className="gap-2.5"><SignMailDots face="italic" label="" />Your mail</Button><Button variant="quiet" className="gap-2.5">Next<SignArrowRightDots label="" /></Button></div></div>)}

Contract

  • Underneath: hook. Pretext measures the word, kerning included, and the sign is laid out from those widths.
  • Anatomy: <span class="ot-sign" data-variant="dots | words | fill" role="img" aria-label="word"><span class="ot-sign-glyph">…</span>…</span>: one element per letter or leader, placed by --x, --y, --r and --k, since each one travels on its own when the word is said. An empty label hides it (aria-hidden="true"), for a control that already says the word.
  • An icon made of its own word, after the ampersand (the word "et" worn down into a mark) and Apollinaire's calligrams. Each sign is published three times, one registry item per variant (sign-<name>-dots, -words, -fill), all built on this primitive. The drawings come from Lucide (ISC) converted to strokes a word can read along, or are drawn for 0nlyType; a sign that can't be read in all three variants is left out rather than shipped.
  • Variants:
    • dots: each stroke ruled in middle-dot leaders, at every size; the leaders grow more slowly than the sign, so a large one is drawn finer. The letters wait unseen at the dots and rise out of them when said.
    • words: from 40px up the word is set once, whole, where it reads best: along the drawing's longest straight run (an arrow's word runs toward its head; a ring's word sits on its arc), never upside down (and a word of two letters never turned past 30°, since on end "up" reads "dn"), never kinking more than 20° between letters, tracked no wider than 0.08em and never split across strokes. Every other stroke is ruled in pencil leaders, so the drawing stays quiet and the word is the one thing in ink. Where no stroke holds the word at a size a person reads (a chevron's two short arms, a star, a user), the drawing is drawn a little smaller and the word stands straight beneath it, as a legend under a picture. Stroke words are at least 10px, legends at least 9px. Below 40px no letter can hold a stroke: the sign is drawn as dots, and the docs size control says so.
    • fill: the word set in rows that fill the drawing's silhouette, running on from one row to the next as a paragraph runs round a picture; each run is spread to its ends so the edge of the type is the outline. A drawing's inner strokes (an eye, a keyhole, a clock's hands) are cut out of the silhouette as lines of paper, so the detail still reads.
  • Laid out on the server from a table of advances, so the first paint already shows the sign; Pretext then sets it again with the face's real kerning. The smaller the sign, the heavier its letters (800 at 16px to 500 at 128px), as a punchcutter cuts optical sizes.
  • Yours: face="italic" (data-face="italic") sets it in the expression: a sign for something that belongs to the person (their mail, their home).
  • Said: pointing at the sign, or at the control it sits in, or focusing that control makes the drawing say its word. The letters leave the drawing in reading order, one arpeggio apart, and stand up as the plain word across the middle, no wider than half again the sign (a caption's 11px floor aside); the rest sketch out in pencil and go quiet. Leaving winds them back, last letter first.
  • Right to left: a sign that points the way the reader goes (mirror in its shape: arrows, chevrons, send, undo) turns round, its strokes still read forwards.
  • States: rest, hover, focus. Reduced motion: the word and the drawing change places without travel. Forced colours use CanvasText.

Props

Props of Sign
PropTypeDefaultWhat it does
shapeSignShapeThe drawing and its word. Each sign item passes its own; you only pass one to make a sign of your own.
variant"dots" | "words" | "fill""words"dots rules the strokes in middle-dot leaders at every size. words sets the word once in ink, on its best stroke or as a legend beneath the drawing, with the other strokes in pencil leaders, from 40px up; below 40px it draws the dots, where letters would not read. fill sets the word in rows across the drawing's silhouette, as the calligram does. Each sign item fixes its own.
sizenumber | string24The side of the square, in pixels or as a CSS length.
face"roman" | "italic""roman"roman for what the interface offers; italic for what belongs to the person: their mail, their home.
labelstringWhat a reader hears. Defaults to the word. Pass an empty string when the sign sits beside text that already says it.

Craft

Where its move comes from

Where its move comes from
ComponentReferenceMove
SignThe ampersand ("et" worn down into a mark); Apollinaire, Calligrammes, 1918An icon made of its own word; pointing says the word

How it moves

How it moves
ComponentArticulationWhat moves
SignSaidThe letters leave the drawing in reading order, one arpeggio apart, and stand up as the plain word; echoes sketch out in pencil