Preview
Loading GPUI
Custom Label
Loading GPUI
ThreeDButton::new("open-panel", "Open Panel").dark(is_dark)Install
cargo add evilbuttonsUsage
use evilbuttons::ThreeDButton;
use gpui::{div, prelude::*, Context, IntoElement, Render, Window};
struct ButtonDemo;
impl Render for ButtonDemo {
fn render(&mut self, window: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
let is_dark = matches!(
window.appearance(),
gpui::WindowAppearance::Dark | gpui::WindowAppearance::VibrantDark
);
div().child(
ThreeDButton::new("continue", "Continue")
.dark(is_dark)
.on_click(|_, _, _| println!("Continue")),
)
}
}Props
ThreeDButton is a GPUI RenderOnce builder; its press state is keyed by id.
| Method | Type | Default | Description |
|---|---|---|---|
new(id, label) | impl Into<ElementId>, impl Into<SharedString> | - | Unique id and the visible button label. |
dark(bool) | bool | false | Use the dark palette (zinc-900 face, white rim and deck) instead of the light one. |
on_click(f) | Fn(&ClickEvent, &mut Window, &mut App) | - | Fired on click, and on Space/Enter while focused. |
disabled(bool) | bool | false | Dims the button and ignores input. |
Good to know
- The React version switches palettes with Tailwind's
dark:variant; GPUI has no page theme, so passdark(true)on dark backgrounds. - Every layer (deck, face, press spot, sheen, label) rides the same spring (stiffness 620, damping 32, mass 0.5), so retargeting mid-press stays smooth.
- The press spot's
blur-smis drawn as a Gaussian shadow, and the sheen is clipped to the pill row by row, since GPUI has no CSS filters or clip paths.