Skip to content

Components / Sections

Material Index

What the work is made of, as a short index: each material a row with its name, where it comes from and a small swatch, and beside the rows a large card for the one picked, with the swatch drawn big (a weave, a speckle, a grain, a crumb or a ripple, in the colours of its block), a note and what it goes into. The rows are radio buttons, so a click, a tap or the arrow keys pick one; pointing at a row shows its card while the pointer rests there. Zero JavaScript.

Live demo

Materials

What the pieces are made of

Three clays and the glazes we mix from them. Pick one to see it up close.

Materials

Speckled stoneware

A grey clay with dark iron spots that come through the glaze as it fires.

Goes into Cups, bowls, plates

Porcelain

White, smooth and hard to throw thin. It lets a little light through at the rim.

Goes into Espresso cups

Red earthenware

A soft, warm clay that fires at a lower heat and is glazed inside to hold water.

Goes into The low vase

Ash glaze

Wood ash, sieved and mixed with feldspar; it runs in the kiln and pools green.

Goes into Vases, jugs

Live, from the library itself, at full size: scroll, hover, navigate away and back. The demo is never gated.

Variants · each row writes the attribute the prop writes; the section's own CSS answers

tone
density

Measured

JavaScript of its own

0 B

CSS 15.4 kB raw including the base tokens. Measured from a production build, and again in CI for every change that can move it.

Browser support

Baseline · newly available

Chrome 105 · Firefox 121 · Safari 15.4; needs has. Elsewhere: the first material's card stays shown and the rows still read as a list.

Install Pro

The demo above is never gated; the source is. With a key in components.json (see account), the registry serves it like any other item:

terminal
npx shadcn@latest add @moonarc-pro/material-index
src/pages/index.astro
---
import MaterialIndex from '@/components/moonarc/pro/MaterialIndex.astro';
---
<MaterialIndex
  eyebrow="Materials"
  copy="Three clays and the glazes we mix from them."
  materials={[
    { name: 'Speckled stoneware', origin: 'Clay', note: 'A grey clay with iron spots that come through the glaze.', used: 'Cups, bowls', swatch: 'speckle', block: 3 },
    { name: 'Porcelain', origin: 'Clay', note: 'White, smooth and hard to throw thin.', used: 'Espresso cups', swatch: 'solid', block: 4 },
    { name: 'Ash glaze', origin: 'Glaze', note: 'Wood ash and feldspar; it runs in the kiln.', used: 'Vases', swatch: 'ripple', block: 2 },
  ]}
>
  <span slot="headline">What the pieces are <em>made of</em></span>
</MaterialIndex>

Without a key the registry answers 401 with an upgrade message.

Props

PropTypeDefaultDescription
materials{ name, origin?, note, used?, swatch?, block? }[]noneTwo to eight materials. swatch: weave, speckle, grain, crumb, ripple or solid (in turn when unset); block the colours it is drawn in.
eyebrowstringnoneA short line above the heading.
headlinestringnoneThe heading. Slot "headline" wins and may hold an <em>, set in the emphasis face and colour.
copystringnoneA line under the heading.
labelstring'Materials'Accessible name of the rows (the fieldset's legend).
usedLabelstring'Goes into'The words before what a material goes into.
level2 | 32Heading level of the section's heading; each card's title is one below.
tone'surface' | 'muted' | 'ink' | 'brand'unset (paints nothing)The section's ground; the swatches keep their blocks on every tone.
density'compact' | 'cozy' | 'roomy''cozy'Block padding ×0.8 / ×1 / ×1.25 through --ma-density.

Theming and overrides

The section reads the theme contract (shadcn's variable names with the base tokens as fallback), so a pasted theme or one --ma-brand recolours it. Its class names are the override surface and stay stable; a named slot replaces the matching prop with your own markup.

Classes

.ma-materials.ma-materials__body.ma-materials__card.ma-materials__cards.ma-materials__chip.ma-materials__copy.ma-materials__eyebrow.ma-materials__head.ma-materials__headline.ma-materials__list.ma-materials__name.ma-materials__note.ma-materials__origin.ma-materials__row.ma-materials__swatch.ma-materials__text.ma-materials__title.ma-materials__used

Slots

slot="eyebrow"slot="headline"

Reduced motion

A picked card shows at once, without its short rise.

With ClientRouter

CSS only; nothing to rebind.

Why it is built this way

Replaces: Ingredient tabs (Shopify themes) · Material swatch galleries. See the migration table.

Product Art

Backgrounds

A product drawn flat, for a shop slot that has no photograph yet: 29 drawings in six sets (clothes, ceramics, coffee, skincare, furniture and objects, bakery).

every browserhover

Questions people actually ask

Short answers. The long ones are in the docs.

Is it really zero JS?

For 83 of 125, yes, measured from a build.

Does it survive View Transitions?

Yes, verified on Astro 5, 6 and 7.

Do I need Tailwind?

No.

FAQ

Pro

A heading and lead beside a native accordion: one question open at a time, heights animated by the browser, keyboard and screen reader handled by <details>.

newly · Chrome 131 · Firefox 143 · Safari 18.4scrollclick

Shows features in alternating rows of copy and a visual.

Chrome 115 · not Firefox · Safari 26scroll

How a thing is made, as steps sewn on one thread: a stitched line runs down the section and each step is a knot on it (a round number in a colour block, stitched round its edge) with a title, a line and how long it takes.

Chrome 115 · not Firefox · Safari 26scroll

Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown