# ColorField **Category**: react **URL**: https://www.heroui.com/docs/react/components/color-field **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(colors)/color-field.mdx > Color input field with labels, descriptions, and validation built on React Aria ColorField *** ## Import ```tsx import { ColorField, parseColor } from '@heroui/react'; ``` ### Usage ```tsx "use client"; import type {Color} from "@heroui/react"; import {ColorField, ColorSwatch, Label, parseColor} from "@heroui/react"; import {useState} from "react"; export function Basic() { const [color, setColor] = useState(parseColor("#0485F7")); return ( ); } ``` ### Anatomy ```tsx import {ColorField, Label, ColorSwatch, Description, FieldError, parseColor} from '@heroui/react'; export default () => ( ) ``` > **ColorField** combines label, color input, description, and error into a single accessible component. ### With Description ```tsx import {ColorField, Description, Label} from "@heroui/react"; export function WithDescription() { return (
Enter your brand's primary color Used for highlights and CTAs
); } ``` ### Required Field ```tsx import {ColorField, Description, Label} from "@heroui/react"; export function Required() { return (
Required field
); } ``` ### Validation Use `isInvalid` together with `FieldError` to surface validation messages. ```tsx import {ColorField, FieldError, Label} from "@heroui/react"; export function Invalid() { return (
Please enter a valid hex color Invalid color format. Use hex (e.g., #FF5733)
); } ``` ### Channel Editing ColorField supports editing individual color channels (hue, saturation, lightness, red, green, blue, alpha) by setting the `colorSpace` and `channel` props. ```tsx "use client"; import type {Color} from "@heroui/react"; import {ColorField, ColorSwatch, Label, parseColor} from "@heroui/react"; import {useState} from "react"; export function ChannelEditing() { const [color, setColor] = useState(parseColor("#7F007F")); return (

Edit individual HSL channels:

% %
Current: {color ? color.toString("hex") : "(empty)"}
); } ``` ### Controlled Control the value to synchronize with other components or state management. ```tsx "use client"; import type {Color} from "@heroui/react"; import {Button, ColorField, ColorSwatch, Description, Label, parseColor} from "@heroui/react"; import {useState} from "react"; export function Controlled() { const [value, setValue] = useState(parseColor("#0485F7")); return (
Current value: {value ? value.toString("hex") : "(empty)"}
); } ``` ### Disabled State ```tsx "use client"; import {ColorField, Description, Label} from "@heroui/react"; export function Disabled() { return (
This color field is disabled This color field is disabled
); } ``` ### Full Width ```tsx import {ColorField, Label} from "@heroui/react"; export function FullWidth() { return (
); } ``` ### Variants The ColorField.Group component supports two visual variants: - **`primary`** (default) - Standard styling with shadow, suitable for most use cases - **`secondary`** - Lower emphasis variant without shadow, suitable for use in Surface components ```tsx import {ColorField, Label} from "@heroui/react"; export function Variants() { return (
); } ``` ### On Surface When used inside a [Surface](/docs/components/surface) component, use `variant="secondary"` on ColorField.Group to apply the lower emphasis variant suitable for surface backgrounds. ```tsx import {ColorField, Description, Label, Surface} from "@heroui/react"; export function OnSurface() { return ( Select your theme color ); } ``` ### Form Example Complete form example with validation and submission handling. ```tsx "use client"; import type {Color} from "@heroui/react"; import {Button, ColorField, ColorSwatch, Description, Form, Label} from "@heroui/react"; import {useState} from "react"; export function FormExample() { const [value, setValue] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!value) { return; } setIsSubmitting(true); // Simulate API call setTimeout(() => { console.log("Color submitted:", {color: value.toString("hex")}); setValue(null); setIsSubmitting(false); }, 1500); }; return (
Choose your brand's primary color
); } ``` ### Custom Render Function ```tsx "use client"; import type {Color} from "@heroui/react"; import {ColorField, ColorSwatch, Label, parseColor} from "@heroui/react"; import {useState} from "react"; export function CustomRenderFunction() { const [color, setColor] = useState(parseColor("#0485F7")); return (
} value={color} onChange={setColor} >
}> ); } ``` ## Related Components - **ColorSwatch**: Visual preview of a color value - **ColorSwatchPicker**: Color swatch selection from a list of colors - **ColorPicker**: Composable color picker with popover ## Styling ### Passing Tailwind CSS classes ```tsx import {ColorField, Label, ColorSwatch, Description} from '@heroui/react'; function CustomColorField() { return ( Select your brand's primary color. ); } ``` ### Customizing the component classes ColorField has minimal default styling. Override the `.color-field` class to customize the container styling. ```css @layer components { .color-field { @apply flex flex-col gap-1; &[data-invalid="true"], &[aria-invalid="true"] { [data-slot="description"] { @apply hidden; } } [data-slot="label"] { @apply w-fit; } [data-slot="description"] { @apply px-1; } } } ``` ### CSS Classes - `.color-field` – Root container with minimal styling (`flex flex-col gap-1`) > **Note:** Child components ([Label](/docs/components/label), [Description](/docs/components/description), [FieldError](/docs/components/field-error)) have their own CSS classes and styling. See their respective documentation for customization options. ColorField.Group styling is documented below in the API Reference section. ### Interactive States ColorField automatically manages these data attributes based on its state: - **Invalid**: `[data-invalid="true"]` or `[aria-invalid="true"]` - Automatically hides the description slot when invalid - **Required**: `[data-required="true"]` - Applied when `isRequired` is true - **Disabled**: `[data-disabled="true"]` - Applied when `isDisabled` is true - **Focus Within**: `[data-focus-within="true"]` - Applied when any child input is focused ## API Reference ### ColorField Props ColorField inherits all props from React Aria's [ColorField](https://react-aria.adobe.com/ColorField.md) component. #### Base Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `children` | `React.ReactNode \| (values: ColorFieldRenderProps) => React.ReactNode` | - | Child components (Label, ColorField.Group, etc.) or render function. | | `className` | `string \| (values: ColorFieldRenderProps) => string` | - | CSS classes for styling, supports render props. | | `style` | `React.CSSProperties \| (values: ColorFieldRenderProps) => React.CSSProperties` | - | Inline styles, supports render props. | | `fullWidth` | `boolean` | `false` | Whether the color field should take full width of its container | | `id` | `string` | - | The element's unique identifier. | | `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function.| #### Value Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `value` | `Color \| null` | - | Current value (controlled). | | `defaultValue` | `Color \| null` | - | Default value (uncontrolled). | | `onChange` | `(color: Color \| null) => void` | - | Handler called when the value changes. | #### Channel Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `colorSpace` | `ColorSpace` | - | The color space that the color field operates in when `channel` is provided. | | `channel` | `ColorChannel` | - | The color channel to edit. If not provided, edits hex value. | #### Validation Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `isRequired` | `boolean` | `false` | Whether user input is required before form submission. | | `isInvalid` | `boolean` | - | Whether the value is invalid. | | `validate` | `(value: Color) => ValidationError \| true \| null \| undefined` | - | Custom validation function. | | `validationBehavior` | `'native' \| 'aria'` | `'native'` | Whether to use native HTML form validation or ARIA attributes. | #### State Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `isDisabled` | `boolean` | - | Whether the input is disabled. | | `isReadOnly` | `boolean` | - | Whether the input can be selected but not changed. | | `isWheelDisabled` | `boolean` | - | Whether to disable changing the value with scroll. | #### Form Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `name` | `string` | - | Name of the input element, for HTML form submission. | | `autoFocus` | `boolean` | - | Whether the element should receive focus on render. | #### Accessibility Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `aria-label` | `string` | - | Accessibility label when no visible label is present. | | `aria-labelledby` | `string` | - | ID of elements that label this field. | | `aria-describedby` | `string` | - | ID of elements that describe this field. | | `aria-details` | `string` | - | ID of elements with additional details. | ### Composition Components ColorField works with these separate components that should be imported and used directly: - **Label** - Field label component from `@heroui/react` - **ColorField.Group** - Color input group component (documented below) - **ColorField.Input** - Input element within ColorField.Group - **ColorField.Prefix** / **ColorField.Suffix** - Prefix and suffix slots for the input group - **ColorSwatch** - Color preview component from `@heroui/react` - **Description** - Helper text component from `@heroui/react` - **FieldError** - Validation error message from `@heroui/react` Each of these components has its own props API. Use them directly within ColorField for composition: ```tsx import {ColorField, Label, ColorSwatch, Description, FieldError, parseColor} from '@heroui/react'; Select your brand's primary color. Please enter a valid color. ``` ### Color Types ColorField uses `Color` objects from React Aria Components: ```tsx import {parseColor} from '@heroui/react'; // Parse from hex string const color = parseColor('#3B82F6'); // Get hex string from color const hex = color.toString('hex'); // "#3b82f6" // Get RGB values const rgb = color.toString('rgb'); // "rgb(59, 130, 246)" // Use in ColorField {/* ... */} ``` ### ColorFieldRenderProps When using render props with `className`, `style`, or `children`, these values are available: | Prop | Type | Description | |------|------|-------------| | `isDisabled` | `boolean` | Whether the field is disabled. | | `isInvalid` | `boolean` | Whether the field is currently invalid. | | `isReadOnly` | `boolean` | Whether the field is read-only. | | `isRequired` | `boolean` | Whether the field is required. | | `isFocused` | `boolean` | Whether the field is currently focused. | | `isFocusWithin` | `boolean` | Whether any child element is focused. | | `isFocusVisible` | `boolean` | Whether focus is visible (keyboard navigation). | ### ColorField.Group Props ColorField.Group accepts all props from React Aria's `Group` component plus the following: | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Tailwind classes merged with the component styles. | | `fullWidth` | `boolean` | `false` | Whether the color input group should take full width of its container | | `variant` | `"primary" \| "secondary"` | `"primary"` | Visual variant of the component. `primary` is the default style with shadow. `secondary` is a lower emphasis variant without shadow, suitable for use in surfaces. | | `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function.| ### ColorField.Input Props ColorField.Input accepts all props from React Aria's `Input` component plus the following: | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Tailwind classes merged with the component styles. | | `placeholder` | `string` | - | Placeholder text shown when empty. | ### ColorField.Prefix Props ColorField.Prefix accepts standard HTML `div` attributes: | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Tailwind classes merged with the component styles. | | `children` | `ReactNode` | - | Content to display in the prefix slot. | ### ColorField.Suffix Props ColorField.Suffix accepts standard HTML `div` attributes: | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Tailwind classes merged with the component styles. | | `children` | `ReactNode` | - | Content to display in the suffix slot. | ## ColorField.Group Styling ### Customizing the component classes The base classes power every instance. Override them once with `@layer components`. ```css @layer components { .color-input-group { @apply inline-flex h-9 items-center overflow-hidden rounded-field border bg-field text-sm text-field-foreground shadow-field outline-none; &:hover, &[data-hovered="true"] { @apply bg-field-hover; } &[data-focus-within="true"], &:focus-within { @apply status-focused-field; } &[data-invalid="true"] { @apply status-invalid-field; } &[data-disabled="true"], &[aria-disabled="true"] { @apply status-disabled; } } .color-input-group__input { @apply flex flex-1 items-center rounded-none border-0 bg-transparent px-3 py-2 shadow-none outline-none; } .color-input-group__prefix, .color-input-group__suffix { @apply shrink-0 text-field-placeholder flex items-center; } } ``` ### ColorField.Group CSS Classes - `.color-input-group` – Root container styling - `.color-input-group__input` – Input wrapper styling - `.color-input-group__prefix` – Prefix element styling - `.color-input-group__suffix` – Suffix element styling ### ColorField.Group Interactive States - **Hover**: `:hover` or `[data-hovered="true"]` - **Focus Within**: `[data-focus-within="true"]` or `:focus-within` - **Invalid**: `[data-invalid="true"]` (also syncs with `aria-invalid`) - **Disabled**: `[data-disabled="true"]` or `[aria-disabled="true"]`