Skip to content
PorabuildHeroGPUI component library
v0.14.0 · Apache-2.0

Colors

Color Swatch Picker

Choose from a predefined set of colors.

Rust
use herogpui::components::color_picker::ColorSwatchPicker;

ColorSwatchPicker on docs.rsSource at v0.14.0

Usage

Showing Usage, live: HeroGPUI compiled to WebAssembly. The canvas has no accessibility tree; each example's description and code below carry the same information.

Usage

Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ActiveTheme, ColorSwatchPicker, PickerColor, SizeXl};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{App, px};
use herogpui::gpui;

let selected = self.swatch_selected;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![
        ColorSwatchPicker::new("color-swatch-picker-main", palette())
            .value(selected)
            .size(SizeXl::Lg)
            .on_change(cx.listener(|this, c: &PickerColor, _, cx| {
                this.swatch_selected = *c;
                cx.notify();
            }))
            .into_any_element(),
        para(&format!("Selected: {}", selected.to_hex()), cx),
    ])

Also calls palette, para (included when you copy).

Variants

Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ColorSwatchPicker, PickerColor, SwatchShape};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

let selected = self.swatch_selected;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![
        ColorSwatchPicker::new("color-swatch-picker-circle", palette())
            .value(selected)
            .on_change(cx.listener(
                |this, c: &PickerColor, _, cx| {
                    this.swatch_selected = *c;
                    cx.notify();
                },
            ))
            .into_any_element(),
        ColorSwatchPicker::new("color-swatch-picker-sq", palette())
            .value(selected)
            .on_change(cx.listener(
                |this, c: &PickerColor, _, cx| {
                    this.swatch_selected = *c;
                    cx.notify();
                },
            ))
            .shape(SwatchShape::Square)
            .into_any_element(),
    ])

Also calls palette (included when you copy).

Sizes

Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ColorSwatchPicker, PickerColor, SizeXl};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

let selected = self.swatch_selected;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(SizeXl::ALL
        .iter()
        .map(|sz| {
            ColorSwatchPicker::new(format!("color-swatch-picker-{sz:?}"), palette())
                .value(selected)
                .on_change(cx.listener(
                    |this, c: &PickerColor, _, cx| {
                        this.swatch_selected = *c;
                        cx.notify();
                    },
                ))
                .size(*sz)
        }))

Also calls palette (included when you copy).

Disabled

Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ColorSwatchPicker, PickerColor};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

let selected = self.swatch_selected;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![ColorSwatchPicker::new("color-swatch-picker-disabled", palette())
        .value(selected)
        .is_disabled(true)
        .into_any_element()])

Also calls palette (included when you copy).

Disabled Item

`ColorSwatchPicker.Item.isDisabled` dims one swatch — unclickable and out of the tab order — while the rest stay pickable: the difference from the whole-picker `isDisabled` above. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ColorSwatchPicker, PickerColor};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

let selected = self.swatch_selected;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![
        ColorSwatchPicker::new("color-swatch-picker-disabled-item", palette())
            .value(selected)
            .disabled_keys([2])
            .on_change(cx.listener(|this, c: &PickerColor, _, cx| {
                this.swatch_selected = *c;
                cx.notify();
            }))
            .into_any_element(),
    ])

Also calls palette (included when you copy).

Stack Layout

Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ColorSwatchPicker, PickerColor, SwatchLayout};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

let selected = self.swatch_selected;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![ColorSwatchPicker::new("color-swatch-picker-stack", palette())
        .value(selected)
        .on_change(cx.listener(|this, c: &PickerColor, _, cx| {
            this.swatch_selected = *c;
            cx.notify();
        }))
        .layout(SwatchLayout::Stack)
        .into_any_element()])

Also calls palette (included when you copy).

Default Value

An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{ColorSwatchPicker, PickerColor};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![ColorSwatchPicker::new("color-swatch-picker-default", palette())
        .default_value(palette()[2])
        .into_any_element()])

Also calls palette (included when you copy).

Controlled

Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ActiveTheme, ColorSwatchPicker, PickerColor};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{App, px};
use herogpui::gpui;

let selected = self.swatch_selected;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![
        ColorSwatchPicker::new("color-swatch-picker-controlled", palette())
            .value(selected)
            .on_change(cx.listener(|this, c: &PickerColor, _, cx| {
                this.swatch_selected = *c;
                cx.notify();
            }))
            .into_any_element(),
        para(&format!("Selected: {}", selected.to_hex()), cx),
    ])

Also calls palette, para (included when you copy).

Custom Indicator

`indicator` replaces the built-in selected checkmark. The square picker below uses a heart. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ColorSwatchPicker, PickerColor, SizeXl, SwatchShape, icons};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

let selected = self.swatch_selected;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![
        ColorSwatchPicker::new("color-swatch-picker-indicator", palette())
            .value(selected)
            .on_change(cx.listener(|this, c: &PickerColor, _, cx| {
                this.swatch_selected = *c;
                cx.notify();
            }))
            .shape(SwatchShape::Square)
            .size(SizeXl::Lg)
            .indicator(|_, _| {
                gpui::svg()
                    .size(px(12.))
                    .path(icons::HEART_FILL)
                    .text_color(gpui::white())
                    .into_any_element()
            })
            .into_any_element(),
    ])

Also calls palette (included when you copy).

Item Render State

`item_content` receives each item's color plus selected, hovered, pressed, focused, focus-visible, and disabled state. These custom tiles use that state while the picker keeps navigation and selection. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ColorSwatchPicker, PickerColor, SizeXl, icons};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

let selected = self.swatch_selected;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![
        ColorSwatchPicker::new("color-swatch-picker-item-content", palette())
            .value(selected)
            .size(SizeXl::Xl)
            .on_change(cx.listener(|this, c: &PickerColor, _, cx| {
                this.swatch_selected = *c;
                cx.notify();
            }))
            .item_content(|_, state| {
                gpui::div()
                    .size_full()
                    .rounded(px(8.))
                    .bg(state.color.to_hsla())
                    .when(state.is_pressed, |tile| tile.opacity(0.65))
                    .when(state.is_selected, |tile| {
                        tile.child(
                            gpui::svg()
                                .size(px(12.))
                                .path(icons::HEART_FILL)
                                .text_color(gpui::white()),
                        )
                    })
                    .into_any_element()
            })
            .into_any_element(),
    ])

Also calls palette (included when you copy).

Square, stacked

Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ColorSwatchPicker, PickerColor, SwatchLayout, SwatchShape};

let selected = self.swatch_selected;

ColorSwatchPicker::new("color-swatch-picker-square", palette())
    .value(selected)
    .shape(SwatchShape::Square)
    .layout(SwatchLayout::Stack)
    .on_change(cx.listener(|this, c: &PickerColor, _, cx| {
        this.swatch_selected = *c;
        cx.notify();
    }))

Also calls palette (included when you copy).

Helpers used by these examples

Plain functions over the public API, defined once here and copied with each example that calls them.

palette
/// The demo palette used by the color pages.
fn palette() -> Vec<PickerColor> {
    [
        "#0085F5", "#17C964", "#F5A524", "#F31260", "#7828C8", "#0E8AAA", "#71717A", "#18181B",
    ]
    .into_iter()
    .filter_map(PickerColor::from_hex)
    .collect()
}
para
fn para(text: &str, cx: &App) -> gpui::AnyElement {
    let colors = cx.colors();
    gpui::div()
        .text_size(px(14.5))
        .line_height(px(24.))
        .text_color(colors.foreground)
        .max_w(px(720.))
        .child(text.to_owned())
        .into_any_element()
}

Anatomy

Rust types

ColorSwatchPicker

Color Swatch Picker is assembled from these builders. The API reference lists each one.

Customization

Shared appearance belongs on ThemeBuilder::components and .recipe("name"). Typed builders change how Color Swatch Picker looks at one call site. Every builder also carries sx for placement, width and flex: it takes GPUI's own styling methods and refines them over the component's root after the theme, so an instance override wins. Behaviour builders live in the API reference below.

Styling

Color Swatch Picker styling
MethodValuesDescription
size(SizeXl)xs | sm | md | lg | xlDrives item edge, border, radius, indicator, hit geometry, wrapping, and grid navigation stride.
shape(SwatchShape)circle | squareSelects the per-size item and swatch radii.
Rust
// The one slot for caller-owned low-level styling: GPUI's
// styling methods, refined over the root element last.
.sx(|el| {
    el.bg(gpui::rgba(0xffa500ff))             // background
        .text_color(gpui::rgba(0x000000ff))   // text
        .w(gpui::px(13.))                     // size
        .h(gpui::px(12.))
})

API reference

Against HeroUI v3.2.6: 20 entries ported, 3 partial, 3 not ported. Partial rows are marked in the tables; entries not ported are listed under each table with the reason.

Builders

Color Swatch Picker builders
BuilderValuesDefaultDescription
value(PickerColor)string | Color—Controlled selection changes only when the owner supplies the reported color.
default_value(PickerColor)string | Color—Seeds picker-owned selection once.
on_change(callback)Fn(value: Color) -> ()—Reports pointer and keyboard selection changes.
size(SizeXl)xs | sm | md | lg | xlSizeXl::MdDrives item edge, border, radius, indicator, hit geometry, wrapping, and grid navigation stride.
shape(SwatchShape)circle | squareSwatchShape::CircleSelects the per-size item and swatch radii.
layout(SwatchLayout)grid | stackSwatchLayout::GridGrid wraps and uses geometric row navigation; stack is vertical and uses Up/Down.
new(id, Vec<PickerColor>)PartialAnyElement—The Rust constructor receives a concrete palette and composes one item per color.
new(id, Vec<PickerColor>) / item_contentstring | ColorrequiredEach palette color is supplied by index and reaches item render state.
disabled_keys(indices)true | falsefalsePer-index disabled items dim, leave navigation, and mask interaction state.
item_content(render)AnyElement | render closureSwatch + IndicatorReplacement content receives color, hover, press, selection, focus, focus-visible, and disabled state.
indicator(render)AnyElement | render closurecheckmarkReplacement indicator content receives the complete item state.
Not ported3 HeroUI entries not ported
Color Swatch Picker builders not ported
HeroUI v3Why it is not ported
ColorSwatchPicker.classNameBrowser classes are unavailable.
ColorSwatchPicker.renderThe GPUI root element cannot be replaced.
ColorSwatchPicker.Item.classNameBrowser classes are unavailable.

Parts

Color Swatch Picker parts
PartDescription
ColorSwatchPickerSelection owner and wrapping grid or vertical stack.
ColorSwatchPickerStable focus, pointer, selection, and render-state owner.
ColorSwatchPickerCheckerboard-backed color visual with selected and hover geometry.
ColorSwatchPickerCentered selected marker with luminance-aware default color or caller content.

States

Color Swatch Picker states
StateBuilderDescription
HoveredinteractionEnabled unselected swatches grow to 1.1 and item content receives hover.
PressedinteractionEnabled item content receives live pointer and keyboard press state.
Selectedresolved valueThe color border is revealed by a 0.77 inner swatch and item/indicator state updates.
FocusedcursorExactly one enabled item owns the roving focus handle.
Focus visiblewith_focus_ringKeyboard-origin focus draws the shared ring and reaches item state.
Disabledis_disabledWhole-picker and per-item disabling dim, suppress events, remove navigation stops, and mask state.