pub struct ButtonProps {Show 14 fields
pub class: MaybeProp<String>,
pub appearance: Signal<ButtonAppearance>,
pub shape: Signal<ButtonShape>,
pub size: Signal<ButtonSize>,
pub button_type: MaybeProp<ButtonType>,
pub block: Signal<bool>,
pub icon: MaybeProp<Icon>,
pub disabled: Signal<bool>,
pub disabled_focusable: Signal<bool>,
pub loading: Signal<bool>,
pub aria_pressed: MaybeProp<String>,
pub on_click: Option<Callback<MouseEvent>>,
pub children: Option<Children>,
pub comp_ref: ComponentRef<ButtonRef>,
}Expand description
Props for the Button component.
Runs a single command when activated — form submits, dialog confirmations, toolbar actions, and inline commands.
Pick ButtonAppearance::Primary for the one main action on a surface. Wire async work with loading and on_click. For navigation, use Link instead.
§When to use
- Submitting forms, confirming dialogs, or firing one-off commands - Toolbar and card actions where a single clear primary action is needed - Icon-only affordances when space is tight (pair with
aria-labelon a wrapper)
§Usage
- Pick an
ButtonAppearance—Primaryfor the main action,Secondaryfor alternatives. 2. Wireon_clickwithCallbackwhen the button should run logic (not submit a native form). 3. Setloadingwhile async work runs; disable the control when input is invalid or work is in-flight. 4. For E2E hooks, wrap the button in a native element withdata-testid(see project UI rules).
§Best Practices
§Do’s
- Use
appearance=ButtonAppearance::Primaryfor the main action on a surface * Showloadingduring async handlers so users see in-progress state * Disable while the form is invalid or a request is outstanding * Useiconfor recognizable actions (save, search, add)
§Don’ts
- Do not stack multiple primary buttons in one row * Do not use
data-testidon the component itself — wrap with a native element * Do not use icon-only buttons without an accessible name on the wrapper
§Button family
Orbital ships several command controls. When Button is not the right fit:
- Single command on click —
Button(this component). UseLinkfor navigation. - Primary command plus related alternates —ActionMenuButton(Save + Save as / Export). - Menu of options, no primary segment —MenuButton, orMenufor custom triggers. - Primary label plus supporting line —CompoundButton. - One action pinned to the viewport —FloatingButton. - Primary float plus fan-out secondaries —FloatingActionsMenu. - Merge adjacent buttons visually —ButtonGroup(layout only; style each child explicitly). - Toolbar on/off pressed state —ToggleButton. PreferSwitchfor immediate settings.
§Examples
§Primary button
Default call-to-action on a form or dialog footer.
view! {
<div data-testid="button-preview">
<Button appearance=ButtonAppearance::Primary>
"Save"
</Button>
</div>
}§Secondary outline
Secondary actions beside the primary—cancel, back, or low-commit choices. Outline styling keeps emphasis below Primary without blending into the surface.
view! {
<div data-testid="button-secondary">
<Button appearance=ButtonAppearance::Secondary>
"Cancel"
</Button>
</div>
}§Subtle and transparent
Low-emphasis actions that blend into the surface until hovered.
view! {
<div data-testid="button-subtle">
<Button appearance=ButtonAppearance::Subtle>"More"</Button>
<Button appearance=ButtonAppearance::Transparent>"Dismiss"</Button>
</div>
}§With icon
Leading icon reinforces the action (save, add, search) while the text label keeps meaning clear for sighted users and screen readers.
view! {
<div data-testid="button-icon">
<Button appearance=ButtonAppearance::Primary icon=icondata::AiSaveOutlined>
"Save"
</Button>
</div>
}§Icon-only
Compact affordance when toolbar space is tight. Wrap with aria-label in app code—the button has no visible text for assistive technologies.
view! {
<div data-testid="button-icon-only">
<Button icon=icondata::AiSearchOutlined appearance=ButtonAppearance::Subtle />
</div>
}§Sizes
Small fits toolbars and dense rows; medium is the default; large suits prominent mobile CTAs or hero actions. Set each with size=ButtonSize::….
use crate::{Button, ButtonSize};
view! {
<div data-testid="button-sizes">
<Button size=ButtonSize::Small>"Small"</Button>
<Button size=ButtonSize::Medium>"Medium"</Button>
<Button size=ButtonSize::Large>"Large"</Button>
</div>
}§Block (full width)
Stretches to the full container width—common for mobile form footers, stacked dialog actions, and narrow layouts.
view! {
<div data-testid="button-block">
<Button block=true appearance=ButtonAppearance::Primary>
"Continue"
</Button>
</div>
}§Loading state
Spinner replaces the icon slot and blocks clicks while async work runs. Pair with disabled form controls to prevent double submission.
view! {
<div data-testid="button-loading">
<Button appearance=ButtonAppearance::Primary loading=true>
"Saving…"
</Button>
</div>
}§Click handler
use leptos::prelude::*;
view! {
<Button
appearance=ButtonAppearance::Primary
on_click=|_| {}
>
"Run action"
</Button>
}§Shapes
Rounded is the default for labeled buttons. Circular and square fit icon-only controls in toolbars, floating actions, and compact settings grids.
use crate::{Button, ButtonShape};
view! {
<div data-testid="button-shapes">
<Button shape=ButtonShape::Rounded>"Rounded"</Button>
<Button shape=ButtonShape::Circular icon=icondata::AiPlusOutlined />
<Button shape=ButtonShape::Square icon=icondata::AiSettingOutlined />
</div>
}§Disabled
Unavailable actions stay visibly disabled and ignore clicks. disabled_focusable keeps the button in tab order for tooltips or custom disabled messaging.
view! {
<div data-testid="button-disabled">
<Button appearance=ButtonAppearance::Primary disabled=true>
"Unavailable"
</Button>
<Button appearance=ButtonAppearance::Secondary disabled_focusable=true>
"Focusable when disabled"
</Button>
</div>
}§Theme: primary uses brand token
Wrap in OrbitalThemeProvider with a custom brand palette so primary buttons use the theme’s brand color token.
use leptos::prelude::*;
use orbital_theme::{BrandPalette, OrbitalThemeProvider, Theme, ThemeMode};
view! {
<div data-testid="button-theme-brand">
<OrbitalThemeProvider theme=RwSignal::new(Theme::with_brand(
ThemeMode::Light,
BrandPalette { primary: "#E3008C".to_string() },
))>
<Button appearance=ButtonAppearance::Primary>"Brand action"</Button>
</OrbitalThemeProvider>
</div>
}§Imperative handle
// Focus or programmatically click via ButtonRef after mount.
use crate::{Button, ButtonRef};
use orbital_base_components::ComponentRef;
let btn_ref = ComponentRef::<ButtonRef>::default();
view! {
<Button comp_ref=btn_ref appearance=ButtonAppearance::Primary>"Focus me"</Button>
}§Optional Props
- class:
impl Into<MaybeProp<String>>- Extra CSS class names merged onto the root
<button>element.
- Extra CSS class names merged onto the root
- appearance:
impl Into<Signal<ButtonAppearance>>- Visual emphasis: primary, secondary, subtle, or transparent.
- shape:
impl Into<Signal<ButtonShape>>- Border shape: rounded (default), circular, or square.
- size:
impl Into<Signal<ButtonSize>>- Control size.
- button_type:
impl Into<MaybeProp<ButtonType>>- Native button
typeattribute (submit,reset, orbutton).
- Native button
- block:
impl Into<Signal<bool>>- When true, the button stretches to the full width of its container.
- icon:
impl Into<MaybeProp<IconData>>- Leading icon from the icondata catalog; omit
childrenfor icon-only buttons.
- Leading icon from the icondata catalog; omit
- disabled:
impl Into<Signal<bool>>- When true, the button does not respond to clicks or submit actions.
- disabled_focusable:
impl Into<Signal<bool>>- When true, the button stays focusable while disabled (for tooltips or custom UX).
- loading:
impl Into<Signal<bool>>- When true, shows a spinner and blocks click handling until cleared.
- aria_pressed:
impl Into<MaybeProp<String>>- Optional
aria-pressedfor toggle buttons.
- Optional
- on_click:
Callback<leptos::ev::MouseEvent>- Handler invoked on click when not disabled or loading.
- children:
Children- Button label text; optional when
iconalone is sufficient.
- Button label text; optional when
- comp_ref:
ComponentRef<ButtonRef>- Imperative handle for
focusandclickon the underlying DOM button.
- Imperative handle for
Fields§
§class: MaybeProp<String>Extra CSS class names merged onto the root <button> element.
appearance: Signal<ButtonAppearance>Visual emphasis: primary, secondary, subtle, or transparent.
shape: Signal<ButtonShape>Border shape: rounded (default), circular, or square.
size: Signal<ButtonSize>Control size.
Native button type attribute (submit, reset, or button).
block: Signal<bool>When true, the button stretches to the full width of its container.
icon: MaybeProp<Icon>Leading icon from the icondata catalog; omit children for icon-only buttons.
disabled: Signal<bool>When true, the button does not respond to clicks or submit actions.
disabled_focusable: Signal<bool>When true, the button stays focusable while disabled (for tooltips or custom UX).
loading: Signal<bool>When true, shows a spinner and blocks click handling until cleared.
aria_pressed: MaybeProp<String>Optional aria-pressed for toggle buttons.
on_click: Option<Callback<MouseEvent>>Handler invoked on click when not disabled or loading.
children: Option<Children>Button label text; optional when icon alone is sufficient.
comp_ref: ComponentRef<ButtonRef>Imperative handle for focus and click on the underlying DOM button.
Implementations§
Source§impl ButtonProps
impl ButtonProps
Sourcepub fn builder() -> ButtonPropsBuilder<((), (), (), (), (), (), (), (), (), (), (), (), (), ())>
pub fn builder() -> ButtonPropsBuilder<((), (), (), (), (), (), (), (), (), (), (), (), (), ())>
Create a builder for building ButtonProps.
On the builder, call .class(...)(optional), .appearance(...)(optional), .shape(...)(optional), .size(...)(optional), .button_type(...)(optional), .block(...)(optional), .icon(...)(optional), .disabled(...)(optional), .disabled_focusable(...)(optional), .loading(...)(optional), .aria_pressed(...)(optional), .on_click(...)(optional), .children(...)(optional), .comp_ref(...)(optional) to set the values of the fields.
Finally, call .build() to create the instance of ButtonProps.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for ButtonProps
impl !Sync for ButtonProps
impl !UnwindSafe for ButtonProps
impl Freeze for ButtonProps
impl Send for ButtonProps
impl Unpin for ButtonProps
impl UnsafeUnpin for ButtonProps
Blanket Implementations§
Source§impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
Source§fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
Source§fn adapt_into(self) -> D
fn adapt_into(self) -> D
Source§impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
Source§fn arrays_from(colors: C) -> T
fn arrays_from(colors: C) -> T
Source§impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
Source§fn arrays_into(self) -> C
fn arrays_into(self) -> C
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
Source§type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
parameters when converting.Source§fn cam16_into_unclamped(
self,
parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>,
) -> T
fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T
self into C, using the provided parameters.Source§impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
Source§fn components_from(colors: C) -> T
fn components_from(colors: C) -> T
Source§impl<T> FromAngle<T> for T
impl<T> FromAngle<T> for T
Source§fn from_angle(angle: T) -> T
fn from_angle(angle: T) -> T
angle.Source§impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
Source§fn from_stimulus(other: U) -> T
fn from_stimulus(other: U) -> T
other into Self, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
Source§fn into_angle(self) -> U
fn into_angle(self) -> U
T.Source§impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
Source§type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
parameters when converting.Source§fn into_cam16_unclamped(
self,
parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>,
) -> T
fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T
self into C, using the provided parameters.Source§impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
Source§fn into_color(self) -> U
fn into_color(self) -> U
Source§impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
Source§fn into_color_unclamped(self) -> U
fn into_color_unclamped(self) -> U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoStimulus<T> for T
impl<T> IntoStimulus<T> for T
Source§fn into_stimulus(self) -> T
fn into_stimulus(self) -> T
self into T, while performing the appropriate scaling,
rounding and clamping.Source§impl<T> SerializableKey for T
impl<T> SerializableKey for T
Source§impl<T> StorageAccess<T> for T
impl<T> StorageAccess<T> for T
Source§fn as_borrowed(&self) -> &T
fn as_borrowed(&self) -> &T
Source§fn into_taken(self) -> T
fn into_taken(self) -> T
Source§impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
Source§type Error = <C as TryFromComponents<T>>::Error
type Error = <C as TryFromComponents<T>>::Error
try_into_colors fails to cast.Source§fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
Source§impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
Source§fn try_into_color(self) -> Result<U, OutOfBounds<U>>
fn try_into_color(self) -> Result<U, OutOfBounds<U>>
OutOfBounds error is returned which contains
the unclamped color. Read more