| Crates.io | yew-bs |
| lib.rs | yew-bs |
| version | 0.1.1 |
| created_at | 2025-10-11 23:41:19.215957+00 |
| updated_at | 2025-10-11 23:47:53.175057+00 |
| description | Bootstrap components for Yew - unofficialy impure |
| homepage | |
| repository | https://github.com/cyber-boost/yew-bs |
| max_upload_size | |
| id | 1878661 |
| size | 1,810,688 |
Version: 0.1.0 | Bootstrap 5.3 | Yew 0.21
| # | Section | Anchor |
|---|---|---|
| 1 | Getting Started | getting‑started |
| 2 | Layout & Grid | layout‑grid |
| 3 | Navigation & Breadcrumbs | navigation‑breadcrumbs |
| 4 | Content & Display Components | content‑display |
| 5 | Interaction & Overlays | interaction‑overlays |
| 6 | Utilities (Spacing, Sizing, Visibility, …) | utilities |
| 7 | Accessibility Guidelines | accessibility‑guidelines |
| 8 | Performance & Best Practices | performance‑best‑practices |
| 9 | Running the Example Apps | running‑examples |
| 10 | Full Component Reference | full‑reference |
| 11 | License | license |
| Tool | Minimum Version |
|---|---|
| Rust | 1.73+ (stable) |
| cargo | bundled with Rust |
| Yew-BS | cargo add yew-bs |
| trunk (for running the demo apps) | 0.19+ – cargo install trunk |
cargo add yew-bs
# Cargo.toml
[dependencies]
yew = "0.21"
yew-bs = "0.1.0"
All components are re‑exported from yew_bs::prelude::*, so import once in each file:
use yew::prelude::*;
use yew_bs::prelude::*;
#[function_component(App)]
fn app() -> Html {
html! {
<Container class="my-5">
<Heading level={HeadingLevel::H1}>{"Yew‑Bootstrap Demo"}</Heading>
<Badge variant={Variant::Primary}>{"Primary badge"}</Badge>
</Container>
}
}
#[wasm_bindgen(start)]
pub fn init_web_app() {
// Initialize logging if you want to
wasm_logger::init(wasm_logger::Config::default());
// Initialize Yew-BS (Bootstrap)
yew_bs::init();
// Mount the app
yew::Renderer::<App>::new().render();
}
Compile & serve with trunk:
trunk serve
# open http://localhost:8080
The Yew-Bootstrap library is organized into three main directories that serve different purposes in development and documentation:
docs/ DirectoryContains comprehensive markdown documentation for each component, providing:
Each component has its own .md file (e.g., badge.md, navbar.md, carousel.md) for easy reference and maintenance.
examples/ DirectoryHouses interactive examples demonstrating component usage:
Cargo.toml and Trunk.toml for build configurationindex.html with Bootstrap CSS/JS and the compiled Wasm bundlesrc/lib.rs showing practical implementationcd examples/<component> && trunk servesrc/ DirectoryThe core library implementation:
components/ – Individual Rust modules for each Bootstrap componentassets/ – Bundled Bootstrap 5.3 CSS and JavaScript fileslib.rs – Main library entry point with component exportsinterop.rs – JavaScript interop utilities for interactive componentsBootstrap’s responsive grid is the backbone of any UI. Yew‑Bootstrap offers two parallel approaches:
| Approach | When to use | Key component |
|---|---|---|
Classic (Container / Row / Col) |
Simple tables, forms, or when you need direct control over the column break‑points. | Container, Row, Col |
High‑level (Grid / GridItem) |
Automatic gutter handling, fluid containers, ordering, offsetting, and a cleaner syntax for complex responsive layouts. | Grid, GridItem |
html! {
<Container>
<Row>
<Col xs={12} md={8}>
<div class="p-3 bg-light border">{"Main area"}</div>
</Col>
<Col xs={12} md={4}>
<div class="p-3 bg-light border">{"Sidebar"}</div>
</Col>
</Row>
</Container>
}
| Prop | Type | Default | Description |
|---|---|---|---|
xs, sm, md, lg, xl, xxl |
Option<u8> (1‑12) |
None |
Column width per breakpoint |
class |
Option<AttrValue> |
None |
Extra CSS classes |
node_ref |
NodeRef |
– | Direct DOM reference (rarely needed) |
html! {
<Grid fluid={true} gutter={Some(3)}>
<GridItem size={GridSize::Fixed(4)} order={Some(GridOrder::First)} offset={Some(2)}>
<div class="p-3 bg-primary text-white">{"First (ordered)"}</div>
</GridItem>
<GridItem size={GridSize::Auto}>
<div class="p-3 bg-secondary text-white">{"Auto‑sized column"}</div>
</GridItem>
</Grid>
}
| Prop | Type | Description |
|---|---|---|
fluid |
bool |
Full‑width container |
breakpoint |
Option<Breakpoint> |
Becomes fluid at the given breakpoint |
gutter / gutter_x / gutter_y |
Option<u8> |
Global spacing (0‑5) |
container_class / row_class |
Option<AttrValue> |
Additional classes |
| GridItem props | ||
size |
Option<GridSize> |
Auto or Fixed(1..12) for all break‑points |
xs … xxl |
Option<GridSize> |
Override per breakpoint |
offset |
Option<u8> |
Space left of the column (1‑11) |
order |
Option<GridOrder> |
First, Last, or Number(0..5) |
class |
Option<AttrValue> |
Extra CSS classes |
Grid over Colg-3, gx-2, …).Ratio)Useful for video embeds, cards, or any media that must keep a fixed aspect ratio.
html! {
<Ratio ratio={AspectRatio::Ratio16x9}>
<iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ"
title="Demo video"
allowfullscreen={true} />
</Ratio>
}
| Prop | Type | Description |
|---|---|---|
ratio |
AspectRatio |
One of Ratio1x1, Ratio4x3, Ratio16x9, Ratio21x9 |
class |
Option<AttrValue> |
Extra CSS classes |
children |
Children |
Usually an <img> or <iframe> |
A fully responsive navigation header with optional dark/light theming, background colours, and sticky/fixed positioning.
html! {
<Navbar expand={Some(NavbarExpand::Lg)}
bg={Some(NavbarBg::Primary)}
dark={true}
placement={Some(NavbarPlacement::StickyTop)}>
<Container>
<NavbarBrand href="#">{"MyApp"}</NavbarBrand>
<NavbarToggler target="#mainNav"
expanded={!*collapsed}
onclick={toggle_collapse} />
<NavbarCollapse id="mainNav" show={!*collapsed}>
<NavbarNav>
<NavItem>
<NavLink href="#" active={true}>{"Home"}</NavLink>
</NavItem>
<NavItem>
<NavLink href="#">{"Features"}</NavLink>
</NavItem>
<NavItem>
<NavLink href="#" disabled={true}>{"Disabled"}</NavLink>
</NavItem>
</NavbarNav>
</NavbarCollapse>
</Container>
</Navbar>
}
| Prop | Type | Default | Description |
|---|---|---|---|
expand |
Option<NavbarExpand> |
None (always collapsed) |
Break‑point where the navbar expands horizontally (Sm, Md, Lg, Xl, Xxl) |
bg |
Option<NavbarBg> |
None |
Background colour (Light, Dark, Primary, …) |
light / dark |
bool |
false |
Switch text colour for contrast |
placement |
Option<NavbarPlacement> |
None |
FixedTop, FixedBottom, StickyTop, StickyBottom |
class |
Option<AttrValue> |
None |
Extra classes |
| Component | Core Props | Typical Use |
|---|---|---|
NavbarBrand |
href, onclick, class |
Logo or text that links to home |
NavbarNav |
class |
Wrapper for NavItems |
NavbarToggler |
target, expanded, onclick |
Hamburger button for mobile |
NavbarCollapse |
id, show |
Collapsible menu container |
Nav can be styled as pills, tabs, vertical, filled, or justified.
html! {
<Nav pills={true} fill={Some(NavFill::Fill)} class="mb-3">
<NavItem><NavLink href="#" active={true}>{"Active"}</NavLink></NavItem>
<NavItem><NavLink href="#">{"Link"}</NavLink></NavItem>
<NavItem><NavLink href="#" disabled={true}>{"Disabled"}</NavLink></NavItem>
</Nav>
}
| Prop | Type | Description |
|---|---|---|
pills |
bool |
Pill‑style navigation |
tabs |
bool |
Tab‑style navigation |
fill |
Option<NavFill> |
Fill – equal width, Justified – equal width + justified text |
align |
Option<NavAlign> |
Start, Center, End |
orientation |
Option<NavOrientation> |
Horizontal (default) or Vertical |
Shows the user’s location within a hierarchy.
let crumbs = vec![
BreadcrumbItem { text: "Home".into(), href: Some("/".into()), active: false },
BreadcrumbItem { text: "Library".into(), href: Some("/library".into()), active: false },
BreadcrumbItem { text: "Data".into(), href: None, active: true }
];
html! { <Breadcrumb items={crumbs} /> }
| Prop | Type | Description |
|---|---|---|
items |
Vec<BreadcrumbItem> |
Ordered list of breadcrumb entries |
class |
Option<AttrValue> |
Extra classes |
aria_label |
Option<AttrValue> |
Defaults to "breadcrumb" |
Automatically highlights nav items based on scroll position.
html! {
<Row>
<Col xs={4}>
<ScrollSpyNav variant={Some(ScrollSpyNavVariant::Pills)} class="flex-column">
<ScrollSpyNavItem href="section1">{"Section 1"}</ScrollSpyNavItem>
<ScrollSpyNavItem href="section2">{"Section 2"}</ScrollSpyNavItem>
</ScrollSpyNav>
</Col>
<Col xs={8}>
<ScrollSpyContent>
<ScrollSpySection id="section1"><h4>{"Section 1"}</h4><p>{"Lorem…"}</p></ScrollSpySection>
<ScrollSpySection id="section2"><h4>{"Section 2"}</h4><p>{"Dolor…"}</p></ScrollSpySection>
</ScrollSpyContent>
</Col>
</Row>
}
| Prop (nav) | Type | Description |
|---|---|---|
variant |
Option<ScrollSpyNavVariant> |
Pills, Tabs, or Underline |
class |
Option<AttrValue> |
Extra classes (e.g., position-sticky) |
| Prop (content) | Type | Description |
|---|---|---|
offset |
i32 |
Pixel offset for when a section is considered “active” |
method |
ScrollMethod |
Auto, Offset, Position – how the active element is calculated |
Small status labels, counters, or “new” tags.
html! {
<Badge variant={Variant::Success} pill={true}>{"Success Pill"}</Badge>
<Badge variant={Variant::Danger}>{"Error"}</Badge>
}
| Prop | Type | Default |
|---|---|---|
variant |
Variant |
Primary |
pill |
bool |
false |
class |
Option<AttrValue> |
None |
children |
Children |
– |
Button (not reproduced here) works like Bootstrap’s <button> with colour variant, size size, and optional outline / loading states.
html! {
<ButtonGroup aria_label={"Basic group"}>
<Button variant={Variant::Primary}>{"Left"}</Button>
<Button variant={Variant::Primary}>{"Middle"}</Button>
<Button variant={Variant::Primary}>{"Right"}</Button>
</ButtonGroup>
}
| Prop | Type | Default |
|---|---|---|
vertical |
bool |
false |
size |
Option<ButtonGroupSize> |
None (default) |
aria_label |
Option<AttrValue> |
None |
class |
Option<AttrValue> |
None |
Wraps several ButtonGroups and adds automatic spacing.
html! {
<ButtonToolbar aria_label={"Toolbar"}>
<ButtonGroup><Button variant={Variant::Primary}>{"1"}</Button></ButtonGroup>
<ButtonGroup><Button variant={Variant::Secondary}>{"2"}</Button></ButtonGroup>
</ButtonToolbar>
}
Boostrap‑styled <img> with fluid, thumbnail, rounding, floating, and lazy‑loading support.
html! {
<Image src="https://picsum.photos/500/300"
alt="Random"
fluid={true}
rounded={Some(ImageRounded::Rounded)}
class="my-3" />
}
| Core Props | Type | Description |
|---|---|---|
src |
AttrValue |
URL |
alt |
Option<AttrValue> |
Alt text |
fluid |
bool |
img-fluid – scales with parent |
thumbnail |
bool |
img-thumbnail |
rounded |
Option<ImageRounded> |
Circle, Rounded, etc. |
float_* |
bool |
float-start, float-end, responsive variants (float_sm_start, …) |
loading |
Option<ImageLoading> |
Lazy or Eager |
decoding |
Option<ImageDecoding> |
Auto, Sync, Async |
class |
Option<AttrValue> |
Extra classes |
html! {
<Figure class="my-4">
<Image src="photo.jpg" alt="A photo" fluid={true} />
<Figcaption>{"This is the caption."}</Figcaption>
</Figure>
}
A slideshow with optional indicators, controls, captions, auto‑play, pause‑on‑hover, touch support, and programmatic control.
html! {
<Carousel interval={Some(4000)} ride={true}>
<img src="slide1.jpg" class="d-block w-100" alt="First" />
<img src="slide2.jpg" class="d-block w-100" alt="Second" />
<img src="slide3.jpg" class="d-block w-100" alt="Third" />
</Carousel>
}
| Prop | Type | Default |
|---|---|---|
indicators |
bool |
true |
controls |
bool |
true |
captions |
bool |
false |
ride |
bool |
true (auto‑start) |
pause |
bool |
true (pause on hover) |
wrap |
bool |
true |
touch |
bool |
true |
interval |
Option<u32> |
None (default 5000 ms) |
keyboard |
bool |
true |
active_index |
usize |
0 |
on_slide_change |
Option<Callback<usize>> |
None |
Advanced usage – control via state: update active_index and set ride={false}.
Show/hide content with smooth animation.
html! {
<Button onclick={toggle}>{"Toggle"}</Button>
<Collapse id="demo-collapse" expanded={*is_open}>
<Card><CardBody>{"Hidden content"}</CardBody></Card>
</Collapse>
}
| Prop | Type | Default |
|---|---|---|
id |
AttrValue |
required – used for aria-controls |
expanded |
bool |
false |
class |
Option<AttrValue> |
None |
node_ref |
NodeRef |
– |
Sliding panels that appear from any edge – great for mobile menus, filters, carts, etc.
html! {
<Button onclick={show_offcanvas}>{"Open Sidebar"}</Button>
<Offcanvas show={*open}
placement={OffcanvasPlacement::End}
backdrop={true}
backdrop_close={true}
on_hidden={hide_offcanvas}>
<OffcanvasHeader>
<OffcanvasTitle>{"Menu"}</OffcanvasTitle>
<CloseButton data_bs_dismiss="offcanvas" aria_label="Close" />
</OffcanvasHeader>
<OffcanvasBody>
<Nav>{/* navigation items */}</Nav>
</OffcanvasBody>
</Offcanvas>
}
| Prop | Type | Default |
|---|---|---|
show |
bool |
false |
placement |
OffcanvasPlacement |
End |
backdrop |
bool |
true |
backdrop_close |
bool |
true |
keyboard |
bool |
true |
scroll |
bool |
false |
Event callbacks (on_show, on_shown, on_hide, on_hidden) |
Option<Callback<()>> |
None |
Indicates completion of a task (single bar or stacked bars).
html! {
<Progress value={70} variant={Some(Variant::Success)} animation={Some(ProgressAnimation::Both)} />
}
| Prop | Type | Default |
|---|---|---|
value |
Option<u8> |
None (use child ProgressBars for stacked) |
variant |
Option<Variant> |
None |
animation |
Option<ProgressAnimation> |
None |
striped |
bool |
false |
animated |
bool |
false |
height |
Option<AttrValue> |
None (default 1 rem) |
children |
Children |
– (for stacked bars) |
Stacked example
html! {
<Progress>
<ProgressBar value={30} variant={Some(Variant::Success)} />
<ProgressBar value={20} variant={Some(Variant::Warning)} />
<ProgressBar value={50} variant={Some(Variant::Danger)} />
</Progress>
}
Navigate through large data sets.
html! {
<Pagination active_page={*page}
total_pages={42}
on_page_change={set_page}
size={Some(Size::Large)}
alignment={Some(PaginationAlignment::Center)}
show_first_last={true}
prev_text={"← Prev".into()}
next_text={"Next →".into()} />
}
| Prop | Type | Default |
|---|---|---|
active_page |
usize |
required |
total_pages |
usize |
required |
on_page_change |
Callback<usize> |
required |
size |
Option<Size> |
None |
alignment |
Option<PaginationAlignment> |
None |
max_page_buttons |
usize |
7 |
show_first_last |
bool |
false |
prev_text / next_text / first_text / last_text |
AttrValue |
"Previous", "Next", "First", "Last" |
aria_label |
AttrValue |
"Page navigation" |
Show loading skeletons while data is fetched.
html! {
<PlaceholderWrapper animation={Some(PlaceholderAnimation::Glow)}>
<Placeholder width={"80%".into()} height={"1rem".into()} variant={"primary".into()} />
<Placeholder width={"60%".into()} height={"1rem".into()} variant={"secondary".into()} />
</PlaceholderWrapper>
}
| Core Props | Type | Description |
|---|---|---|
size |
PlaceholderSize |
ExtraSmall, Small, Medium (default), Large, ExtraLarge |
width / height |
Option<AttrValue> |
Custom dimensions ("200px", "75%") |
variant |
Option<AttrValue> |
Background colour (e.g., "primary") |
animation (via PlaceholderWrapper) |
Option<PlaceholderAnimation> |
Glow, Wave, or None |
Pre‑built skeletons
PlaceholderCard – card layout with avatar, title, content, and actions.PlaceholderTable – table skeleton with configurable rows/columns.Lightweight, auto‑dismissable notifications.
html! {
<ToastContainer placement={ToastPlacement::BottomEnd}>
<Toast show={true}
variant={Some(Variant::Success)}
delay={4000}
on_hide={hide_toast}>
<strong class="me-auto">{"Success!"}</strong>
{"Your operation completed."}
</Toast>
</ToastContainer>
}
| Toast Props | Type | Default |
|---|---|---|
show |
bool |
true |
variant |
Option<Variant> |
None |
delay |
u32 (ms) |
5000 (0 = no auto‑hide) |
dismissible |
bool |
true |
on_hide |
Option<Callback<()>> |
None |
class |
Option<AttrValue> |
None |
| ToastContainer Props | Type | Default |
|---|---|---|
placement |
ToastPlacement |
TopEnd |
children |
Children |
– |
class |
Option<AttrValue> |
None |
Rich overlay with optional HTML content, triggered by click, hover, focus or manually.
html! {
<Popover title={"User Info".into()}
content={r#"<div class="text-center"><img src="avatar.jpg" class="rounded-circle mb-2" width="64"/><p>John Doe</p></div>"#.into()}
allow_html={true}
placement={PopoverPlacement::Right}
trigger={PopoverTrigger::Hover}>
<img src="avatar-thumb.jpg" class="rounded-circle" alt="User" />
</Popover>
}
| Prop | Type | Default |
|---|---|---|
title |
Option<AttrValue> |
None |
content |
Option<AttrValue> |
None |
placement |
PopoverPlacement |
Top |
trigger |
PopoverTrigger |
Click |
show |
bool |
false (used only for Manual) |
allow_html |
bool |
false |
animation |
bool |
true |
delay |
Option<u32> |
None |
class |
Option<AttrValue> |
None |
Simple text‑only overlays, typically on hover or focus.
html! {
<Tooltip title={"Save changes"} placement={TooltipPlacement::Top}>
<Button variant={Variant::Success}>{"Save"}</Button>
</Tooltip>
}
| Prop | Type | Default |
|---|---|---|
title |
AttrValue |
required |
placement |
TooltipPlacement |
Top |
trigger |
TooltipTrigger |
Hover |
show |
bool |
false (only for Manual) |
class |
Option<AttrValue> |
None |
Semantic <h1>‑<h6> with optional display size, colour, alignment, and all text utilities.
html! {
<Heading level={HeadingLevel::H2}
display={Some(DisplayHeading::D2)}
color={Some(Variant::Info)}
text_align={Some(TextAlign::Center)}
weight={Some(FontWeight::Bold)}>
{"Big Section Title"}
</Heading>
}
| Prop | Type | Default |
|---|---|---|
level |
HeadingLevel |
required |
display |
Option<DisplayHeading> |
None |
lead |
bool |
false |
color |
Option<Variant> |
None |
text_align |
Option<TextAlign> |
None |
weight |
Option<FontWeight> |
None |
style |
Option<FontStyle> |
None |
transform |
Option<TextTransform> |
None |
decoration |
Option<TextDecoration> |
None |
wrap |
Option<TextWrap> |
None |
truncate |
bool |
false |
break_text |
bool |
false |
Same utilities as Heading but renders a <p>.
html! {
<Paragraph color={Some(Variant::Dark)} weight={Some(FontWeight::Light)} text_align={Some(TextAlign::Justify)}>
{"Long paragraph with justified alignment and light weight."}
</Paragraph>
}
Optional citation footer.
html! {
<Blockquote footer={html!{<>{"— ", <cite>{"Author"}</cite>}</>}>
{"The only limit to our realization of tomorrow is our doubts of today."}
</Blockquote>
}
Wrap any inline element (span, strong, code, …) and apply colour, weight, transform, decoration, wrapping, truncation, etc.
html! {
<p>
{"Press "}<Text element={TextElement::Kbd}>{"Ctrl+S"}</Text>{" to save."}
</p>
}
element |
TextElement |
Rendered HTML tag |
|---|---|---|
Span |
default | <span> |
Strong |
→ <strong> |
|
Em |
→ <em> |
|
Code |
→ <code> |
|
Kbd |
→ <kbd> |
|
Mark |
→ <mark> |
|
Del |
→ <del> |
|
Ins |
→ <ins> |
|
Sub / Sup |
→ <sub> / <sup> |
|
Pre |
→ <pre> |
This section groups components that require user interaction or appear above the main UI.
| Component | Typical Usage | Key Props |
|---|---|---|
| Popover | Contextual rich overlay (profile card, action menu) | title, content, placement, trigger, allow_html |
| Tooltip | Small hint text (form help, icon description) | title, placement, trigger |
| Collapse | Accordion sections, show/hide panels | id, expanded, class |
| Offcanvas | Mobile side‑menu, settings panel, cart drawer | show, placement, backdrop, keyboard |
| Toast | Brief notifications (success, error, info) | show, variant, delay, placement (via container) |
| Spinner | Loading indicator (inline, centered, small) | spinner_type, variant, size, centered |
| ButtonGroup / Toolbar | Grouped actions (text editor toolbar, media controls) | vertical, size |
| Progress | Upload/processing status (single or stacked) | value, variant, animation |
| Carousel | Slideshows, hero banners, product showcases | interval, ride, controls, indicators |
| Pagination | Page navigation for tables/lists | active_page, total_pages, on_page_change |
| Placeholder | Skeleton UI while loading data | size, width, height, variant, animation |
Accessibility Checklist (applies to all interactive components)
FocusRing or native outline).aria-label, aria-labelledby) when icons have no text.Popover, Tooltip, Offcanvas, Toast), manage focus trapping if they become modal‑like (e.g., Offcanvas).Enter, Space, Esc) where appropriate (e.g., PopoverTrigger::Focus, Offcanvas ESC to close).Bootstrap’s utility‑first approach is mirrored in Yew‑Bootstrap with dedicated components that accept enums instead of manual class strings.
html! {
<Spacing margin={Some(MarginSpacing::MY(SpacingSize::Size3))}
padding={Some(PaddingSpacing::PX(SpacingSize::Size2))} />
}
| Enum | Examples |
|---|---|
MarginSpacing::M(size) |
m-3 |
MarginSpacing::MT(size) |
mt-4 |
MarginSpacing::MB(size) |
mb-2 |
MarginSpacing::MS(size) |
ms-1 |
MarginSpacing::ME(size) |
me-5 |
MarginSpacing::MX(size) |
mx-auto |
MarginSpacing::MY(size) |
my-3 |
PaddingSpacing::P(size) |
p-3 |
PaddingSpacing::PT(size) |
pt-4 |
PaddingSpacing::PX(size) |
px-2 |
PaddingSpacing::PY(size) |
py-5 |
SpacingSize values: Size0 (0), Size1 (0.25rem), Size2 (0.5rem), Size3 (1rem), Size4 (1.5rem), Size5 (3rem), Auto (auto).
html! {
<Sizing width={Some(Width::W50)} height={Some(Height::H25)} class="bg-light" />
}
| Prop | Enum | CSS class |
|---|---|---|
width |
Width::W25, W50, W75, W100, Auto |
w-25, w-50, … |
height |
Height::H25, H50, H75, H100, Auto |
h-25, h-50, … |
max_width |
MaxWidth::MW100 |
mw-100 |
max_height |
MaxHeight::MH100 |
mh-100 |
viewport |
ViewportSize::VW100, VH100 |
vw-100, vh-100 |
html! {
<Visibility visibility={Visibility::Invisible}>{"Hidden but takes space"}</Visibility>
}
| Enum | CSS |
|---|---|
Visible |
visibility: visible |
Invisible |
visibility: hidden (space preserved) |
html! {
<VerticalAlign align={VerticalAlign::Middle}>
<i class="bi bi-star"></i>
{"Starred"}
</VerticalAlign>
}
| Enum | CSS class |
|---|---|
Baseline |
align-baseline |
Top |
align-top |
Middle |
align-middle |
Bottom |
align-bottom |
TextTop |
align-text-top |
TextBottom |
align-text-bottom |
html! {
<FocusRing color={Some(FocusRingColor::Success)}>
<button class="btn btn-outline-success">{"Focus me"}</button>
</FocusRing>
}
| Enum | CSS |
|---|---|
Primary |
focus-ring-primary |
Success |
focus-ring-success |
Danger |
focus-ring-danger |
Info |
focus-ring-info |
None (default) |
focus-ring |
html! {
<Clearfix>
<div class="float-start">{"Left"}</div>
<div class="float-end">{"Right"}</div>
</Clearfix>
}
Adds clearfix class (::after { content:""; display:block; clear:both; }).
| Component | Accessibility Concern | Recommended Fix |
|---|---|---|
| Badge | Decorative only – may be ignored by screen readers. | Add aria-label if the badge conveys meaning (e.g., "4 new messages"). |
| Button / ButtonGroup | Must have discernible text or aria-label. |
Use <Button aria_label="Close"> when icon‑only. |
| Navbar / Nav | Proper landmark roles and ARIA current on active items. | role="navigation" added automatically; add aria-current="page" manually if needed. |
| Carousel | Slides should have aria-label/aria-roledescription="carousel" and each slide should be reachable via keyboard. |
Yew‑Bootstrap adds appropriate attributes; you can override with aria-label. |
| Collapse / Accordion | Need aria-controls on toggler and aria-expanded reflecting state. |
Example in Collapse docs. |
| Offcanvas | Should trap focus while open and restore focus on close. | Handled by the component; ensure you don’t nest interactive elements that break focus. |
| Popover / Tooltip | Must be attached via aria-describedby on the trigger; should disappear on Esc. |
The library attaches IDs automatically. |
| Toast | Should have role="alert" and aria-live="assertive" for urgent messages. |
Default implementation includes these. |
| Modal (if you use a separate Modal component) | Needs role="dialog" and aria-modal="true". |
Follow the Modal documentation (not included in this merged file). |
| Placeholder | Content is decorative – hide from screen readers. | aria-hidden="true" applied automatically. |
| Visibility | visibility:hidden still exposed to AT. Use aria-hidden="true" when you truly want it hidden. |
Add attribute manually if needed. |
| FocusRing | Visual focus indicator for custom controls. | Ensure you include tabindex on non‑native focusable elements. |
| Area | Recommendation |
|---|---|
| State Management | Keep component state as small as possible. Use use_state for simple booleans, use_reducer for complex UI (e.g., pagination + filters). |
| Lazy Loading | Use ImageLoading::Lazy for off‑screen images, Placeholder while fetching data, and Carousel with ride={false} for manual control. |
| Avoid Over‑Rendering | When showing/hiding large sections, prefer conditional rendering (if show { … }) rather than merely toggling Visibility unless you need the layout to stay stable. |
| Throttle ScrollSpy / Scroll Events | ScrollSpy uses IntersectionObserver by default (efficient). If you resort to ScrollMethod::Offset, debounce updates. |
| Z‑Index Management | Stick to Bootstrap’s predefined values (z-0 … z-3, z-n1) to avoid unexpected stacking conflicts. |
| Animations | Use CSS‑only animations (animate props) – they are cheap. Avoid heavy JavaScript timers for UI animation unless necessary. |
| Component Size | If you only need a subset of components, enable Cargo features (default-features = false, then features = ["badge","navbar",...]). |
| Responsive Images | Combine fluid with explicit width/height attributes to prevent CLS (Cumulative Layout Shift). |
| Testing for Reduced Motion | Respect prefers-reduced-motion when using animation flags (Glow, Wave). |
| Server‑Side Rendering (SSR) | All components render to static HTML; avoid using browser‑only APIs (e.g., window) during the first render. |
Each component ships with a minimal example under examples/<component_name>. To explore them:
# Clone the repo
git clone https://github.com/cyber-boost/yew-bs.git
cd yew-bs
# Install trunk (if not already)
cargo install trunk
# Run a specific example (e.g., badge)
cd examples/badge
trunk serve
# Open http://localhost:8080 in your browser
Replace badge with any of:
accordion button-group breadcrumb carousel clearfix close-button
col collapse color-background colored-links focus-ring
grid icon-link image nav navbar
offcanvas pagination placeholders popovers position
progress ratio scrollspy sizing spacing
spinners table text toasts tooltips
typography vertical-align visibility z-index
All examples share a common index.html that loads the compiled Wasm bundle; you can edit the source file to experiment.
The tables below summarize the most frequently used props.
For the exhaustive list (including less‑common attributes and callbacks), see each component’s individual markdown file (badge.md,navbar.md, …) located in the repository root.
| Component | Key Props | Variants / Enums |
|---|---|---|
Container |
fluid: bool |
– |
Row |
class, gutter (via Spacing) |
– |
Col |
xs, sm, md, lg, xl, xxl: Option<u8> |
– |
Grid |
fluid, breakpoint, gutter, gutter_x, gutter_y, container_class, row_class |
Breakpoint |
GridItem |
size, xs…xxl, offset, order |
GridSize, GridOrder |
Ratio |
ratio: AspectRatio |
Ratio1x1, Ratio4x3, Ratio16x9, Ratio21x9 |
Position |
position: Position, coordinates: Vec<PositionCoordinate> |
Position, PositionCoordinate |
ZIndex |
z_index: ZIndex |
Z0, Z1, Z2, Z3, ZN1 |
Clearfix |
class |
– |
Sizing |
width, height, max_width, max_height, viewport |
Width, Height, MaxWidth, MaxHeight, ViewportSize |
Spacing |
margin, padding |
MarginSpacing, PaddingSpacing |
VerticalAlign |
align: VerticalAlign |
Baseline, Top, Middle, Bottom, TextTop, TextBottom |
Visibility |
visibility: Visibility |
Visible, Invisible |
FocusRing |
color: Option<FocusRingColor>, tabindex |
Primary, Success, Danger, Info |
| Component | Key Props | Variants / Enums |
|---|---|---|
Navbar |
expand, bg, placement, light, dark |
NavbarExpand, NavbarBg, NavbarPlacement |
NavbarBrand |
href, onclick |
– |
NavbarNav |
class |
– |
NavbarToggler |
target, expanded, onclick |
– |
NavbarCollapse |
id, show |
– |
Nav |
pills, tabs, fill, align, orientation |
NavFill, NavAlign, NavOrientation |
NavItem |
class |
– |
NavLink |
href, active, disabled |
– |
TabTrigger |
active, target, onclick |
– |
TabContent / TabPane |
active, fade, id |
– |
Breadcrumb |
items: Vec<BreadcrumbItem> |
– |
ScrollSpyNav |
variant, class |
ScrollSpyNavVariant |
ScrollSpyNavItem |
href, active, disabled |
– |
ScrollSpyContent / ScrollSpySection |
id |
– |
| Component | Key Props | Variants / Enums |
|---|---|---|
Badge |
variant, pill |
Variant |
ButtonGroup / ButtonToolbar |
vertical, size, aria_label |
ButtonGroupSize |
Image |
src, alt, fluid, thumbnail, rounded, float_*, loading, decoding |
ImageRounded, ImageLoading, ImageDecoding |
Figure / Figcaption |
class |
– |
Progress / ProgressBar |
value, variant, animation, striped, animated, height |
ProgressAnimation |
Pagination |
active_page, total_pages, on_page_change, size, alignment, show_first_last |
PaginationAlignment, Size |
Placeholder / PlaceholderButton / PlaceholderCard / PlaceholderTable |
size, width, height, variant, animation |
PlaceholderSize, PlaceholderAnimation |
Carousel |
indicators, controls, ride, pause, wrap, touch, interval, keyboard, active_index, on_slide_change |
– |
Collapse |
id, expanded |
– |
Offcanvas |
show, placement, backdrop, backdrop_close, keyboard, scroll |
OffcanvasPlacement |
Spinner |
spinner_type, variant, size, centered |
SpinnerType, Size |
Toast / ToastContainer |
show, variant, delay, dismissible, placement (via container) |
ToastPlacement |
Popover |
title, content, placement, trigger, show, allow_html, animation, delay |
PopoverPlacement, PopoverTrigger |
Tooltip |
title, placement, trigger, show |
TooltipPlacement, TooltipTrigger |
Table |
striped, bordered, borderless, hover, size, variant, responsive, responsive_breakpoint, caption |
TableSize, ResponsiveBreakpoint |
Heading |
level, display, lead, color, text_align, weight, style, transform, decoration, wrap, truncate, break_text |
HeadingLevel, DisplayHeading, TextAlign, FontWeight, FontStyle, TextTransform, TextDecoration, TextWrap |
Paragraph |
Same as Heading minus level/display |
– |
Blockquote |
footer |
– |
Text |
element, color, align, weight, style, transform, decoration, wrap, truncate, break_text |
TextElement, TextAlign, FontWeight, FontStyle, TextTransform, TextDecoration, TextWrap |
Typography (collection of Heading, Paragraph, Blockquote, Text) |
– | – |
This project is released under the BBL License. See LICENSE for the full text.
unofficial = not endorsed by yew or bootstrap. impure = just a wrapper around bootstrap 5.
All components are thin wrappers around Bootstrap’s CSS classes backed by the Bootstrap JavaScript plugins where interaction is required (e.g., Carousel, Popover, Tooltip, Offcanvas, Collapse).
The library intentionally mirrors the Bootstrap API so that developers familiar with Bootstrap can transition to Yew with minimal friction, while still enjoying type‑safety and Rust‑centric ergonomics.# yew-bs