Color Slider
Edit hue, alpha, individual channels, or gradient positions on a color track.
Try it
Drag the hue slider to update the preview and committed hue. This preview runs the exact code sample below.
Basic use
use gpui::{Context, Entity, Render, Window, div, prelude::*, px};
use xgpui_luma::controls::slider::{SliderControl, SliderEventExt};
use xgpui_luma_color::color_slider::ColorSliderBuilder;
use xgpui_luma::theme::ControlSize;
struct Example {
control: Entity<SliderControl>,
preview: f32,
committed: f32,
}
impl Example {
fn new(cx: &mut Context<Self>) -> Self {
let control = ColorSliderBuilder::hue("hue", 210.0)
.size(ControlSize::Sm).thumb_medium()
.spawn(cx)
.on_value_changed(cx, |owner: &mut Self, _, value, cx| {
owner.preview = value;
cx.notify();
})
.on_release(cx, |owner, _, value, cx| {
owner.committed = value;
cx.notify();
});
Self { control, preview: 210.0, committed: 210.0 }
}
}
impl Render for Example {
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
div().w(px(240.0)).child(self.control.clone())
}
}Channels and gradients
hue uses degrees (0..360); alpha uses 0..1 and a supplied color specification. channel looks up a named channel’s bounds and step from that specification and returns Result<_, String>. Gradient construction accepts retained ColorValue stops and returns anyhow::Result.
fn red_channel(cx: &mut gpui::Context<Example>)
-> Result<gpui::Entity<SliderControl>, String> {
use xgpui_luma_color::color_slider::RgbaSpec;
let rgba = RgbaSpec { r: 0.8, g: 0.3, b: 0.2, a: 1.0 };
Ok(ColorSliderBuilder::channel("red", rgba.r, rgba, RgbaSpec::RED)?.spawn(cx))
}
fn gradient(cx: &mut gpui::Context<Example>)
-> Result<gpui::Entity<SliderControl>, Box<dyn std::error::Error + Send + Sync>> {
use xgpui_luma::color::ColorValue;
use xgpui_luma_color::color_slider::ColorInterpolation;
Ok(ColorSliderBuilder::gradient("gradient", 0.5, vec![
ColorValue::srgb(1.0, 0.0, 0.0, 1.0),
ColorValue::srgb(0.0, 0.0, 1.0, 0.5),
])?.interpolation(ColorInterpolation::Lab).spawn(cx))
}Events
| Event | Payload | Callback |
|---|---|---|
Change | thumb_id: ThumbIdvalue: f32 | on_value_changedUpdate the live preview. |
Release | thumb_id: ThumbIdvalue: f32 | on_releaseCommit the interaction value. |
DragStart | thumb_id: ThumbId | on_drag_startBegin a pointer gesture. |
DragEnd | thumb_id: ThumbIdvalue: f32 | on_drag_endFinish a pointer gesture. |
ThumbAdded | thumb_id: ThumbIdvalue: f32 | on_thumb_addedTrack an added gradient stop. |
ThumbRemoved | thumb_id: ThumbId | on_thumb_removedTrack a removed stop. |
ThumbSelected | thumb_id: ThumbId | on_thumb_selectedUpdate the selected thumb. |
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. |
These are SDK SliderEvent callbacks, available through SliderEventExt. The builders return Entity<SliderControl>. Each callback receives the owner, the listed payload values, and the owner context. Register callbacks after spawn; use on_event or cx.subscribe for the full event stream. See Slider events.
Appearance and synchronization
Use horizontal/vertical, size(ControlSize), thumb_size(SliderThumbSize), thumb_square, thumb_bar, rounded, and edge_to_edge. Gradient interpolation supports RGB, HSL, and Lab. multi_stop, dual_stop, and thumb_policy configure multiple thumbs.
Capture domain_renderer() and track_context() before consuming the builder. When a base color changes, replace its delegate with update_domain_delegate and call refresh_color_slider to refresh thumb previews. ColorCompositionSync::sync_color_slider combines these updates. Changing only the numeric slider value does not replace a delegate’s color specification.
Custom thumb painting
Implement ColorSliderDelegate::thumb_painter(&self, context: &ColorSliderTrackContext, position: f32) -> Option<ColorThumbPainter> to supply a custom thumb background for a normalized track position. The default returns None, preserving the normal thumb preview. ColorSliderBuilder::new connects the delegate to the thumb template automatically; track painting and slider behavior remain owned by their existing delegate and SDK control.
ColorThumbPainter is an Arc callback that receives Bounds<Pixels>, a mutable Window, and a mutable App, and returns anyhow::Result<()>. The callback must be Send + Sync. The thumb invokes it inside an inset canvas over the normal background. Paint failures are currently discarded by the thumb renderer, so handle any required diagnostics in the callback.
For a custom template that constructs its own ColorThumb, attach the painter directly with background_painter:
fn custom_thumb(
painter: xgpui_luma_color::color_slider::color_thumb::ColorThumbPainter,
) -> xgpui_luma_color::color_slider::color_thumb::ColorThumb {
xgpui_luma_color::color_slider::color_thumb::ColorThumb::new(gpui::px(20.0))
.background_painter(painter)
}