๐Ÿ“œ Introduction

Open SASS Kit is a modular toolkit for building fast, modern, and framework-agnostic web applications. Launching a new project or improving an existing one? Open SASS gives you the tools to scale with composable components, powerful CLI tooling, and full freedom from CSS framework lock-in.

๐ŸŽฏ Why Use Open SASS?

  1. ๐ŸŽจ CSS-Framework Agnostic: Works seamlessly with Tailwind, Bootstrap, Bulma, etc, or just plain CSS.
  2. ๐Ÿงฉ Modular Components: Import only what you need. No bloat, just the essentials.
  3. ๐Ÿ” Reusable & Composable: Write once, use everywhere across projects.
  4. โš™๏ธ CLI Tooling: Scaffold projects in seconds with our Open SASS CLI.
  5. ๐ŸŒ WASM-Ready: Built for modern Rust + WebAssembly stacks like Yew, Dioxus, and Leptos.

๐Ÿ“ฆ Installation

Install the CLI globally using Cargo:

cargo install opensass

Then import a new component:

os add accordion-rs yew

๐Ÿ’ก The CLI will automatically generate file structures and integrate styles where needed.

๐Ÿ”Œ Use with Any Stack

Open SASS components are fully decoupled from specific CSS frameworks. Compatible with:

Your stack. Your rules. No dependencies or vendor lock-in.

๐Ÿงช WASM Framework Compatibility

All components are designed to work with popular WebAssembly-based frontend frameworks:

Integration guides available in the components page.

๐Ÿค Contributing

We welcome all contributions! Help us improve Open SASS by submitting:

  1. Bug reports.
  2. Feature suggestions.
  3. Code contributions.

To contribute:

  1. Fork the repo.
  2. Create a new branch (feature/my-awesome-feature).
  3. Submit a pull request.

๐Ÿ“œ License

Open SASS is released under the MIT License. Free for personal and commercial use.

๐Ÿ™Œ Final Thoughts

Open SASS is crafted by developers, for developers, built to be the universal, unopinionated toolkit for modern web projects. From vanilla CSS to the latest WASM frameworks, Open SASS lets you move fast and build confidently.

Stop re-inventing the wheel. Start shipping faster โšก

๐Ÿงฉ Open SASS Components

Open SASS Components are a growing collection of UI elements designed to be modular, framework-agnostic, and ready for any stack. All components are built with flexibility in mind and work with TailwindCSS, Bootstrap, or vanilla CSS.

๐Ÿ“ฆ Component Categories

CategoryComponents
Data DisplayAccordion, Avatar, Badge, Card, Code, Image, Snippet, Table, User
Data EntryCheckbox, Form, Input, Listbox, OTP, Radio, Select, Slider, Switch
Date & TimeCalendar, Date, Time Input
FeedbackAlert, Progress, Skeleton, Spinner, Toast, Tooltip
Landing PageHero
NavigationBreadcrumbs, Browser, Navbar, Pagination, Sidebar, Tabs
OverlaysDrawer, Dropdown, Modal, Popover
StructureDivider, Spacer
UtilitiesAutocomplete, Kbd, OTP
LocalizationI18n
SystemELD, Theme
TypographyKbd, Link

๐Ÿš€ Getting Started

To use a component, simply import it via the CLI:

os add component-name framework-name

๐Ÿ’ก Example: Accordion Component (Yew / Rust)

โœ… Works with Any CSS Framework

๐ŸŒ€ TailwindCSS

<Accordion
    size={Size::Medium}
    expanded={html! { <h3>{ "Section Expanded" }</h3> }}
    collapsed={html! { <h3>{ "Section Collapsed" }</h3> }}
    class="bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-700 rounded-md shadow"
    expanded_class="bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200"
    collapsed_class="bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-300"
    content_class="p-4"
    style=""
    expanded_style=""
    collapsed_style=""
    content_style=""
    will_open={on_will_open.clone()}
    did_open={on_did_open.clone()}
    will_close={on_will_close.clone()}
    did_close={on_did_close.clone()}
>
    <List>
        <Item align={Align::Left}>{ "Item 1 - Left" }</Item>
        <Item align={Align::Right}>{ "Item 2 - Right" }</Item>
    </List>
</Accordion>

๐ŸŽฉ Bootstrap

<Accordion
    size={Size::Medium}
    expanded={html! { <h3 class="accordion-header">{ "Section Expanded" }</h3> }}
    collapsed={html! { <h3 class="accordion-header collapsed">{ "Section Collapsed" }</h3> }}
    class="accordion border border-secondary rounded"
    expanded_class="accordion-body bg-light text-dark"
    collapsed_class="accordion-body bg-white text-secondary"
    content_class="accordion-collapse"
    style=""
    expanded_style=""
    collapsed_style=""
    content_style="padding: 1rem;"
    will_open={on_will_open.clone()}
    did_open={on_did_open.clone()}
    will_close={on_will_close.clone()}
    did_close={on_did_close.clone()}
>
    <List>
        <Item align={Align::Left}>{ "Item 1 - Left" }</Item>
        <Item align={Align::Right}>{ "Item 2 - Right" }</Item>
    </List>
</Accordion>

๐Ÿงฑ Vanilla CSS

<Accordion
    size={Size::Medium}
    expanded={html! { <h3 class="os-accordion-title">{ "Section Expanded" }</h3> }}
    collapsed={html! { <h3 class="os-accordion-title os-collapsed">{ "Section Collapsed" }</h3> }}
    class="os-accordion-container"
    expanded_class="os-expanded"
    collapsed_class="os-collapsed"
    content_class="os-content"
    style="border: 1px solid #ccc; border-radius: 6px;"
    expanded_style="background: #f0f8ff; color: #003366;"
    collapsed_style="background: #fafafa; color: #666;"
    content_style="padding: 1rem;"
    will_open={on_will_open.clone()}
    did_open={on_did_open.clone()}
    will_close={on_will_close.clone()}
    did_close={on_did_close.clone()}
>
    <List>
        <Item align={Align::Left}>{ "Item 1 - Left" }</Item>
        <Item align={Align::Right}>{ "Item 2 - Right" }</Item>
    </List>
</Accordion>

๐Ÿงฐ Component Features

  • Accessible markup (ARIA support where applicable).
  • Mobile-friendly by default.
  • Supports theming via CSS custom properties.
  • Light/Dark mode compatible.
  • Lightweight, no runtime dependencies.
  • Multi-language support (i18n-ready components).
  • Theme Switcher.

๐Ÿ™‹ Need Help?

Join our developer community, open issues, or request a new component:

๐Ÿ”ง Open SASS Components: Made to fit your stack, not the other way around.

Accordion RS

Edit Component

Y Accordion RS Yew Usage

Adding Accordion RS to your project is simple:

  1. Make sure your project is set up with Yew. Refer to their Getting Started Guide for setup instructions.

  2. Add the Accordion component to your dependencies by including it in your Cargo.toml file.

    cargo add accordion-rs --features=yew
    
  3. Import the Accordion component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Incorporating Yew Accordion into your application is easy. Follow these steps:

  1. Import the Accordion component into your Yew project:

    use yew::prelude::*;
    use accordion_rs::yew::Accordion;
  2. Define the accordion sections and use the Accordion component in your Yew component:

    use accordion_rs::yew::{Accordion, Item, List};
    use accordion_rs::{Size, Align};
    use yew::prelude::*;
    
    #[function_component(App)]
    pub fn app() -> Html {
        let on_will_open = Callback::from(|_| log::info!("Accordion will open!"));
        let on_did_open = Callback::from(|_| log::info!("Accordion did open!"));
        let on_will_close = Callback::from(|_| log::info!("Accordion will close!"));
        let on_did_close = Callback::from(|_| log::info!("Accordion did close!"));
        html! {
            <Accordion
                size={Size::XLarge}
                expanded={html! { <h3>{ "Accordion Expanded" }</h3> }}
                collapsed={html! { <h3>{ "Accordion Collapsed" }</h3> }}
                class="bg-gray-900 text-gray-300 border border-gray-700 p-4 rounded-lg"
                expanded_class="text-white bg-gray-800"
                collapsed_class="text-gray-400 bg-gray-800"
                did_open={on_did_open.clone()}
                will_open={on_will_open.clone()}
                did_close={on_did_close.clone()}
                will_close={on_will_close.clone()}
            >
                <List>
                    <Item align={Align::Left}>{ "Item 1 - Left" }</Item>
                    <Item align={Align::Right}>{ "Item 2 - Right" }</Item>
                </List>
            </Accordion>
        }
    }

๐Ÿ”ง Props

Main Props

PropertyTypeDescriptionDefault
expandUseStateHandle<bool>State handle managing whether the accordion is initially expanded or collapsed.false
expandedHtmlContent to display when the accordion is expanded.""
collapsedHtmlContent to display when the accordion is collapsed.""
childrenHtmlChild elements displayed within the accordion container.""
sizeSizeSize of the accordion ("small", "medium", "large", etc.).Size::XXLarge
durationu64Animation duration for expand/collapse transitions, in milliseconds.600

Styling Props

+-----------------------------------------------------------+
|                  [Accordion Container]                    |  <-- `class` & `style`
|                                                           |
|   +-----------------------------------------------+       |  <-- `collapsed_class` & `collapsed_style`
|   |             [Collapsed Content]               |       |  <-- `collapsed`
|   +-----------------------------------------------+       |
|                                                           |
|   +-----------------------------------------------+       |  <-- `expanded_class` & `expanded_style`
|   |             [Expanded Content]                |       |  <-- `expanded`
|   +-----------------------------------------------+       |
|                                                           |
|   +-----------------------------------------------+       |  <-- `content_class` & `content_style`
|   |              [Accordion Content]              |       |  <-- `children`
|   +-----------------------------------------------+       |
|                                                           |
+-----------------------------------------------------------+
PropertyTypeDescriptionDefault
class&'static strCSS class for the accordion container.""
expanded_class&'static strCSS class for the expanded content.""
collapsed_class&'static strCSS class for the collapsed content.""
content_class&'static strCSS class for the content section.""
style&'static strCustom inline styles for the accordion container.""
expanded_style&'static strCustom inline styles for the expanded element.""
collapsed_style&'static strCustom inline styles for the collapsed element.""
content_style&'static strCustom inline styles for the accordion content.""

Callback Props

PropertyTypeDescriptionDefault
will_openCallback<()>Callback triggered before the accordion opens.No-op
did_openCallback<()>Callback triggered after the accordion opens.No-op
will_closeCallback<()>Callback triggered before the accordion closes.No-op
did_closeCallback<()>Callback triggered after the accordion closes.No-op

A11Y Props

PropertyTypeDescriptionDefault
aria_controls&'static strARIA controls attribute for accessibility.""
aria_enabledboolWhether ARIA attributes are enabled for screen reader accessibility.true

๐Ÿ’ก Notes

  • Use the expand prop to control the open/close state of the accordion programmatically.
  • The size prop can be customized to adjust the width of the accordion.
  • Callback props like will_open and did_close provide hooks to perform actions during the accordion's lifecycle.
  • Custom classes and styles allow for extensive customization of the accordion's appearance and behavior.
  • ARIA attributes can be enabled/disabled using the aria_enabled prop for better screen reader compatibility.

Usage

CLI Usage

You can import Accordion RS directly into your project to customize and modify it using the opensass cli:

os add accordion-rs yew

Image RS

Edit Component

Y Image RS Yew Usage

Adding Image RS to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Image RS component to your dependencies by including it in your Cargo.toml file:

    cargo add image-rs --features=yew
    
  3. Import the Image component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Incorporating Image RS into your Yew application is easy. Follow these steps:

  1. Import the Image component into your Yew project:

    use yew::prelude::*;
    use image_rs::yew::Image;
    use image_rs::Layout;
  2. Use the Image component within your Yew application:

    use yew::prelude::*;
    use image_rs::yew::Image;
    use image_rs::Layout;
    
    #[function_component(App)]
    pub fn app() -> Html {
        html! {
            <Image
                src="/images/photo.jpg"
                alt="A beautiful view"
                width="800"
                height="600"
                layout={Layout::Responsive}
            />
        }
    }

๐Ÿ”ง Props

๐Ÿ–ผ๏ธ Main Props

PropertyTypeDescriptionDefault
src&'static strThe image source URL.""
alt&'static strAlt text for accessibility."Image"
fallback_src&'static strImage shown if the primary source fails.""
width&'static strWidth in pixels.""
height&'static strHeight in pixels.""
layoutLayoutLayout type: Responsive, Fixed, etc.Responsive
placeholder&'static strPlaceholder image while loading."empty"
loadingLoadingLazy or Eager loading strategy.Lazy
prioritybool(Deprecated) Use loading = Eager instead.false

๐ŸŽจ Styling Props

+-----------------------------------------------------------+
|                  [Image Container]                        |  <-- `class` & `style`
|                                                           |
|   +-----------------------------------------------+       |  <-- `layout`
|   |              [Loaded Image]                   |       |  <-- `src`
|   +-----------------------------------------------+       |
|                                                           |
+-----------------------------------------------------------+
PropertyTypeDescriptionDefault
style&'static strInline CSS styles.""
class&'static strCSS class name(s).""
object_fitObjectFitHow the image fits: Contain, Cover, Fill, etc.Contain
object_positionPositionImage position inside container (e.g., TopRight).Center
sizes&'static strDefines image sizes for responsive rendering.""
quality&'static strImage quality hint ("low", "high").""
blur_data_url&'static strLow-quality blur-up image while loading.""

โš™๏ธ Behavioral Props

PropertyTypeDescriptionDefault
on_loadCallback<()>Triggered when image finishes loading.No-op
on_errorCallback<String>Triggered if the image fails to load.No-op
decodingDecodingControls image decode strategy: Auto, Sync, AsyncAuto

๐ŸŒ Network & Source Props

PropertyTypeDescriptionDefault
srcset&'static strComma-separated list of responsive image sources.""
crossoriginCrossOriginCORS policy (Anonymous, UseCredentials).CrossOrigin::None
referrerpolicyReferrerPolicyReferrer policy for requests.NoReferrer
usemap&'static strAssociates the image with a <map> by ID.""
ismapboolEnables server-side image maps (inside <a href>).false

โšก Performance Props

PropertyTypeDescriptionDefault
fetchpriorityFetchPriorityNetwork priority (High, Low, Auto).Auto
elementtiming&'static strMarks image with ID for PerformanceElementTiming.""
attributionsrc&'static strURL for Attribution Reporting (experimental).""
lazy_boundary&'static strDistance from viewport to trigger lazy load (e.g. 200px)."100px"
unoptimizedboolDisables built-in image optimization.false

๐Ÿง  Accessibility Props (ARIA)

PropertyTypeDescriptionDefault
aria_current&'static strIndicates the current step/page ("page", "step", etc).""
aria_describedby&'static strID of an element describing the image.""
aria_expanded&'static str"true" or "false" for expanded/collapsed state.""
aria_hidden&'static strHides image from assistive tech ("true" or "false")."false"
aria_liveAriaLiveDynamic update priority (Off, Polite, Assertive).Off
aria_pressedAriaPressedIndicates toggle state (True, False, Mixed, or Undefined).False
aria_controls&'static strID of the element that the image controls.""
aria_labelledby&'static strID of the label element for the image.""

๐Ÿงฑ Utility

PropertyTypeDescriptionDefault
node_refNodeRefReference to the DOM image element for JS interop or tracking.Default

๐Ÿ’ก Notes

  • The src and alt attributes are required for basic functionality.
  • The width and height are essential for Responsive, Intrinsic, and Fixed layouts.
  • Use the placeholder and blur_data_url properties for a smoother loading experience.
  • Customize the appearance and behavior using class, style, and other props like layout and object_fit.
  • Callbacks like on_load and on_error allow you to handle the image loading process effectively.
  • The Layout::Fill value ignores the width and height props and stretches to fill the container.
  • Accessibility attributes like aria-label and aria-hidden can be used directly on the image element.
  • Priority images (priority = true) are loaded eagerly rather than lazily.
  • If both src and fallback_src fail, the on_error callback is triggered with an error message.
  • blur_data_url is used for rendering a low-quality blurred image while the full image loads.
  • IntersectionObserver: This is used for intelligent lazy loading of images as they enter the viewport.
  • Async/Await: Fetch operations use non-blocking async/await for smoother fallback handling.

๐Ÿ“ˆ Benchmark

  1. Open browser DevTools (Press F12) > Lighthouse tab.
  2. Record page load by clicking "Analyze Page Load".
  3. Observe:
    • First Contentful Paint (FCP)
    • Largest Contentful Paint (LCP)
    • Time to Interactive (TTI)
    • Total network transfer size
    • Memory usage

๐Ÿš€ Summary

FeatureYew Image RSNext.js Image
Native Rust+Wasmโœ…โŒ
Built-in Image Optimizationโœ…โœ…
SSR/SEO Friendlyโœ…โœ…
Fine-grained DOM Controlโœ…โŒ
Smaller JS Payloadโœ…โœ…

๐Ÿ“Š Performance Results

When loading 10 images, Yew Image RS and Next.js Image are on par:

MetricYew (Wasm)Next.js
Performance Score (Lighthouse)100100
Memory Usage (Heap)~8 MB~8 MB

However, when scaling up to 10,000 images loaded simultaneously:

MetricYew (Wasm)Next.js
Performance Score (Lighthouse)64โŒ (Lighthouse fails)
Memory Usage (Heap)~78 MB~83 MB
Scrolling SmoothnessVery SmoothLaggy

Key observations:

  • Wasm (Yew) handles large DOM updates much better than JavaScript.
  • Memory usage is slightly lower with Wasm.
  • Next.js site failed Lighthouse audit at 10,000 images (due to TTI timeout).
  • Smoothness is significantly better with Yew under heavy load.

๐Ÿ› ๏ธ Future Improvements

  • Image RS is working on automatic image optimization.
  • Progressive loading and lazy hydration strategies are being researched for even better large-scale performance.

Usage

CLI Usage

You can import Image RS directly into your project to customize and modify it using the opensass cli:

os add image-rs yew

Table RS

Edit Component

๐Ÿ“Š Table RS Yew Usage

Adding Table RS to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Table RS component to your dependencies by including it in your Cargo.toml file:

    cargo add table-rs --features=yew
    
  3. Import the Table component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Incorporating Table RS into your Yew application is easy. Follow these steps:

  1. Import the Table component into your Yew project:

    use yew::prelude::*;
    use table_rs::yew::table::Table;
    use table_rs::yew::types::Column;
    use maplit::hashmap;
  2. Use the Table component within your Yew application:

    use yew::prelude::*;
    use table_rs::yew::table::Table;
    use table_rs::yew::types::Column;
    use maplit::hashmap;
    
    
    #[function_component(App)]
    pub fn app() -> Html {
        let data = vec![
            hashmap! { "name" => "Ferris".to_string(), "email" => "ferris@opensass.org".to_string() },
            hashmap! { "name" => "Ferros".to_string(), "email" => "ferros@opensass.org".to_string() },
            hashmap! { "name" => "Crab".to_string(), "email" => "crab@opensass.org".to_string() },
        ];
    
        let columns = vec![
            Column {
                id: "name",
                header: "Name",
                sortable: true,
                ..Default::default()
            },
            Column {
                id: "email",
                header: "Email",
                sortable: false,
                ..Default::default()
            },
        ];
    
        html! {
            <Table data={data} columns={columns} />
        }
    }

๐Ÿ”ง Props

Table Component Props

Main Props

PropertyTypeDescriptionDefault
dataVec<HashMap<&'static str, String>>The row data to be rendered in the table.[]
columnsVec<Column>List of column definitions.[]
page_sizeusizeNumber of rows per page.10
loadingboolWhether to show a loading state.false
paginateboolEnables pagination UI.false
searchboolEnables search input field.false
classesTableClassesCSS class names for customization.See below
stylesHashMap<&'static str, &'static str>Inline styles for different parts of the table.{}
textsTableTextsCustomizable text labels for UI elements.See below

Column Props

PropertyTypeDescriptionDefault
id&'static strKey used to fetch data from row objects.""
header&'static strText shown in the table header.""
accessorCallback<()>Optional callback for custom rendering or cell behavior.Callback::noop()
sortableboolWhether this column can be sorted.false
min_widthu32Minimum width for the column in pixels.100
styleOption<&'static str>Optional inline styles for the column header.Some("padding: 8px; font-weight: 600; text-align: left;")
classOption<&'static str>Optional CSS class for the column header.Some("table-header-cell")

TableClasses (Class Name Overrides)

PropertyTypeDescriptionDefault
container&'static strWrapper container for the whole table."table-container"
table&'static strThe <table> element."table"
thead&'static strThe <thead> element."thead"
tbody&'static strThe <tbody> element."tbody"
pagination&'static strPagination controls wrapper."pagination-controls"
search_input&'static strClass for the search input element."search-input"
header_cell&'static strClass for table header cells (<th>)."th"
body_cell&'static strClass for table body cells (<td>)."td"
row&'static strClass for rows (<tr>)."tr"
loading_row&'static strRow shown during loading state."loading-row"
empty_row&'static strRow shown when there's no data."empty-row"
pagination_button&'static strClass for pagination buttons."pagination-button"

TableTexts (UI Labels)

PropertyTypeDescriptionDefault
loading&'static strText shown during loading state."Loading..."
empty&'static strText shown when no data matches the filter."No results found"
search_placeholder&'static strPlaceholder text for search input."Search..."
previous_button&'static strLabel for the previous page button."Previous"
next_button&'static strLabel for the next page button."Next"
page_indicator&'static strFormat string for pagination text."Page {current} of {total}"

๐Ÿงฑ Style/Layout Structure

+-------------------------------------------------------------+
|                      [container]                            |  <-- class: "table-container"
|                                                             |
|   +-----------------------------------------------------+   |
|   |                    [search_input]                   |   |  <-- class: "search-input"
|   |          (optional search <input> element)          |   |
|   +-----------------------------------------------------+   |
|                                                             |
|   +-----------------------------------------------------+   |
|   |                       [table]                       |   |  <-- class: "table"
|   |   +--------------------[thead]--------------------+ |   |  <-- class: "thead"
|   |   |   Column Headers (e.g., Name, Email)          | |   |
|   |   +-----------------------------------------------+ |   |
|   |   +--------------------[tbody]--------------------+ |   |  <-- class: "tbody"
|   |   |  Data rows (from `data` prop, each row = <tr>)| |   |
|   |   +-----------------------------------------------+ |   |
|   +-----------------------------------------------------+   |
|                                                             |
|   +-----------------------------------------------------+   |
|   |                  [pagination]                       |   |  <-- class: "pagination-controls"
|   |   Page selector / next-prev buttons (if enabled)    |   |
|   +-----------------------------------------------------+   |
+-------------------------------------------------------------+

๐Ÿ’ก Notes

  • The data must match the id values defined in each Column.
  • The search prop enables input-based filtering across all columns.
  • Pagination is controlled using the page_size and paginate props.
  • Sorting is column-specific via sortable = true and on_sort_column.
  • All style classes can be customized via TableClasses.
  • All texts are configurable via TableTexts.
  • The component handles loading and empty states out-of-the-box.
  • You can inject additional per-column styling via Column.style and Column.class.

๐Ÿ“Š Benchmark: TanStack Table vs Table RS

MetricTanStack Table (React)Table RS (Yew + WASM)
Page Load Time (1M rows)~10 seconds~2 seconds
Memory Heap Usage>3 GB (heap overflow)~1.1 GB (stable)
Initial RenderingHeavy blocking, slow DOM paintEfficient, lightweight rendering
Browser ResponsivenessDelayed interactivitySmooth after hydration
Sorting Performance2-4s for large columnsSub-1s due to WASM speed
Search PerformanceAcceptable, but slowerInstantaneous, even at scale
Lighthouse Performance Score49/10060/100
ScalabilityLimited due to memory and VDOMNear-native scalability

๐ŸŸจ TanStack Table (React)

  • Uses Virtual DOM and JS heap to manage massive data.
  • Runtime bottlenecks emerge with >100k rows.
  • Memory allocation during sorting and filtering can spike to 3GB+, often leading to heap overflow during intensive usage.
  • Lighthouse audit shows poor TTI and CPU blocking.

๐ŸŸฉ Table RS (Yew + WASM)

  • WASM-compiled logic is highly memory-efficient and deterministic.
  • DOM rendering is direct, bypassing React's reconciliation.
  • ~1.1 GB of memory heap used even with 1 million rows.
  • Built-in support for search/sort with stable paging.
  • No hydration issues (client-only generation).
  • Lighthouse performance significantly better, especially in CPU/Memory metrics.

For large-data UI benchmarks like tables with millions of rows, table-rs in Yew/WASM is a superior choice compared to React + TanStack.

Usage

CLI Usage

You can import Table RS directly into your project to customize and modify it using the opensass cli:

os add table-rs yew

Input RS

Edit Component

Y Input RS Yew Usage

Adding Input RS to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Input RS component to your dependencies by including it in your Cargo.toml file:

    cargo add input-rs --features=yew
    
  3. Import the Input component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Incorporating Yew Input RS into your application is easy. Follow these steps:

  1. Import the Input component into your Yew project:

    use yew::prelude::*;
    use input_rs::yew::Input;
    use regex::Regex;
  2. Use the Input component within your Yew application:

    use yew::prelude::*;
    use regex::Regex;
    use input_rs::yew::Input;
    
    fn validate_email(email: String) -> bool {
        let pattern = Regex::new(r"^[^ ]+@[^ ]+\.[a-z]{2,3}$").unwrap();
        pattern.is_match(&email)
    }
    
    #[function_component(App)]
    pub fn app() -> Html {
        let input_email_ref = use_node_ref();
        let input_email_handle = use_state(String::default);
        let email_valid_handle = use_state(|| true);
    
        html! {
            <form>
                <Input
                    r#type="email"
                    name="email"
                    r#ref={input_email_ref}
                    handle={input_email_handle}
                    valid_handle={email_valid_handle}
                    validate_function={validate_email}
                    placeholder="Enter your email"
                    label="Email Address"
                    required={true}
                    error_message="Please provide a valid email address"
                    class="form-field"
                    label_class="form-label"
                    input_class="form-input"
                    error_class="error-text"
                />
            </form>
        }
    }

๐Ÿ”ง Props

Main Props

PropertyTypeDescriptionDefault
type&'static strInput type, e.g., "text", "email", "password", "textarea"."text"
name&'static strName attribute for the input element.""
label&'static strText label displayed above the input.""
placeholder&'static strPlaceholder text inside the input field.""
id&'static strID attribute for the input element.""
requiredboolIndicates whether the field is required.false
handleUseStateHandle<String>State handle for managing the value of the input.None
valid_handleUseStateHandle<bool>State handle for managing the validity of the input value.None
validate_functionCallback<String, bool>Validation function that checks the input value and returns a boolean.None
error_message&'static strMessage displayed when the input value is invalid.""

Styling Props

+-----------------------------+  <-- `class`
|                             |
|  +-----------------------+  |  <-- `label_class`
|  |       Label           |  |
|  +-----------------------+  |
|                             |
|  +-----------------------+  |  <-- `field_class`
|  | +-------+  +--------+ |  |
|  | | Input |  |  Icon  | |  |  <-- `input_class` and `icon_class`
|  | +-------+  +--------+ |  |
|  +-----------------------+  |
|                             |
|  +-----------------------+  |  <-- `error_class` (if invalid)
|  |       Error Message   |  |
|  +-----------------------+  |
+-----------------------------+
PropertyTypeDescriptionDefault
class&'static strCSS class applied to the wrapper container.""
label_class&'static strCSS class applied to the label element.""
input_class&'static strCSS class applied to the input element.""
field_class&'static strCSS class applied to the input wrapper element (includes icons, etc.).""
error_class&'static strCSS class applied to the error message container when validation fails.""
icon_class&'static strCSS class applied to the optional icon (if specified).""

Password Icon Props

PropertyTypeDescriptionDefault
eye_active&'static strIcon CSS class for showing the "visible" state in password fields."cursor-pointer right-4 top-1 text-2xl text-gray-600 toggle-button fa fa-eye"
eye_disabled&'static strIcon CSS class for showing the "hidden" state in password fields."cursor-pointer right-4 top-1 text-2xl text-gray-600 toggle-button fa fa-eye-slash"

Accessibility Props

PropertyTypeDescriptionDefault
aria_label&'static strAria-label for the input element for screen reader users.""
aria_required&'static strSpecifies whether the input is required for screen readers."true"
aria_invalid&'static strIndicates whether the input value is invalid for screen readers."false"
aria_describedby&'static strID of the element that describes the input (e.g., error message container).""

๐Ÿ’ก Notes

  • The Input component can be used for various input types like text, password, etc.
  • You can bind the component to state hooks for two-way data binding.
  • Utilize validate_function to validate user input and display error messages.
  • The eye_active and eye_disabled props allow for password visibility toggling with FontAwesome icons.
  • Customize the appearance with CSS classes for better integration into your app's design.

Usage

CLI Usage

You can import Input RS directly into your project to customize and modify it using the opensass cli:

os add input-rs yew

Radio RS

Edit Component

Y Radio RS Yew Usage

Adding Radio RS to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Radio RS component to your dependencies by including it in your Cargo.toml file:

    cargo add radiors --features=yew
    
  3. Import the Radio component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Incorporating Yew Radio RS into your application is easy. Follow these steps:

  1. Import the Group and the Radio components into your Yew project:

    use yew::prelude::*;
    use radiors::yew::{Radio, Group};
  2. Use the Radio component within your Yew application:

    use radiors::yew::{Radio, Group};
    use radiors::{Size, Type, Orientation};
    use yew::prelude::*;
    
    #[function_component(App)]
    pub fn app() -> Html {
        let selected_value = use_state(|| "Option1".to_string());
        let onchange = {
            let selected_value = selected_value.clone();
            Callback::from(move |new_value: String| {
                selected_value.set(new_value);
            })
        };
    
        html! {
            <Group
                selected={(*selected_value).clone()}
                onchange={onchange}
                orientation={Orientation::Vertical}
                class="radio-group"
            >
                <Radio
                    label="Option 1"
                    value="Option1"
                    class="radio-button"
                />
                <Radio
                    label="Option 2"
                    value="Option2"
                    class="radio-button"
                />
            </Group>
        }
    }

๐Ÿ”ง Props

Group Component Props

Main Props

PropertyTypeDescriptionDefault
selectedStringThe currently selected value of the radio group.""
childrenChildrenWithProps<Radio>Child Radio components to render within the group.""

Styling Props

+-----------------------------------------------------------+
|                  [Group Container]                        |  <-- `class` & `style`
|                                                           |
|   +-----------------------------------------------+       |  <-- `orientation`
|   |              [Child Radio Buttons]            |       |  <-- `children`
|   +-----------------------------------------------+       |
|                                                           |
+-----------------------------------------------------------+
PropertyTypeDescriptionDefault
style&'static strInline styles for the radio group container.""
class&'static strCSS class for the radio group container.""
orientationOrientationOrientation of the radio group (Horizontal or Vertical).Orientation::Horizontal

Behavioral Props

PropertyTypeDescriptionDefault
onchangeCallback<String>Callback triggered when the selected value changes.No-op

Radio Component Props

Main Props

PropertyTypeDescriptionDefault
label&'static strText label displayed alongside the radio button.""
value&'static strUnique value for the radio button.""
src&'static strOptional image URL to display next to the radio button.""
selectedboolIndicates whether this radio button is selected.false
disabledboolDisables the radio button when true.false

Styling Props

+-----------------------------------------------------------+
|                   [Radio Container]                       |  <-- `class` & `style`
|                                                           |
|   +-------------------------------------------------+     |  <-- `selected_class` & `selected_style` (when selected)
|   |               [Radio Button]                    |     |  <-- `disabled_class` & `disabled_style` (when disabled)
|   |                                                 |     |
|   |   +---------------------------------------+     |     |
|   |   |           [Hidden Input]              |     |     |  <-- `input_class` & `input_style`
|   |   +---------------------------------------+     |     |
|   |                                                 |     |
|   |   +---------------------------------------+     |     |
|   |   |         [Optional Image]              |     |     |  <-- `image_class` & `image_style`
|   |   +---------------------------------------+     |     |
|   |                                                 |     |
|   |   +---------------------------------------+     |     |
|   |   |          [Radio Label]                |     |     |  <-- `label_class` & `label_style`
|   |   +---------------------------------------+     |     |
|   +-------------------------------------------------+     |
|                                                           |
+-----------------------------------------------------------+
PropertyTypeDescriptionDefault
style&'static strCustom inline styles for the radio container.""
class&'static strCSS class for the radio container.""
label_style&'static strInline styles for the radio label.""
label_class&'static strCSS class for the radio label.""
image_style&'static strInline styles for the image (if src is provided).""
image_class&'static strCSS class for the image (if src is provided).""
sizeSizeSize of the radio button (Small, Medium, Large).Size::XSmall
typeTypeStyling type of the radio button (e.g., Primary, Secondary).Type::None
selected_style&'static strInline styles for the selected state of the radio button.""
selected_class&'static strCSS class for the selected state of the radio button.""
disabled_style&'static strInline styles for the disabled state of the radio button.""
disabled_class&'static strCSS class for the disabled state of the radio button.""
animation_style&'static strInline styles for animations applied to the radio button.""
animation_class&'static strCSS class for animations applied to the radio button.""
input_style&'static strInline styles for the hidden <input> element.HIDDEN_INPUT_STYLE
input_class&'static strCSS class for the hidden <input> element.""

Behavioral Props

PropertyTypeDescriptionDefault
onclickCallback<String>Callback triggered when the radio button is clicked.No-op

๐Ÿ’ก Notes

  • Use the Group component to manage state for multiple Radio components easily.
  • Callback props like onchange and onclick allow you to handle user interactions effectively.
  • Make sure the value for each Radio is unique within the Group to avoid conflicts.
  • The orientation prop in the Group component helps align the radio buttons vertically or horizontally.
  • Customize the appearance using the provided class and style props or by applying your own CSS (pure css, tailwind, bootstrap, etc).

Usage

CLI Usage

You can import Radio RS directly into your project to customize and modify it using the opensass cli:

os add radiors yew

Select RS

Edit Component

Y Select RS Yew Usage

Adding Select RS to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the select-rs crate to your dependencies by including it in your Cargo.toml file:

    cargo add selectrs --features=yew
    
  3. Import the Select, Option, and Group components into your Yew component and start using them in your app.

๐Ÿ› ๏ธ Usage

Incorporating Select RS into your application is easy. Follow these steps:

  1. Import the Select, Option, and Group components into your Yew project:

    use yew::prelude::*;
    use selectrs::yew::{Select, Option, Group};
  2. Use the Select component in your Yew application:

    use yew::prelude::*;
    use selectrs::yew::{Select, Option, Group};
    
    #[function_component(App)]
    pub fn app() -> Html {
        let onchange = Callback::from(|selected_values: Vec<String>| {
            log::info!("Selected: {:?}", selected_values);
        });
    
        html! {
            <Select
                class="custom-select"
                style="width: 250px"
                placeholder="Select an option..."
                onchange={onchange}
            >
                <Group>
                    <Option value="Option1" label="Option 1" />
                    <Option value="Option2" label="Option 2" />
                    <Option value="Option3" label="Option 3" />
                </Group>
            </Select>
        }
    }

๐Ÿ”ง Props

Select Component

Main Props

PropertyTypeDescriptionDefault
name&'static strThe name attribute of the select component, important for form submission.""
id&'static strThe unique ID for the select element.""
placeholder&'static strPlaceholder text displayed when no option is selected.""
multipleboolWhether multiple options can be selected.false
requiredboolMarks the field as required for form submission.false
sizeu64Number of visible options in the dropdown (applies only for multiple=true).0
form&'static strAssociates the select element with a specific form by its ID.""
autocomplete&'static strProvides an autocomplete hint.""
autofocusboolAutomatically focuses the select element on page load.false
childrenChildrenWithProps<Group>Child Group components containing options to render within the select box.""

Styling Props

+--------------------------------------------------+
|                  [Select Container]              |  <-- `class` & `style`
|                                                  |
|   +------------------------------------------+   |
|   |             [Selected Labels]            |   |  <-- Rendered only for `multiple=true`
|   |                                          |   |
|   |   +----------------------------------+   |   |
|   |   |         [Label (Chip)]           |   |   |  <-- `label_class` & `label_style`
|   |   |    +--------------------------+  |   |   |
|   |   |    |    Close Button ("x")    |  |   |   |  <-- `close_class` & `close_style`
|   |   |    +--------------------------+  |   |   |
|   |   +----------------------------------+   |   |
|   +------------------------------------------+   |
|                                                  |
|   +------------------------------------------+   |
|   |              [Select Element]            |   |  <-- `<select>` element
|   |                                          |   |
|   |   +----------------------------------+   |   |
|   |   |      [Option (Placeholder)]      |   |   |  <-- Rendered if `placeholder` is set
|   |   +----------------------------------+   |   |
|   |                                          |   |
|   |   +----------------------------------+   |   |
|   |   |        [Options Group]           |   |   |  <-- Rendered dynamically via children
|   |   +----------------------------------+   |   |
|   +------------------------------------------+   |
|                                                  |
+--------------------------------------------------+
PropertyTypeDescriptionDefault
class&'static strCSS class for the outer select container.""
style&'static strInline styles for the outer select container.""
labels_class&'static strCSS class for the label container.""
labels_style&'static strInline styles for the label container.""
label_class&'static strCSS class for individual labels.""
label_style&'static strInline styles for individual labels.""
close_class&'static strCSS class for the close button (multi-select).""
close_style&'static strInline styles for the close button.""
select_class&'static strCSS class for the dropdown select box.""
select_style&'static strInline styles for the dropdown select box.""

Behavioral Props

PropertyTypeDescriptionDefault
onchangeCallback<Vec<String>>Callback triggered when the selected values change.No-op

Group Component

Main Props

PropertyTypeDescriptionDefault
label&'static strText label for the group, useful for describing a set of options.""
groupboolIndicates whether this is a group of options.false
selectedStringThe currently selected option within the group.""
childrenChildrenWithProps<Option>Child Option components to display within this group.""

Styling Props

+--------------------------------------------------+
|               [OptGroup Container]               |  <-- Rendered if `group=true`
|              (`<optgroup>` element)              |
|   +------------------------------------------+   |
|   |         [Group Label/Text Header]        |   |  <-- `label` attribute (not styled)
|   +------------------------------------------+   |
|                                                  |
|   +------------------------------------------+   |
|   |              [Group Options]             |   |  <-- Rendered via child `Option` components
|   |   +----------------------------------+   |   |
|   |   |          [Option Label]          |   |   |
|   |   +----------------------------------+   |   |
|   +------------------------------------------+   |
|                                                  |
+--------------------------------------------------+
PropertyTypeDescriptionDefault
class&'static strCSS class for the group container.""
style&'static strInline styles for the group container.""

Behavioral Props

PropertyTypeDescriptionDefault
onchangeCallback<String>Callback triggered when the selected option changes.No-op

Option Component

Main Props

PropertyTypeDescriptionDefault
value&'static strThe underlying value associated with the option.""
labelChildrenContent displayed for the option, such as text or custom elements.None
selectedboolIndicates if the option is currently selected.false
disabledboolDisables the option, making it unselectable by the user.false

Styling Props

+--------------------------------------+
|         [Option Container]           |  <-- `<option>` element
|                                      |
|   +------------------------------+   |
|   |          [Label]             |   |  <-- Rendered dynamically via `label` prop
|   +------------------------------+   |
|                                      |
|      [Selected State Styling]        |  <-- Applies `selected_class` & `selected_style` if selected
+--------------------------------------+
PropertyTypeDescriptionDefault
class&'static strCSS class for the option container.""
style&'static strInline styles for the option container.""
selected_class&'static strCSS class applied when the option is selected.""
selected_style&'static strInline styles applied when the option is selected.""

Behavioral Props

PropertyTypeDescriptionDefault
on_clickCallback<()>Callback triggered when the option is clicked.No-op

๐Ÿ’ก Notes

  • Use the Group component to organize related Option components within a Select component.
  • The onchange callback is triggered with a list of selected values.
  • If using the multiple prop, the size prop determines the number of visible options in the dropdown.
  • Use class and style props to fully customize the appearance of the Select component, either with your own CSS or css libraries like Tailwind, Bootstrap, etc.

Usage

CLI Usage

You can import Select RS directly into your project to customize and modify it using the opensass cli:

os add select-rs yew

Slider RS

Edit Component

Slider RS Yew Usage

Adding Slider RS to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Slider RS component to your dependencies by including it in your Cargo.toml file:

    cargo add slider-rs --features=yew
    
  3. Import the Slider component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Incorporating Slider RS into your Yew application is easy. Follow these steps:

  1. Import the Slider component into your Yew project:

    use yew::prelude::*;
    use slider_rs::yew::Slider;
  2. Use the Slider component within your Yew application:

    use yew::prelude::*;
    use slider_rs::yew::Slider;
    use slider_rs::Orientation;
    
    #[function_component(App)]
    pub fn app() -> Html {
        let min = use_state(|| 10.0);
        let max = use_state(|| 90.0);
        let value = use_state(|| 50.0);
    
        html! {
            <Slider
                min={*min}
                max={*max}
                step={1.0}
                value={Some(*value)}
                on_change={Callback::from(|val| log::info!("Slider changed to: {}", val))}
                orientation={Orientation::Horizontal}
                show_value=true
                show_steps=true
            />
        }
    }

๐Ÿ”ง Props

Slider Component Props

Main Props

PropertyTypeDescriptionDefault
label&'static strLabel text displayed above the slider.""
minf64The minimum value of the slider.0.0
maxf64The maximum value of the slider.10.0
stepf64The step size between slider values.1.0
valueOption<f64>The current value of the slider (single mode).None
rangeOption<(f64, f64)>The current range values (start, end) in double mode.None
doubleboolEnables double slider mode (range selector).false
disabledboolDisables interaction with the slider if set to true.false

Styling & Layout Props

+---------------------------------------------------------------+
|                     [Slider Container]                        |  <-- `container_class` & `container_style`
|                                                               |
|   +------------------------[Label]------------------------+   |  <-- `label_class` & `label_style`
|   |                                                       |   |
|   +-------------------------------------------------------+   |
|                                                               |
|   +----------------[Icons & Inputs Wrapper]---------------+   |  <-- layout wrapper
|   |  [Icon Start]   [Input Thumb 1]   [Input Thumb 2]     |   |  <-- double thumb if enabled
|   |                                                       |   |
|   +-------------------------------------------------------+   |
|                                                               |
|   +------------------------[Ticks]------------------------+   |  <-- visual tick marks (if enabled)
|                                                               |
|   +------------------------[Output]-----------------------+   |  <-- value display (if `show_value`)
|                                                               |
|   +------------------------[Steps]------------------------+   |  <-- step indicators (if `show_steps`)
+---------------------------------------------------------------+
PropertyTypeDescriptionDefault
orientationOrientationOrientation of the slider: Horizontal or Vertical.Horizontal
sizeSizeSize variant for the slider appearance.Default
colorColorColor theme variant for styling the slider.Default
cursor_styleCursorCursor style when hovering over the slider.Default
container_class&'static strCSS class for the outer container."slider-container"
container_style&'static strInline style for the outer container.flex column center layout
label_class&'static strCSS class for the label element."slider-label"
label_style&'static strInline style for the label element.font-size, margin
input_class&'static strCSS class for the slider input element."slider-input"
input_style&'static strInline style for the slider input element.border-radius, appearance, outline
output_class&'static strCSS class for the output value display."slider-output"
output_style&'static strInline style for the output value display.font-size, margin
tooltip_style&'static strInline style for the tooltip element above the thumb.dark background tooltip styling
steps_style&'static strInline style for the step indicators below the track.flex spaced indicators
slider_widthWidthCustom width for the slider track.Default
slider_heightHeightCustom height for the slider track.Default
custom_thumb_cssOption<&'static str>Custom CSS applied to the slider thumb.None
custom_thumb_htmlOption<Html>Custom HTML content inside the slider thumb.None
icon_startOption<Html>Optional icon displayed before the slider track.None
icon_endOption<Html>Optional icon displayed after the slider track.None

Behavioral Props

PropertyTypeDescriptionDefault
show_valueboolWhether to display the current value below the slider.false
show_stepsboolWhether to display step indicators below the slider.false
show_tooltipboolWhether to show a tooltip on hover above the thumb.false
on_changeCallback<f64>Callback when slider value changes (single mode).No-op
on_change_rangeCallback<(f64, f64)>Callback when range changes (double mode).No-op
on_focusCallback<()>Callback triggered when slider gains focus.No-op
on_blurCallback<()>Callback triggered when slider loses focus.No-op
keyboard_stepf64Increment step for keyboard arrow key adjustments.1.0

Accessibility Props

PropertyTypeDescriptionDefault
aria_labelOption<&'static str>ARIA label for screen readers.None
aria_describedbyOption<&'static str>ARIA describedby attribute for accessibility hints.None

๐Ÿ’ก Notes

  • value is for single sliders; range is for double sliders (set double: true).
  • Props like size, color, cursor_style are used for visual styling presets.
  • The component is accessible with proper ARIA support.
  • Callbacks like on_change, on_input (implicit), and focus events help in state handling.
  • Inline styles and CSS classes allow full custom styling.
  • Tooltips, ticks, steps, and icons are optional add-ons for richer UI.

Usage

CLI Usage

You can import Slider RS directly into your project to customize and modify it using the opensass cli:

os add slider-rs yew

Alert RS

Edit Component

Y Alert RS Yew Usage

Adding Alert RS to your project is simple:

  1. Make sure your project is set up with Yew. Refer to their Getting Started Guide for setup instructions.

  2. Add the Alert component to your dependencies by including it in your Cargo.toml file.

    cargo add alert-rs --features=yew
    
  3. Import the Alert component into your Yew component and start showing alerts in your app.

๐Ÿ› ๏ธ Usage

Incorporating Yew Alert into your application is easy. Follow these steps:

  1. Import the Alert component into your Yew project:

    use yew::prelude::*;
    use alert_rs::yew::Alert;
  2. Define the alert properties and use the Alert component in your Yew component:

    use yew::prelude::*;
    use alert_rs::yew::Alert;
    use alert_rs::{IconType, Position};
    
    
    #[function_component(App)]
    pub fn app() -> Html {
        let show_alert = use_state(|| true);
        html! {
            <Alert
                title={"Alert Title"}
                body={"This is an alert message"}
                show_alert={show_alert}
                timeout={2500}
                icon_class={"flex justify-center"}
                confirm_button_text={"Okay"}
                cancel_button_text={"Cancel"}
                confirm_button_class={"bg-green-500 text-white rounded"}
                cancel_button_class={"bg-red-500 text-white rounded"}
                show_confirm_button={true}
                show_cancel_button={true}
                show_close_button={true}
                on_confirm={Callback::noop()}
                on_cancel={Callback::noop()}
                position={Position::TopRight}
                icon_type={IconType::Success}
                alert_class={"flex items-center text-center justify-center bg-gray-800 text-white border border-gray-600"}
                title_class={"dark:text-white"}
                body_class={"dark:text-gray-300"}
                icon_color={""}
                icon_width={"50"}
            />
        }
    }

๐Ÿ”ง Props

Main Props

PropertyTypeDescriptionDefault
show_alertUseStateHandle<bool>The state handle controlling the visibility of the alert.false
title&'static strThe title text for the alert."Info"
body&'static strThe message content of the alert.""
timeoutu32Timeout duration in milliseconds for the alert to auto-close.2500 ms
show_confirm_buttonboolWhether to display the confirm button.true
show_cancel_buttonboolWhether to display the cancel button.true
show_close_buttonboolWhether to display the close button.false

Callback Props

PropertyTypeDescriptionDefault
on_confirmCallback<()>Callback triggered when the confirm button is clicked.No-op
on_cancelCallback<()>Callback triggered when the cancel button is clicked.No-op
on_closeCallback<()>Callback triggered when the close button is clicked.No-op
will_openCallback<()>Callback triggered before the alert opens.No-op
did_openCallback<()>Callback triggered after the alert opens.No-op
did_closeCallback<()>Callback triggered after the alert closes.No-op

Alert Appearance & Positioning

PropertyTypeDescriptionDefault
nativeboolWhether to use the native browser alert instead of custom one.false
positionPositionPosition of the alert on the screen (Position::TopRight, etc.).TopRight
icon_typeIconTypeThe type of icon to display with the alert (e.g., Info, Warning).IconType::Info
icon_color&'static strThe color of the icon.""
icon_width&'static strThe width of the icon."50"

Styling Props

+-----------------------------------------------------------+  <-- `alert_class`
|                                                           |
|  +-----------------------------------------------+        |  <-- `close_button_style` (if `show_close_button`)
|  |               [X] Close Button                |        |
|  +-----------------------------------------------+        |
|                                                           |
|  +-----------------------------------------------+        |  <-- `icon_class` and `icon_style`
|  |                  [Icon]                       |        |  <-- `icon_tag`
|  +-----------------------------------------------+        |
|                                                           |
|  +-----------------------------------------------+        |  <-- `title_class` and `title_style`
|  |                [Alert Title]                  |        |  <-- `props.title`
|  +-----------------------------------------------+        |
|                                                           |
|  +-----------------------------------------------+        |  <-- `separator_style`
|  |             [--- Separator ---]               |        |
|  +-----------------------------------------------+        |
|                                                           |
|  +-----------------------------------------------+        |  <-- `message_style` and `body_class`
|  |                [Alert Message]                |        |  <-- `props.body`
|  +-----------------------------------------------+        |
|                                                           |
|  +-----------------------------------------------+        |  <-- `confirm_button_class` and `confirm_button_style`
|  |                [Confirm Button]               |        |  <-- `props.confirm_button_text`
|  +-----------------------------------------------+        |
|                                                           |
|  +-----------------------------------------------+        |  <-- `cancel_button_class` and `cancel_button_style`
|  |                [Cancel Button]                |        |  <-- `props.cancel_button_text`
|  +-----------------------------------------------+        |
|                                                           |
+-----------------------------------------------------------+
PropertyTypeDescriptionDefault
alert_class&'static strCSS class for styling the alert container.""
icon_class&'static strCSS class for styling the icon.""
confirm_button_class&'static strCSS class for styling the confirm button.""
cancel_button_class&'static strCSS class for styling the cancel button.""
title_class&'static strCSS class for styling the alert title.""
message_class&'static strCSS class for styling the message text in the alert.""

Inline Styles

PropertyTypeDescriptionDefault
alert_style&'static strInline CSS styles for the alert.DEFAULT_ALERT_STYLE
close_button_style&'static strInline CSS styles for the close button.DEFAULT_CLOSE_BUTTON_STYLE
confirm_button_style&'static strInline CSS styles for the confirm button.DEFAULT_CONFIRM_BUTTON_STYLE
cancel_button_style&'static strInline CSS styles for the cancel button.DEFAULT_CANCEL_BUTTON_STYLE
icon_style&'static strInline CSS styles for the icon.DEFAULT_ICON_STYLE
title_style&'static strInline CSS styles for the title text.DEFAULT_TITLE_STYLE
separator_style&'static strInline CSS styles for the separator.DEFAULT_SEPARATOR_STYLE
message_style&'static strInline CSS styles for the message text.DEFAULT_MESSAGE_STYLE

๐Ÿ’ก Notes

  • The native prop can be set to true to use the browser's default alert behavior instead of the custom component.
  • The alert is displayed based on the show_alert state, which should be controlled by the parent component.
  • Timeout behavior can be adjusted using the timeout property, and alert visibility can be toggled using the show_alert state.
  • You can customize the alert's appearance, including the icon, buttons, position, and styles.

Usage

CLI Usage

You can import Alert RS directly into your project to customize and modify it using the opensass cli:

os add alert-rs yew

Skeleton RS

Edit Component

Y Skeleton RS Yew Usage

Adding Skeleton RS to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Skeleton RS component to your dependencies by including it in your Cargo.toml file:

    cargo add skeleton-rs --features=yew
    
  3. Import the Skeleton component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Incorporating Skeleton RS into your Yew application is easy. Follow these steps:

  1. Import the Skeleton component into your Yew project:

    use yew::prelude::*;
    use skeleton_rs::yew::Skeleton;
    use skeleton_rs::Variant;
  2. Use the Skeleton component within your Yew application:

    use yew::prelude::*;
    use skeleton_rs::yew::Skeleton;
    use skeleton_rs::Variant;
    
    
    #[function_component(App)]
    pub fn app() -> Html {
        html! {
            <Skeleton
                variant={Variant::Text}
                width="100%"
                height="1.2em"
                animate_on_visible={true}
            />
        }
    }

๐Ÿ”ง Props

PropertyTypeDescriptionDefault
variantVariantVisual variant: Text, Circle, Rect, etc.Text
animationAnimationAnimation style: Pulse, Wave, None.Pulse
directionDirectionAnimation direction: LeftToRight, RightToLeft, TopToBottom, etc.LeftToRight
themeThemeTheme for light/dark variants.Light
showboolManually control visibility of the skeleton.false
delay_msu32Delay before showing the skeleton in milliseconds.0
infer_sizeboolInfers width/height from child content if true.false
responsiveboolEnables scaling for responsive layouts.false
childrenHtmlContent to wrap in skeleton loading.None

๐ŸŽจ Styling Props

PropertyTypeDescriptionDefault
width&'static strWidth of the skeleton block."100%"
height&'static strHeight of the skeleton block."1em"
font_sizeOption<&str>Font size used for text variant.None
border_radius&'static strBorder radius for rounded shapes."4px"
line_height&'static strLine height of the skeleton block."1"
margin&'static strExternal margin styling.""
custom_style&'static strInline custom styles.""

โš™๏ธ Visibility Behavior

PropertyTypeDescriptionDefault
animate_on_hoverboolStarts animation on hover.false
animate_on_focusboolStarts animation on focus.false
animate_on_activeboolStarts animation on active interaction (e.g., click).false
animate_on_visibleboolUses IntersectionObserver to trigger animation when in view.false

๐Ÿ“ Layout Constraints

PropertyTypeDescriptionDefault
max_widthOption<&str>Max width of the skeleton.None
min_widthOption<&str>Min width of the skeleton.None
max_heightOption<&str>Max height of the skeleton.None
min_heightOption<&str>Min height of the skeleton.None

๐Ÿง  DOM Utility

PropertyTypeDescriptionDefault
node_refNodeRefDOM reference used internally (e.g., for visibility tracking).Default

๐Ÿ’ก Notes

  • The Skeleton component is primarily designed for loading states and placeholder UI.
  • IntersectionObserver is used when animate_on_visible is enabled to improve performance.
  • You can control the component via the show prop or allow it to handle visibility with internal state.
  • Use infer_size with children when you want the skeleton to match their dimensions.
  • For better performance, delay the appearance of skeletons using delay_ms to avoid flicker.
  • You can use custom_style and class to style it further as needed.

Usage

CLI Usage

You can import Skeleton RS directly into your project to customize and modify it using the opensass cli:

os add skeleton-rs yew

Hero

Edit Component

Hero Yew Usage

Adding Hero to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Hero component to your dependencies by including it in your Cargo.toml file:

    cargo add hero --features=yew
    
  3. Import a Hero component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

At the current release, hero comes with 4 built-in, highly customizable Hero sections designed for various layout needs and visual styles. Each Hero variant is modular, accessible, and easily styled through a comprehensive set of props. Follow these steps to integrate a Hero component into your Yew application:

Available Components

use hero::yew::hero1::Hero as Hero1;
use hero::yew::hero2::Hero as Hero2;
use hero::yew::hero3::Hero as Hero3;
use hero::yew::hero4::Hero as Hero4;

Basic Usage Example (hero1)

use yew::prelude::*;
use hero::yew::hero1::Hero;

#[function_component(App)]
pub fn app() -> Html {
    html! {
        <Hero
            heading="Build Fast in Rust"
            description="Drop-in hero sections for Yew, Leptos, and Dioxus."
            title_style="font-size: 3rem; font-weight: bold; color: #4F46E5;"
            description_style="font-size: 1.25rem; color: #6B7280;"
            cta_style="padding: 0.75rem 1.5rem; background-color: #4F46E5; color: white; border-radius: 0.5rem;"
        />
    }
}

Styling with Tailwind (or CSS Classes)

Each component exposes full control over styles and class names. For example, with hero1:

use yew::prelude::*;
use hero::yew::hero1::Hero;

#[function_component(App)]
pub fn app() -> Html {
    html! {
        <Hero
            heading="Launch Ultra-Fast Apps"
            description="Style your hero section with Tailwind, inline styles, or any CSS framework."
            container_class="max-w-6xl mx-auto px-4 py-24"
            title_class="text-5xl font-extrabold text-center text-white"
            description_class="mt-4 text-xl text-center text-gray-300"
            cta_class="mt-6 bg-white text-black px-6 py-3 rounded-full shadow-lg hover:bg-gray-100"
        />
    }
}

Customization Options

Each Hero component supports:

  • Content props: heading, description, tabs, cta_style, etc.
  • Style props: title_style, description_style, container_style, etc.
  • Class props: container_class, title_class, etc.
  • Semantic options: heading_tag, aria_label, etc.

You can combine inline styles and utility classes for full control over design.

๐Ÿ’ก Notes

  • Framework-Agnostic: Can be used in Yew, Leptos, or Dioxus.
  • Accessible: Semantic HTML and keyboard navigable by default.
  • Dark Mode Friendly: Works well with Tailwind's dark variants or your custom themes.
  • Completely Customizable: Override layout, inject your own components, or style everything.

Usage

CLI Usage

You can import Hero directly into your project to customize and modify it using the opensass cli:

os add hero dio

Browser RS

Edit Component

Browser RS Yew Usage

Adding Browser RS to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Browser RS component to your dependencies by including it in your Cargo.toml file:

    cargo add browser-rs --features=yew
    
  3. Import the BrowserFrame component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Follow these steps to integrate BrowserFrame into your Yew application:

Import the Required Component

use yew::prelude::*;
use browser_rs::yew::BrowserFrame;

Basic Example

Wrap any content inside the BrowserFrame and customize its behavior with props:

use yew::prelude::*;
use browser_rs::yew::BrowserFrame;

#[function_component(App)]
pub fn app() -> Html {
    let on_close = Callback::from(|_| log::info!("Browser closed"));

    html! {
        <BrowserFrame
            url={"https://opensass.org".to_string()}
            on_close={on_close}
        >
            <p>{ "Your embedded content here." }</p>
        </BrowserFrame>
    }
}

Add Custom Buttons

You can include custom buttons in the header using the custom_buttons prop:

use yew::prelude::*;
use browser_rs::yew::BrowserFrame;

#[function_component(App)]
pub fn app() -> Html {
    let custom_button = html! {
        <button>{ "Custom Button" }</button>
    };

    html! {
        <BrowserFrame
            url={"https://opensass.org".to_string()}
            custom_buttons={vec![custom_button]}
        >
            <p>{ "Custom button in the header!" }</p>
        </BrowserFrame>
    }
}

Customize Styling

Override default styles and classes to match your app's design:

use yew::prelude::*;
use browser_rs::yew::BrowserFrame;

#[function_component(App)]
pub fn app() -> Html {
    html! {
        <BrowserFrame
            url={"https://opensass.org".to_string()}
            class={"rounded-xl shadow-xl"}
            input_class={"bg-gray-200 text-gray-900"}
            container_class={"flex-1 mx-4"}
        >
            <p>{ "Styled browser frame!" }</p>
        </BrowserFrame>
    }
}

๐Ÿ”ง Props

PropertyTypeDefault ValueDescription
childrenChildren""The child components to render inside the browser frame.
urlString""The current URL displayed in the address bar.
placeholder&'static str""Placeholder text for the address bar input.
on_url_changeOption<Callback<InputEvent>>NoneTriggered when the address bar's URL is edited by the user.
on_closeCallback<()>No-op callbackCalled when the close button is clicked.
on_minimizeCallback<()>No-op callbackCalled when the minimize button is clicked.
on_maximizeCallback<()>No-op callbackCalled when the maximize button is clicked.
show_controlsbooltrueWhether to show the window controls (close, minimize, maximize).
show_address_barbooltrueWhether to display the address bar.
read_onlyboolfalseIf true, the address bar input is read-only.
sizeSizeMediumSets the browser frame size (Small, Medium, Large).
variantVariantDefaultVisual variant of the browser frame.
custom_buttonsVec<Html>[]Optional custom buttons to render in the header.
class&'static str"rounded-lg border shadow-lg..."Outer container CSS classes.
frame_class&'static str""Additional CSS classes for the frame element.
style&'static str""Inline styles for the outer container.
id&'static str""Optional container ID.
aria_label&'static str"Browser window"ARIA label for the browser frame container.
aria_describedby&'static str""ARIA description for the browser frame.
container_class&'static str""CSS classes for the address bar container.
input_class&'static str"text-black dark:text-white"CSS classes for the address input element.
refresh_button_style&'static str"position: absolute; ..."Inline styles for the refresh button.
refresh_button_aria_label&'static str"Refresh"ARIA label for the refresh button.
icon_button_style&'static str"padding: 4px; cursor: pointer; ..."Inline styles for icon buttons (close, minimize, maximize).
address_wrapper_base_style&'static str"flex: 1; display: ..."Style for the address bar wrapper.
header_base_style&'static str"display: flex; align-items: ..."Style for the header container.

Close button (close_*)

PropertyTypeDefaultDescription
on_close_mouse_overCallback<()>No-opCalled on mouse over the close button.
on_close_mouse_outCallback<()>No-opCalled on mouse out of the close button.
on_close_focusCallback<FocusEvent>No-opCalled when the close button gains focus.
on_close_blurCallback<FocusEvent>No-opCalled when the close button loses focus.
close_class&'static str""CSS class for the close button.
close_svg_class&'static str""CSS class for the close button's SVG element.
close_path_class&'static str""CSS class for the close button's SVG path.
close_button_type&'static str"button"The type attribute for the close button element.
close_aria_label&'static str""ARIA label for the close button.
close_title&'static str""Title attribute for the close button.
close_tabindex&'static str"0"Tab index for keyboard navigation.

Minimize button (minimize_*)

(Same structure as above)

Maximize button (maximize_*)

(Same structure as above)

Share button (share_*)

PropertyTypeDefaultDescription
share_button_style&'static str""Inline styles for the share button.
share_onclickCallback<()>No-opCalled on click.
share_onmouseoverCallback<()>No-opCalled on mouse over.
share_onmouseoutCallback<()>No-opCalled on mouse out.
share_onfocusCallback<FocusEvent>No-opCalled on focus.
share_onblurCallback<FocusEvent>No-opCalled on blur.
share_tabindex&'static str""Tab index for accessibility.

Tabs button (tabs_*)

(Same structure as share button)

More button (more_*)

(Same structure as share button)

๐Ÿ’ก Notes

  1. Accessible: All elements support ARIA labels, roles, and keyboard navigation (Escape triggers close).

  2. Dark Mode Ready: Default styles are compatible with Tailwind's dark theme classes.

  3. Customizable Controls: All button elements (close, minimize, maximize, refresh, tabs, share, more) support individual style, label, and event customization.

  4. Component Structure: Internally splits into header and content subcomponents (BrowserHeader, BrowserContent) for modular control.

  5. Use Anywhere: Can be used to wrap iframes, widgets, editors, or any arbitrary HTML/Yew content.

Usage

CLI Usage

You can import Browser RS directly into your project to customize and modify it using the opensass cli:

os add browser-rs yew

Navbar

Edit Component

๐Ÿ” Navbar Yew Usage

Adding the Navbar component to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Navbar component to your dependencies by including it in your Cargo.toml file:

    cargo add navbar --features=yew
    
  3. Import the Navbar component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Integrating the Navbar into your Yew application is simple. Here's how:

use yew::prelude::*;
use navbar::yew::{Navbar, Menu};

#[function_component(App)]
pub fn app() -> Html {
    html! {
        <Navbar
            logo_src="/assets/logo.svg"
            logo_alt="My App"
            menus={vec![
                Menu { id: 1, link: "/", name: "Dashboard", icon_start: None, icon_end: None },
                Menu { id: 2, link: "/reports", name: "Reports", icon_start: None, icon_end: None }
            ]}
            button_text="Sign Up"
            button_href="/signup"
            show_search=true
            show_mega_menu=true
            show_profile_menu=true
        />
    }
}

๐Ÿงฉ Props

Main Props

PropertyTypeDescriptionDefault
logo_src&'static strPath to the logo image.""
logo_alt&'static strAlt text for the logo."Logo"
logo_link&'static strOptional link for the logo."/"
menusVec<MenuItem>List of top-level menu items.[]
show_searchboolDisplays the search input if true.false
search_stateUseStateHandle<String>Optional shared state for the search input.None
search_placeholder&'static strPlaceholder for the search input."Search"
button_text&'static strText for the CTA button.""
button_href&'static strLink for the CTA button."#"
button_target&'static strTarget attribute for CTA link (e.g. _blank)."_self"
show_mega_menuboolEnables the mega menu when true.false
mega_menu_itemsVec<MegaMenuItem>Items to show in the mega menu.[]
show_profile_menuboolShows the profile dropdown menu.false
dropdown_itemsVec<DropdownItem>Items for the profile dropdown.[]
profile_image_url&'static strURL for profile image.""
profile_button_text&'static strText label for profile menu toggle."Profile"

Styling Props

+--------------------------------------------------------------------------+
|                                [Navbar]                                  |  <-- `navbar_class` & `navbar_style`
|                                                                          |
|   +--------------------------------------------------------------+       |  <-- `container_class` & `container_style`
|   | [Logo] [Menu Items] [Search] [CTA Button] [Profile Menu]     |       |
|   +--------------------------------------------------------------+       |
|                                                                          |
+--------------------------------------------------------------------------+
PropertyTypeDescriptionDefault Style
navbar_class&'static strClass for outer navbar element.""
navbar_style&'static strStyle for outer navbar element.display: flex; justify-content: space-between; ...
container_class&'static strClass for max-width inner container.""
container_style&'static strStyle for inner container.max-width: 1200px; margin: auto; ...
inner_class&'static strClass for the content wrapper.""
inner_style&'static strStyle for the content wrapper.display: flex; align-items: center; ...
logo_class&'static strClass for the logo.""
logo_style&'static strStyle for the logo.height: 40px;
menu_item_class&'static strClass for menu items.""
menu_item_style&'static strStyle for each menu item.padding: 0.5rem 1rem; color: black;
dropdown_class&'static strClass for dropdown menu.""
dropdown_style&'static strStyle for dropdown menu.position: absolute; box-shadow: 0 4px 8px rgba(0,0,0,0.1);
dropdown_item_class&'static strClass for dropdown items.""
dropdown_item_style&'static strStyle for dropdown items.padding: 0.5rem 1rem;
search_input_class&'static strClass for search input.""
search_input_style&'static strStyle for search input.padding: 0.5rem; font-size: 1rem;
button_class&'static strClass for CTA button wrapper.""
button_style&'static strStyle for CTA button wrapper.margin-left: 1rem;
button_link_class&'static strClass for CTA anchor inside button.""
button_link_style&'static strStyle for CTA anchor inside button.background: #007bff; color: white; ...
more_button_class&'static strClass for the mega menu "More" button.""
more_button_style&'static strStyle for the mega menu "More" button.font-weight: bold; border: none;
mega_menu_class&'static strClass for mega menu wrapper.""
mega_menu_style&'static strStyle for mega menu wrapper.position: absolute; padding: 0;
mega_menu_card_class&'static strClass for each mega menu card.""
mega_menu_card_style&'static strStyle for each mega menu card.background: white; display: flex; ...
menu_toggle_class&'static strClass for mobile hamburger icon.""
menu_toggle_style&'static strStyle for mobile hamburger icon.flex-direction: column; gap: 5px;
line_class&'static strClass for hamburger icon lines.""
line_style&'static strStyle for hamburger icon lines.width: 25px; height: 2px; background: black;

๐Ÿ’ก Notes

  • The navbar is responsive by default and adapts to screen size.
  • Hamburger toggle appears when the window width is <= 768px.
  • Click outside to auto-close mobile and dropdown menus via event listeners.
  • You can fully customize the layout using style and class props for each section.
  • Mega menu, search, CTA button, and profile menu are optional features that can be toggled via props.
  • All callback-based interactions like search input or menu toggling are handled with use_state, Callback, and use_effect.
  • Supports accessibility with custom labels, alt tags, and interactive behaviors.

Usage

CLI Usage

You can import Navbar directly into your project to customize and modify it using the opensass cli:

os add navbar yew

Sidebar

Edit Component

Y Sidebar Yew Usage

Adding Sidebar to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Sidebar component to your dependencies by including it in your Cargo.toml file:

    cargo add sidebar --features=yew
    
  3. Import the Sidebar component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Integrating the Sidebar into your Yew application is straightforward. Follow the steps below:

  1. Import the Sidebar, Menu, MenuItem, Submenu, and Profile components:

    use yew::prelude::*;
    use sidebar::yew::item::MenuItem;
    use sidebar::yew::menu::Menu;
    use sidebar::yew::sidebar::Sidebar;
    use sidebar::yew::submenu::Submenu;
  2. Use them in your application:

    use yew::prelude::*;
    use sidebar::yew::item::MenuItem;
    use sidebar::yew::menu::Menu;
    use sidebar::yew::sidebar::Sidebar;
    use sidebar::yew::submenu::Submenu;
    
    #[function_component(App)]
    pub fn app() -> Html {
        let selected = use_state(|| String::from("Dashboard"));
    
        html! {
            <Sidebar
                user_name="Ferris"
                designation="Admin"
                user_img="/assets/logo.webp"
                on_logout={Callback::from(|_| log::info!("Logout!"))}
                logo_img_url="/logo.svg"
                logo_href="/"
            >
                <Menu sub_heading="Main">
                    <MenuItem
                        label="Dashboard"
                        href="/dashboard"
                        icon_html={html! {<span>{ "๐Ÿ“Š" }</span>}}
                        selected={selected.clone()}
                    />
                    <MenuItem
                        label="Settings"
                        href="/settings"
                        icon_html={html! {<span>{ "โš™๏ธ" }</span>}}
                        selected={selected.clone()}
                    />
                    <Submenu title="More" icon_html={html! {<span>{ "โž•" }</span>}}>
                        <MenuItem
                            label="Reports"
                            href="/reports"
                            icon_html={html! {<span>{ "๐Ÿ“" }</span>}}
                            selected={selected.clone()}
                        />
                    </Submenu>
                </Menu>
            </Sidebar>
        }
    }

๐Ÿ”ง Props

+---------------------------------------------------------------+
|                          Sidebar                              |
|  (style: width: 270px; background: white;)                    |
|                                                               |
|  +---------------------------------------------------------+  |
|  |                     Header (Logo + Toggle)              |  |
|  |   (header_style: display: flex; align-items: center;)   |  |
|  |                                                         |  |
|  |   [Logo]                             [Toggle โ—€ or โ–ถ]    |  |
|  +---------------------------------------------------------+  |
|                                                               |
|  +---------------------------------------------------------+  |
|  |                        Menu                             |  |
|  |  (sub_heading shown if not collapsed)                   |  |
|  |                                                         |  |
|  |   +-------------------+   +-------------------+         |  |
|  |   |    MenuItem       |   |    MenuItem       |         |  |
|  |   |  [Icon] Label     |   |  [Icon] Label     |         |  |
|  |   +-------------------+   +-------------------+         |  |
|  |                                                         |  |
|  |   +-------------------+                                 |  |
|  |   |     Submenu       |                                 |  |
|  |   |  [Icon] Label  โ–ผ  |(click to expand โ–ผ or collapse โ–ฒ)|  |
|  |   +-------------------+                                 |  |
|  |       |                                                 |  |
|  |       |--> +-------------------+                        |  |
|  |            |    MenuItem       |                        |  |
|  |            |  [Icon] Label     |                        |  |
|  |            +-------------------+                        |  |
|  +---------------------------------------------------------+  |
|                                                               |
|  +---------------------------------------------------------+  |
|  |                       Profile                           |  |
|  |  (shown only if not collapsed)                          |  |
|  |                                                         |  |
|  |  [Avatar] Username        Designation          [-]      |  |
|  +---------------------------------------------------------+  |
+---------------------------------------------------------------+
PropertyTypeDescriptionDefault
childrenChildrenWithProps<Menu>The Menu components rendered in sidebar[]
show_profileboolWhether to show the profile sectiontrue
user_name&'static strUser's name displayed in profile""
designation&'static strUser role/designation""
user_img&'static strPath to user image""
on_logoutCallback<()>Callback invoked when logout is clickedNo-op
style&'static strInline CSS for sidebar container"width: 270px; background: white;"
class&'static strCSS class for sidebar container""
header_style&'static strCSS for the sidebar header section"display: flex; ..."
header_class&'static strClass for the header div""
logo_img_url&'static strLogo image path""
logo_href&'static strLogo link target""
PropertyTypeDescriptionDefault
sub_heading&'static strOptional section heading""
childrenChildrenChildren MenuItem or Submenu[]
style&'static strInline styles"padding: 1rem;"
class&'static strCSS class""
PropertyTypeDescriptionDefault
label&'static strMenu item label""
href&'static strNavigation URL""
icon_htmlHtmlIcon HTML for the itemhtml!{}
badgeOption<&'static str>Optional badge (e.g., "3", "new")None
selectedUseStateHandle<String>Currently selected item stateRequired
anchor_style&'static strStyles for anchor wrapper"text-decoration: none;"
anchor_class&'static strClass for anchor wrapper""
item_style&'static strStyles when sidebar is expanded"display: flex; ..."
item_class&'static strClass for item container""
collapsed_style&'static strStyles for collapsed sidebar"display: flex; ..."
collapsed_label_style&'static strStyles for label text in collapsed mode"font-size: 10px; text-align: center;"
selected_style&'static strStyles for selected item"background-color: #1e293b; color: white;"
badge_style&'static strStyle for badge"background: red; ..."
PropertyTypeDescriptionDefault
title&'static strSubmenu title""
icon_htmlHtmlOptional iconhtml!{}
childrenChildrenWithProps<MenuItem>Menu items to be shown when expanded[]
class&'static strCSS class""
style&'static strInline style"padding: 10px; cursor: pointer; ..."

Profile Component Props

PropertyTypeDescriptionDefault
user_name&'static strName of the user""
designation&'static strUser's designation/role""
user_img&'static strProfile image path""
is_collapsedboolWhether sidebar is collapsedfalse
on_logoutCallback<()>Callback triggered on logout clickNo-op
style&'static strStyling for the profile container"display: flex; align-items: center; ..."
class&'static strClass for the container""

๐Ÿ’ก Notes

  • Sidebar handles responsive behavior based on viewport width (< 768px = collapsed).
  • MenuItem auto-detects and highlights current item using the selected state and URL query param selected.
  • You must pass a shared UseStateHandle<String> to selected in every MenuItem to track active selection.
  • Submenu provides collapsible behavior to group nested items.
  • Profile is automatically hidden in collapsed mode.
  • Customize with style and class props for full design flexibility.
  • ContextProvider enables state sharing (collapsed/expanded) across components via SidebarContext.

Usage

CLI Usage

You can import Sidebar directly into your project to customize and modify it using the opensass cli:

os add sidebar yew

I18n RS

Edit Component

Y i18nrs Yew Usage

Adding i18nrs to your Yew project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the i18nrs library to your dependencies by including it in your Cargo.toml file:

    cargo add i18nrs --features=yew
    
  3. Import the I18nProvider component into your Yew application and wrap it around your app's main component to provide translations.

๐Ÿ› ๏ธ Usage

Follow these steps to integrate i18nrs into your Yew application:

Step 1: Import the Required Components

Import the I18nProvider and any related types into your Yew project:

use yew::prelude::*;
use i18nrs::yew::I18nProvider;
use i18nrs::yew::I18nProviderConfig;
use std::collections::HashMap;

Step 2: Define Translations

Define your translations in a HashMap where keys are language codes (e.g., en, fr), and values are the translation strings in JSON format:

use yew::prelude::*;
use std::collections::HashMap;

#[function_component(App)]
pub fn app() -> Html {
    let translations = HashMap::from([
        ("en", r#"{"greeting": "Hello", "farewell": "Goodbye"}"#),
        ("fr", r#"{"greeting": "Bonjour", "farewell": "Au revoir"}"#),
    ]);
    html! {
    }
}

Step 3: Wrap Your App with the I18nProvider

Wrap your main app component inside the I18nProvider to give it access to the internationalization context:

use yew::prelude::*;
use i18nrs::yew::I18nProvider;
use i18nrs::yew::I18nProviderConfig;
use std::collections::HashMap;

#[function_component(App)]
pub fn app() -> Html {
    let translations = HashMap::from([
        ("en", r#"{"greeting": "Hello", "farewell": "Goodbye"}"#),
        ("fr", r#"{"greeting": "Bonjour", "farewell": "Au revoir"}"#),
    ]);

    let config = I18nProviderConfig {
        translations: translations,
        default_language: "en".to_string(),
        ..Default::default()
    };

    html! {
        <I18nProvider ..config>
            <MainApp />
        </I18nProvider>
    }
}

#[function_component(MainApp)]
pub fn main_app() -> Html {
    html! {
        <h1>{ "Welcome to i18nrs Example!" }</h1>
    }
}

fn main() {
    // yew::Renderer::<App>::new().render();
}

Step 4: Access Translations with the use_translation Hook

Use the use_translation hook to access translation functions within your components:

use yew::prelude::*;
use i18nrs::yew::use_translation;

#[function_component(MainApp)]
pub fn main_app() -> Html {
    let (i18n, set_language) = use_translation();

    let greeting = i18n.t("greeting"); // Retrieves translation for key "greeting"

    html! {
        <div>
            <h1>{ greeting }</h1>
            <button onclick={Callback::from(move |_| set_language.emit("fr".to_string()))}>
                { "Switch to French" }
            </button>
        </div>
    }
}

fn main() {
    // yew::Renderer::<MainApp>::new().render();
}

๐Ÿ”ง Props

I18nProviderConfig Props

Main Props

PropertyTypeDescriptionDefault
languagesVec<&'static str>List of supported languages.["en", "fr"]
translationsHashMap<&'static str, &'static str>Mapping of language codes to translation JSON content. Defaults to an empty map.{}
childrenHtmlChild components that will have access to the i18n context.Required
storage_typeStorageTypeType of browser storage for persisting the selected language (LocalStorage or SessionStorage).LocalStorage
storage_nameStringKey name in browser storage for saving the selected language."i18nrs"
default_languageStringLanguage to fall back to if none is found in storage."en"

Behavioral Props

PropertyTypeDescriptionDefault
onchangeCallback<String>Callback triggered when the language is changed. Receives the new language code as a String.No-op
onerrorCallback<String>Callback triggered when an error occurs in the i18n process. Receives the error message.No-op

๐Ÿ’ก Notes

  1. Translation Keys: Use dot-separated keys to organize translations hierarchically, e.g., menu.file.open. Translation files use a JSON format and can include nested keys for better organization.

    • Example:

      {
        "menu": {
          "file": {
            "open": "Open",
            "save": "Save"
          },
          "edit": "Edit"
        }
      }
      
  2. Language Switching: The set_language callback dynamically updates the language and persists it using the specified storage type.

  3. Fallback Mechanism: If a translation is not found for the current language, the default language is used.

Usage

CLI Usage

You can import I18n RS directly into your project to customize and modify it using the opensass cli:

os add i18nrs yew

ELD

TODO

Theme RS

Edit Component

Theme Yew Usage

Adding Theme to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Theme component to your dependencies by including it in your Cargo.toml file:

    cargo add theme --features=yew
    
  3. Import the ThemeProvider component into your Yew component and start using it in your app.

๐Ÿ› ๏ธ Usage

Follow these steps to integrate theme into your Yew application:

1. Import the Required Components

Import the ThemeProvider and related types into your Yew project:

use yew::prelude::*;
use theme::yew::ThemeProvider;
use theme::{Theme, StorageType};

2. Define Custom Themes (Optional)

You can define and register custom themes using the CustomTheme type:

use std::collections::HashMap;
use std::rc::Rc;
use theme::{CustomTheme, ColorTokens};

let mut custom_themes = HashMap::new();

custom_themes.insert(
    "solarized".to_string(),
    Rc::new(CustomTheme {
        name: "solarized".to_string(),
        base: None, // or Some("light".to_string()) if you want to inherit
        tokens: ColorTokens {
            primary: "#268bd2".to_string(),
            secondary: "#2aa198".to_string(),
            background: "#fdf6e3".to_string(),
            text: "#657b83".to_string(),
            error: Some("#dc322f".to_string()),
            warning: Some("#cb4b16".to_string()),
            success: Some("#859900".to_string()),
        },
    }),
);

3. Wrap Your App with the ThemeProvider

Wrap your main app component inside the ThemeProvider to provide theme context and behavior to your app:

use std::rc::Rc;
use yew::prelude::*;
use theme::yew::ThemeProvider;
use std::collections::HashMap;
use theme::{Theme, StorageType, CustomTheme, ColorTokens};

#[function_component(App)]
pub fn app() -> Html {
    let mut custom_themes = HashMap::new();
    custom_themes.insert(
        "solarized".to_string(),
        Rc::new(CustomTheme {
            name: "solarized".to_string(),
            base: None,
            tokens: ColorTokens {
                primary: "#268bd2".to_string(),
                secondary: "#2aa198".to_string(),
                background: "#fdf6e3".to_string(),
                text: "#657b83".to_string(),
                error: Some("#dc322f".to_string()),
                warning: Some("#cb4b16".to_string()),
                success: Some("#859900".to_string()),
            },
        }),
    );

    html! {
        <ThemeProvider
            default_theme={Theme::System}
            storage_type={StorageType::LocalStorage}
            storage_name={"theme"}
            custom_themes={custom_themes}
            forced_theme={None}
        >
            <MainApp />
        </ThemeProvider>
    }
}

#[function_component(MainApp)]
pub fn main_app() -> Html {
    html! {
        <h1>{ "Welcome to the themed app!" }</h1>
    }
}

fn main() {
    // yew::Renderer::<App>::new().render();
}

4. Access the Theme Context with the use_theme Hook

Use the use_theme hook to access the current theme, resolved theme, and control functions within your components:

use yew::prelude::*;
use theme::yew::use_theme;
use theme::Theme;

#[function_component(MainApp)]
pub fn main_app() -> Html {
    let ctx = use_theme();

    let onclick = {
        let set_theme = ctx.set_theme.clone();
        Callback::from(move |_| set_theme.emit(Theme::Dark))
    };

    html! {
        <div>
            <h2>{ format!("Current Theme: {:?}", *ctx.resolved_theme) }</h2>
            <button onclick={onclick}>{ "Switch to Dark Theme" }</button>
        </div>
    }
}

fn main() {
    // yew::Renderer::<MainApp>::new().render();
}

๐Ÿ”ง Props

ThemeProviderProps Props

Main Props

PropertyTypeDescriptionDefault
default_themeThemeThe theme to use if nothing is stored or detected.Theme::System
storage_typeStorageTypeWhether to persist the theme in LocalStorage or SessionStorage.LocalStorage
storage_name&'static strKey name for storing the selected theme in browser storage."theme"
forced_themeOption<Theme>Overrides all other theme logic if provided.None
custom_themesHashMap<String, Rc<CustomTheme>>Map of user-defined themes. Can be applied and previewed.{}
childrenHtmlChild components that will have access to the theme context.Required

Behavioral Props

PropertyTypeDescriptionDefault
reset_to_systemCallback<()>Reverts the theme to follow the system theme.no-op
apply_previewCallback<Theme>Applies a temporary theme preview (doesn't persist or update state).no-op
set_custom_themeCallback<Rc<CustomTheme>>Adds a new custom theme if it passes validation.no-op

๐Ÿ’ก Notes

  1. Auto System Theme Support: When Theme::System is used, the component tracks prefers-color-scheme and switches between light and dark automatically based on system settings.

  2. Time-Based Theme Switching: If no preference is stored, Theme::System will fall back to light mode during 7 AM - 6:59 PM and dark mode otherwise.

  3. Forced Theme: When forced_theme is provided, it overrides all system, storage, or runtime theme choices, effectively locking the app to that theme.

  4. Custom Themes: Add your own themes and styles dynamically. Each must implement the validate() method to ensure it's structured correctly.

  5. Tailwind Compatibility (v3 or lower): This provider works with Tailwind CSS's data-theme= and class= bindings, making it compatible with libraries like DaisyUI. It sets:

    • data-theme
    • class
    • style="color-scheme:..." on the root HTML element.
  6. Storage Syncing: Theme changes are synced across tabs and windows using the storage event.

  7. Easy API: Use set_theme, reset_to_system, or apply_preview to control appearance from any component.

  8. Hooks First: Just use use_theme() to access all theme information and actions within your components.

Usage

CLI Usage

You can import Theme RS directly into your project to customize and modify it using the opensass cli:

os add theme yew