Grain Gradient Nav
A floating header pill you can drag by its dot handle, that opens into a mega menu. Hovering the wordmark or a link opens a panel beneath the bar; running along the menu slides one strip sideways while its height retargets, so the whole thing reads as a single surface reshaping rather than as panels swapping. Scrolling collapses the links to zero width and shrinks the pill to the wordmark until you hover it again, and the contact panel is wider than the others, so opening it widens and re-centres the bar in the same motion. Ships the two-column link panels with arrow chips, the contact panel with a working enquiry form (text, email, option pills, textarea, drag-and-drop attachments, consent), and the Grain Gradient Field shader as the pill's surface.
npx shadcn@latest add https://ui.aryank.space/r/grain-gradient-nav.jsonInstalls from ui.aryank.space. To add it by hand, copy the files in Usage below, or register the @compronents namespace via the docs.
| Prop | Type | Default | Description |
|---|---|---|---|
| brand / menu / contactLabel | string / NavPanel[] / string | BLANK / 3 panels / Contact | The wordmark, the panels it opens, and the label of the always-last contact panel. |
| contactHeading / contactSections | string / NavContactSection[] | 3 sections | Left column of the contact panel: a heading and rule-separated groups of contact lines. |
| formHeading / formText / formFields / onSubmit | string / string / NavFormField[] / function | 6 fields | The enquiry form. onSubmit receives the collected values plus the names of any attached files. |
| panelWidth / expandedWidth | number | 420 / 996 | Minimum bar width (and so the width of every ordinary panel), and the width it animates to when contact opens. |
| draggable / collapseAfter / offsetTop | boolean / number / number | true / 3 / 42 | Whether the handle drags the bar, the scroll distance that collapses the links, and the bar's resting distance from the top. |
| surface / baseColor / shapeColor | boolean / string / string | true / #242422 / #5c5d55 | Whether to run the shader behind the bar at all, and its two colours. False gives a flat pill with every interaction intact. |
| children | ReactNode | undefined | Replaces the bar's interior. The mega panel is not rendered, so this is the surface-only mode. |
menutextPanels in order. The first is opened by the wordmark rather than by a link of its own; contact is always appended last.
baseColor / shapeColorcolorThe bar's ground and the colour of the crest sweeping through it. Keep them close in value or the crest reads as a highlight rather than as material.
panelWidth / expandedWidthtupleWidth of the bar and its ordinary panels, and the wider width it grows to for contact.
formFieldstextSix field types: text, email, textarea, option pills, drag-and-drop file, and consent.