shadcn.io is not affiliated with official shadcn/ui
Brand Colour Picker Form Block for React
A brand colour field that makes a scale: a hex input and the colour picker kept in sync, eight named presets, and five derived steps by lightness, each with its hex and a copy button.
Installation
Overview
Turn one colour into a scale, with this colour picker form for React with Base UI. A compact header sits over a hairline frame with a plus mark on each corner, in two cells. At the start, a hex Input and the catalog Color Picker trigger kept in sync: type six digits, with or without the hash, or open the picker and drag, and the other follows. Below it, eight named presets (Ink, Brick, Marigold, Moss, Teal, Cobalt, Plum, Slate) are native radios, and an outline Badge names the preset you are on, or Custom. A field that is not six hex digits says "Use six hex digits." when you leave it. At the end, a side cell lists five steps of the scale made from the same hue by moving HSL lightness toward white and toward black (50, 300, your colour, 700, 900), each with its hex and a copy button. Save colour, the only Shine Button, says what it did. It's built from Input, Color Picker, Copy Button, Badge, Field and Guides. For brand kits, themes, labels and any field that picks a colour.
FAQ
The blocks use theme tokens only. Why are there colours here?
Because here the colours are the content, not decoration: a colour picker that cannot show the colour is useless. Only the swatches carry colour, inline as one CSS variable each (--swatch), marked with a code comment; the digits are held without the hash so no colour literal sits in the source, and everything else (the frame, the text, the focus rings) stays in theme tokens. In your app the swatches are the only place that reads the visitor's colour.
How is the scale made, and can I change it?
hslOf turns the hex into hue, saturation and lightness; scaleOf keeps the hue and saturation and moves lightness: step 50 goes 90 percent of the way to white, 300 goes halfway, 700 is 70 percent of the lightness and 900 is 40 percent, with your colour as 500. Edit those shares, or add steps to the list. It is a simple scale: HSL lightness is not perceptually even, so for a production palette generate it in a perceptual space (OKLCH) and check contrast for each step.
How do the field and the picker stay in sync?
One value, six hex digits, is the block's state. Typing six digits updates it and the picker's value; dragging in the picker sends its colour back as text, which is read into the same digits. Anything that is not yet six digits stays in the field only (the picker keeps the last good colour), and the problem is shown when you leave the field, then follows your typing until it is fixed. Pasting "#B4381E" works: the hash is dropped and the digits are lowercased.
Is it usable without a mouse?
Yes. The picker button, the hex field, the presets and each Copy button are real controls in the tab order. The presets are native radios: arrow keys move between them and the colour follows. The picker's area and hue slider take the arrow keys when focused, and copy buttons say once, in the foot's polite status, what was copied.
What stays local, and how do I connect it for real?
Save colour sets the saved colour in the page and says nothing was saved; the Copy buttons really use the clipboard, which needs a secure page and a user press (if the browser refuses, the foot says so). In your app save the six digits from submit, regenerate any asset that depends on the colour on the server, and keep the scale as a derived view.
How do I connect it to react-hook-form or TanStack Form?
Keep the six digits as the field's value. With react-hook-form, use Controller for the hex input and call field.onChange from the picker's value change too; validate with a regular expression in a resolver. With TanStack Form, validate on blur with the same pattern and derive the scale from field.state.value, never store it.
Related
- Pro
Text Input with Address Preview Form
Text fieldsA form panel with one required project-name field that shows the web address it will get as you type, flags a name that is taken or past 50 characters, and offers the next free address.
- Pro
URL Input with Paste Cleanup Form
Text fieldsA website field with a fixed https:// in front that cleans what you paste, then reads the address with the browser's URL parser into Host, Path and Secure cells.
- Pro
Logo File Input Form
Numbers and pickersA single-file field with rules read from the file itself: a square PNG or JPG, 1 MB or less, at least 256 by 256 pixels, shown as one row with its size, type and pixels, or refused with a named reason.
- Pro
A default project view picker with four radio tiles (list, board, calendar, timeline), each with a drawn thumbnail, and the chosen view redrawn large in a framed preview with what it is best for.
- Pro
Tone Filter Gallery
Filter, sort and tabsFive greyscale swatches (Paper to Ink) with counts, a Sort by contrast button and twelve framed pictures whose tone and contrast are read from their own drawings.
- Pro
Case Quantity Number Input Form
Numbers and pickersA quantity field that sells in cases of six: typing a number snaps it up to a whole case on leaving, the keys and buttons move one case or five, and the line total is worked out in whole cents.