ccf-gpui-widgets
Reusable GPUI widgets for building desktop applications.
Features
- Themeable: All widgets support custom themes via global context or per-widget override
- Accessible: Keyboard navigation support where applicable
- Event-driven: All widgets emit events for state changes
- Builder pattern: Fluent API for widget configuration
Installation
Add to your Cargo.toml:
[]
= "0.1"
# For file/directory pickers (adds rfd and dirs dependencies)
# ccf-gpui-widgets = { version = "0.1", features = ["file-picker"] }
Quick Start
use *;
use ;
new.run;
Available Widgets
Input Widgets
| Widget | Description |
|---|---|
TextInput |
Full-featured text input with cursor, selection, clipboard |
PasswordInput |
Text input with visibility toggle |
NumberStepper |
Numeric input with +/- buttons |
Slider |
Horizontal slider for numeric ranges |
Selection Widgets
| Widget | Description |
|---|---|
Checkbox |
Simple checkbox with optional label |
ToggleSwitch |
On/off toggle with configurable label position |
Dropdown |
Select/dropdown with keyboard navigation |
RadioGroup |
Single-selection from multiple choices |
CheckboxGroup |
Multi-selection from multiple choices |
ColorSwatch |
Color picker with hex input, HSV canvas |
Display Widgets
| Widget | Description |
|---|---|
Tooltip |
Hover tooltip |
ProgressBar |
Progress indicator (determinate/indeterminate) |
Spinner |
Loading spinner in multiple sizes |
Layout & Navigation
| Widget | Description |
|---|---|
Collapsible |
Expandable/collapsible section |
TabBar |
Tab navigation with keyboard support |
ConfirmationDialog |
Modal dialogs (Info/Default/Warning/Danger styles) |
Repeatable Widgets
| Widget | Description |
|---|---|
RepeatableTextInput |
Text input with add/remove for lists |
File Widgets (requires file-picker feature)
| Widget | Description |
|---|---|
FilePicker |
File selection with native dialog |
DirectoryPicker |
Directory selection with native dialog |
RepeatableFilePicker |
File picker with add/remove for lists |
RepeatableDirectoryPicker |
Directory picker with add/remove for lists |
Utilities
| Function | Description |
|---|---|
primary_button() |
Blue/accent styled button |
secondary_button() |
Gray styled button |
danger_button() |
Red styled button |
with_focus_actions() |
Add Tab/Shift-Tab focus navigation to elements |
Theming
Widgets use a Theme struct for colors. You can:
- Set a global theme:
cx.set_global(Theme::dark()) - Use per-widget themes:
TextInput::new(cx).theme(my_theme) - Use the default (dark theme) if nothing is set
use Theme;
// Built-in themes
let dark = dark;
let light = light;
// Customize with builder methods
let custom = dark
.with_accent
.with_primary;
Widget Usage Examples
TextInput
let input = cx.new;
cx.subscribe.detach;
Checkbox
let checkbox = cx.new;
cx.subscribe.detach;
Dropdown
let dropdown = cx.new;
cx.subscribe.detach;
NumberStepper
let stepper = cx.new;
ColorSwatch
let swatch = cx.new;
cx.subscribe.detach;
The color picker popup includes:
- 2D saturation/brightness canvas (HSV model)
- Hue slider (0-359°)
- Alpha slider (when enabled)
- RGB component sliders
- Old/New color comparison
- Hex value display
Supports hex input (#RGB, #RRGGBB, #RRGGBBAA) and all 140 CSS named colors.
Slider
let slider = cx.new;
cx.subscribe.detach;
ToggleSwitch
let toggle = cx.new;
cx.subscribe.detach;
TabBar
let tabs = cx.new;
cx.subscribe.detach;
ConfirmationDialog
let dialog = cx.new;
cx.subscribe.detach;
FilePicker (requires file-picker feature)
let picker = cx.new;
Keybindings
Some widgets require keybindings to be registered at startup. Call register_all_keybindings(cx) once during app initialization:
new.run;
Or register individual widgets:
register_keybindings;
register_keybindings;
License
MIT OR Apache-2.0