Icon

@sushindustries/ui

The glyph set, generated from a Markdown table where every drawing carries its reason. One component, typed names, no icon font.

2 min read
View as Markdown

Every glyph on this site comes through this one component: a typed name, an optional size, and an inline SVG that inherits the text color around it. There is no icon font to load and no sprite sheet to configure - the whole set compiles into the component.

Viewport width
Desktop100%whatever the page has
tanstacktanstack add https://adamjurek.com/r/tanstack/icon.jsonshadcnpnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/icon.json

Why it is built this way

The set is written in Markdown and generated into code. Each drawing in glyphs.md sits next to the reason it exists, because a glyph without a reason is how icon sets grow to four hundred entries nobody can name. The generator turns that table into icon.tsx, and the type of name is the table - a typo is a compile error, not an empty box.

It inherits, never decides. currentColor and the surrounding text size are the defaults, so an icon dropped into a label, a button or a heading looks like it was drawn there. size exists for the places that measure in pixels on purpose.

What it does not do

It does not take arbitrary SVGs - a glyph joins the set by joining the table, with a reason, through the generator. And it does not ship per-icon files: the set is one component because twenty-glyph icon systems do not need a bundler strategy.

Install

tanstack add https://adamjurek.com/r/tanstack/icon.json
shell
pnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/icon.json
shell
pnpm add @sushindustries/ui @sushindustries/atoms
shell

What you get

Version0.1.0
Categorycontent · Primitives
Filesicon.tsx
DependenciesNone
Tagsicons, svg, generated, no-deps

No runtime dependencies

It brings nothing with it beyond the stylesheet.

Used byAccordionAccordiondetails, stacked - every behaviour ships in the element, and items open independently on purpose.@sushindustries/ui · layoutArchiveArchiveA filterable grid with categories, subcategories and tags. Renders its own links through a callback so the router stays yours.@sushindustries/ui · layoutCardCardTitle, optional meta, arbitrary body. Heading level is a prop so the outline stays correct.@sushindustries/ui · layoutCollapsibleCollapsibleOne details, dressed - a sentence that opens, for prose rather than lists.@sushindustries/ui · layoutContext MenuContext MenuOne menu, reachable by right-click, by long press, and by a button. Escape and arrow keys included.@sushindustries/ui · layoutDesk WindowDesk WindowA window you can drag, close and stack. Position is written to the element during a drag and to state only on release.@sushindustries/ui · layoutDialogDialogA native dialog driven by props: top layer, focus trap and Escape from the element, click-outside from here.@sushindustries/ui · layoutDockDockA launcher, what is open, and a corner. Search opens upward and results are the consumer's to compute.@sushindustries/ui · layoutFolder ShelfFolder ShelfA desktop of folders that open into draggable windows, several at once, remembered between visits.@sushindustries/ui · layoutItemItemOne row of a list: tile, title, description, meta - the nav panel's anatomy, extracted for reuse.@sushindustries/ui · layoutNav BarNav BarA site header whose panels expand. Built on <details>, so it works before hydration and closes on Escape.@sushindustries/ui · layoutSheetSheetThe dialog docked to an edge, for content tall enough that centring it would mean scrolling a floating box.@sushindustries/ui · layoutTheme ToggleTheme ToggleA segmented control that reports which option was pressed and knows nothing about themes. Roving focus, and `aria-checked` is the selector that draws it.@sushindustries/ui · layoutCode BlockCode BlockA highlighted code slab with the CLI's colours, a lit top edge, and a copy button that confirms in place.@sushindustries/ui · contentCopy ButtonCopy ButtonA glass chip that writes to the clipboard and confirms in the button itself, then hands back.@sushindustries/ui · contentEmptyEmptyNothing, said properly: what is missing, why that is fine, and what to do next - in that order, quietly.@sushindustries/ui · contentNative SelectNative SelectThe platform's own select in the site's clothes - the phone wheel and the OS menu, kept.@sushindustries/ui · contentTypographyTypographyThe type scale as components: Heading with outline and size separated, the Label eyebrow, the Lead. One decision, made once.@sushindustries/ui · contentVideo PlayerVideo PlayerA video held behind a picture of itself. The player is a child, so it mounts on play and unmounts on stop - no vendor, no bytes and no cookies until somebody asks.@sushindustries/ui · contentBreadcrumbBreadcrumbThe trail, told twice from one list: a visible nav with correct ARIA, and the schema.org BreadcrumbList rendered from the same array.@sushindustries/ui · docsCommand PaletteCommand PaletteSearch over everything the host can name, in a native dialog: substring filter, arrow keys, and the host keeps the router.@sushindustries/ui · docsDoc NavDoc NavThe left rail of a documentation page: the sections of a library, the elements in each, and the one that is open. A sticky column on a wide screen, a collapsed row below it.@sushindustries/ui · docsHeroHeroThe head of a documentation page: trail, element name, version, measured facts, actions and a responsive shot. Folds to one column by the room it has, not by the size of the window.@sushindustries/ui · docsPaginationPaginationPages as links with first and last always reachable. The window everyone already knows, and nothing that breaks middle-click.@sushindustries/ui · docsShowcaseShowcaseA component in a real iframe at every width it has to survive, side by side, with its source and install commands.@sushindustries/ui · docs
Mentioned inDoc NavBlog Layout