Preview
Loading GPUI
Props
Secondary
Loading GPUI
AquaButton::new("cancel", "Cancel").variant(AquaButtonVariant::Secondary)Icon Button
Make it a fixed square with a smaller radius for a compact icon button.
Loading GPUI
AquaButton::new("menu", "")
.square(px(36.0))
.radius(px(6.0))
.icon(|scale| disclosure_triangle(scale).into_any_element())Install
cargo add evilbuttonsUsage
use evilbuttons::{AquaButton, AquaButtonVariant};
use gpui::{div, prelude::*, px, Context, IntoElement, Render, Window};
struct ButtonDemo;
impl Render for ButtonDemo {
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
div()
.flex()
.gap(px(16.0))
.child(AquaButton::new("cancel", "Cancel").variant(AquaButtonVariant::Secondary))
.child(AquaButton::new("save", "Save").on_click(|_, _, _| save()))
}
}The icon closure gets the press scale, so the icon shrinks with the button. Paint with window.text_style().color to follow the label colour:
fn disclosure_triangle(scale: f32) -> impl IntoElement {
canvas(
|_, _, _| {},
|bounds, _, window, _| {
// M1 3 L9 3 L5 8 Z on a 10-unit grid.
let unit = bounds.size.width / 10.0;
let p = |x: f32, y: f32| point(bounds.origin.x + unit * x, bounds.origin.y + unit * y);
let mut path = PathBuilder::fill();
path.move_to(p(1.0, 3.0));
path.line_to(p(9.0, 3.0));
path.line_to(p(5.0, 8.0));
path.close();
if let Ok(path) = path.build() {
let color = window.text_style().color;
window.paint_path(path, color);
}
},
)
.size(px(11.0 * scale))
}Props
AquaButton 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 label. Pass "" for an icon-only button. |
variant(v) | AquaButtonVariant | Primary | Blue Aqua gel (Primary) or adaptive silver/dark glass (Secondary). |
dark(bool) | bool | window appearance | Use the dark palette for the secondary variant. |
square(side) | impl Into<Pixels> | - | Fixed square size with no padding, for icon buttons. |
radius(r) | impl Into<Pixels> | full pill | Corner radius. |
icon(f) | Fn(f32) -> AnyElement | - | Content after the label; receives the press scale. |
font_family(family) | impl Into<SharedString> | inherited | Font family for the label. |
on_click(f) | Fn(&ClickEvent, &mut Window, &mut App) | - | Fired on click. |
disabled(bool) | bool | false | Dims the button and ignores input. |
Good to know
- Sized from a 16px
emlike the original: 28px tall, at least 96px wide, 32px side padding. - Like the live React button, the shadows stay put on hover and press (the original's inline
box-shadowoverrides its hover and active shadows); hover lifts it 1px, press scales it to 97%. - GPUI has no
filter: blur(), so the bottom glow is softened with blurred shadows instead.