Actions
Icon Button
A square button that shows only an icon, with a label and an optional pressed state.


use iced::widget::{column, container, row, text};
use iced::{Alignment, Element, Length};
use iced_cube::{Glyph, icon_button, lucide, vertical_separator};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Align {
Start,
Center,
End,
}
#[derive(Debug, Clone)]
pub enum Message {
ToggleBold,
ToggleItalic,
ToggleUnderline,
Align(Align),
}
#[derive(Debug)]
pub struct Example {
bold: bool,
italic: bool,
underline: bool,
align: Align,
}
impl Default for Example {
fn default() -> Self {
Self {
bold: true,
italic: false,
underline: false,
align: Align::Start,
}
}
}
impl Example {
pub fn update(&mut self, message: Message) {
match message {
Message::ToggleBold => self.bold = !self.bold,
Message::ToggleItalic => self.italic = !self.italic,
Message::ToggleUnderline => self.underline = !self.underline,
Message::Align(align) => self.align = align,
}
}
pub fn view(&self) -> Element<'_, Message> {
let toggle = |glyph: Glyph, label: &'static str, on: bool, message: Message| {
icon_button(glyph)
.label(label)
.pressed(on)
.on_press(message)
};
let align = |glyph: Glyph, label: &'static str, align: Align| {
toggle(glyph, label, self.align == align, Message::Align(align))
};
let toolbar = row![
toggle(lucide!(Bold), "Bold", self.bold, Message::ToggleBold),
toggle(
lucide!(Italic),
"Italic",
self.italic,
Message::ToggleItalic
),
toggle(
lucide!(Underline),
"Underline",
self.underline,
Message::ToggleUnderline
),
container(vertical_separator()).height(20),
align(lucide!(TextAlignStart), "Align left", Align::Start),
align(lucide!(TextAlignCenter), "Align centre", Align::Center),
align(lucide!(TextAlignEnd), "Align right", Align::End),
]
.spacing(4)
.align_y(Alignment::Center);
let on: Vec<&str> = [
(self.bold, "bold"),
(self.italic, "italic"),
(self.underline, "underline"),
]
.into_iter()
.filter_map(|(on, name)| on.then_some(name))
.collect();
let status = match on.as_slice() {
[] => String::from("Plain text"),
names => format!("Formatting: {}", names.join(", ")),
};
column![toolbar, text(status).size(14)]
.spacing(12)
.width(Length::Fixed(260.0))
.into()
}
}Usage
Give every icon button a label. The icon alone rarely says enough, and the label shows as a tooltip so people can check what a button does before they press it. iced 0.14 has no screen reader support, so the label cannot reach assistive technology yet.
A pressed icon button is a toggle: the app holds the on or off value and passes it to .pressed, and the button’s message flips it. Use pressed buttons for formatting in a toolbar, or for a group where exactly one option is on, such as text alignment.
Icon buttons share their sizes and colours with Button. There is no Link variant, because a link needs text to read as one; on an icon alone it would look the same as Ghost. The icon-button feature turns on button and tooltip.
A disabled icon button draws its icon at half opacity, like the label of a disabled text button.
Examples
Variants
The same variants as a text button.
use iced::Element;
use iced::widget::row;
use iced_cube::primitives::icon_button::Variant;
use iced_cube::{icon_button, lucide};
#[derive(Debug, Clone)]
pub enum Message {
Pressed(Variant),
}
#[derive(Debug, Default)]
pub struct Example {
last: Option<Variant>,
}
impl Example {
pub fn update(&mut self, message: Message) {
let Message::Pressed(variant) = message;
self.last = Some(variant);
}
pub fn view(&self) -> Element<'_, Message> {
row(Variant::ALL.map(|variant| {
icon_button(lucide!(Heart))
.label(format!("{variant:?}"))
.variant(variant)
.on_press(Message::Pressed(variant))
.into()
}))
.spacing(8)
.into()
}
}Sizes
Small, medium and large squares.
use iced::widget::row;
use iced::{Alignment, Element};
use iced_cube::primitives::button::Size;
use iced_cube::primitives::icon_button::Variant;
use iced_cube::{icon_button, lucide};
#[derive(Debug, Clone)]
pub enum Message {
Pressed,
}
#[derive(Debug, Default)]
pub struct Example;
impl Example {
pub fn update(&mut self, _message: Message) {}
pub fn view(&self) -> Element<'_, Message> {
row([Size::Sm, Size::Md, Size::Lg].map(|size| {
icon_button(lucide!(Settings))
.label(format!("Settings ({size:?})"))
.variant(Variant::Outline)
.size(size)
.on_press(Message::Pressed)
.into()
}))
.spacing(8)
.align_y(Alignment::Center)
.into()
}
}Enabled and disabled
Undo and redo turn off when there is nothing to undo or redo. A disabled icon is drawn at half opacity.
use iced::widget::{row, text};
use iced::{Alignment, Element, Length};
use iced_cube::{button, icon_button, lucide};
#[derive(Debug, Clone)]
pub enum Message {
Edit,
Undo,
Redo,
}
#[derive(Debug)]
pub struct Example {
done: u32,
undone: u32,
}
impl Default for Example {
fn default() -> Self {
Self { done: 2, undone: 0 }
}
}
impl Example {
pub fn update(&mut self, message: Message) {
match message {
Message::Edit => {
self.done += 1;
self.undone = 0;
}
Message::Undo => {
self.done -= 1;
self.undone += 1;
}
Message::Redo => {
self.undone -= 1;
self.done += 1;
}
}
}
pub fn view(&self) -> Element<'_, Message> {
let edits = match self.done {
1 => String::from("1 edit"),
count => format!("{count} edits"),
};
row![
icon_button(lucide!(Undo2))
.label("Undo")
.on_press_maybe((self.done > 0).then_some(Message::Undo)),
icon_button(lucide!(Redo2))
.label("Redo")
.on_press_maybe((self.undone > 0).then_some(Message::Redo)),
button("Make an edit").on_press(Message::Edit),
text(edits).size(14),
]
.spacing(8)
.align_y(Alignment::Center)
.width(Length::Fixed(300.0))
.into()
}
}API
| Item | Description |
|---|---|
icon_button(glyph) | Creates a square ghost button showing a Lucide icon. It renders disabled until it has a message. |
.label(text) | Names the action, such as "Bold". The label shows as a tooltip on hover. |
.tooltip(Option<Position>) | Where the label's tooltip appears, or None to never show it. Defaults to Some(Position::Top). |
.pressed(bool) | Draws the button as switched on, for toolbar toggles. Pass the value your app holds. |
.variant(Variant) | Primary, Secondary, Destructive, Outline or Ghost: the text button variants without Link. Defaults to Ghost. |
.size(Size) | The button Size: Sm is 32 pixels square, Md is 36 and Lg is 40. Defaults to Md. |
.on_press(message) / .on_press_maybe(option) | Sets the message emitted on press. None disables the button. |
.id(id) | Sets a widget id, for clicking the button in tests. |
colours(tokens, variant, pressed, status) / style(...) | The resolved colours and iced style, for reuse in custom widgets. |