SvColorInput

A color swatch that opens a portalled popover with a hex field, the native picker, and a preset palette.

SvColorInput shows the current color as a swatch with its hex value; clicking it opens an animated popover carrying a hex text field, the browser's native color picker, and a grid of preset swatches. The popover is portalled to <body> and anchored to the trigger, so it escapes the grid's scroll container and never clips. It emits a normalized hex string and is the styled renderer over the headless createColorInput core. Its label / hint / error chrome comes from SvField.

Related: SvTextInput · SvTagsInput · Inputs overview

Installation

Add it with the CLI - this drops a ready-to-edit SvColorInput starter into your app:

Prefer to see it first? npx @svgrid/ui try color-input opens it in a throwaway sandbox - no project needed.

Or install the package and import it directly. SvColorInput ships free in @svgrid/grid and is part of the grid's editor kit - the same control SvGrid mounts when you edit a matching cell:

The examples on this page import from @svgrid/grid:

<script lang="ts">
  import { SvColorInput } from '@svgrid/grid'

  // The bound value behind each example below.
  let accent = $state('')
</script>
import { SvColorInput } from '@svgrid/grid'

Example

Open the live example: Color input (Inputs)

<script lang="ts">
  import { SvColorInput } from '@svgrid/grid'
  let color = $state('#3b82f6')
</script>

<SvColorInput label="Brand color" bind:value={color} />

Props

SvColorInput extends the shared SvEditorProps (disabled, readonly, required, invalid, error, label, hint, size, dir, name, id, ariaLabel) and adds:

Prop Type Default Description
value string #3b82f6 The hex color. Bindable with bind:value.
onChange (hex: string) => void - Fires with the normalized hex on change.
palette string[] - Preset swatches shown in the popover.
autoOpen boolean false Focus the trigger and open on mount.
messages Partial<ColorMessages> - Override the built-in popover strings.
block boolean false Stretch to the container width (else hugs its content).

The box, size, invalid state and focus ring are owned by SvField's shared frame chrome.

ColorMessages is { dialog; picker; hex }.

Examples

Custom preset palette

Pass your brand's swatches as palette so the popover offers on-brand choices first:

<SvColorInput
  bind:value={accent}
  palette={['#0ea5e9', '#8b5cf6', '#f59e0b', '#10b981', '#ef4444']}
/>

Open immediately as a cell editor

Set autoOpen when mounting inside a grid cell so the popover appears the moment editing starts:

<SvColorInput bind:value={row.color} autoOpen />

Live-retheme the grid from a swatch

The component emits a normalized hex, so wire onChange straight into the grid's --sg-accent token for an instant theme preview:

<script lang="ts">
  import { SvColorInput } from '@svgrid/grid'
  let accent = $state('#2563eb')
  function apply(hex: string) {
    document.documentElement.style.setProperty('--sg-accent', hex)
  }
</script>

<SvColorInput
  label="Grid accent"
  bind:value={accent}
  onChange={apply}
  palette={['#2563eb', '#7c3aed', '#db2777', '#ea580c', '#16a34a']}
/>

Tip: onChange always hands you the normalized hex (whether the user typed it, used the native picker, or clicked a preset), so you never have to sanitize the value before storing it.

Accessibility

More examples

Color input - headless

createColorInput drives the portalled SvColorInput and a custom inline swatch + palette panel.

Open the live example: Color input - headless (Headless Editors)

Sizes

Every control takes the same three sizes, so a dense toolbar and a roomy form can share components.

<script lang="ts">
  import { SvColorInput } from '@svgrid/grid'

  let color = $state('')
</script>

<SvColorInput bind:value={color} size="sm" />
<SvColorInput bind:value={color} size="md" />
<SvColorInput bind:value={color} size="lg" />

In a form

The shared field props behave the same on every editor: label names it, hint explains it, and error plus invalid mark it - which is why a validated form does not need per-component handling.

<script lang="ts">
  import { SvColorInput } from '@svgrid/grid'

  let color = $state('')
</script>

<SvColorInput
  bind:value={color}
  label="Label"
  hint="A short hint"
  required
/>

<SvColorInput
  bind:value={color}
  label="Label"
  error="Something is wrong"
  invalid
/>

See also

Live examples

  • Color input - SvColorInput on its own: a swatch that opens an animated, portalled popover with a hex field, the native picker and a preset palette. Emits a hex string.
  • Color input - headless - createColorInput drives the portalled SvColorInput and a custom inline swatch + palette panel.