Color Swatch
Preview a retained source color, or use a swatch as an SDK button.
Try it
Click the small swatch to open Studio’s saturation/value, hue, and opacity picker. This preview runs the exact code sample shown on this page.
Preview and clickable swatch
use std::sync::Arc;
use gpui::{Context, Entity, Render, Subscription, Window, div, prelude::*, px};
use xgpui_luma::color::ColorValue;
use xgpui_luma_color::ColorSwatch;
use xgpui_luma_look_shadcn::ShadcnLook;
// The same app-level picker composition used by Luma Studio.
use luma_app_common::color_picker::{ColorPickerEvent, ColorPickerPopover};
struct Example {
picker: Entity<ColorPickerPopover>,
source: ColorValue,
_subscription: Subscription,
}
impl Example {
fn new(cx: &mut Context<Self>) -> Self {
let source = ColorValue::srgb(0.2, 0.5, 0.9, 0.65);
let look = cx.try_global::<ShadcnLook>().cloned().unwrap_or_else(ShadcnLook::built_in);
let picker = cx.new(|cx| ColorPickerPopover::new(Arc::new(look), source, "accent-picker", cx));
let subscription = cx.subscribe(&picker, |owner: &mut Self, _, event: &ColorPickerEvent, cx| {
let ColorPickerEvent::Change(color) = event;
owner.source = *color;
cx.notify();
});
Self { picker, source, _subscription: subscription }
}
}
impl Render for Example {
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
div().w(px(360.0)).max_w(gpui::relative(1.0)).flex().flex_col().gap_3()
.child(div().flex().items_center().gap(px(8.0))
.child(div().w(px(80.0)).child(ColorSwatch::new(self.source).checkerboard(true).height(px(30.0))))
.child(self.picker.clone()))
.child(div().h(px(24.0)).truncate().child(self.source.to_css().unwrap_or_else(|_| "Invalid color".into())))
}
}
Appearance and source colors
ColorSwatch is a renderable element; it has no events or spawned entity. Configure size(ControlSize), height, rounded, checkerboard, and bordered. Checkerboard is off by default on static swatches; enable it to reveal alpha.
Both swatch forms take ColorValue, retaining its source space and components. Previews use an sRGB fallback with CssLocalMinde mapping. Static swatches can select another policy with mapping. Invalid source colors render transparently; validate input with the strict source-color API when errors need to be reported.
Button events and updates
ColorSwatchButtonTemplate is a template for Button<ColorSwatchData>. The SDK Button handles click, focus, hover, and enabled events; no separate swatch event enum is needed. The example sets an application flag: it does not construct a picker automatically.
| Event | Payload | Callback |
|---|---|---|
Click | None | on_clickOpen the application’s picker. |
FocusChanged | focused: bool | on_focus_changedReact to keyboard focus. |
HoverChanged | hovered: bool | on_hover_changedReact to pointer hover. |
EnabledChanged | enabled: bool | on_enabled_changedReact to enablement changes. |
Update the typed payload with button.update(cx, |button, cx| button.set_data(data, cx)) when the selected source color changes. Keep the source color in the owner model too, so previews and picker content share the same value. See picker composition and Button events.