Ir al contenido
Formularios

ColorPicker

Un campo que abre un selector de color, con paleta, espectro, valores y los últimos colores usados. Trabaja en OKLCH.

import { ColorPicker } from "sebs7n-ui/color-picker"

Ejemplos

Con recientes

El componente muestra la lista, no la guarda. Acá se suma el color al cerrar el panel: elegí uno, cerrá, y volvé a abrir.

import { ColorPicker } from "sebs7n-ui/color-picker"
import { Label } from "sebs7n-ui/label"
import { hexOfOklch, type Oklch } from "sebs7n-ui/lib/contrast"
import { useId, useState } from "react"

function Recientes() {
  const id = useId()
  const [color, setColor] = useState<Oklch>([0.573, 0.214, 258])
  const [recientes, setRecientes] = useState<Oklch[]>([
    [0.55, 0.16, 35],
    [0.515, 0.099, 183],
    [0.53, 0.13, 162],
  ])
  return (
    <div className="flex w-full max-w-xs flex-col gap-2">
      <Label htmlFor={id}>Color de la etiqueta</Label>
      <ColorPicker
        id={id}
        onOpenChange={(abierto) => {
          if (abierto) return
          // El más nuevo adelante, sin repetidos, y ocho como mucho.
          setRecientes((lista) => [color, ...lista.filter((otro) => hexOfOklch(otro) !== hexOfOklch(color))].slice(0, 8))
        }}
        onValueChange={setColor}
        recent={recientes}
        value={color}
      />
    </div>
  )
}

Básico

Sin `recent`, la sección no aparece. Con `name`, el color viaja en el formulario como hexadecimal.

import { ColorPicker } from "sebs7n-ui/color-picker"
import { Label } from "sebs7n-ui/label"
import { useId } from "react"

function Basico() {
  const id = useId()
  return (
    <div className="flex w-full max-w-xs flex-col gap-2">
      <Label htmlFor={id}>Color</Label>
      <ColorPicker defaultValue={[0.55, 0.16, 35]} id={id} name="color" />
    </div>
  )
}

Tamaños y pie

Las mismas tres alturas que `Input`. `footer` recibe el color actual: sirve para una vista previa.

import { ColorPicker } from "sebs7n-ui/color-picker"
import { hexOfOklch } from "sebs7n-ui/lib/contrast"

function TamanosYPie() {
  return (
    <div className="flex w-full max-w-xs flex-col gap-3">
      <ColorPicker aria-label="Chico" defaultValue={[0.515, 0.099, 183]} size="sm" />
      <ColorPicker
        aria-label="Con vista previa"
        defaultValue={[0.53, 0.13, 162]}
        footer={(color) => (
          <div
            className="flex h-10 items-center justify-center rounded-full text-callout font-medium text-white"
            style={{ backgroundColor: hexOfOklch(color) }}
          >
            Vista previa
          </div>
        )}
      />
      <ColorPicker aria-label="Grande" defaultValue={[0.55, 0.16, 35]} size="lg" />
      <ColorPicker aria-label="Deshabilitado" disabled />
    </div>
  )
}

Props

Generadas del TypeScript del paquete. Las propias del componente, más las heredadas del primitivo que tienen algo que explicar —marcadas «heredada de Base UI»—. El resto está en la línea «hereda de».

ColorPicker

Hereda las props de <button>.

PropTipoPor defectoDescripción
defaultValueOklchDEFAULTEl color con el que arranca, sin controlar.
disabledboolean—Apaga la interacción y lo marca con data-disabled, que es el atributo del que cuelgan los estilos de apagado.
footerReact.ReactNode | ((color: Oklch) => React.ReactNode)—Lo que va abajo del panel: una vista previa, un aviso de contraste. Recibe el color actual.
labelsPartial<ColorPickerLabels>—Los textos del panel.
localestring"es-AR"El idioma de los números de la pestaña Valores, como lo entiende Intl. Por defecto, es-AR.
namestring—El nombre con el que el color viaja en un formulario, como #0070f3.
onOpenChange(open: boolean) => void—Avisa cuando se abre o se cierra. Es el momento para guardar el color en los recientes.
onValueChange(color: Oklch) => void—Avisa el color en cada cambio, también mientras se arrastra.
openboolean—El panel abierto o cerrado, controlado.
popupClassNamestring—Clases del panel.
recentreadonly Oklch[]—Los últimos colores usados, del más nuevo al más viejo. Se muestran arriba de la paleta; sin lista, la sección no aparece. El componente los muestra, no los guarda: qué cuenta como «usado» y dónde vive la lista —un estado, localStorage, la base— lo decide la app. Lo más común es sumar el color al cerrar el panel, con onOpenChange.
size"sm" | "md" | "lg""md"Las mismas tres alturas que Input.
valueOklch—El color elegido, controlado. En OKLCH, como se escribe en CSS: [0.573, 0.214, 258].
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

Teclado

Enter · Espacio
Abre el panel.
Escape
Cierra y devuelve el foco al campo.
Tab
Recorre las pestañas, las muestras y los controles.
← → ↑ ↓
En el espectro, croma y luminosidad. Con Shift, de a pasos más grandes.

Accesibilidad

  • El campo es un botón: necesita aria-label, aria-labelledby o un <Label htmlFor> apuntando a su id.
  • Cada muestra se llama por su hexadecimal y anuncia si es la elegida con aria-pressed.
  • El espectro es un role="slider" de dos ejes que se maneja con las flechas; la tira de matices es un <input type="range"> de verdad.
  • El componente no opina sobre el contraste del color elegido. Si el color va a llevar texto encima, medilo con sebs7n-ui/lib/contrast y mostralo en footer.

Reglas de uso

  • En una pantalla angosta (< 640 px) el panel se abre en la hoja de abajo, como el Popover.
  • Para elegir un color libre: una etiqueta, una categoría, el color de marca. Si las opciones son cinco y fijas, es un RadioGroup o un ToggleGroup.
  • recent muestra los últimos colores usados. El componente no los guarda: la app decide qué cuenta como «usado» y dónde vive la lista. Lo más común es sumar el color al cerrar, con onOpenChange.
  • El valor es OKLCH ([0.573, 0.214, 258]). Para guardar o mostrar un hexadecimal están hexOfOklch y oklchOfHex; con name, el formulario lo recibe ya como #0070f3.
  • Reemplaza a <input type="color">, cuyo panel es del sistema operativo.

Relacionados