Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Leptos-Use – Collection of essential Leptos utilities

Collection of essential Leptos utilities

Inspired by React-Use / VueUse / SolidJS-USE

Crates.io SSR Docs & Demos 90 Functions

Get Started

Installation

Every function lives in its own small crate. Add the ones you need, for example:

cargo add leptos-use-mouse

Each function’s page in this book tells you which crate to add.

The all-in-one leptos-use crate still exists but only re-exports the micro crates with deprecation notes. It will not receive new functionality.

Examples

Usage Example

Simply import the functions you need from their crates

use leptos::prelude::*;
use leptos_use_mouse::{use_mouse, UseMouseReturn};

#[component]
fn Demo() -> impl IntoView {
    let UseMouseReturn { x, y, .. } = use_mouse();
    
    view! { cx,
        {x} " x " {y}
    }
}

Please refer to the functions list for more details.

Stable Rust

Just like leptos this library can be safely run on stable rust. In the Getting Started section of the leptos docs you can read more about what this means.

Options

Most functions in Leptos-Use come with a version ..._with_options. For example use_css_var has a version use_css_var_with_options. As the name suggests, you can provide additional options to those versions of the functions.

These options are defined as structs with the corresponding PascalCase name. For our example use_css_var_with_options the name of the struct is UseCssVarOptions. Every option struct implements Default and the builder pattern to make it easy to change only the values needed. This can look like the following example.

#![allow(unused)]
fn main() {
let (color, set_color) = use_css_var_with_options(
    "--color",
    UseCssVarOptions::default()
        .target(el)
        .initial_value("#eee"),
);
}

Here only the values target and initial_value are changed and everything else is left to default.

TODO : automatic conversion like Fn and Option

Element Parameters

Many functions in this library operate on HTML/SVG elements. For example, the function use_element_size returns the width and height of an element:

#![allow(unused)]
fn main() {
use leptos::{*, html::Div};
use leptos_use_element_size::{use_element_size, UseElementSizeReturn};

#[component]
pub fn Component() -> impl IntoView {
let el = NodeRef::<Div>::new();

let UseElementSizeReturn { width, height } = use_element_size(el);

view! {
    <div node_ref=el></div>
}
}
}

In the example above we used a Leptos NodeRef to pass into the function. But that is not the only way you can do that. All of these work as well:

#![allow(unused)]
fn main() {
use_element_size(window().body()); // Option<web_sys::Element>
use_element_size(window().body().unwrap()); // web_sys::Element
use_element_size("div > p.some-class"); // &str or String intepreted as CSS selector

pub fn some_directive(el: HtmlElement<AnyElement>) {
    use_element_size(el); // leptos::html::HtmlElement<T>
}
}

Signal of Strings: Signal<String>, ReadSignal<String>, RwSignal<String>, Memo<String>; also works with &str:

#![allow(unused)]
fn main() {
let (str_signal, set_str_signal) = signal("div > p.some-class");
use_element_size(str_signal);
}

Signals of Elements: Signal<web_sys::Element>, ReadSignal<web_sys::Element>, RwSignal<web_sys::Element>, Memo<web_sys::Element>; also works with Option<web_sys::Element> and SendWrapper<web_sys::Element>:

#![allow(unused)]
fn main() {
let (el_signal, set_el_signal) = signal(document().query_selector("div > p.some-class").unwrap());
use_element_size(el_signal);
}

How it works

Looking at the source code of use_element_size you’ll find sth like

#![allow(unused)]
fn main() {
pub fn use_element_size(el: Into<ElementMaybeSignal<...>>) -> UseElementSizeReturn {}
}

All the above code works because there are From implementations for all of these types for ElementMaybeSignal.

ElementsMaybeSignal

Some functions work on one or more elements. Take use_resize_observer for example. This works very much the same way as described above but instead of Into<ElementMaybeSignal> it takes an Into<ElementsMaybeSignal> (note the plural). This means you can use it exactly in the same ways as you saw with the singular ElementMaybeSignal. Only this time, when you use String or &str it will be interpreted as CSS selector with query_selector_all.

But you can also use it with containers.

#![allow(unused)]
fn main() {
// Array of Option<web_sys::Element>
use_resize_observer([window().body(), document().query_selector("div > p.some-class").unsrap()]);

// Vec of &str. All of them will be interpreted as CSS selectors with query_selector_all() and the
// results will be merged into one Vec.
use_resize_observer(vec!["div > p.some-class", "p.some-class"]);

// Slice of NodeRef
let node_ref1 = NodeRef::<Div>::new();
let node_ref2 = NodeRef::<Div>::new();
use_resize_observer(vec![node_ref1, node_ref2].as_slice());
}

Usage in Options

Some functions have options that take Element(s)MaybeSignal. They can be used in the same way.

#![allow(unused)]
fn main() {
use_mouse_with_options(
    UseMouseOptions::default().target("div > p.some-class")
);
}

See also “Excluding Elements” in on_click_outside.

Server-Side Rendering

When using together with server-side rendering (SSR) you have to enable the feature ssr similar to how you do it for leptos.

Every Leptos-Use crate that you use (e.g. leptos-use-mouse, leptos-use-color-mode, …) has an ssr feature. In your Cargo.toml file enable these ssr features only from your project’s ssr feature:

[dependencies]
leptos-use-color-mode = "0.20"   # do NOT enable the "ssr" feature here
leptos-use-mouse = "0.20"

...

[features]
hydrate = [
    "leptos/hydrate",
    ...
]
ssr = [
    ...
    "leptos/ssr",
    ...
    "leptos-use-color-mode/ssr", # <== add this
    "leptos-use-mouse/ssr",      # <== and this for every leptos-use crate
]

...

Please see the ssr example in the examples folder for a simple working demonstration.

Many functions work differently on the server and on the client. If that’s the case you will find information about these differences in their respective docs under the section “Server-Side Rendering”. If you don’t find that section, it means that the function works exactly the same on both, the client and the server.

Do not enable the ssr feature directly!

Don’t do the following.

[dependencies]
leptos-use-mouse = { version = "0.20", features = ["ssr"] }  # this is wrong

The ssr feature is used to select which version of the functions are built. Effectively it means your application is built two times: with ssr enabled to build the server executable, and with ssr disabled to build the client’s WASM binary module.

So if you enable a Leptos-Use crate’s ssr feature globally, you will get the server version of the functions in the client.

By adding "leptos-use-mouse/ssr" to the ssr feature of your project, it will only be enabled when your project is built with ssr, and you will get the server functions server-side, and the client functions client-side.

Functions that read request headers on the server (e.g. use_cookie, use_locales, use_color_mode) additionally have the features axum and actix to select your server framework, for example "leptos-use-cookie/axum".

WASM on the server

If you enable ssr in your project on a wasm32 target architecture, you will get a compile-time warning in the console because it is a common mistake that users enable ssr globally. If you’re using wasm32 on the server however you can safely disable this warning by enabling the wasm_ssr feature together with ssr.

Functions with Target Elements

A lot of functions like use_resize_observer and use_element_size are only useful when a target HTML/SVG element is available. This is not always the case on the server. If you use them with NodeRefs they will just work in SSR. But what if you want to use them with window() or document()?

To enable that we provide the helper functions use_window() and use_document() which return a new-type-wrapped Option<web_sys::Window> or Option<web_sys::Document> respectively. These can be used safely on the server. The following code works on both the client and the server:

#![allow(unused)]
fn main() {
use leptos::prelude::*;
use leptos::ev::keyup;
use leptos_use_event_listener::use_event_listener;
use leptos_use_window::use_window;

use_event_listener(use_window(), keyup, | evt| {
...
});
}

There are some convenience methods provided as well, like use_document().body() which just propagate a None on the server.

Encoding and Decoding Data

Several functions encode and decode data for storing it and/or sending it over the network. To do this, codecs from the crate codee are used. They implement the traits Encoder with the method encode and Decoder with the method decode.

There are two types of codecs: One that encodes as binary data (Vec[u8]) and another type that encodes as strings (String). There is also an adapter Base64 that can be used to wrap a binary codec and make it a string codec by representing the binary data as a base64 string.

Please check the documentation of codee for more details and a list of all available codecs.

Example

In this example, a codec is given to use_cookie that stores data as a string in the JSON format. Since cookies can only store strings, we have to use string codecs here.

use leptos::*;
use leptos_use_cookie::use_cookie;
use serde::{Deserialize, Serialize};
use codee::string::JsonCodec;

#[component]
pub fn App(cx: Scope) -> impl IntoView {
#[derive(Serialize, Deserialize, Clone)]
struct MyState {
    chicken_count: i32,
    egg_count: i32,
}

let (cookie, set_cookie) = use_cookie::<MyState, JsonCodec>("my-state-cookie");    
view! {}
}

Custom Codecs

If you don’t find a suitable codec for your needs, you can implement your own; it’s straightforward! If you want to create a string codec, you can look at JsonSerdeCodec. In case it’s a binary codec, have a look at BincodeSerdeCodec.

Versioning

For a discussion on how to implement versioning please refer to the relevant section in the docs for codee.

Changelog

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Since 0.20.0 every micro crate has its own changelog in crates/<crate>/CHANGELOG.md.

[0.20.0] - 2026-10-19

Breaking Changes 🛠

  • Leptos-Use has been split into micro crates. Every function now lives in its own crate named after it, for example use_mouse is now in leptos-use-mouse (leptos_use_mouse::use_mouse). Related functions share a crate (leptos-use-storage, leptos-use-math, leptos-use-is, leptos-use-preferences, …) and the former core/utils modules became leptos-use-core, leptos-use-element, leptos-use-maybe-rw-signal, leptos-use-filters, … The Leptos-independent helpers are now the standalone crates wasm-js-macros (js!, js_fut!) and sendwrap-fn (sendwrap_fn!). Every crate has its own ssr feature (and axum/actix where it reads request headers).

  • The leptos-use crate still compiles with the same features and paths but only contains deprecated forwarding wrappers that tell you which micro crate to add instead.

  • use_calendar is now generic over the date type via the new trait CalendarDateType. UseCalendarOptions, UseCalendarReturn and CalendarDate got a date type parameter and use_calendar() needs a type annotation, e.g. use_calendar::<chrono::NaiveDate>().

  • The feature use_calendar no longer enables chrono. Enable one of the new features chrono, jiff or time (chrono is part of the default features).

  • CalendarDate comparison methods (is_selected, is_before, …) compare by calendar day.

  • WatchOptions and UseStorageOptions got a filter type parameter which defaults to the new NoFilter. debounce/throttle/filter change it to FilterOptions. This way the debounce and throttle code is only compiled into your app when you use it. Code that names these types with a filter has to write WatchOptions<FilterOptions> / UseStorageOptions<T, E, D, FilterOptions>.

  • The default target of UseColorModeOptions is the document’s root element instead of the selector "html", which saves the code that looks up elements by selector. UseColorModeOptions::default() is now of the type UseColorModeOptions<Option<web_sys::Element>, _>.

New Features 🚀

  • use_calendar supports jiff (jiff::civil::Date, jiff::Zoned) and time (time::Date, time::OffsetDateTime) behind the features jiff and time.
  • use_calendar supports chrono::DateTime<Utc>, chrono::DateTime<Local> and chrono::DateTime<FixedOffset>.
  • Every micro crate has browser tests (wasm-bindgen-test in headless Chrome), run in CI.
  • The book shows how much each function adds to the gzipped wasm binary of an app.

Changes ✨

  • use_color_mode: with cookie_enabled, store Auto as auto-dark / auto-light so SSR renders the right mode without the Sec-CH-Prefers-Color-Scheme header
  • use_color_mode: new option cookie_max_age (defaults to one year) so the cookie outlives the browser session
  • use_color_mode: with cookie_enabled, the cookie is the only storage and storage_enabled is ignored

Fixes 🍕

  • use_device_orientation never listened for deviceorientation events, so it never reported any values
  • use_clipboard with read(true) never listened for copy/cut events
  • use_web_notification never closed the notification when the page became visible again
  • use_infinite_scroll stopped loading after a load that grew the content without filling the element
  • use_idle listens for activity on window instead of document, so the default resize event counts as activity

[0.19.3] - 2026-10-13

Fixes 🍕

  • on_click_outside: the iOS workaround no longer builds its no-op listener with new Function(""), which a CSP without 'unsafe-eval' blocks, aborting hydration on iOS

Changes ✨

  • Updated mdbook version to 0.5

[0.19.2] - 2026-08-31

Fixes 🍕

  • use_broadcast_channel: drop dead close-event listener (thanks @sabify)
  • use_storage: detect external notifications on first watch tick, stop panicking on custom event creation, and reset value synchronously on remove (thanks @sabify)
  • use_cookie: restart expiration countdown on every write and suppress broadcast echoes to avoid cross-tab loops (thanks @sabify)
  • use_websocket: restore reconnects on reopen/cancel on close and ignore events from superseded connections (thanks @sabify)
  • use_event_source: cancel pending reconnect on close (thanks @sabify)
  • use_draggable: pass element position to on_start (thanks @sabify)
  • use_mouse_in_element: classify left/top edges as inside (thanks @sabify)
  • use_mouse: report touch Screen coordinates in screen space (thanks @sabify)
  • use_scroll: report horizontal edges of rtl containers correctly (thanks @sabify)
  • use_color_mode: apply mode to custom targets that mount late (thanks @sabify)
  • use_geolocation: clear previous watch on resume (thanks @sabify)
  • use_drop_zone: prevent drag counter underflow (thanks @sabify)
  • use_infinite_scroll: stop re-triggering loads when no new content arrives (thanks @sabify)
  • use_screen_orientation: stop panicking when orientation API is unavailable (thanks @sabify)
  • use_permission: keep reactive owner so change listener is cleaned up (thanks @sabify)
  • use_mutation_observer: honour documented default of attributes (thanks @sabify)
  • use_css_var: fall back to initial_value for undefined variables (thanks @sabify)
  • use_raf_fn: reset frame timestamp when pausing (thanks @sabify)
  • use_interval_fn: don’t fire immediate callback again when interval changes (thanks @sabify)
  • use_locale: prefer exact locale match over first loose match (thanks @sabify)
  • signal_debounced / signal_throttled: react to filter period changes instead of sampling once (thanks @sabify)
  • use_throttle_fn: wait full duration for first trailing call when leading is disabled (thanks @sabify)
  • use_debounce_fn / debounce_filter: clear max_wait timer on cleanup and re-arm after it fires (thanks @sabify)
  • core: degrade gracefully when location.href is inaccessible, stop panicking on pre-epoch system clock, and don’t unwrap SendWrapper element signals on server (thanks @sabify)
  • utils: return None from header() when header is absent (thanks @sabify)
  • clamp timer durations to i32::MAX for browser timers (use_idle, use_interval_fn, use_timeout_fn, debounce/throttle) (thanks @sabify)
  • use_web_lock: track web-sys 0.3.104 renames (request_with_options) (thanks @EvanCarroll)

Changes 🔥

  • use passive event listeners where possible (thanks @maz)

[0.19.1] - 2026-07-23

Fixes 🍕

  • use_cycle_list: panic when the list becomes empty (thanks @sabify)
  • use_user_media / use_display_media: devices not released on unmount (thanks @sabify)
  • watch_with_options: previous return value lost across filtered runs (thanks @sabify)

[0.19.0] - 2026-06-22

New Functions 🚀

  • use_intl_datetime_format
  • js! macro is now documented as well as more powerful (thanks @Davoodeh)

Breaking Changes 🛠

  • Updated a bunch of dependencies

Changes

  • Made use_infinite_scroll SSR safe

Fixes 🍕

  • fixed tracking context warning with use_mutation_observer.
  • use_timeout_fn now properly handles timeouts and cleanup when repeatedly calling start (thanks @EvanCarroll).
  • enabling only the use_favicon Cargo feature now works correctly (thanks @arnaudpoullet-dkt).

Special thanks to our sponsor

  • @benwis

[0.18.3] - 2026-02-25

Fixes 🍕

  • Updated web-sys to min version ^0.3.89 because of yanked versions of js-sys.

Special thanks to our sponsor

  • @benwis

(yanked) [0.18.2] - 2026-02-25

Fixes 🍕

  • Made things work with both, cfg flag web_sys_unstable_apis enabled and disabled (thanks to @emilbonnek).

Special thanks to our sponsor

  • @benwis

(yanked) [0.18.1] - 2026-02-24

Fixes 🍕

  • Added GeolocationPosition and GeolocationPositionError web-sys features as dependencies for use_geolocation.
  • Updated web-sys to min version 0.3.86 because of Geolocation API changes.

Special thanks to our sponsor

  • @benwis

[0.18.0] - 2026-01-11

Breaking Changes 🛠

  • Element(s)MaybeSignal is now internally sendwrapped for SSR robustness. Some automatic conversions have been removed when they can’t really be made SSR safe like Signal<web_sys::Element>. Use Signal<SendWrapper<web_sys::Element>> instead.
  • OptionLocalSignal now has a clone free .read() implementation (thanks to @luxalpa).

New

  • There’s now an OptionLocalRwSignal for dealing with non-Send/non-Sync values in an SSR safe manner (thanks to @luxalpa).

Special thanks to our sponsor

  • @benwis

[0.17.0] - 2025-12-18

Huge thanks to @DrFlowerkick for all of this excellent work on this release.

Breaking Changes 🛠

  • Updated Rust Edition to 2024
  • use_cookie now requires its value type to be PartialEq to be able to compare values to avoid infinite update loops.
  • use_event_source (all thanks to @DrFlowerkick):
    • It now accepts its url parameter as impl Into<Signal<String>>
    • UseEventSourceReturn now longer has the fields event_source, event or data. Instead there is now a message field which is a Signal<Option<UseEventSourceMessage>>. Please check the docs for more info.
    • UseEventSourceOptions now accepts an on_event generic event handler.
    • UseEventSourceError has changed (again => pls see docs).
  • use_websocket no longer returns access to ws to prevent SSR issues (thanks to @DrFlowerkick).
  • A bunch of functions had local signals in their return types which could cause SSR issues. These have been replaced by our new OptionLocalSignal which is basically a Signal<Option<SendWrapper<T>>>. This solves the SSR issues (all thanks to @DrFlowerkick):
    • use_broadcast_channel
    • use_geolocation
    • use_web_notification
    • use_display_media
    • use_user_media
    • use_intl_number_format

New Functions 🚀

  • use_screen_orientation

Fixes 🍕

  • use_event_source SSR fixed
  • ElementsMaybeSignal and ElementMaybeSignal can now be successfully created from &strs (thanks to @fhgalano).
    • When using &strs as selectors in these cases, internally it will create signals that wait for the selector to appear in the DOM if not found immediately.
  • Fixed broken link in docs for use_locale (thanks to @cocoliliace).

Special thanks to our sponsor

  • @benwis

[0.16.3] - 2025-09-30

Change

  • Implemented PartialEq for core::Position

Fixes 🍕

  • Fixed effects running simultaneously in use_cookie (thanks to @ cbishopvelti)
  • Fixed link to Leptos Getting Started in the book (thanks to @mbergkvist)
  • Fixed SSR in use_interval_fn (thanks to @johansmitsnl)

Special thanks to our sponsor

  • @benwis

[0.16.2] - 2025-06-18

Fixes 🍕

  • use_color_mode frontend-only logic behind feature gate to fix SendWrapper issues with SSR (thanks to @BakerNet)

Special thanks to our sponsor

  • @benwis

[0.16.1] - 2025-06-16

Dependency Fixes 🐛

  • Removed version pin for chrono
  • Made chrono optional in Cargo.toml (thanks to @emilbonnek)

Special thanks to our sponsor

  • @benwis

[0.16.0] - 2025-06-12

Breaking Change 🛠

  • Updated dependency Leptos to version 0.8.0 (thanks to @DerKnerd, @jaystile, @ifiokjr)

New Features 🚀

  • Added month_by_date to use_calendar (thanks to @tomaszkubacki)
  • Added target_offset to use_draggable (thanks to @theredfish)
  • UseRwSignal can now be converted from anything that implements the respective reactive Leptos traits. This includes Signals, Memos, Store fields, … meaning the sync_signal now works with everything.
  • ElementMaybeSignal can be converted from Signal<SendWrapper<web_sys::Element>> improving interop with other crates.

Fixes 🍕

  • use_cookie with SSR has been fixed. This fixes the use_color_mode SSR issues as well.
  • use_event_source with infinity reconnect limit has been fixed.
  • Conversion of ElementMaybeSignal from &str has been fixed.

Special thanks to our sponsor

  • @benwis

[0.16.0-beta2] - 2025-03-20

Breaking Change 🛠

  • Updated dependency Leptos to version 0.8.0 (thanks to @DerKnerd, @jaystile)

New Feature 🚀

  • Added target_offset to use_draggable options for more flexible positioning (thanks to @theredfish)

Special thanks to our sponsors

  • @benwis
  • @spencewenski

[0.16.0-beta] - 2025-03-20

Breaking Change 🛠

  • Updated dependency Leptos to version 0.8.0-beta (thanks to @ifiokjr)

New Feature 🚀

  • Added month_by_date to use_calendar (thanks to @tomaszkubacki)

Special thanks to our sponsors

  • @benwis
  • @spencewenski

[0.16.0-alpha] - 2025-03-17

Breaking Changes 🛠

  • Removed the feature spin and it’s backend integration dependency leptos-spin (thanks to @ifiokjr)
  • Updated dependency Leptos to version 0.8.0-alpha (thanks to @ifiokjr)
  • Updated dependency getrandom to version 0.3
  • Updated dependency rand to version 0.9

Special thanks to our sponsor

  • @spencewenski

[0.15.8] - 2025-06-12

New Features 🚀

  • Added month_by_date to use_calendar (thanks to @tomaszkubacki)
  • Added target_offset to use_draggable (thanks to @theredfish)
  • UseRwSignal can now be converted from anything that implements the respective reactive Leptos traits. This includes Signals, Memos, Store fields, … meaning the sync_signal now works with everything.
  • ElementMaybeSignal can be converted from Signal<SendWrapper<web_sys::Element>> improving interop with other crates.

Fixes 🍕

  • use_cookie with SSR has been fixed. This fixes the use_color_mode SSR issues as well.
  • use_event_source with infinity reconnect limit has been fixed.
  • Conversion of ElementMaybeSignal from &str has been fixed.

Special thanks to our sponsor

  • @benwis

[0.15.7] - 2025-03-17

Change

  • Updated codee version to 0.3.0 in line with the latest 0.7 Leptos versions

Special thanks to our sponsor

  • @spencewenski

[0.15.6] - 2025-02-08

Fix 🍕

  • Fixed use_storage overwriting stored values with SSR (thanks to @BakerNet).

Special thanks to our sponsor

  • @spencewenski

[0.15.5] - 2025-01-15

Fix 🍕

  • sync_signal with immediate = true now syncs the signals on the server once initially. This fixes use_color_mode with cookies enabled to give wrong results during SSR.

Special thanks to our sponsor

  • @spencewenski

[0.15.4] - 2025-01-15

Fixes 🍕

  • downgraded codee to 0.2.0 to be compatible with Leptos 0.7
  • fixed use_mutation_observer (thanks to @bpwarner)

Changes 🔥

  • improxed DX: implemented Clone + Copy for UseDropZoneReturn (thanks to @mahmoud-eltahawy)

Special thanks to our sponsor

  • @spencewenski

[0.15.3] - 2025-01-08 (yanked)

New Function 🚀

  • use_calendar

Fix 🍕

  • added Debug to Size (thanks to @Ahlman)

Special thanks to our sponsor

  • @spencewenski

[0.15.2] - 2025-01-03

Fixes 🍕

  • Fixed path of use_color_mode cookie
  • ElementMaybeSignal and ElementsMaybeSignal are now properly Clone and Copy

Special thanks to our sponsor

  • @spencewenski

[0.15.1] - 2024-12-31

Fixes 🍕

  • Fixed use_element_hover not properly cancelling it’s timeout (thanks to @jcold).
  • Fixed use_storage not writing default values.
  • Fixed unidirectional sync_signal not syncing properly.

Special thanks to our sponsors

[0.15.0] - 2024-12-17

New Functions 🚀

  • signal_throttled and signal_debounced now have ..._local variants (thanks to @bicarlsen)

Breaking Changes 🛠

  • use_storage now accepts a Signal as it’s key parameter (thanks to LeftClick)
  • use_websocket now supports sending heartbeats (thanks to LeftClick)

Fix 🍕

  • Fixed use_storage to actually remove the key when remove is called (thanks to @flaviopezzini)

Special thanks to our sponsors

[0.14.0] - 2024-12-01

Highlights since 0.13

  • Updated to Leptos 0.7
  • Refactored ElementMaybeSignal and ElementsMaybeSignal to have a simpler implementation. For the vast majority of cases this should continue to work as before.
  • Almost everything returned from functions is now Send + Sync.

Changes since 0.14.0-rc5

  • Updated Leptos to use stable 0.7 version
  • Updated wasm-bindgen to 0.2.96
  • Updated web-sys 0.3.73

Special thanks to our sponsor:

  • @spencewenski

[0.14.0-rc5] - 2024-11-27

  • fixed error messages for get_header
  • added Send + Sync to storage return closure

Special thanks to our sponsor:

  • @spencewenski

[0.14.0-rc4] - 2024-11-26

  • Updated to Leptos 0.7.0-rc2
  • Fixed WASM on the serverside (thanks to @GuillaumeDelorme)
  • Fixed use_storage.
  • Made all returned closures Send + Sync.

Special thanks to our sponsor:

  • @spencewenski

[0.14.0-rc3] - 2024-11-14

  • Fixed potential SSR panic in use_locale(s) (thanks to @veigaribo)
  • Make use_locale prioritize user preferred locales over app preferred ones

[0.14.0-rc2] - 2024-11-10

  • Updated to Leptos 0.7.0-rc1
  • Updated to web-sys 0.3.72 and unpinned version (thanks to @sabify)
  • Added dependabot (thanks to @sabify)
  • Reverted use_user_media to have video enabled by default
  • Fixed exponential increase on websocket reconnects

[0.14.0-rc1] - 2024-11-06

  • Fixed MediaTrackConstraints dependency (thanks to @mollymorphous)
  • Fixed warnings and tests (thanks to @SleeplessOne1917 and @jheuel)
  • Unpinned the wasm-bindgen version (thanks to @jheuel)

[0.14.0-rc0] - 2024-11-03

  • Latest changes up to version 0.13.7 ported
  • Updated to Leptos 0.7.0-rc0

[0.14.0-gamma2] - 2024-10-16

  • Updated to Leptos 0.7.0-gamma3 by using Signal instead of MaybeSignal

[0.14.0-gamma1] - 2024-10-10

  • Adapted to the latest changes in Leptos (thanks to @BakerNet and @nikessel)
  • Fixed all the examples
  • use_active_element ported
  • use_drop_zone now returns Signal<Vec<SendSignal<web_sys::File>>> instead of Signal<Vec<web_sys::File>, LocalStorage> to make it easier to use with <For>

[0.14.0-beta4] - 2024-09-15

  • Latest changes from version 0.13.4 and 0.13.5 ported

[0.14.0-beta3] - 2024-09-02

Breaking Changes 🛠

  • Refactored ElementMaybeSignal and ElementsMaybeSignal to have a simpler implementation. For the vast majority of cases this should continue to work as before.

[0.14.0-beta2] - 2024-09-09

Change 🔥

  • Latest Leptos 0.7 beta changed the trigger trait method (thanks to @BakerNet)
  • Latest changes from version 0.13.3 ported

[0.14.0-beta1] - 2024-09-02

Ported everything to Leptos 0.7 Some example don’t run yet.

[0.13.12] - 2025-01-03

  • Fixed path of use_color_mode cookie

Thanks to our generous sponsor:

  • @spencewenski

[0.13.11] - 2024-11-22

  • Updated web-sys version to 0.3.72

Thanks to our generous sponsor:

  • @spencewenski

[0.13.10] - 2024-11-14

  • Fixed potential SSR crash in use_locale(s) (thanks to @veigaribo)

[0.13.9] - 2024-11-10

  • Reverted use_user_media to have video enabled by default
  • Fixed exponential increase on websocket reconnects

[0.13.8] - 2024-11-06

  • Backported fixes from 0.14.0-rc1

[0.13.7] - 2024-10-20

  • Added video and audio options to use_user_media (thanks to @sauloco).
  • Fixed cookies in SSR (thanks to @jim-taylor-business).

[0.13.6] - 2024-10-20

  • Updated leptos-spin version to 0.2 (thanks to @tqq1994516).

[0.13.5] - 2024-09-15

New Function 🚀

  • use_textarea_autosize

[0.13.4] - 2024-09-05

Fix 🍕

  • use_websocket now returns a signal for the websocket instance so the user can actually use it. Before it always returned None.

[0.13.3] - 2024-09-02

Fix 🍕

  • Fixed use_color_mode with cookies enabled

[0.13.2] - 2024-09-02

Fix 🍕

  • Fixed web-sys unstable_apis flag for use_web_lock

[0.13.1] - 2024-09-01

New Functions 🚀

  • use_web_lock
  • use_window_size

Change 🔥

  • UseWebsocket::protocols now supports a signal. It is read right before open is called. (thanks to @zakstucke)

[0.13.0] - 2024-08-28

New Functions 🚀

  • use_toggle
  • use_prefers_reduced_motion (thanks to @hcandelaria)

Breaking Changes 🛠

  • use_websocket now supports different types for sending and receiving messages
  • SyncSignalOptions now can take now either transformations or assignment functions but not both.
  • updated to codee version 0.2.0

Fixes 🍕

  • use_websocket fixed error with cleanup and reconnect (thanks to @BakerNet).

New Features 🚀

  • There is now a feature for almost every function to get better compile and rust-analyzer times.
  • use_web_notification now supports the vibrate option (thanks to @hcandelaria).
  • UseDocument now supports a whole bunch of methods more from document (thanks to @luckynumberke7in).

[0.12.0] - 2024-08-14

Make sure you also update cargo-leptos to the latest version if you use that.

Breaking Changes 🛠

  • Updated to web_sys 0.3.70 which unfortunately is breaking some things.
  • use_clipboard doesn’t need the unstable flags anymore.
  • use_locale now uses unic_langid::LanguageIdentifier and proper locale matching (thanks to @mondeja).
  • Removed UseMouseEventExtractorDefault and reworked UseMouseCoordType (thanks to @carloskiki)
  • use_preferred_dark and use_color_mode now try to read the Sec-CH-Prefers-Color-Scheme header in SSR. This brings the necessity to enable an additional feature for them (axum / actix / spin).

Fixes 🍕

  • Fixed the codec chapter in the book to refer to crate codee.

[0.11.4] - 2024-08-12

New Features 🚀

  • use_web_notification now supports the options renotify, silent and image (thanks to @hcandelaria).
  • sync_signal no supports the options assign_ltr and assign_rtl.

[0.11.3] - 2024-07-31

Fix 🍕

  • Made use_timeout_fn SSR-safe

[0.11.2] - 2024-07-30

Change 🔥

  • use_locale has now a supported locale list.

(yanked) [0.11.1] - 2024-07-28

New Functions 🚀

  • use_locale (thanks to @BrandonDyer64)
  • use_locales (thanks to @BrandonDyer64)
  • header – Standard implementations for reading a header on the server.

[0.11.0] - 2024-07-27

New Functions 🚀

  • use_user_media

New Features 🚀

  • Codecs:

    • All codecs now live in their own crate codee
    • There are now binary codecs in addition to string codecs.
      • FromToBytesCodec
      • WebpackSerdeCodec
      • BincodeSerdeCodec
      • ProstCodec (see also the section “Breaking Changes 🛠” below)
    • Every binary codec can be used as a string codec with the Base64 wrapper which encodes the binary data as a base64 string.
      • This required feature base64
      • It can be wrapped for example like this: Base64<WebpackSerdeCodec>.
    • There is now an OptionCodec wrapper that allows to wrap any string codec that encodes T to encode Option<T>.
      • Use it like this: OptionCodec<FromToStringCodec<f64>>.
  • ElementMaybeSignal is now implemented for websys::HtmlElement (thanks to @blorbb).

  • UseStorageOptions now has delay_during_hydration which has to be used when you conditionally show parts of the DOM controlled by a value from storage. This leads to hydration errors which can be fixed by setting this new option to true.

  • cookie::SameSite is now re-exported

  • Changing the signal returned by use_cookie now tries and changes the headers during SSR.

  • New book chapter about codecs

  • The macro use_derive_signal! is now exported (thanks to @mscofield0).

Breaking Changes 🛠

  • UseStorageOptions and UseEventSourceOptions no longer accept a codec value because this is already provided as a generic parameter to the respective function calls.
  • Codecs have been refactored. There are now two traits that codecs implement: Encoder and Decoder. The trait StringCodec is gone. The methods are now associated methods and their params now always take references.
    • JsonCodec has been renamed to JsonSerdeCodec.
    • The feature to enable this codec is now called json_serde instead of just serde.
    • ProstCodec now encodes as binary data. If you want to keep using it with string data you can wrap it like this: Base64<ProstCodec>.
    • All of these structs, traits and features now live in their own crate called codee
    • A bunch of new codecs are available. Have a look at the docs for crate codee.
  • use_websocket:
    • UseWebsocketOptions has been renamed to UseWebSocketOptions (uppercase S) to be consistent with the return type.
    • UseWebSocketOptions::reconnect_limit and UseEventSourceOptions::reconnect_limit is now ReconnectLimit instead of u64. Use ReconnectLimit::Infinite for infinite retries or ReconnectLimit::Limited(...) for limited retries.
    • use_websocket now uses codecs to send typed messages over the network.
      • When calling you have give type parameters for the message type and the codec: use_websocket::<String, WebpackSerdeCodec>
      • You can use binary or string codecs.
      • The UseWebSocketReturn::send closure now takes a &T which is encoded using the codec.
      • The UseWebSocketReturn::message signal now returns an Option<T> which is decoded using the codec.
      • UseWebSocketReturn::send_bytes and UseWebSocketReturn::message_bytes are gone.
      • UseWebSocketOptions::on_message and UseWebSocketOptions::on_message_bytes have been renamed to on_message_raw and on_message_raw_bytes.
      • The new UseWebSocketOptions::on_message takes a &T.
      • UseWebSocketOptions::on_error now takes a UseWebSocketError instead of a web_sys::Event.
  • use_storage now always saves the default value to storage if the key doesn’t exist yet.
  • Renamed BreakpointsSematic to BreakpointsSemantic and breakpoints_sematic to breakpoints_semantic (note the n) (thanks to @mondeja).

Fixes 🍕

  • Fixed auto-reconnect in use_websocket
  • Fixed typo in compiler error messages in use_cookie (thanks to @SleeplessOne1917).
  • Fixed potential signal out of scope issue with use_raf_fn

Other Changes 🔥

  • Better links in docs that work both in the book and in rustdoc (thanks to @mondeja).
  • Better CI/CD (thanks to @EstebanBorai).

[0.10.10] - 2024-05-10

Change 🔥

  • Added compile-time warning when you use ssr feature with wasm32. You can enable wasm_ssr to remove the warning.

[0.10.9] - 2024-04-27

Fixes 🍕

  • Fixed use_color_mode without cookies and make cookies sync properly with local storage
  • Fixed use_infinite_scroll edge case bug with disposed signals

[0.10.8] - 2024-04-19

Change 🔥

  • use_cookie now supports Spin out of the box (thanks to @javierEd).

[0.10.7] - 2024-04-10

New Function 🚀

  • sync_signal

Change 🔥

  • use_color_mode now supports cookies.

[0.10.6] - 2024-04-02

Fixes 🍕

  • Corrected docs of use_cookie’s max-age unit to milliseconds (thanks to @sify21).
  • Fixed setting multiple cookies in the browser (thanks to @sbking).

[0.10.5] - 2024-03-12

Fix 🍕

  • Fixed SSR detection from an url query parameter for use_color_mode (thanks to @mondeja).

[0.10.4] - 2024-03-05

New Functions 🚀

  • use_event_source

Changes 🔥

  • Wrapped callbacks in a non-reactive zone to remove potential warnings.
  • Updated SSR chapter in the book to make it more clear and beginner-friendly (thanks to @flupke).

[0.10.3] - 2024-02-23

New Functions 🚀

  • use_or
  • use_and
  • use_not

Fix 🍕

  • Removed signal warnings from use_websocket’s send... methods.

Changes 🔥

  • use_color_mode now supports detection from an url query parameter. (thanks to @mondeja)

[0.10.2] - 2024-02-09

New Functions 🚀

  • use_permission
  • use_clipboard
  • use_timeout_fn

[0.10.1] - 2024-01-31

Fix 🍕

  • Fixed docs.rs build

[0.10.0] - 2024-01-31

New Functions 🚀

  • use_broadcast_channel
  • use_cookie (thanks to @rakshith-ravi)
  • use_mouse_in_element
  • use_device_orientation (thanks to @mondeja)
  • use_device_pixel_ratio (thanks to @mondeja)
  • use_element_bounding

Breaking Changes 🛠

  • The leptos version is now 0.6
  • The trait Codec has been renamed to StringCodec and has been moved to util::StringCodec.
    • The struct StringCodec has been renamed to FromToStringCodec and has been moved to util::FromToStringCodec.
    • The structs JsonCodec and ProstCodec have been moved to util as well.
  • The function use_storage now requires type parameters for the stored type and the codec like all the other ...storage... functions.

Fixes 🍕

  • Fixed use_geolocation SSR compile issue
  • Fixed use_intl_number_format maximum fraction digits option

Changes 🔥

  • The UseMouseReturn signals x, y, and source_type are now of type Signal<f64> instead of ReadSignal<f64>.
  • You can now convert leptos::html::HtmlElement<T> into Element(s)MaybeSignal. This should make functions a lot easier to use in directives.
  • There’s now a chapter in the book especially for Element(s)MaybeSignal.
  • Throttled or debounced callbacks (in watch__ or __fn) no longer are called after the containing scope was cleaned up.
  • The document returned from use_document now supports the methods query_selector and query_selector_all.

[0.9.0] - 2023-12-06

New Functions 🚀

  • use_display_media (thanks to @seanaye)

Breaking Changes 🛠

  • (@feral-dot-io) The use use_<type>_storage functions have been rewritten to use Codecs instead of always requiring serde.
    • This also removes the feature storage
    • By default the StringCodec is used which relies on types implementing FromString + ToString
    • If you want to use JsonCodec you have to enable the feature serde
    • If you want to use ProstCodec (new!) you have to enable the feature prost.
  • (@feral-dot-io) The Rust flag --cfg=web_sys_unstable_apis is not needed anymore since relevant web_sys APIs are now stable. This affects in particular
    • use_element_size
    • use_resize_observer

Fixes 🍕

  • use_raf_fn and use_timestamp no longer spam warnings because of getting signals outside of reactive contexts.
  • use_infinite_scroll no longer calls the callback twice for the same event
  • use_scroll now uses try_get_untracked in the debounced callback to avoid panics if the context has been destroyed while the callback was waiting to be called.
  • use_idle works properly now (no more idles too early).
  • use_web_notification doesn’t panic on the server anymore.

[0.8.2] - 2023-11-09

Fixes 🍕

  • Fixed SSR for
    • use_timestamp
    • use_raf_fn
    • use_idle

[0.8.1] - 2023-10-28

Fixes 🍕

  • Using strings for ElementMaybeSignal and ElementsMaybeSignal is now SSR safe.
    • This fixes specifically use_color_mode to work on the server.

[0.8.0] - 2023-10-24

New Functions 🚀

  • use_web_notification (thanks to @centershocks44)
  • use_infinite_scroll
  • use_service_worker (thanks to @lpotthast)

Breaking Changes 🛠

  • use_scroll returns impl Fn(T) + Clone instead of Box<dyn Fn(T)>.

Other Changes 🔥

  • UseScrollReturn is now documented

[0.7.2] - 2023-10-21

Fixes 🍕

  • Some functions still used window() which could lead to panics in SSR. This is now fixed. Specifically for use_draggable.

[0.7.1] - 2023-10-02

New Function 🚀

  • use_sorted

[0.7.0] - 2023-09-30

New Functions 🚀

  • use_timestamp
  • use_idle
  • use_document
  • use_window
  • use_geolocation
  • signal_debounced
  • signal_throttled

Breaking Changes 🛠

  • Leptos version is now 0.5
  • No cx: Scope params are supported/needed anymore because of the changes in Leptos. Please check the release notes of Leptos 0.5 for how to upgrade.
  • watch is now deprecated in favor of leptos::watch and will be removed in a future release. watch_with_options will continue to exist.
  • use_event_listener_with_options now takes a UseEventListenerOptions instead of a web_sys::AddEventListenerOptions.
  • use_mutation_observer_with_options now takes a UseMutationObserverOptions instead of a web_sys::MutationObserverInit.
  • use_websocket:
    • takes now a &str instead of a String as its url parameter.
    • same for the returned send method.
    • The ready_state return type is now renamed to ConnectionReadyState instead of UseWebSocketReadyState.
    • The returned signals ready_state, message, message_bytes have now the type Signal<...> instead of ReadSignal<...> to make them more consistent with other functions.
    • The options reconnect_limit and reconnect_interval now take a u64 instead of Option<u64> to improve DX.
    • The option manual has been renamed to immediate to make it more consistent with other functions. To port please note that immediate is the inverse of manual (immediate = !manual).
    • Added documentation how pass it ergonomically as context.
  • use_color_mode:
    • The optional on_changed handler parameters have changed slightly. Please refer to the docs for more details.
  • Throttled or debounced functions cannot be FnOnce anymore.
  • All traits ClonableFn... have been removed.

Other Changes 🔥

  • use_websocket can use relative urls now
  • Callbacks in options don’t require to be cloneable anymore
  • Callback in use_raf_fn doesn’t require to be cloneable anymore
  • All (!) functions can now be safely called on the server. Specifically this includes the following that before panicked on the server:
    • use_scroll
    • use_event_listener
    • use_element_hover
    • on_click_outside
    • use_drop_zone
    • use_element_size
    • use_element_visibility
    • use_resize_observer
    • use_intersection_observer
    • use_mutation_observer

Fixes 🍕

  • use_element_visibility didn’t work in some cases on Chrome properly. This has been fixed.

[0.6.3] - 2023-08-12

Fixes 🍕

  • use_websocket panicked after unmount

[0.6.2] - 2023-08-03

Fixes 🍕

  • use_event_listener_with_options removes the handlers now correctly.

[0.6.1] - 2023-08-03

Fixes 🍕

  • use_storage now uses .get_untracked() to avoid warnings.

[0.6.0] - 2023-07-17

New Functions 🚀

  • use_draggable
  • use_to_string
  • is_err
  • is_ok
  • is_none
  • is_some
  • use_raf_fn

Breaking Changes 🛠

  • The following functions now accept a MaybeRwSignal as their initial/default value which means you can use a synchronized RwSignal in those places.
    • use_color_mode
    • use_cycle_list
    • use_favicon
    • use_storage
    • use_local_storage
    • use_session_storage
  • Instead of returning ReadSignal, the following functions now return Signal.
    • use_color_mode
    • use_favicon
    • use_storage
    • use_local_storage
    • use_session_storage

Fixes 🍕

  • use_drop_zone now uses .get_untracked() in event handlers

[0.5.0] - 2023-07-15

New Functions 🚀

  • use_drop_zone
  • use_websocket (thanks @sectore)
  • use_intl_number_format

Changes 🔥

  • Crate is ready for Server-Side Rendering. Enable feature ssr like you do for leptos.

[0.4.1] - 2023-07-07

New Functions 🚀

  • use_window_focus
  • use_window_scroll
  • use_document_visibility

[0.4.0] - 2023-07-03

Breaking Changes 🛠

  • Required leptos version is now 0.4
  • Following the changes in leptos there is no longer a stable crate feature required in order to use this library with a stable toolchain. If you want to use it with a nightly toolchain you have to enable the nightly feature only on leptos directly. No change is required for leptos-use itself.

[0.3.3] - 2023-06-24

New Functions 🚀

  • use_color_mode
  • use_cycle_list
  • use_active_element

Changes 🔥

  • You can now use this crate with the stable toolchain (thanks @lpotthast)
  • Set leptos dependency to default-features = false in order to enable SSR.

[0.3.2] - 2023-06-17

New Functions 🚀

  • use_css_var
  • use_element_hover

[0.3.1] - 2023-06-15

New Functions 🚀

  • use_interval_fn
  • use_interval

[0.3.0] - 2023-06-13

Breaking Changes 🛠

  • use_event_listener no longer returns a Box<dyn Fn()> but a impl Fn() + Clone

Changes 🔥

  • You can now specify a &str or Signal<String> with CSS selectors wherever a node ref is accepted
  • Callbacks of the following functions no longer require Clone
    • use_resize_observer
    • use_intersection_observer
  • These functions now also accept multiple target elements in addition to a single one:
    • use_resize_observer
    • use_intersection_observer

New Functions 🚀

  • whenever
  • use_mutation_observer
  • use_abs
  • on_click_outside

[0.2.1] - 2023-06-11

New Functions

  • use_intersection_observer
  • use_element_visibility

[0.2.0] - 2023-06-11

Breaking Changes

  • watch doesn’t accept immediate as a direct argument anymore. This is only provided by the option variant.
  • watch has now variant watch_with_options which allows for debouncing and throttling.

New Functions

  • use_storage
  • use_local_storage
  • use_session_storage
  • watch_debounced
  • watch_throttled
  • watch_pausable
  • use_ceil
  • use_round
  • use_media_query
  • use_preferred_dark
  • use_preferred_contrast
  • use_favicon
  • use_breakpoints

Other Changes

  • Function count badge in readme

[0.1.8/9] - 2023-06-05

  • Fixed documentation and doc tests running for functions behind #[cfg(web_sys_unstable_apis)]

[0.1.7] - 2023-06-05

New Function

  • use_element_size

[0.1.6] - 2023-06-03

Changes

  • Fixed documentation so all feature are documented

[0.1.5] - 2023-06-03

New Functions

  • use_floor
  • use_max
  • use_min

Changes

  • New feature: math that has to be activated in order to use the math functions.

[0.1.4] - 2023-06-02

New Functions

  • use_supported
  • use_resize_observer
  • watch
  • use_mouse

Changes

  • Use the crate default-struct-builder to provide ergonimic function options.

[0.1.3] - 2023-05-28

New Functions

  • use_scroll
  • use_debounce_fn

Other Changes

  • Better and more beautiful demo integration into the guide.

Functions

Storage

Elements

Browser

Intl

Sensors

Network

Animation

Watch

Utilities

Math

use_local_storage

Reactive LocalStorage.

LocalStorage stores data in the browser with no expiration time. Access is given to all pages from the same origin (e.g., all pages from “https://example.com” share the same origin). While data doesn’t expire the user can view, modify and delete all data stored. Browsers allow 5MB of data to be stored.

This is in contrast to use_session_storage which clears data when the page session ends and is not shared.

Usage

See use_storage for more details on how to use.

Installation

cargo add leptos-use-storage

Options

UseStorageOptions

Options for use with use_local_storage_with_options, use_session_storage_with_options and use_storage_with_options. Options for use_storage_with_options.

The filter is a type parameter so that the debounce and throttle code is only compiled into your app if you use it.

Every option is set with a builder method of the same name, e.g. UseStorageOptions::default().on_error(...). See also the API docs.

on_error

Type: Arc<dyn Fn(UseStorageError<E, D>) + Send + Sync>

listen_to_storage_changes

Type: bool

initial_value

Type: MaybeRwSignal<T>

filter

Type: F

delay_during_hydration

Type: bool

Delays the reading of the value from storage by one animation frame during hydration. This ensures that during hydration the value is the initial value just like it is on the server which helps prevent hydration errors. Defaults to false.

Source

Source • Docs

use_session_storage

Reactive SessionStorage.

SessionStorages stores data in the browser that is deleted when the page session ends. A page session ends when the browser closes the tab. Data is not shared between pages. While data doesn’t expire the user can view, modify and delete all data stored. Browsers allow 5MB of data to be stored.

Use use_local_storage to store data that is shared amongst all pages with the same origin and persists between page sessions.

Usage

See use_storage for more details on how to use.

Installation

cargo add leptos-use-storage

Options

UseStorageOptions

Options for use with use_local_storage_with_options, use_session_storage_with_options and use_storage_with_options. Options for use_storage_with_options.

The filter is a type parameter so that the debounce and throttle code is only compiled into your app if you use it.

Every option is set with a builder method of the same name, e.g. UseStorageOptions::default().on_error(...). See also the API docs.

on_error

Type: Arc<dyn Fn(UseStorageError<E, D>) + Send + Sync>

listen_to_storage_changes

Type: bool

initial_value

Type: MaybeRwSignal<T>

filter

Type: F

delay_during_hydration

Type: bool

Delays the reading of the value from storage by one animation frame during hydration. This ensures that during hydration the value is the initial value just like it is on the server which helps prevent hydration errors. Defaults to false.

Source

Source • Docs

use_storage

Reactive Storage.

The function returns a triplet (read_signal, write_signal, delete_from_storage_fn).

Demo

Usage

Pass a StorageType to determine the kind of key-value browser storage to use. The specified key is where data is stored. All values are stored as UTF-16 strings which is then encoded and decoded via the given *Codec. This value is synced with other calls using the same key on the same page and across tabs for local storage. See UseStorageOptions to see how behavior can be further customised.

Values are (en)decoded via the given codec. You can use any of the string codecs or a binary codec wrapped in Base64.

Please check the codec chapter to see what codecs are available and what feature flags they require.

Example

use leptos::prelude::*;
use leptos_use_storage::{StorageType, use_local_storage, use_session_storage, use_storage};
use serde::{Deserialize, Serialize};
use codee::string::{FromToStringCodec, JsonSerdeCodec, Base64};
use codee::binary::ProstCodec;

#[component]
pub fn Demo() -> impl IntoView {
// Binds a struct:
let (state, set_state, _) = use_local_storage::<MyState, JsonSerdeCodec>("my-state");

// Binds a bool, stored as a string:
let (flag, set_flag, remove_flag) = use_session_storage::<bool, FromToStringCodec>("my-flag");

// Binds a number, stored as a string:
let (count, set_count, _) = use_session_storage::<i32, FromToStringCodec>("my-count");
// Binds a number, stored in JSON:
let (count, set_count, _) = use_session_storage::<i32, JsonSerdeCodec>("my-count-kept-in-js");

// Bind string with SessionStorage stored in ProtoBuf format:
let (id, set_id, _) = use_storage::<String, Base64<ProstCodec>>(
    StorageType::Session,
    "my-id",
);
   view! { }
}

// Data stored in JSON must implement Serialize, Deserialize.
// And you have to add the feature "serde" to your project's Cargo.toml
#[derive(Serialize, Deserialize, Clone, PartialEq)]
pub struct MyState {
    pub hello: String,
    pub greeting: String,
}

// Default can be used to implement initial or deleted values.
// You can also use a signal via UseStorageOptions::default_value`
impl Default for MyState {
    fn default() -> Self {
        Self {
            hello: "hi".to_string(),
            greeting: "Hello".to_string()
        }
    }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the returned signals will just read/manipulate the initial_value without persistence.

If you use a value from storage to control conditional rendering you might run into issues with hydration.

use leptos::prelude::*;
use leptos_use_storage::use_session_storage;
use codee::string::FromToStringCodec;

#[component]
pub fn Example() -> impl IntoView {
let (flag, set_flag, _) = use_session_storage::<bool, FromToStringCodec>("my-flag");

view! {
    <Show when=move || flag.get()>
        <div>Some conditional content</div>
    </Show>
}
}

You can see hydration warnings in the browser console and the conditional parts of the app might never show up when rendered on the server and then hydrated in the browser. The reason for this is that the server has no access to storage and therefore will always use initial_value as described above. So on the server your app is always rendered as if the value from storage was initial_value. Then in the browser the actual stored value is used which might be different, hence during hydration the DOM looks different from the one rendered on the server which produces the hydration warnings.

The recommended way to avoid this is to use use_cookie instead because values stored in cookies are available on the server as well as in the browser.

If you still want to use storage instead of cookies you can use the delay_during_hydration option that will use the initial_value during hydration just as on the server and delay loading the value from storage by an animation frame. This gets rid of the hydration warnings and makes the app correctly render things. Some flickering might be unavoidable though.

use leptos::prelude::*;
use leptos_use_storage::{use_local_storage_with_options, UseStorageOptions};
use codee::string::FromToStringCodec;

#[component]
pub fn Example() -> impl IntoView {
let (flag, set_flag, _) = use_local_storage_with_options::<bool, FromToStringCodec>(
    "my-flag",
    UseStorageOptions::default().delay_during_hydration(true),
);

view! {
    <Show when=move || flag.get()>
        <div>Some conditional content</div>
    </Show>
}
}

Installation

cargo add leptos-use-storage

Options

UseStorageOptions

Options for use with use_local_storage_with_options, use_session_storage_with_options and use_storage_with_options. Options for use_storage_with_options.

The filter is a type parameter so that the debounce and throttle code is only compiled into your app if you use it.

Every option is set with a builder method of the same name, e.g. UseStorageOptions::default().on_error(...). See also the API docs.

on_error

Type: Arc<dyn Fn(UseStorageError<E, D>) + Send + Sync>

listen_to_storage_changes

Type: bool

initial_value

Type: MaybeRwSignal<T>

filter

Type: F

delay_during_hydration

Type: bool

Delays the reading of the value from storage by one animation frame during hydration. This ensures that during hydration the value is the initial value just like it is on the server which helps prevent hydration errors. Defaults to false.

Source

Source • Demo • Docs

use_active_element

Reactive document.activeElement

Demo

Usage

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_active_element::use_active_element;

#[component]
fn Demo() -> impl IntoView {
let active_element = use_active_element();

Effect::new(move || {
    log!("focus changed to {:?}", active_element.get());
});

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns a Signal that always contains the value None.

Installation

cargo add leptos-use-active-element

Source

Source • Demo • Docs

use_document

SSR safe document(). This returns just a new-type wrapper around Option<Document>. Calling this amounts to None on the server and Some(Document) on the client.

It provides some convenient methods for working with the document like body().

Usage

use leptos::prelude::*;
use leptos_use_document::use_document;

#[component]
fn Demo() -> impl IntoView {
let document = use_document();

// Returns `None` on the server but will not panic.
let body = document.body();

view! { }
}

Installation

cargo add leptos-use-document

Types

Source

Source • Docs

use_document_visibility

Reactively track document.visibilityState

Demo

Usage

use leptos::prelude::*;
use leptos_use_document_visibility::use_document_visibility;

#[component]
fn Demo() -> impl IntoView {
let visibility = use_document_visibility();

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns a Signal that always contains the value web_sys::VisibilityState::Hidden.

Installation

cargo add leptos-use-document-visibility

Source

Source • Demo • Docs

use_draggable

Make elements draggable.

Demo

Usage

use leptos::prelude::*;
use leptos::html::Div;
use leptos_use_draggable::{use_draggable_with_options, UseDraggableOptions, UseDraggableReturn};
use leptos_use_core::Position;

#[component]
fn Demo() -> impl IntoView {
let el = NodeRef::<Div>::new();

// `style` is a helper string "left: {x}px; top: {y}px;"
let UseDraggableReturn {
    x,
    y,
    style,
    ..
} = use_draggable_with_options(
    el,
    UseDraggableOptions::default().initial_value(Position { x: 40.0, y: 40.0 }),
);

view! {
    <div node_ref=el style=move || format!("position: fixed; {}", style.get())>
        Drag me! I am at { x }, { y }
    </div>
}
}

Installation

cargo add leptos-use-draggable

Options

UseDraggableOptions

Options for use_draggable_with_options.

Every option is set with a builder method of the same name, e.g. UseDraggableOptions::default().exact(...). See also the API docs.

exact

Type: Signal<bool>

Only start the dragging when click on the element directly. Defaults to false.

prevent_default

Type: Signal<bool>

Prevent events defaults. Defaults to false.

stop_propagation

Type: Signal<bool>

Prevent events propagation. Defaults to false.

dragging_element

Type: DragEl

Element to attach pointermove and pointerup events to. Defaults to window.

handle

Type: Option<HandleEl>

Handle that triggers the drag event. Defaults to target.

pointer_types

Type: Vec<PointerType>

Pointer types that listen to. Defaults to [Mouse, Touch, Pen].

initial_value

Type: MaybeRwSignal<Position>

Initial position of the element. Defaults to { x: 0, y: 0 }.

target_offset

Type: Arc<dyn Fn(web_sys::EventTarget) -> (f64, f64)>

Computes the initial offset of the target element for drag positioning. Defaults to using its bounding client rectangle’s left and top values.

on_start

Type: Arc<dyn Fn(UseDraggableCallbackArgs) -> bool + Send + Sync>

Callback when the dragging starts. Return false to prevent dragging.

on_move

Type: Arc<dyn Fn(UseDraggableCallbackArgs) + Send + Sync>

Callback during dragging.

on_end

Type: Arc<dyn Fn(UseDraggableCallbackArgs) + Send + Sync>

Callback when dragging end.

Source

Source • Demo • Docs

use_drop_zone

Create a zone where files can be dropped.

Demo

Usage

use leptos::prelude::*;
use leptos::html::Div;
use leptos_use_drop_zone::{use_drop_zone_with_options, UseDropZoneOptions, UseDropZoneReturn};

#[component]
fn Demo() -> impl IntoView {
let drop_zone_el = NodeRef::<Div>::new();

let on_drop = |event| {
    // called when files are dropped on zone
};

let UseDropZoneReturn {
    is_over_drop_zone,
    ..
} = use_drop_zone_with_options(
    drop_zone_el,
    UseDropZoneOptions::default().on_drop(on_drop)
);

view! {
    <div node_ref=drop_zone_el>
        "Drop files here"
    </div>
}
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the returned file signal always contains an empty Vec and is_over_drop_zone contains always false

Installation

cargo add leptos-use-drop-zone

Options

UseDropZoneOptions

Options for use_drop_zone_with_options.

Every option is set with a builder method of the same name, e.g. UseDropZoneOptions::default().on_drop(...). See also the API docs.

on_drop

Type: Arc<dyn Fn(UseDropZoneEvent) + Send + Sync>

Event handler for the drop event

on_enter

Type: Arc<dyn Fn(UseDropZoneEvent) + Send + Sync>

Event handler for the dragenter event

on_leave

Type: Arc<dyn Fn(UseDropZoneEvent) + Send + Sync>

Event handler for the dragleave event

on_over

Type: Arc<dyn Fn(UseDropZoneEvent) + Send + Sync>

Event handler for the dragover event

Source

Source • Demo • Docs

use_element_bounding

Reactive bounding box of an HTML element

Demo

Usage

use leptos::prelude::*;
use leptos::html::Div;
use leptos_use_element_bounding::{use_element_bounding, UseElementBoundingReturn};

#[component]
fn Demo() -> impl IntoView {
let el = NodeRef::<Div>::new();
let UseElementBoundingReturn {
    x, y, top,right,bottom,left, width, height, ..
} = use_element_bounding(el);

view! { <div node_ref=el></div> }
}

SendWrapped Return

The returned closure update is a sendwrapped function. It can only be called from the same thread that called use_element_bounding.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the returned signals always are 0.0 and update is a no-op.

Installation

cargo add leptos-use-element-bounding

Options

UseElementBoundingOptions

Options for use_element_bounding_with_options.

Every option is set with a builder method of the same name, e.g. UseElementBoundingOptions::default().reset(...). See also the API docs.

reset

Type: bool

Reset values to 0 on component disposal

Default: true

window_resize

Type: bool

Listen to window resize event

Default: true

window_scroll

Type: bool

Listen to window scroll event

Default: true

immediate

Type: bool

Immediately call update

Default: true

Source

Source • Demo • Docs

use_element_size

Reactive size of an HTML element.

Please refer to ResizeObserver on MDN for more details.

Demo

Usage

use leptos::{html::Div, prelude::*};
use leptos_use_element_size::{use_element_size, UseElementSizeReturn};

#[component]
fn Demo() -> impl IntoView {
let el = NodeRef::<Div>::new();

let UseElementSizeReturn { width, height } = use_element_size(el);

view! {
    <div node_ref=el>
        "Width: " {width}
        "Height: " {height}
    </div>
}
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the returned signals always contain the value of the initial_size option.

See also

Installation

cargo add leptos-use-element-size

Options

UseElementSizeOptions

Options for use_element_size_with_options.

Every option is set with a builder method of the same name, e.g. UseElementSizeOptions::default().initial_size(...). See also the API docs.

initial_size

Type: Size

Initial size returned before any measurements on the target are done. Also the value reported at first when the target is a signal and changes.

box_

Type: Option<web_sys::ResizeObserverBoxOptions>

The box that is used to determine the dimensions of the target. Defaults to ContentBox.

Source

Source • Demo • Docs

use_element_visibility

Tracks the visibility of an element within the viewport.

Demo

Usage

use leptos::prelude::*;
use leptos::html::Div;
use leptos_use_element_visibility::use_element_visibility;

#[component]
fn Demo() -> impl IntoView {
let el = NodeRef::<Div>::new();

let is_visible = use_element_visibility(el);

view! {
    <div node_ref=el>
        <h1>{is_visible}</h1>
    </div>
}
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns a Signal that always contains the value false.

See also

Installation

cargo add leptos-use-element-visibility

Options

UseElementVisibilityOptions

Options for use_element_visibility_with_options.

Every option is set with a builder method of the same name, e.g. UseElementVisibilityOptions::default().viewport(...). See also the API docs.

viewport

Type: Option<El>

A web_sys::Element or web_sys::Document object which is an ancestor of the intended target, whose bounding rectangle will be considered the viewport. Any part of the target not visible in the visible area of the root is not considered visible. Defaults to None (which means the root document will be used). Please note that setting this to a Some(document) may not be supported by all browsers. See Browser Compatibility

Source

Source • Demo • Docs

use_intersection_observer

Reactive IntersectionObserver.

Detects that a target element’s visibility inside the viewport.

Demo

Usage

use leptos::prelude::*;
use leptos::html::Div;
use leptos_use_intersection_observer::use_intersection_observer;

#[component]
fn Demo() -> impl IntoView {
let el = NodeRef::<Div>::new();
let (is_visible, set_visible) = signal(false);

use_intersection_observer(
    el,
    move |entries, _| {
        set_visible.set(entries[0].is_intersecting());
    },
);

view! {
    <div node_ref=el>
        <h1>"Hello World"</h1>
    </div>
}
}

SendWrapped Return

The returned closures pause, resume and stop are sendwrapped functions. They can only be called from the same thread that called use_intersection_observer.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this amounts to a no-op.

See also

Installation

cargo add leptos-use-intersection-observer

Options

UseIntersectionObserverOptions

Options for use_intersection_observer_with_options.

Every option is set with a builder method of the same name, e.g. UseIntersectionObserverOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

If true, the IntersectionObserver will be attached immediately. Otherwise it will only be attached after the returned resume closure is called. That is use_intersections_observer will be started “paused”.

root

Type: Option<El>

A web_sys::Element or web_sys::Document object which is an ancestor of the intended target, whose bounding rectangle will be considered the viewport. Any part of the target not visible in the visible area of the root is not considered visible. Defaults to None (which means the root document will be used). Please note that setting this to a Some(document) may not be supported by all browsers. See Browser Compatibility

root_margin

Type: String

A string which specifies a set of offsets to add to the root’s bounding box when calculating intersections, effectively shrinking or growing the root for calculation purposes. The syntax is approximately the same as that for the CSS margin property; see The intersection root and root margin for more information on how the margin works and the syntax. The default is "0px".

thresholds

Type: Vec<f64>

A Vec of numbers between 0.0 and 1.0, specifying a ratio of intersection area to total bounding box area for the observed target. A value of 0.0 means that even a single visible pixel counts as the target being visible. 1.0 means that the entire target element is visible. See Thresholds for a more in-depth description of how thresholds are used. The default is a single threshold of [0.0].

Source

Source • Demo • Docs

use_mouse_in_element

Reactive mouse position related to an element.

Demo

Usage

use leptos::prelude::*;
use leptos::html::Div;
use leptos_use_mouse_in_element::{use_mouse_in_element, UseMouseInElementReturn};

#[component]
fn Demo() -> impl IntoView {
let target = NodeRef::<Div>::new();
let UseMouseInElementReturn { x, y, is_outside, .. } = use_mouse_in_element(target);

view! {
    <div node_ref=target>
        <h1>Hello world</h1>
    </div>
}
}

SendWrapped Return

The returned closure stop is a sendwrapped function. It can only be called from the same thread that called use_mouse_in_element.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns simple Signals with the initial_value for x and y, no-op for stop, is_outside = true and 0.0 for the rest of the signals.

Installation

cargo add leptos-use-mouse-in-element

Options

UseMouseInElementOptions

Options for use_mouse_in_element_with_options.

Every option is set with a builder method of the same name, e.g. UseMouseInElementOptions::default().coord_type(...). See also the API docs.

coord_type

Type: UseMouseCoordType<Ex>

How to extract the x, y coordinates from mouse events or touches

target

Type: El

Listen events on target element. Defaults to window

touch

Type: bool

Listen to touchmove events. Defaults to true.

reset_on_touch_ends

Type: bool

Reset to initial value when touchend event fired. Defaults to false

initial_value

Type: Position

Initial values. Defaults to {x: 0.0, y: 0.0}.

handle_outside

Type: bool

If true updates the element_x and element_y signals even if the mouse is outside of the element. If false it doesn’t update them when outside. Defaults to true.

Source

Source • Demo • Docs

use_mutation_observer

Reactive MutationObserver.

Watch for changes being made to the DOM tree.

Demo

Usage

use leptos::prelude::*;
use leptos::html::Pre;
use leptos_use_element::{use_mutation_observer_with_options, UseMutationObserverOptions};

#[component]
fn Demo() -> impl IntoView {
let el = NodeRef::<Pre>::new();
let (text, set_text) = signal("".to_string());

use_mutation_observer_with_options(
    el,
    move |mutations, _| {
        if let Some(mutation) = mutations.first() {
            set_text.update(|text| *text = format!("{text}\n{:?}", mutation.attribute_name()));
        }
    },
    UseMutationObserverOptions::default().attributes(true),
);

view! {
    <pre node_ref=el>{ text }</pre>
}
}

SendWrapped Return

The returned closure stop is a sendwrapped function. It can only be called from the same thread that called use_mouse_in_element.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this amounts to a no-op.

Installation

cargo add leptos-use-element

Options

UseMutationObserverOptions

Options for use_mutation_observer_with_options.

Every option is set with a builder method of the same name, e.g. UseMutationObserverOptions::default().subtree(...). See also the API docs.

subtree

Type: bool

Set to true to extend monitoring to the entire subtree of nodes rooted at target. All of the other properties are then extended to all of the nodes in the subtree instead of applying solely to the target node. The default value is false.

child_list

Type: bool

Set to true to monitor the target node (and, if subtree is true, its descendants) for the addition of new child nodes or removal of existing child nodes. The default value is false.

attributes

Type: bool

Set to true to watch for changes to the value of attributes on the node or nodes being monitored. The default value is true if either of attribute_filter or attribute_old_value is specified, otherwise the default value is false.

attribute_filter

Type: Option<Vec<String>>

An array of specific attribute names to be monitored. If this property isn’t included, changes to all attributes cause mutation notifications.

attribute_old_value

Type: bool

Set to true to record the previous value of any attribute that changes when monitoring the node or nodes for attribute changes; See Monitoring attribute values for an example of watching for attribute changes and recording values. The default value is false.

character_data

Type: Option<bool>

Set to true to monitor the specified target node (and, if subtree is true, its descendants) for changes to the character data contained within the node or nodes. The default value is true if character_data_old_value is specified, otherwise the default value is false.

character_data_old_value

Type: bool

Set to true to record the previous value of a node’s text whenever the text changes on nodes being monitored. The default value is false.

Source

Source • Demo • Docs

use_resize_observer

Reports changes to the dimensions of an Element’s content or the border-box.

Please refer to ResizeObserver on MDN for more details.

Demo

Usage

use leptos::{html::Div, prelude::*};
use leptos_use_resize_observer::use_resize_observer;

#[component]
fn Demo() -> impl IntoView {
let el = NodeRef::<Div>::new();
let (text, set_text) = signal("".to_string());

use_resize_observer(
    el,
    move |entries, observer| {
        let rect = entries[0].content_rect();
        set_text.set(format!("width: {}\nheight: {}", rect.width(), rect.height()));
    },
);

view! {
    <div node_ref=el>{ move || text.get() }</div>
}
}

SendWrapped Return

The returned closure stop is a sendwrapped function. It can only be called from the same thread that called use_resize_observer.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this amounts to a no-op.

See also

Installation

cargo add leptos-use-resize-observer

Options

UseResizeObserverOptions

Options for use_resize_observer_with_options.

Every option is set with a builder method of the same name, e.g. UseResizeObserverOptions::default().box_(...). See also the API docs.

box_

Type: Option<web_sys::ResizeObserverBoxOptions>

The box that is used to determine the dimensions of the target. Defaults to ContentBox.

Source

Source • Demo • Docs

use_window

SSR safe window(). This returns just a new-type wrapper around Option<Window>. Calling this amounts to None on the server and Some(Window) on the client.

It provides some convenient methods for working with the window like document() and navigator(). These will all return None on the server.

Usage

use leptos::prelude::*;
use leptos_use_window::use_window;

#[component]
fn Demo() -> impl IntoView {
let window = use_window();

// Returns `None` on the server but will not panic.
let navigator = window.navigator();

view! { }
}

Installation

cargo add leptos-use-window

Types

Source

Source • Docs

use_window_focus

Reactively track window focus with window.onfocus and window.onblur events.

Demo

Usage

use leptos::prelude::*;
use leptos_use_window_focus::use_window_focus;

#[component]
fn Demo() -> impl IntoView {
let focused = use_window_focus();

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns a Signal that is always true.

Installation

cargo add leptos-use-window-focus

Source

Source • Demo • Docs

use_window_scroll

Reactive window scroll.

Demo

Usage

use leptos::prelude::*;
use leptos_use_window_scroll::use_window_scroll;

#[component]
fn Demo() -> impl IntoView {
let (x, y) = use_window_scroll();

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns Signals that are always 0.0.

Installation

cargo add leptos-use-window-scroll

Source

Source • Demo • Docs

use_window_size

Reactive window size.

Demo

Usage

use leptos::*;
use leptos_use_window_size::{use_window_size, UseWindowSizeReturn};

#[component]
fn Demo() -> impl IntoView {
let UseWindowSizeReturn { width, height } = use_window_size();

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the width and height are always initial_size which defaults to Size { width: INFINITY, height: INFINITY }.

Installation

cargo add leptos-use-window-size

Options

UseWindowSizeOptions

Options for use_window_size_with_options.

Every option is set with a builder method of the same name, e.g. UseWindowSizeOptions::default().initial_size(...). See also the API docs.

initial_size

Type: Size

The initial size before anything is measured (like on the server side). Defaults to Size { width: INFINITY, height: INFINITY }.

listen_orientation

Type: bool

Listen to the window orientationchange event. Defaults to true.

include_scrollbar

Type: bool

Whether the scrollbar should be included in the width and height Only effective when measure_type is MeasureType::Inner. Defaults to true.

measure_type

Type: MeasureType

Use window.innerWidth or window.outerWidth. Defaults to MeasureType::Inner.

Source

Source • Demo • Docs

use_breakpoints

Reactive viewport breakpoints.

Demo

Usage

use leptos::prelude::*;
use leptos_use_breakpoints::{use_breakpoints, BreakpointsTailwind, breakpoints_tailwind};

#[component]
fn Demo() -> impl IntoView {

let screen_width = use_breakpoints(breakpoints_tailwind());

use BreakpointsTailwind::*;

let sm_and_larger = screen_width.ge(Sm);
let larger_than_sm = screen_width.gt(Sm);
let lg_and_smaller = screen_width.le(Lg);
let smaller_than_lg = screen_width.lt(Lg);

view! { }
}

Breakpoints

There are many predefined breakpoints for major UI frameworks. The following are provided.

You can also provide your own breakpoints.

use std::collections::HashMap;
use leptos::prelude::*;
use leptos_use_breakpoints::use_breakpoints;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum MyBreakpoints {
    Tablet,
    Laptop,
    Desktop,
}

fn my_breakpoints() -> HashMap<MyBreakpoints, u32> {
    use MyBreakpoints::*;

    HashMap::from([
        (Tablet, 640),
        (Laptop, 1024),
        (Desktop, 1280),
    ])
}

#[component]
fn Demo() -> impl IntoView {
    let screen_width = use_breakpoints(my_breakpoints());

    use MyBreakpoints::*;

    let laptop = screen_width.between(Laptop, Desktop);

    view! { }
}

Non-reactive methods

For every reactive method there is also a non-reactive variant that is prefixed with is_

use leptos::prelude::*;
use leptos_use_breakpoints::{use_breakpoints, BreakpointsTailwind, breakpoints_tailwind};

#[component]
fn Demo() -> impl IntoView {

let screen_width = use_breakpoints(breakpoints_tailwind());

use BreakpointsTailwind::*;

let sm_and_larger = screen_width.is_ge(Sm);
let larger_than_sm = screen_width.is_gt(Sm);
let lg_and_smaller = screen_width.is_le(Lg);
let smaller_than_lg = screen_width.is_lt(Lg);

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

Since internally this uses use_media_query, which returns always false on the server, the returned methods also will return false.

Installation

cargo add leptos-use-breakpoints

Types

Source

Source • Demo • Docs

use_broadcast_channel

Reactive BroadcastChannel API.

Closes a broadcast channel automatically when the component is cleaned up.

Demo

Usage

The BroadcastChannel interface represents a named channel that any browsing context of a given origin can subscribe to. It allows communication between different documents (in different windows, tabs, frames, or iframes) of the same origin.

Messages are broadcasted via a message event fired at all BroadcastChannel objects listening to the channel.

use leptos::prelude::*;
use leptos_use_broadcast_channel::{use_broadcast_channel, UseBroadcastChannelReturn};
use codee::string::FromToStringCodec;

#[component]
fn Demo() -> impl IntoView {
let UseBroadcastChannelReturn {
    is_supported,
    message,
    post,
    error,
    close,
    ..
} = use_broadcast_channel::<bool, FromToStringCodec>("some-channel-name");

post(&true);

close();

view! { }
}

Values are (en)decoded via the given codec. You can use any of the string codecs or a binary codec wrapped in Base64.

Please check the codec chapter to see what codecs are available and what feature flags they require.

use leptos::prelude::*;
use serde::{Deserialize, Serialize};
use leptos_use_broadcast_channel::use_broadcast_channel;
use codee::string::JsonSerdeCodec;

// Data sent in JSON must implement Serialize, Deserialize:
#[derive(Serialize, Deserialize, Clone, PartialEq)]
pub struct MyState {
    pub playing_lego: bool,
    pub everything_is_awesome: String,
}

#[component]
fn Demo() -> impl IntoView {
use_broadcast_channel::<MyState, JsonSerdeCodec>("everyting-is-awesome");
view! { }
}

SendWrapped Return

The returned closures post and close are sendwrapped functions. They can only be called from the same thread that called use_broadcast_channel.

Installation

cargo add leptos-use-broadcast-channel

Source

Source • Demo • Docs

use_clipboard

Reactive Clipboard API.

Provides the ability to respond to clipboard commands (cut, copy, and paste) as well as to asynchronously read from and write to the system clipboard. Access to the contents of the clipboard is gated behind the Permissions API. Without user permission, reading or altering the clipboard contents is not permitted.

Demo

Usage

use leptos::prelude::*;
use leptos_use_clipboard::{use_clipboard, UseClipboardReturn};

#[component]
fn Demo() -> impl IntoView {
let UseClipboardReturn { is_supported, text, copied, copy } = use_clipboard();

view! {
    <Show
        when=move || is_supported.get()
        fallback=move || view! { <p>Your browser does not support Clipboard API</p> }
    >
        <button on:click={
            let copy = copy.clone();
            move |_| copy("Hello!")
        }>
            <Show when=move || copied.get() fallback=move || "Copy">
                "Copied!"
            </Show>
        </button>
    </Show>
}
}

SendWrapped Return

The returned closures copy is a sendwrapped function. It can only be called from the same thread that called use_clipboard.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the returnd text signal will always be None and copy is a no-op.

Installation

cargo add leptos-use-clipboard

Options

UseClipboardOptions

Options for use_clipboard_with_options.

Every option is set with a builder method of the same name, e.g. UseClipboardOptions::default().read(...). See also the API docs.

read

Type: bool

When true event handlers are added so that the returned signal text is updated whenever the clipboard changes. Defaults to false.

Please note that clipboard changes are only detected when copying or cutting text inside the same document.

copied_reset_delay

Type: f64

After how many milliseconds after copying should the returned signal copied be set to false? Defaults to 1500.

Source

Source • Demo • Docs

use_color_mode

Reactive color mode (dark / light / customs) with auto data persistence.

Demo

Usage

use leptos::prelude::*;
use leptos_use_color_mode::{use_color_mode, UseColorModeReturn};

#[component]
fn Demo() -> impl IntoView {
let UseColorModeReturn {
    mode, // Signal<ColorMode::dark | ColorMode::light>
    set_mode,
    ..
} = use_color_mode();

view! { }
}

By default, it will match with users’ browser preference using use_preferred_dark (a.k.a. ColorMode::Auto). When reading the signal, it will by default return the current color mode (ColorMode::Dark, ColorMode::Light or your custom modes ColorMode::Custom("some-custom")). The ColorMode::Auto variant can be included in the returned modes by enabling the emit_auto option and using use_color_mode_with_options. When writing to the signal (set_mode), it will trigger DOM updates and persist the color mode to local storage (or your custom storage). You can pass ColorMode::Auto to set back to auto mode.

use leptos::prelude::*;
use leptos_use_color_mode::{ColorMode, use_color_mode, UseColorModeReturn};

#[component]
fn Demo() -> impl IntoView {
let UseColorModeReturn { mode, set_mode, .. } = use_color_mode();

mode.get(); // ColorMode::Dark or ColorMode::Light

set_mode.set(ColorMode::Dark); // change to dark mode and persist

set_mode.set(ColorMode::Auto); // change to auto mode

view! { }
}

Options

use leptos::prelude::*;
use leptos_use_color_mode::{use_color_mode_with_options, UseColorModeOptions, UseColorModeReturn};

#[component]
fn Demo() -> impl IntoView {
let UseColorModeReturn { mode, set_mode, .. } = use_color_mode_with_options(
    UseColorModeOptions::default()
        .attribute("theme") // instead of writing to `class`
        .custom_modes(vec![
            // custom colors in addition to light/dark
            "dim".to_string(),
            "cafe".to_string(),
        ]),
); // Signal<ColorMode::Dark | ColorMode::Light | ColorMode::Custom("dim") | ColorMode::Custom("cafe")>

view! { }
}

To persist color mode in a cookie, use use_cookie_with_options and specify .cookie_enabled(true).

Note: To work with SSR you have to add the axum or actix feature as described in use_cookie.

#![allow(unused)]
fn main() {
use leptos::prelude::*;
use leptos_meta::*;
use leptos_use_color_mode::{use_color_mode_with_options, UseColorModeOptions, UseColorModeReturn};

#[component]
fn Demo() -> impl IntoView {
let UseColorModeReturn { mode, set_mode, .. } = use_color_mode_with_options(
    UseColorModeOptions::default()
        .cookie_enabled(true),
);

// This adds the color mode class to the `<html>` element even with SSR
view! {
    <Html {..} class=move || mode.get().to_string()/>
}
}
}

For a working example please check out the ssr example.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this will try to read the Sec-CH-Prefers-Color-Scheme header to determine the color mode. If the header is not present it will return ColorMode::Light. Please have a look at the linked documentation above for that header to see browser support as well as potential server requirements.

If you’re using axum you have to enable the "axum" feature in your Cargo.toml. In case it’s actix-web enable the feature "actix".

Bring your own header

In case you’re neither using Axum nor Actix or the default implementation is not to your liking, you can provide your own way of reading the color scheme header value using the option UseColorModeOptions::ssr_color_header_getter.

If cookie_enabled is set to true, a cookie will be used and if present this value will be used on the server as well as on the client. Please note that you have to add the axum or actix feature as described in use_cookie.

ColorMode::Auto is stored together with the system’s mode it resolves to (auto-dark or auto-light), and rewritten when the system switches while a page is open. Without the header above, the server renders that stored system mode, so only a first visit, or a system that switched between two visits, shows ColorMode::Light until hydration. A custom mode therefore can’t start with auto-. The cookie lives for a year by default (UseColorModeOptions::cookie_max_age).

See also

Installation

cargo add leptos-use-color-mode

Options

UseColorModeOptions

Every option is set with a builder method of the same name, e.g. UseColorModeOptions::default().target(...). See also the API docs.

target

Type: El

Element that the color mode will be applied to. Defaults to the root element of the document (<html>).

attribute

Type: String

HTML attribute applied to the target element. Defaults to "class".

initial_value

Type: MaybeRwSignal<ColorMode>

Initial value of the color mode. Defaults to "Auto".

initial_value_from_url_param

Type: Option<String>

Discover the initial value of the color mode from an URL parameter. Defaults to None.

initial_value_from_url_param_to_storage

Type: bool

Write the initial value of the discovered color mode from URL parameter to storage. This only has an effect if initial_value_from_url_param is specified. Defaults to false.

custom_modes

Type: Vec<String>

Custom modes that you plan to use as ColorMode::Custom(x). Defaults to vec![].

on_changed

Type: OnChangedFn

Custom handler that is called on updates. If specified this will override the default behavior. To get the default behaviour back you can call the provided default_handler function. It takes two parameters: - mode: ColorMode: The color mode to change to. -default_handler: Arc<dyn Fn(ColorMode)>: The default handler that would have been called if the on_changed handler had not been specified.

storage_signal

Type: Option<RwSignal<ColorMode>>

When provided, useStorage will be skipped. Defaults to None.

storage_key

Type: String

Key to persist the data into localStorage/sessionStorage. Defaults to "leptos-use-color-scheme".

storage

Type: StorageType

Storage type, can be Local or Session or custom. Defaults to Local.

storage_enabled

Type: bool

If the color mode should be persisted. Ignored when cookie_enabled is set: the cookie is then the only copy, since the server can read it and a second one could only disagree with it. Defaults to true.

Type: String

Name of the cookie that should be used to persist the color mode. Defaults to "leptos-use-color-scheme".

Type: bool

If the color mode should be persisted through a cookie. Defaults to false.

Type: Option<i64>

Max-Age of the cookie in milliseconds. None makes it a session cookie. Defaults to one year.

emit_auto

Type: bool

Emit auto mode from state

When set to true, preferred mode won’t be translated into light or dark. This is useful when the fact that auto mode was selected needs to be known.

Defaults to false.

transition_enabled

Type: bool

If transitions on color mode change are enabled. Defaults to false.

listen_to_storage_changes

Type: bool

Listen to changes to this storage key from somewhere else. Defaults to true.

ssr_color_header_getter

Type: Arc<dyn Fn() -> Option<String> + Send + Sync>

Getter function to return the string value of the Sec-CH-Prefers-Color-Scheme header. When you use one of the features "axum" or "actix" there’s a valid default implementation provided.

Source

Source • Demo • Docs

use_cookie

SSR-friendly and reactive cookie access.

You can use this function multiple times for the same cookie and their signals will synchronize (even across windows/tabs). But there is no way to listen to changes to document.cookie directly so in case something outside of this function changes the cookie, the signal will not be updated.

When the options max_age or expire is given then the returned signal will automatically turn to None after that time.

Demo

Usage

The example below creates a cookie called counter. If the cookie doesn’t exist, it is initially set to a random value. Whenever we update the counter variable, the cookie will be updated accordingly.

use leptos::prelude::*;
use leptos_use_cookie::use_cookie;
use codee::string::FromToStringCodec;
use rand::random;


#[component]
fn Demo() -> impl IntoView {
let (counter, set_counter) = use_cookie::<u32, FromToStringCodec>("counter");

let reset = move || set_counter.set(Some(random()));

if counter.get().is_none() {
    reset();
}

let increase = move || {
    set_counter.set(counter.get().map(|c| c + 1));
};

view! {
    <p>Counter: {move || counter.get().map(|c| c.to_string()).unwrap_or("—".to_string())}</p>
    <button on:click=move |_| reset()>Reset</button>
    <button on:click=move |_| increase()>+</button>
}
}

Values are (en)decoded via the given codec. You can use any of the string codecs or a binary codec wrapped in Base64.

Please check the codec chapter to see what codecs are available and what feature flags they require.

As part of the options when you use use_cookie_with_options you can specify cookie attributes.

use cookie::SameSite;
use leptos::prelude::*;
use leptos_use_cookie::{use_cookie_with_options, UseCookieOptions};
use codee::string::FromToStringCodec;

#[component]
fn Demo() -> impl IntoView {
let (cookie, set_cookie) = use_cookie_with_options::<bool, FromToStringCodec>(
    "user_info",
    UseCookieOptions::default()
        .max_age(3600_000) // one hour
        .same_site(SameSite::Lax)
);

view! {}
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

This works equally well on the server or the client. On the server this function reads the cookie from the HTTP request header and writes it back into the HTTP response header according to options (if provided). The returned WriteSignal may not affect the cookie headers on the server! It will try and write the headers but if this happens after the headers have already been streamed to the client then this will have no effect.

If you’re using axum you have to enable the "axum" feature in your Cargo.toml. In case it’s actix-web enable the feature "actix"..

Bring your own header

In case you’re neither using Axum nor Actix or the default implementation is not to your liking, you can provide your own way of reading and writing the cookie header value.

use cookie::Cookie;
use leptos::prelude::*;
use serde::{Deserialize, Serialize};
use leptos_use_cookie::{use_cookie_with_options, UseCookieOptions};
use codee::string::JsonSerdeCodec;

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct Auth {
    pub username: String,
    pub token: String,
}

#[component]
fn Demo() -> impl IntoView {
use_cookie_with_options::<Auth, JsonSerdeCodec>(
    "auth",
    UseCookieOptions::default()
        .ssr_cookies_header_getter(|| {
            #[cfg(feature = "ssr")]
            {
                Some("Somehow get the value of the cookie header as a string".to_owned())
            }
            #[cfg(not(feature = "ssr"))]
            None
        })
        .ssr_set_cookie(|cookie: &Cookie| {
            #[cfg(feature = "ssr")]
            {
                // somehow insert the Set-Cookie header for this cookie
            }
        }),
);
view! {}
}

Installation

cargo add leptos-use-cookie

Options

UseCookieOptions

Options for use_cookie_with_options.

Every option is set with a builder method of the same name, e.g. UseCookieOptions::default().max_age(...). See also the API docs.

max_age

Type: Option<i64>

Max-Age of the cookie in milliseconds. The returned signal will turn to None after the max age is reached. Default: None

The cookie storage model specification states that if both expires and max_age is set, then max_age takes precedence, but not all clients may obey this, so if both are set, they should point to the same date and time!

If neither of expires and max_age is set, the cookie will be session-only and removed when the user closes their browser.

expires

Type: Option<i64>

Expiration date-time of the cookie as UNIX timestamp in seconds. The signal will turn to None after the expiration date-time is reached. Default: None

The cookie storage model specification states that if both expires and max_age is set, then max_age takes precedence, but not all clients may obey this, so if both are set, they should point to the same date and time!

If neither of expires and max_age is set, the cookie will be session-only and removed when the user closes their browser.

http_only

Type: bool

Specifies the HttpOnly cookie attribute. When true, the HttpOnly attribute is set; otherwise it is not. By default, the HttpOnly attribute is not set.

Be careful when setting this to true, as compliant clients will not allow client-side JavaScript to see the cookie in document.cookie.

secure

Type: bool

Specifies the value for the Secure cookie attribute. When true, the Secure attribute is set; otherwise it is not. By default, the Secure attribute is not set.

Be careful when setting this to true, as compliant clients will not send the cookie back to the server in the future if the browser does not have an HTTPS connection. This can lead to hydration errors.

domain

Type: Option<String>

Specifies the value for the Domain cookie attribute. By default, no domain is set, and most clients will consider applying the cookie only to the current domain.

path

Type: Option<String>

Specifies the value for the Path cookie attribute. By default, the path is considered the “default path”.

same_site

Type: Option<SameSite>

Specifies the value for the SameSite cookie attribute.

  • 'Some(SameSite::Lax)' will set the SameSite attribute to Lax for lax same-site enforcement.
  • 'Some(SameSite::None)' will set the SameSite attribute to None for an explicit cross-site cookie.
  • 'Some(SameSite::Strict)' will set the SameSite attribute to Strict for strict same-site enforcement.
  • None will not set the SameSite attribute (default).

More information about the different enforcement levels can be found in the specification.

default_value

Type: Option<T>

The default cookie value in case the cookie is not set. Defaults to None.

readonly

Type: bool

If true the returned WriteSignal will not affect the actual cookie. Default: false

ssr_cookies_header_getter

Type: Arc<dyn Fn() -> Option<String> + Send + Sync>

Getter function to return the string value of the cookie header. When you use one of the features "axum" or "actix" there’s a valid default implementation provided.

Type: Arc<dyn Fn(&Cookie) + Send + Sync>

Function to add a set cookie header to the response on the server. When you use one of the features "axum" or "actix" there’s a valid default implementation provided.

on_error

Type: Arc<dyn Fn(CodecError<E, D>) + Send + Sync>

Callback for encoding/decoding errors. Defaults to logging the error to the console.

Source

Source • Demo • Docs

use_css_var

Manipulate CSS variables.

Demo

Usage

use leptos::prelude::*;
use leptos_use_css_var::use_css_var;

#[component]
fn Demo() -> impl IntoView {
let (color, set_color) = use_css_var("--color");

set_color.set("red".to_string());

view! { }
}

The variable name itself can be a Signal.

use leptos::prelude::*;
use leptos_use_css_var::use_css_var;

#[component]
fn Demo() -> impl IntoView {
let (key, set_key) = signal("--color".to_string());
let (color, set_color) = use_css_var(key);

view! { }
}

You can specify the element that the variable is applied to as well as an initial value in case the variable is not set yet. The option to listen for changes to the variable is also available.

use leptos::prelude::*;
use leptos::html::Div;
use leptos_use_css_var::{use_css_var_with_options, UseCssVarOptions};

#[component]
fn Demo() -> impl IntoView {
let el = NodeRef::<Div>::new();

let (color, set_color) = use_css_var_with_options(
    "--color",
    UseCssVarOptions::default()
        .target(el)
        .initial_value("#eee")
        .observe(true),
);

view! {
    <div node_ref=el>"..."</div>
}
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this simply returns signal(options.initial_value).

Installation

cargo add leptos-use-css-var

Options

UseCssVarOptions

Options for use_css_var_with_options.

Every option is set with a builder method of the same name, e.g. UseCssVarOptions::default().target(...). See also the API docs.

target

Type: El

The target element to read the variable from and set the variable on. Defaults to the document.documentElement.

initial_value

Type: String

The initial value of the variable before it is read. Also the default value if the variable isn’t defined on the target. Defaults to “”.

observe

Type: bool

If true use a MutationObserver to monitor variable changes. Defaults to false.

Source

Source • Demo • Docs

use_display_media

Reactive mediaDevices.getDisplayMedia streaming.

Demo

Usage

use leptos::prelude::*;
use leptos::logging::{log, error};
use leptos_use_display_media::{use_display_media, UseDisplayMediaReturn};

#[component]
fn Demo() -> impl IntoView {
let video_ref = NodeRef::<leptos::html::Video>::new();

let UseDisplayMediaReturn { stream, start, .. } = use_display_media();

start();

Effect::new(move |_|
    video_ref.get().map(|v| {
        match stream.get() {
            Some(Ok(s)) => v.set_src_object(Some(&s)),
            Some(Err(e)) => error!("Failed to get media stream: {:?}", e),
            None => log!("No stream yet"),
        }
    })
);

view! { <video node_ref=video_ref controls=false autoplay=true muted=true></video> }
}

SendWrapped Return

The returned closures start and stop are sendwrapped functions. They can only be called from the same thread that called use_display_media.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server calls to start or any other way to enable the stream will be ignored and the stream will always be None.

Installation

cargo add leptos-use-display-media

Options

UseDisplayMediaOptions

Options for use_display_media.

Every option is set with a builder method of the same name, e.g. UseDisplayMediaOptions::default().enabled(...). See also the API docs.

enabled

Type: MaybeRwSignal<bool>

If the stream is enabled. Defaults to false.

audio

Type: bool

A value of true indicates that the returned MediaStream will contain an audio track, if audio is supported and available for the display surface chosen by the user. The default value is false.

Source

Source • Demo • Docs

use_event_listener

Use EventListener with ease.

Register using addEventListener on mounted, and removeEventListener automatically on cleanup.

Usage

use leptos::prelude::*;
use leptos::ev::visibilitychange;
use leptos::logging::log;
use leptos_use_document::use_document;
use leptos_use_event_listener::use_event_listener;

#[component]
fn Demo() -> impl IntoView {
use_event_listener(use_document(), visibilitychange, |evt| {
    log!("{:?}", evt);
});
   view! { }
}

You can also pass a NodeRef as the event target, use_event_listener will unregister the previous event and register the new one when you change the target.

use leptos::prelude::*;
use leptos::ev::click;
use leptos::logging::log;
use leptos_use_event_listener::use_event_listener;

#[component]
fn Demo() -> impl IntoView {
let element = NodeRef::new();

use_event_listener(element, click, |evt| {
    log!("click from element {:?}", event_target::<web_sys::HtmlDivElement>(&evt));
});

let (cond, set_cond) = signal(true);

view! {
    <Show
        when=move || cond.get()
        fallback=move || view! { <div node_ref=element>"Condition false"</div> }
    >
        <div node_ref=element>"Condition true"</div>
    </Show>
}
}

You can also call the returned to unregister the listener.

use leptos::prelude::*;
use leptos::ev::keydown;
use leptos::logging::log;
use web_sys::KeyboardEvent;
use leptos_use_event_listener::use_event_listener;

#[component]
fn Demo() -> impl IntoView {
let cleanup = use_event_listener(document().body(), keydown, |evt: KeyboardEvent| {
    log!("{}", &evt.key());
});

cleanup();

   view! { }
}

SendWrapped Return

The returned closure is a sendwrapped function. It can only be called from the same thread that called use_event_listener.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this amounts to a noop.

Installation

cargo add leptos-use-event-listener

Options

UseEventListenerOptions

Options for use_event_listener_with_options.

Every option is set with a builder method of the same name, e.g. UseEventListenerOptions::default().capture(...). See also the API docs.

capture

Type: bool

A boolean value indicating that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree. If not specified, defaults to false.

once

Type: bool

A boolean value indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked. If not specified, defaults to false.

passive

Type: Option<bool>

A boolean value that, if true, indicates that the function specified by listener will never call preventDefault(). If a passive listener does call preventDefault(), the user agent will do nothing other than generate a console warning. If not specified, defaults to false – except that in browsers other than Safari, defaults to true for the wheel, mousewheel, touchstart and touchmove events. See Improving scrolling performance with passive listeners to learn more.

Source

Source • Demo • Docs

use_favicon

Reactive favicon.

Demo

Usage

use leptos::prelude::*;
use leptos_use_favicon::use_favicon;

#[component]
fn Demo() -> impl IntoView {

let (icon, set_icon) = use_favicon();

set_icon.set(Some("dark.png".to_string())); // change current icon

   view! { }
}

Passing a Source Signal

You can pass a Signal to use_favicon_with_options. Change from the source signal will be reflected in your favicon automatically.

use leptos::prelude::*;
use leptos_use_favicon::{use_favicon_with_options, UseFaviconOptions};
use leptos_use_preferences::use_preferred_dark;

#[component]
fn Demo() -> impl IntoView {

let is_dark = use_preferred_dark();

let (icon, _) = use_favicon_with_options(
    UseFaviconOptions::default().new_icon(
        Signal::derive(move || {
            Some((if is_dark.get() { "dark.png" } else { "light.png" }).to_string())
        }),
    )
);

   view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server only the signals work but no favicon will be changed obviously.

Installation

cargo add leptos-use-favicon

Options

UseFaviconOptions

Options for use_favicon_with_options.

Every option is set with a builder method of the same name, e.g. UseFaviconOptions::default().new_icon(...). See also the API docs.

new_icon

Type: MaybeRwSignal<Option<String>>

New input favicon. Can be a RwSignal in which case updates will change the favicon. Defaults to None.

base_url

Type: String

Base URL of the favicon. Defaults to “”.

rel

Type: String

Rel attribute of the tag. Defaults to “icon”.

Source

Source • Demo • Docs

use_media_query

Reactive Media Query.

Demo

Usage

use leptos::prelude::*;
use leptos_use_media_query::use_media_query;

#[component]
fn Demo() -> impl IntoView {

let is_large_screen = use_media_query("(min-width: 1024px)");

let is_dark_preferred = use_media_query("(prefers-color-scheme: dark)");

   view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this functions returns a Signal that is always false.

See also

Installation

cargo add leptos-use-media-query

Source

Source • Demo • Docs

use_permission

Reactive Permissions API.

Demo

Usage

use leptos::prelude::*;
use leptos_use_permission::use_permission;

#[component]
fn Demo() -> impl IntoView {
let microphone_access = use_permission("microphone");

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the returned signal will always be PermissionState::Unknown.

Installation

cargo add leptos-use-permission

Types

Source

Source • Demo • Docs

use_preferred_contrast

Reactive prefers-contrast media query.

Usage

use leptos::prelude::*;
use leptos_use_preferences::use_preferred_contrast;

#[component]
fn Demo() -> impl IntoView {

let preferred_contrast = use_preferred_contrast();

   view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns a Signal that always contains the value PreferredContrast::NoPreference.

See also

Installation

cargo add leptos-use-preferences

Types

Source

Source • Docs

use_preferred_dark

Reactive dark theme preference.

Usage

use leptos::prelude::*;
use leptos_use_preferences::use_preferred_dark;

#[component]
fn Demo() -> impl IntoView {

let is_dark_preferred = use_preferred_dark();

   view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this will try to read the Sec-CH-Prefers-Color-Scheme header to determine the color mode. If the header is not present it will return ColorMode::Light. Please have a look at the linked documentation above for that header to see browser support as well as potential server requirements.

If you’re using axum you have to enable the "axum" feature in your Cargo.toml. In case it’s actix-web enable the feature "actix".

Bring your own header

In case you’re neither using Axum nor Actix or the default implementation is not to your liking, you can provide your own way of reading the color scheme header value using the option UsePreferredDarkOptions::ssr_color_header_getter.

See also

Installation

cargo add leptos-use-preferences

Options

UsePreferredDarkOptions

Options for use_preferred_dark_with_options.

Every option is set with a builder method of the same name, e.g. UsePreferredDarkOptions::default().ssr_color_header_getter(...). See also the API docs.

ssr_color_header_getter

Type: Arc<dyn Fn() -> Option<String> + Send + Sync>

Getter function to return the string value of the Sec-CH-Prefers-Color-Scheme header. When you use one of the features "axum" or "actix" there’s a valid default implementation provided.

Source

Source • Docs

use_prefers_reduced_motion

Reactive reduced motions preference.

Demo

Usage

use leptos::prelude::*;
use leptos_use_preferences::use_prefers_reduced_motion;

#[component]
fn Demo() -> impl IntoView {
let is_reduced_motion_preferred = use_prefers_reduced_motion();

view! {
    <div>
        <p>Prefers reduced motions: {move || if is_reduced_motion_preferred.get() { "Yes" } else { "No" }}</p>
        <p>
            Update reduce motion preference
            <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion#user_preferences">
                documentation.
            </a>
        </p>
    </div>
}
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this will try to read the Sec-CH-Prefers-Reduced-Motion header to indicate the preference for animations to be displayed with reduced motion. Please have a look at the linked documentation above to see browser support as well as potential serve requirements.

If you’re using axum you have to enable the "axum" feature in your Cargo.toml. In case it’s actix-web enable the feature "actix".

Bring your own header

In case you’re neither using Axum nor Actix or the default implementation is not to your liking, you can provide your own way of reading the reduced motion header value using the option UsePrefersReducedMotionOptions::ssr_motion_header_getter.

See also

Installation

cargo add leptos-use-preferences

Options

UsePrefersReducedMotionOptions

Options for use_prefers_reduced_motion_with_options.

Every option is set with a builder method of the same name, e.g. UsePrefersReducedMotionOptions::default().ssr_motion_header_getter(...). See also the API docs.

ssr_motion_header_getter

Type: Arc<dyn Fn() -> Option<String> + Send + Sync>

Getter function to return the string value of the Sec-CH-Prefers-Reduced-Motion header. When you use one of the features "axum" or "actix" there’s a valid default implementation provided.

Source

Source • Demo • Docs

use_screen_orientation

Reactive Screen Orientation API. It provides web developers with information about the user’s current screen orientation.

Demo

Usage

use leptos::prelude::*;
use leptos_use_screen_orientation::{use_screen_orientation, UseScreenOrientationReturn};

#[component]
fn Demo() -> impl IntoView {
let UseScreenOrientationReturn { orientation, angle, lock_orientation, unlock_orientation } = use_screen_orientation();

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server orientation will always be ScreenOrientation::PortraitPrimary and angle will always be 0. The locking functions will be no-ops.

Installation

cargo add leptos-use-screen-orientation

Source

Source • Demo • Docs

use_service_worker

Reactive ServiceWorker API.

Please check the working example.

Usage

use leptos::prelude::*;
use leptos_use_service_worker::{use_service_worker_with_options, UseServiceWorkerOptions, UseServiceWorkerReturn};

#[component]
fn Demo() -> impl IntoView {
let UseServiceWorkerReturn {
        registration,
        installing,
        waiting,
        active,
        skip_waiting,
        check_for_update,
} = use_service_worker_with_options(UseServiceWorkerOptions::default()
    .script_url("service-worker.js")
    .skip_waiting_message("skipWaiting"),
);

view! { }
}

SendWrapped Return

The returned closures check_for_update and skip_waiting are sendwrapped functions. They can only be called from the same thread that called use_service_worker.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

This function does not support SSR. Call it inside a create_effect.

Installation

cargo add leptos-use-service-worker

Options

UseServiceWorkerOptions

Options for use_service_worker_with_options.

Every option is set with a builder method of the same name, e.g. UseServiceWorkerOptions::default().script_url(...). See also the API docs.

script_url

Type: String

The name of your service-worker file. Must be deployed alongside your app. The default name is ‘service-worker.js’.

skip_waiting_message

Type: String

The message sent to a waiting ServiceWorker when you call the skip_waiting callback. The callback is part of the return type of use_service_worker! The default message is ‘skipWaiting’.

on_controller_change

Type: Arc<dyn Fn()>

What should happen when a new service worker was activated? The default implementation reloads the current page.

Source

Source • Demo • Docs

use_textarea_autosize

Automatically update the height of a textarea depending on the content.

Demo

Usage

Simple example

use leptos::prelude::*;
use leptos::html::Textarea;
use leptos_use_textarea_autosize::{use_textarea_autosize, UseTextareaAutosizeReturn};

#[component]
fn Demo() -> impl IntoView {
let textarea = NodeRef::new();

let UseTextareaAutosizeReturn {
    content,
    set_content,
    trigger_resize
} = use_textarea_autosize(textarea);

view! {
    <textarea
        prop:value=content
        on:input=move |evt| set_content.set(event_target_value(&evt))
        node_ref=textarea
        class="resize-none"
        placeholder="What's on your mind?"
    />
}
}

Make sure that you set box-sizing: border-box on the textarea element.

It’s also recommended to reset the scrollbar styles for the textarea element to avoid incorrect height values for large amounts of text.

#![allow(unused)]
fn main() {
textarea {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

textarea::-webkit-scrollbar {
  display: none;
}
}

With rows attribute

If you need support for the rows attribute on a textarea element, then you should set the style_prop option to "min-height".

use leptos::prelude::*;
use leptos::html::Textarea;
use leptos_use_textarea_autosize::{use_textarea_autosize_with_options, UseTextareaAutosizeOptions, UseTextareaAutosizeReturn};

#[component]
fn Demo() -> impl IntoView {
let textarea = NodeRef::new();

let UseTextareaAutosizeReturn {
    content,
    set_content,
    ..
} = use_textarea_autosize_with_options(
    textarea,
    UseTextareaAutosizeOptions::default().style_prop("min-height"),
);

view! {
    <textarea
        prop:value=content
        on:input=move |evt| set_content.set(event_target_value(&evt))
        node_ref=textarea
        class="resize-none"
        placeholder="What's on your mind?"
        rows="3"
    />
}
}

SendWrapped Return

The returned closure trigger_resize is a sendwrapped function. It can only be called from the same thread that called use_textarea_autosize.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this will always return an empty string as ´contentand a no-optrigger_resize`.

Installation

cargo add leptos-use-textarea-autosize

Options

UseTextareaAutosizeOptions

Options for use_textarea_autosize_with_options.

Every option is set with a builder method of the same name, e.g. UseTextareaAutosizeOptions::default().content(...). See also the API docs.

content

Type: MaybeRwSignal<String>

Textarea content

watch

Type: Arc<dyn Fn() + Send + Sync>

Watch sources that should trigger a textarea resize

on_resize

Type: Arc<dyn Fn() + Send + Sync>

Function called when the textarea size changes

style_target

Type: ElementMaybeSignal<web_sys::Element>

Specify style target to apply the height based on textarea content. If not provided it will use textarea it self.

style_prop

Type: String

Specify the style property that will be used to manipulate height. Should be "height" or "min-height". Default value is "height".

Source

Source • Demo • Docs

use_user_media

Reactive mediaDevices.getUserMedia streaming.

Demo

Usage

use leptos::prelude::*;
use leptos::logging::{log, error};
use leptos_use_user_media::{use_user_media, UseUserMediaReturn};

#[component]
fn Demo() -> impl IntoView {
let video_ref = NodeRef::<leptos::html::Video>::new();

let UseUserMediaReturn { stream, start, .. } = use_user_media();

start();

Effect::new(move |_|
    video_ref.get().map(|v| {
        match stream.get() {
            Some(Ok(s)) => v.set_src_object(Some(&s)),
            Some(Err(e)) => error!("Failed to get media stream: {:?}", e),
            None => log!("No stream yet"),
        }
    })
);

view! { <video node_ref=video_ref controls=false autoplay=true muted=true></video> }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server calls to start or any other way to enable the stream will be ignored and the stream will always be None.

Installation

cargo add leptos-use-user-media

Options

UseUserMediaOptions

Options for use_user_media_with_options.

Either or both constraints must be specified. If the browser cannot find all media tracks with the specified types that meet the constraints given, then the returned promise is rejected with NotFoundError

Every option is set with a builder method of the same name, e.g. UseUserMediaOptions::default().enabled(...). See also the API docs.

enabled

Type: MaybeRwSignal<bool>

If the stream is enabled. Defaults to false.

video

Type: VideoConstraints

Constraint parameter describing video media type requested The default value is true.

audio

Type: AudioConstraints

Constraint parameter describing audio media type requested The default value is false.

Types

Source

Source • Demo • Docs

use_web_lock

Rustified Web Locks API.

The Web Locks API allows scripts running in one tab or worker to asynchronously acquire a lock, hold it while work is performed, then release it. While held, no other script executing in the same origin can acquire the same lock, which allows a web app running in multiple tabs or workers to coordinate work and the use of resources.

This function requires --cfg=web_sys_unstable_apis to be activated as described in the wasm-bindgen guide.

Demo

Usage

use leptos::prelude::*;
use leptos_use_web_lock::use_web_lock;

async fn my_process(_lock: web_sys::Lock) -> i32 {
    // do sth
    42
}

#[component]
fn Demo() -> impl IntoView {
leptos::task::spawn_local(async {
    let res = use_web_lock("my_lock", my_process).await;
    assert!(matches!(res, Ok(42)));
});

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns Err(UseWebLockError::Server) and the task is not executed.

Installation

cargo add leptos-use-web-lock

Options

UseWebLockOptions

Options for use_web_lock_with_options.

Every option is set with a builder method of the same name, e.g. UseWebLockOptions::default().mode(...). See also the API docs.

mode

Type: LockMode

The default mode is LockMode::Exclusive, but LockMode::Shared can be specified. There can be only one Exclusive holder of a lock, but multiple Shared requests can be granted at the same time. This can be used to implement the readers-writer pattern.

if_available

Type: bool

If true, the lock request will fail if the lock cannot be granted immediately without waiting. The callback is invoked with null. Defaults to false.

steal

Type: bool

If true, then any held locks with the same name will be released, and the request will be granted, preempting any queued requests for it. Defaults to false.

Types

Source

Source • Demo • Docs

use_web_notification

Reactive Notification API.

The Web Notification interface of the Notifications API is used to configure and display desktop notifications to the user.

Demo

Usage

use leptos::prelude::*;
use leptos_use_web_notification::{use_web_notification_with_options, UseWebNotificationOptions, ShowOptions, UseWebNotificationReturn, NotificationDirection};

#[component]
fn Demo() -> impl IntoView {
let UseWebNotificationReturn {
    show,
    close,
    ..
} = use_web_notification_with_options(
    UseWebNotificationOptions::default()
        .direction(NotificationDirection::Auto)
        .language("en")
        .renotify(true)
        .tag("test"),
);

show(ShowOptions::default().title("Hello World from leptos-use"));

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

This function is basically ignored on the server. You can safely call show but it will do nothing.

Installation

cargo add leptos-use-web-notification

Options

ShowOptions

Options for UseWebNotificationReturn::show.

This can be used to override options passed to use_web_notification. See MDN Docs for more info.

The following implementations are missing:

Every option is set with a builder method of the same name, e.g. ShowOptions::default().title(...). See also the API docs.

title

Type: Option<String>

The title property of the Notification interface indicates the title of the notification

body

Type: Option<String>

The body string of the notification as specified in the constructor’s options parameter.

direction

Type: Option<NotificationDirection>

The text direction of the notification as specified in the constructor’s options parameter. Can be LeftToRight, RightToLeft or Auto (default). See web_sys::NotificationDirection for more info.

language

Type: Option<String>

The language code of the notification as specified in the constructor’s options parameter.

tag

Type: Option<String>

The ID of the notification(if any) as specified in the constructor’s options parameter.

icon

Type: Option<String>

The URL of the image used as an icon of the notification as specified in the constructor’s options parameter.

image

Type: Option<String>

The URL of the image to be displayed as part of the notification as specified in the constructor’s options parameter.

require_interaction

Type: Option<bool>

A boolean value indicating that a notification should remain active until the user clicks or dismisses it, rather than closing automatically.

renotify

Type: Option<bool>

A boolean value specifying whether the user should be notified after a new notification replaces an old one. The default is false, which means they won’t be notified. If true, then tag also must be set.

silent

Type: Option<bool>

A boolean value specifying whether the notification should be silent, regardless of the device settings. The default is null, which means the notification is not silent. If true, then the notification will be silent.

vibrate

Type: Option<Vec<u16>>

A Vec<u16> specifying the vibration pattern in milliseconds for vibrating and not vibrating. The last entry can be a vibration since it stops automatically after each period.

UseWebNotificationOptions

Options for use_web_notification_with_options. See MDN Docs for more info.

The following implementations are missing:

Every option is set with a builder method of the same name, e.g. UseWebNotificationOptions::default().title(...). See also the API docs.

title

Type: String

The title property of the Notification interface indicates the title of the notification

body

Type: Option<String>

The body string of the notification as specified in the constructor’s options parameter.

direction

Type: NotificationDirection

The text direction of the notification as specified in the constructor’s options parameter. Can be LeftToRight, RightToLeft or Auto (default). See web_sys::NotificationDirection for more info.

language

Type: Option<String>

The language code of the notification as specified in the constructor’s options parameter.

tag

Type: Option<String>

The ID of the notification(if any) as specified in the constructor’s options parameter.

icon

Type: Option<String>

The URL of the image used as an icon of the notification as specified in the constructor’s options parameter.

image

Type: Option<String>

The URL of the image to be displayed as part of the notification as specified in the constructor’s options parameter.

require_interaction

Type: bool

A boolean value indicating that a notification should remain active until the user clicks or dismisses it, rather than closing automatically.

renotify

Type: bool

A boolean value specifying whether the user should be notified after a new notification replaces an old one. The default is false, which means they won’t be notified. If true, then tag also must be set.

silent

Type: Option<bool>

A boolean value specifying whether the notification should be silent, regardless of the device settings. The default is null, which means the notification is not silent. If true, then the notification will be silent.

vibrate

Type: Option<Vec<u16>>

A Vec<u16> specifying the vibration pattern in milliseconds for vibrating and not vibrating. The last entry can be a vibration since it stops automatically after each period.

on_click

Type: Rc<dyn Fn(web_sys::Event)>

Called when the user clicks on displayed Notification.

on_close

Type: Rc<dyn Fn(web_sys::Event)>

Called when the user closes a Notification.

on_error

Type: Rc<dyn Fn(web_sys::Event)>

Called when something goes wrong with a Notification (in many cases an error preventing the notification from being displayed.)

on_show

Type: Rc<dyn Fn(web_sys::Event)>

Called when a Notification is displayed

Source

Source • Demo • Docs

on_click_outside

Listen for clicks outside an element. Useful for modals or dropdowns.

Demo

Usage

use leptos::prelude::*;
use leptos::logging::log;
use leptos::html::Div;
use leptos_use_on_click_outside::on_click_outside;

#[component]
fn Demo() -> impl IntoView {
let target = NodeRef::<Div>::new();

on_click_outside(target, move |event| { log!("{:?}", event); });

view! {
    <div node_ref=target>"Hello World"</div>
    <div>"Outside element"</div>
}
}

This function uses Event.composedPath() which is not supported by IE 11, Edge 18 and below. If you are targeting these browsers, we recommend you to include this code snippet on your project.

SendWrapped Return

The return value of this function is a sendwrapped function to remove all event listeners. It can only be called from the same thread that called on_click_outside.

Excluding Elements

Use this to ignore clicks on certain elements.

use leptos::prelude::*;
use leptos::logging::log;
use leptos::html::Div;
use leptos_use_on_click_outside::{on_click_outside_with_options, OnClickOutsideOptions};

#[component]
fn Demo() -> impl IntoView {
let target = NodeRef::<Div>::new();

on_click_outside_with_options(
    target,
    move |event| { log!("{:?}", event); },
    OnClickOutsideOptions::default().ignore(["input", "#some-id"]),
);

view! {
    <div node_ref=target>"Hello World"</div>
}
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this amounts to a no-op.

Installation

cargo add leptos-use-on-click-outside

Options

OnClickOutsideOptions

Options for on_click_outside_with_options.

Every option is set with a builder method of the same name, e.g. OnClickOutsideOptions::default().ignore(...). See also the API docs.

ignore

Type: ElementsMaybeSignal<web_sys::EventTarget>

List of elementss that should not trigger the callback. Defaults to [].

capture

Type: bool

Use capturing phase for internal event listener. Defaults to true.

detect_iframes

Type: bool

Run callback if focus moves to an iframe. Defaults to false.

Source

Source • Demo • Docs

use_device_orientation

Reactive DeviceOrientationEvent.

Provide web developers with information from the physical orientation of the device running the web page.

Demo

Usage

use leptos::prelude::*;
use leptos_use_device_orientation::{use_device_orientation, UseDeviceOrientationReturn};

#[component]
fn Demo() -> impl IntoView {
let UseDeviceOrientationReturn {
    is_supported,
    absolute,
    alpha,
    beta,
    gamma,
} = use_device_orientation();

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this function returns values as if the orientation capabilties were not supported by the device.

Installation

cargo add leptos-use-device-orientation

Source

Source • Demo • Docs

use_device_pixel_ratio

Reactive window.devicePixelRatio

NOTE: there is no event listener for window.devicePixelRatio change. So this function uses the same mechanism as described in this example.

Demo

Usage

use leptos::prelude::*;
use leptos_use_device_pixel_ratio::use_device_pixel_ratio;

#[component]
fn Demo() -> impl IntoView {
let pixel_ratio = use_device_pixel_ratio();

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this function returns a Signal that is always 1.0.

Installation

cargo add leptos-use-device-pixel-ratio

Source

Source • Demo • Docs

use_element_hover

Reactive element’s hover state.

Demo

Usage

use leptos::prelude::*;
use leptos::html::Button;
use leptos_use_element_hover::use_element_hover;

#[component]
fn Demo() -> impl IntoView {
let el = NodeRef::<Button>::new();
let is_hovered = use_element_hover(el);

view! {
    <button node_ref=el>{ move || format!("{:?}", is_hovered.get()) }</button>
}
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns a Signal that always contains the value false.

Installation

cargo add leptos-use-element-hover

Options

UseElementHoverOptions

Options for use_element_hover_with_options.

Every option is set with a builder method of the same name, e.g. UseElementHoverOptions::default().delay_enter(...). See also the API docs.

delay_enter

Type: u64

The time in ms the mouse has to be hovered over the element before the signal is changed to true. Defaults to 0.

delay_leave

Type: u64

The time in ms after the mouse has left the element before the signal is changed to false. Defaults to 0.

Source

Source • Demo • Docs

use_geolocation

Reactive Geolocation API.

It allows the user to provide their location to web applications if they so desire. For privacy reasons, the user is asked for permission to report location information.

Demo

Usage

use leptos::prelude::*;
use leptos_use_geolocation::{use_geolocation, UseGeolocationReturn};

#[component]
fn Demo() -> impl IntoView {
let UseGeolocationReturn {
    coords,
    located_at,
    error,
    resume,
    pause,
} = use_geolocation();

view! { }
}

SendWrapped Return

The returned closures pause and resume are sendwrapped functions. They can only be called from the same thread that called use_geolocation.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server all signals returns will always contain None and the functions do nothing.

Installation

cargo add leptos-use-geolocation

Options

UseGeolocationOptions

Options for use_geolocation_with_options.

Every option is set with a builder method of the same name, e.g. UseGeolocationOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

If true the geolocation watch is started when this function is called. If false you have to call resume manually to start it. Defaults to true.

enable_high_accuracy

Type: bool

A boolean value that indicates the application would like to receive the best possible results. If true and if the device is able to provide a more accurate position, it will do so. Note that this can result in slower response times or increased power consumption (with a GPS chip on a mobile device for example). On the other hand, if false, the device can take the liberty to save resources by responding more quickly and/or using less power. Default: false.

maximum_age

Type: u32

A positive value indicating the maximum age in milliseconds of a possible cached position that is acceptable to return. If set to 0, it means that the device cannot use a cached position and must attempt to retrieve the real current position. Default: 30000.

timeout

Type: u32

A positive value representing the maximum length of time (in milliseconds) the device is allowed to take in order to return a position. The default value is 27000.

Source

Source • Demo • Docs

use_idle

Tracks whether the user is being inactive.

Demo

Usage

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_idle::{use_idle, UseIdleReturn};

#[component]
fn Demo() -> impl IntoView {
let UseIdleReturn {
    idle, last_active, ..
} = use_idle(5 * 60 * 1000); // 5 minutes

log!("{}", idle.get()); // true or false

view! { }
}

Programatically resetting:

use std::time::Duration;
use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_idle::{use_idle, UseIdleReturn};

#[component]
fn Demo() -> impl IntoView {
let UseIdleReturn {
    idle, last_active, reset
} = use_idle(5 * 60 * 1000); // 5 minutes

reset(); // restarts the idle timer. Does not change the `last_active` value.

view! { }
}

SendWrapped Return

The returned closure reset is a sendwrapped function. It can only be called from the same thread that called use_idle.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this will always return static signals

#![allow(unused)]
fn main() {
UseIdleReturn{
    idle: Signal(initial_state),
    last_active: Signal(now),
    reset: || {}
}
}

Installation

cargo add leptos-use-idle

Options

UseIdleOptions

Options for use_idle_with_options.

Every option is set with a builder method of the same name, e.g. UseIdleOptions::default().events(...). See also the API docs.

events

Type: Vec<String>

Event names to listen to on window for detected user activity. Default: vec!["mousemove", "mousedown", "resize", "keydown", "touchstart", "wheel"].

listen_for_visibility_change

Type: bool

Whether to listen for document visibility change. Defaults to true.

initial_state

Type: bool

Initial state of the returned idle. Defaults to false.

filter

Type: FilterOptions

Allows to debounce or throttle the event listener that is called for every event (from events). Defaults to a throttle by 50ms.

Source

Source • Demo • Docs

use_infinite_scroll

Infinite scrolling of the element.

Demo

Usage

use leptos::prelude::*;
use leptos::html::Div;
use leptos_use_infinite_scroll::{use_infinite_scroll_with_options, UseInfiniteScrollOptions};

#[component]
fn Demo() -> impl IntoView {
let el = NodeRef::<Div>::new();

let (data, set_data) = signal(vec![1, 2, 3, 4, 5, 6]);

let _ = use_infinite_scroll_with_options(
    el,
    move |_| async move {
        let len = data.with(|d| d.len());
        set_data.update(|data| *data = (1..len+6).collect());
    },
    UseInfiniteScrollOptions::default().distance(10.0),
);

view! {
    <div node_ref=el>
        <For each=move || data.get() key=|i| *i let:item>{ item }</For>
    </div>
}
}

The returned signal is true while new data is being loaded.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server-side, use_infinite_scroll will return a signal that is always false. It effectively does nothing on the server, as there are no scroll events to listen to.

Installation

cargo add leptos-use-infinite-scroll

Options

UseInfiniteScrollOptions

Options for use_infinite_scroll_with_options.

Every option is set with a builder method of the same name, e.g. UseInfiniteScrollOptions::default().on_scroll(...). See also the API docs.

on_scroll

Type: Arc<dyn Fn(web_sys::Event) + Send + Sync>

Callback when scrolling is happening.

event_listener_options

Type: UseEventListenerOptions

Options passed to the addEventListener("scroll", ...) call

distance

Type: f64

The minimum distance between the bottom of the element and the bottom of the viewport. Default is 0.0.

direction

Type: Direction

The direction in which to listen the scroll. Defaults to Direction::Bottom.

interval

Type: f64

The interval time between two load more (to avoid too many invokes). Default is 100.0.

Types

Source

Source • Demo • Docs

use_mouse

Reactive mouse position

Demo

Basic Usage

use leptos::prelude::*;
use leptos_use_mouse::{use_mouse, UseMouseReturn};

#[component]
fn Demo() -> impl IntoView {
let UseMouseReturn {
    x, y, source_type, ..
} = use_mouse();
view! { }
}

Touch is enabled by default. To only detect mouse changes, set touch to false. The dragover event is used to track mouse position while dragging.

use leptos::prelude::*;
use leptos_use_mouse::{use_mouse_with_options, UseMouseOptions, UseMouseReturn};

#[component]
fn Demo() -> impl IntoView {
let UseMouseReturn {
    x, y, ..
} = use_mouse_with_options(
    UseMouseOptions::default().touch(false)
);
view! { }
}

Custom Extractor

It’s also possible to provide a custom extractor to get the position from the events.

use leptos::prelude::*;
use leptos::html::Div;
use web_sys::MouseEvent;
use leptos_use_mouse::{use_mouse_with_options, UseMouseOptions, UseMouseReturn, UseMouseEventExtractor, UseMouseCoordType};

#[derive(Clone)]
struct MyExtractor;

impl UseMouseEventExtractor for MyExtractor {
    fn extract_mouse_coords(&self, event: &MouseEvent) -> Option<(f64, f64)> {
        Some((event.offset_x() as f64, event.offset_y() as f64))
    }

    // don't implement fn extract_touch_coords to ignore touch events
}

#[component]
fn Demo() -> impl IntoView {
    let element = NodeRef::<Div>::new();

    let UseMouseReturn {
        x, y, source_type, ..
    } = use_mouse_with_options(
        UseMouseOptions::default()
            .target(element)
            .coord_type(UseMouseCoordType::Custom(MyExtractor))
    );
    view! { <div node_ref=element></div> }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns simple Signals with the initial_values.

Installation

cargo add leptos-use-mouse

Options

UseMouseOptions

Options for use_mouse_with_options.

Every option is set with a builder method of the same name, e.g. UseMouseOptions::default().coord_type(...). See also the API docs.

coord_type

Type: UseMouseCoordType<Ex>

How to extract the x, y coordinates from mouse events or touches

target

Type: El

Listen events on target element. Defaults to window

touch

Type: bool

Listen to touchmove events. Defaults to true.

reset_on_touch_ends

Type: bool

Reset to initial value when touchend event fired. Defaults to false

initial_value

Type: Position

Initial values. Defaults to {x: 0.0, y: 0.0}.

Source

Source • Demo • Docs

use_scroll

We have to check if the scroll amount is close enough to some threshold in order to more accurately calculate arrivedState. This is because scrollTop/scrollLeft are non-rounded numbers, while scrollHeight/scrollWidth and clientHeight/clientWidth are rounded. https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#determine_if_an_element_has_been_totally_scrolled

Installation

cargo add leptos-use-scroll

Options

UseScrollOptions

Options for use_scroll. Options for use_scroll_with_options.

Every option is set with a builder method of the same name, e.g. UseScrollOptions::default().throttle(...). See also the API docs.

throttle

Type: f64

Throttle time in milliseconds for the scroll events. Defaults to 0 (disabled).

idle

Type: f64

After scrolling ends we wait idle + throttle milliseconds before we consider scrolling to have stopped. Defaults to 200.

offset

Type: ScrollOffset

Threshold in pixels when we consider a side to have arrived (UseScrollReturn::arrived_state).

on_scroll

Type: Rc<dyn Fn(web_sys::Event)>

Callback when scrolling is happening.

on_stop

Type: Rc<dyn Fn(web_sys::Event)>

Callback when scrolling stops (after idle + throttle milliseconds have passed).

event_listener_options

Type: UseEventListenerOptions

Options passed to the addEventListener("scroll", ...) call

behavior

Type: Signal<ScrollBehavior>

When changing the x or y signals this specifies the scroll behaviour. Can be Auto (= not smooth) or Smooth. Defaults to Auto.

Source

Source • Demo • Docs

use_event_source

Reactive EventSource

An EventSource or Server-Sent-Events instance opens a persistent connection to an HTTP server, which sends events in text/event-stream format.

Usage

Values are decoded via the given decoder. You can use any of the string codecs or a binary codec wrapped in Base64.

Please check the codec chapter to see what codecs are available and what feature flags they require.

use leptos::prelude::*;
use leptos_use_event_source::{use_event_source, UseEventSourceReturn};
use codee::string::JsonSerdeCodec;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, PartialEq)]
pub struct EventSourceData {
    pub message: String,
    pub priority: u8,
}

#[component]
fn Demo() -> impl IntoView {
let UseEventSourceReturn {
    ready_state, message, error, close, ..
} = use_event_source::<EventSourceData, JsonSerdeCodec>("https://event-source-url");

view! { }
}

Named Events

You can define named events when using use_event_source_with_options.

use leptos::prelude::*;
use leptos_use_event_source::{use_event_source_with_options, UseEventSourceReturn, UseEventSourceOptions};
use codee::string::FromToStringCodec;

#[component]
fn Demo() -> impl IntoView {
let UseEventSourceReturn {
    ready_state, message, error, close, ..
} = use_event_source_with_options::<String, FromToStringCodec>(
    "https://event-source-url",
    UseEventSourceOptions::default()
        .named_events(["notice".to_string(), "update".to_string()])
);

view! { }
}

Custom Event Handler

You can provide a custom on_event handler using use_event_source_with_options. on_event wil be run for every received event, including the built-in open, error, and message events, as well as any named events you have specified.

With the return value of on_event you can control, whether message and named events should be further processed by use_event_source (UseEventSourceOnEventReturn::ProcessMessage) or ignored (UseEventSourceOnEventReturn::IgnoreProcessingMessage).

By default, the handler returns UseEventSourceOnEventReturn::ProcessMessage.

use leptos::prelude::*;
use leptos_use_event_source::{use_event_source_with_options, UseEventSourceReturn, UseEventSourceOptions, UseEventSourceMessage, UseEventSourceOnEventReturn};
use codee::string::FromToStringCodec;

#[component]
fn Demo() -> impl IntoView {
// Custom example handler: log event name and check for named `custom_error` event
let custom_event_handler = |e: &web_sys::Event| {
    leptos::logging::log!("Received event: {}", e.type_());
    if e.type_() == "custom_error" {
        if let Ok(error_message) = UseEventSourceMessage::<String, FromToStringCodec>::try_from(e.clone()) {
            // Decoded successfully, log the error message
            leptos::logging::log!("Error message: {}", error_message.data);
            // skip processing this message event further
            return UseEventSourceOnEventReturn::IgnoreProcessingMessage;
        }
    }
    // Process other message events normally
    UseEventSourceOnEventReturn::ProcessMessage
};
let UseEventSourceReturn {
    ready_state, message, error, close, ..
} = use_event_source_with_options::<String, FromToStringCodec>(
    "https://event-source-url",
    UseEventSourceOptions::default()
        .named_events(["custom_error".to_string()])
        .on_event(custom_event_handler)
);

view! { }
}

Immediate

Auto-connect (enabled by default).

This will call open() automatically for you, and you don’t need to call it by yourself.

Auto-Reconnection

Reconnect on errors automatically (enabled by default).

You can control the number of reconnection attempts by setting reconnect_limit and the interval between them by setting reconnect_interval.

use leptos::prelude::*;
use leptos_use_event_source::{use_event_source_with_options, UseEventSourceReturn, UseEventSourceOptions};
use leptos_use_core::ReconnectLimit;
use codee::string::FromToStringCodec;

#[component]
fn Demo() -> impl IntoView {
let UseEventSourceReturn {
    ready_state, message, error, close, ..
} = use_event_source_with_options::<bool, FromToStringCodec>(
    "https://event-source-url",
    UseEventSourceOptions::default()
        .reconnect_limit(ReconnectLimit::Limited(5))         // at most 5 attempts
        .reconnect_interval(2000)   // wait for 2 seconds between attempts
);

view! { }
}

SendWrapped Return

The returned closures open and close are sendwrapped functions. They can only be called from the same thread that called use_event_source.

To disable auto-reconnection, set reconnect_limit to 0.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server-side, use_event_source will always return ready_state as ConnectionReadyState::Closed, data, event and error will always be None, and open and close will do nothing.

Installation

cargo add leptos-use-event-source

Options

UseEventSourceOptions

Options for use_event_source_with_options.

Every option is set with a builder method of the same name, e.g. UseEventSourceOptions::default().reconnect_limit(...). See also the API docs.

reconnect_limit

Type: ReconnectLimit

Retry times. Defaults to ReconnectLimit::Limited(3). Use ReconnectLimit::Infinite for infinite retries.

reconnect_interval

Type: u64

Retry interval in ms. Defaults to 3000.

on_failed

Type: Arc<dyn Fn() + Send + Sync>

On maximum retry times reached.

immediate

Type: bool

If true the EventSource connection will immediately be opened when calling this function. If false you have to manually call the open function. Defaults to true.

named_events

Type: Vec<String>

List of named events to listen for on the EventSource.

on_event

Type: Arc<dyn Fn(&web_sys::Event) -> UseEventSourceOnEventReturn + Send + Sync>

The on_event is called before processing any event inside of use_event_source. Return UseEventSourceOnEventReturn::Ignore to ignore further processing of the respective event in use_event_source, or UseEventSourceOnEventReturn::Use to process the event as usual.

Beware that ignoring processing the open and error events may yield unexpected results.

You may want to use UseEventSourceMessage::try_from() to access the event data.

Default handler returns UseEventSourceOnEventReturn::Use.

with_credentials

Type: bool

If CORS should be set to include credentials. Defaults to false.

_marker

Type: PhantomData<T>

Source

Source • Docs

use_websocket

Creating and managing a Websocket connection.

Demo

Usage

Values are (en)decoded via the given codec. You can use any of the codecs, string or binary.

Please check the codec chapter to see what codecs are available and what feature flags they require.

use leptos::prelude::*;
use codee::string::FromToStringCodec;
use leptos_use_websocket::{use_websocket, UseWebSocketReturn};
use leptos_use_websocket::ConnectionReadyState;

#[component]
fn Demo() -> impl IntoView {
let UseWebSocketReturn {
    ready_state,
    message,
    send,
    open,
    close,
    ..
} = use_websocket::<String, String, FromToStringCodec>("wss://echo.websocket.events/");

let send_message = move |_| {
    send(&"Hello, world!".to_string());
};

let status = move || ready_state.get().to_string();

let connected = move || ready_state.get() == ConnectionReadyState::Open;

let open_connection = move |_| {
    open();
};

let close_connection = move |_| {
    close();
};

view! {
    <div>
        <p>"status: " {status}</p>

        <button on:click=send_message disabled=move || !connected()>"Send"</button>
        <button on:click=open_connection disabled=connected>"Open"</button>
        <button on:click=close_connection disabled=move || !connected()>"Close"</button>

        <p>"Receive message: " {move || format!("{:?}", message.get())}</p>
    </div>
}
}

Here is another example using msgpack for encoding and decoding. This means that only binary messages can be sent or received. For this to work you have to enable the msgpack_serde feature flag.

use leptos::*;
use codee::binary::MsgpackSerdeCodec;
use leptos_use_websocket::{use_websocket, UseWebSocketReturn};
use serde::{Deserialize, Serialize};

#[component]
fn Demo() -> impl IntoView {
#[derive(Serialize, Deserialize)]
struct SomeData {
    name: String,
    count: i32,
}

let UseWebSocketReturn {
    message,
    send,
    ..
} = use_websocket::<SomeData, SomeData, MsgpackSerdeCodec>("wss://some.websocket.server/");

let send_data = move || {
    send(&SomeData {
        name: "John Doe".to_string(),
        count: 42,
    });
};

view! {}
}

Heartbeats

Heartbeats can be configured by the heartbeat option. You have to provide a heartbeat type, that implements the Default trait and an Encoder for it. This encoder doesn’t have to be the same as the one used for the other websocket messages.

use leptos::*;
use codee::string::FromToStringCodec;
use leptos_use_websocket::{use_websocket_with_options, UseWebSocketOptions, UseWebSocketReturn};
use serde::{Deserialize, Serialize};

#[component]
fn Demo() -> impl IntoView {
#[derive(Default)]
struct Heartbeat;

// Simple example for usage with `FromToStringCodec`
impl std::fmt::Display for Heartbeat {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "<Heartbeat>")
    }
}

let UseWebSocketReturn {
    send,
    message,
    ..
} = use_websocket_with_options::<String, String, FromToStringCodec, _, _>(
    "wss://echo.websocket.events/",
    UseWebSocketOptions::default()
        // Enable heartbeats every 10 seconds. In this case we use the same codec as for the
        // other messages. But this is not necessary.
        .heartbeat::<Heartbeat, FromToStringCodec>(10_000),
);

view! {}
}

Relative Paths

If the provided url is relative, it will be resolved relative to the current page. Urls will be resolved like this the following. Please note that the protocol (http vs https) will be taken into account as well.

Current PageRelative UrlResolved Url
http://example.com/some/where/api/wsws://example.com/api/ws
https://example.com/some/where/api/wswss://example.com/api/ws
https://example.com/some/whereapi/wswss://example.com/some/where/api/ws
https://example.com/some/where//otherdomain.com/api/wswss://otherdomain.com/api/ws

Usage with provide_context

The return value of use_websocket utilizes several type parameters which can make it cumbersome to use with provide_context + expect_context. The following example shows how to avoid type parameters with dynamic dispatch. This sacrifices a little bit of performance for the sake of ergonomics. However, compared to network transmission speeds this loss of performance is negligible.

First we define the struct that is going to be passed around as context.

use leptos::prelude::*;
use std::sync::Arc;

#[derive(Clone)]
pub struct WebsocketContext {
    pub message: Signal<Option<String>>,
    send: Arc<dyn Fn(&String) + Send + Sync>,  // use Arc to make it easily cloneable
}

impl WebsocketContext {
    pub fn new(message: Signal<Option<String>>, send: Arc<dyn Fn(&String) + Send + Sync>) -> Self {
        Self {
            message,
            send,
        }
    }

    // create a method to avoid having to use parentheses around the field
    #[inline(always)]
    pub fn send(&self, message: &str) {
        (self.send)(&message.to_string())
    }
}

Now you can provide the context like the following.

use leptos::prelude::*;
use codee::string::FromToStringCodec;
use leptos_use_websocket::{use_websocket, UseWebSocketReturn};
use std::sync::Arc;
#[derive(Clone)]
pub struct WebsocketContext {
    pub message: Signal<Option<String>>,
    send: Arc<dyn Fn(&String) + Send + Sync>,
}

impl WebsocketContext {
    pub fn new(message: Signal<Option<String>>, send: Arc<dyn Fn(&String) + Send + Sync>) -> Self {
        Self {
            message,
            send,
        }
    }
}

#[component]
fn Demo() -> impl IntoView {
let UseWebSocketReturn {
    message,
    send,
    ..
} = use_websocket::<String, String, FromToStringCodec>("ws://some.websocket.io");

provide_context(WebsocketContext::new(message, Arc::new(send.clone())));

view! {}
}

Finally let’s use the context:

use leptos::prelude::*;
use leptos_use_websocket::{use_websocket, UseWebSocketReturn};
use std::sync::Arc;
#[derive(Clone)]
pub struct WebsocketContext {
    pub message: Signal<Option<String>>,
    send: Arc<dyn Fn(&String) + Send + Sync>,
}

impl WebsocketContext {
    #[inline(always)]
    pub fn send(&self, message: &str) {
        (self.send)(&message.to_string())
    }
}

#[component]
fn Demo() -> impl IntoView {
let websocket = expect_context::<WebsocketContext>();

websocket.send("Hello World!");

view! {}
}

SendWrapped Return

The returned closures open, close, and send are sendwrapped functions. They can only be called from the same thread that called use_websocket.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the returned functions amount to no-ops.

Installation

cargo add leptos-use-websocket

Options

UseWebSocketOptions

Options for use_websocket_with_options.

Every option is set with a builder method of the same name, e.g. UseWebSocketOptions::default().heartbeat(...). See also the API docs.

heartbeat

Type: Option<HeartbeatOptions<Hb, HbCodec>>

Heartbeat options

on_open

Type: Arc<dyn Fn(Event) + Send + Sync>

WebSocket connect callback.

on_message

Type: Arc<dyn Fn(&Rx) + Send + Sync>

WebSocket message callback for typed message decoded by codec.

on_message_raw

Type: Arc<dyn Fn(&str) + Send + Sync>

WebSocket message callback for text.

on_message_raw_bytes

Type: ArcFnBytes

WebSocket message callback for binary.

on_error

Type: Arc<dyn Fn(UseWebSocketError<E, D>) + Send + Sync>

WebSocket error callback.

Error events are only reported for the current socket: not for one replaced by open() (e.g. by calling open() while connecting), nor after the hook’s owner is cleaned up.

on_close

Type: Arc<dyn Fn(CloseEvent) + Send + Sync>

WebSocket close callback.

Only called for the current socket: not for one replaced by open() (e.g. close(); open();), nor after the hook’s owner is cleaned up.

reconnect_limit

Type: ReconnectLimit

Maximum number of consecutive reconnect attempts. The count resets whenever a connection opens, so a server that accepts the connection and closes it right away is retried indefinitely, even with a limit. Defaults to ReconnectLimit::Limited(3). Use ReconnectLimit::Infinite for infinite retries.

reconnect_interval

Type: u64

Retry interval in ms. Defaults to 3000.

immediate

Type: bool

If true the WebSocket connection will immediately be opened when calling this function. If false you have to manually call the open function. Defaults to true.

protocols

Type: Signal<Option<Vec<String>>>

Sub protocols. See MDN Docs.

Can be set as a signal to support protocols only available after the initial render.

Note that protocols are only updated on the next websocket open() call, not whenever the signal is updated. Therefore “lazy” protocols should use the immediate(false) option and manually call open().

Types

Source

Source • Demo • Docs

use_interval

Reactive counter increases on every interval.

Demo

Usage

use leptos::prelude::*;
use leptos_use_interval::{use_interval, UseIntervalReturn};

#[component]
fn Demo() -> impl IntoView {
let UseIntervalReturn {
    counter,
    reset,
    is_active,
    pause,
    resume
}  = use_interval( 200 );
view! { }
}

SendWrapped Return

The returned closures pause, resume and reset are sendwrapped functions. They can only be called from the same thread that called use_intersection_observer.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this function will simply be ignored.

Installation

cargo add leptos-use-interval

Options

UseIntervalOptions

Options for use_interval_with_options

Every option is set with a builder method of the same name, e.g. UseIntervalOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

Start the timer immediately. Defaults to true.

callback

Type: Rc<dyn Fn(u64)>

Callback on every interval.

Source

Source • Demo • Docs

use_interval_fn

Wrapper for set_interval with controls.

Demo

Usage

use leptos::prelude::*;
use leptos_use_interval_fn::use_interval_fn;
use leptos_use_filters::Pausable;

#[component]
fn Demo() -> impl IntoView {
let Pausable { pause, resume, is_active } = use_interval_fn(
    || {
        // do something
    },
    1000,
);
view! { }
}

SendWrapped Return

The returned closures pause and resume are sendwrapped functions. They can only be called from the same thread that called use_interval_fn.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this function will simply be ignored.

Installation

cargo add leptos-use-interval-fn

Options

UseIntervalFnOptions

Options for use_interval_fn_with_options

Every option is set with a builder method of the same name, e.g. UseIntervalFnOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

Start the timer immediately. Defaults to true.

immediate_callback

Type: bool

Execute the callback immediate after calling this function. Defaults to false

Source

Source • Demo • Docs

use_raf_fn

Call function on every requestAnimationFrame. With controls of pausing and resuming.

Demo

Usage

use leptos::prelude::*;
use leptos_use_raf_fn::use_raf_fn;
use leptos_use_filters::Pausable;

#[component]
fn Demo() -> impl IntoView {
let (count, set_count) = signal(0);

let Pausable { pause, resume, is_active } = use_raf_fn(move |_| {
    set_count.update(|count| *count += 1);
});

view! { <div>Count: { count }</div> }
}

You can use use_raf_fn_with_options and set immediate to false. In that case you have to call resume() before the callback is executed.

SendWrapped Return

The returned closures pause and resume are sendwrapped functions. They can only be called from the same thread that called use_interval_fn.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this does basically nothing. The provided closure will never be called.

Installation

cargo add leptos-use-raf-fn

Options

UseRafFnOptions

Options for use_raf_fn_with_options.

Every option is set with a builder method of the same name, e.g. UseRafFnOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

Start the requestAnimationFrame loop immediately on creation. Defaults to true. If false, the loop will only start when you call resume().

Types

Source

Source • Demo • Docs

use_timeout_fn

Wrapper for setTimeout with controls.

Demo

Usage

use leptos::prelude::*;
use leptos_use_timeout_fn::{use_timeout_fn, UseTimeoutFnReturn};

#[component]
fn Demo() -> impl IntoView {
let UseTimeoutFnReturn { start, stop, is_pending, .. } = use_timeout_fn(
    |i: i32| {
        // do sth
    },
    3000.0
);

start(3);

view! { }
}

Rescheduling

Calling start while a previous timer is still pending cancels that pending timer and schedules a fresh one. Only the most recent start call’s callback will fire. This matches VueUse’s useTimeoutFn semantics.

SendWrapped Return

The returned closures start and stop are sendwrapped functions. They can only be called from the same thread that called use_timeout_fn.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the callback will never be run. The returned functions are all no-ops and is_pending will always be false.

Installation

cargo add leptos-use-timeout-fn

Source

Source • Demo • Docs

use_timestamp

Reactive current timestamp.

Demo

Usage

use leptos::prelude::*;
use leptos_use_timestamp::use_timestamp;

#[component]
fn Demo() -> impl IntoView {
let timestamp = use_timestamp();

view! { }
}

With controls:

use leptos::prelude::*;
use leptos_use_timestamp::{use_timestamp_with_controls, UseTimestampReturn};

#[component]
fn Demo() -> impl IntoView {
let UseTimestampReturn {
    timestamp,
    is_active,
    pause,
    resume,
} = use_timestamp_with_controls();

view! { }
}

SendWrapped Return

The returned closures pause and resume of the ..._with_controls versions are sendwrapped functions. They can only be called from the same thread that called use_timestamp_with_controls.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this function will return a signal with the milliseconds since the Unix epoch. But the signal will never update (as there’s no request_animation_frame on the server).

Installation

cargo add leptos-use-timestamp

Options

UseTimestampOptions

Options for use_timestamp_with_controls_and_options.

Every option is set with a builder method of the same name, e.g. UseTimestampOptions::default().offset(...). See also the API docs.

offset

Type: f64

Offset value in milliseconds that is added to the returned timestamp. Defaults to 0.0.

immediate

Type: bool

Whether to update the timestamp immediately. Defaults to true.

interval

Type: TimestampInterval

Update interval in milliseconds or RequestAnimationFrame. Defaults to RequestAnimationFrame.

callback

Type: Rc<dyn Fn(f64)>

Callback to be called whenever the timestamp is updated.

Source

Source • Demo • Docs

use_calendar

Create bare-bone calendar data to use in your component. See UseCalendarOptions for options and UseCalendarReturn for return values.

The calendar is generic over the date type D which has to implement CalendarDateType. Implementations are provided behind feature flags. Enable at least one of them in addition to the use_calendar feature:

FeatureTypes
chronochrono::NaiveDate, chrono::DateTime<Utc>, chrono::DateTime<Local>, chrono::DateTime<FixedOffset>
jiffjiff::civil::Date, jiff::Zoned
timetime::Date, time::OffsetDateTime

For date-time types the calendar works on the calendar day in the value’s time zone. All comparisons (today, selected, before, after, between) are done by calendar day, ignoring the time of day. The generated dates keep the time of day of the displayed date unless it doesn’t exist on a day because of a DST transition, in which case it is shifted.

Demo

Usage

use leptos::prelude::*;
use chrono::NaiveDate;
use leptos_use_calendar::{use_calendar, UseCalendarReturn};

#[component]
fn Demo() -> impl IntoView {
let UseCalendarReturn {
    dates,
    weekdays,
    previous_month,
    today,
    month_by_date,
    next_month
} = use_calendar::<NaiveDate>();

view! {
}
}

Use use_calendar_with_options to change the initial date and first day of the week.

use leptos::prelude::*;
use chrono::NaiveDate;
use leptos_use_calendar::{use_calendar_with_options, UseCalendarReturn, UseCalendarOptions};

#[component]
fn Demo() -> impl IntoView {
let initial_date = RwSignal::new(
    Some(NaiveDate::from_ymd_opt(2022, 1, 1).unwrap())
);

let options = UseCalendarOptions::default()
    .first_day_of_the_week(6)
    .initial_date(initial_date);

let UseCalendarReturn {
    dates,
    weekdays,
    previous_month,
    today,
    month_by_date,
    next_month
} = use_calendar_with_options(options);

view! {
}
}

Using jiff or time

With the feature jiff or time enabled you can use their date types instead.

#[cfg(feature = "jiff")]
mod jiff_demo {
use leptos::prelude::*;
use leptos_use_calendar::{use_calendar, UseCalendarReturn};

#[component]
fn Demo() -> impl IntoView {
let UseCalendarReturn { dates, .. } = use_calendar::<jiff::civil::Date>();

view! {
}
}
}
#[cfg(feature = "time")]
mod time_demo {
use leptos::prelude::*;
use leptos_use_calendar::{use_calendar, UseCalendarReturn};

#[component]
fn Demo() -> impl IntoView {
let UseCalendarReturn { dates, .. } = use_calendar::<time::Date>();

view! {
}
}
}

Custom date types

To use your own date type, implement CalendarDateType for it. This works without enabling any of the backend features. Here is an example with a new-type wrapper around a chrono date:

#[cfg(feature = "chrono")]
mod custom_demo {
use leptos::prelude::*;
use chrono::{Datelike, Local, Months, NaiveDate};
use leptos_use_calendar::{use_calendar, CalendarDateType, UseCalendarReturn};

#[derive(Clone, Copy, PartialEq)]
pub struct MyDate(NaiveDate);

impl CalendarDateType for MyDate {
    fn today() -> Self {
        MyDate(Local::now().date_naive())
    }

    fn ymd(&self) -> (i32, u8, u8) {
        (self.0.year(), self.0.month() as u8, self.0.day() as u8)
    }

    fn prev_day(&self) -> Option<Self> {
        self.0.pred_opt().map(MyDate)
    }

    fn next_day(&self) -> Option<Self> {
        self.0.succ_opt().map(MyDate)
    }

    fn weekday_from_monday(&self) -> u8 {
        self.0.weekday().num_days_from_monday() as u8
    }

    fn add_months(&self, months: i32) -> Option<Self> {
        let date = if months >= 0 {
            self.0.checked_add_months(Months::new(months as u32))
        } else {
            self.0.checked_sub_months(Months::new(months.unsigned_abs()))
        };
        date.map(MyDate)
    }
}

#[component]
fn Demo() -> impl IntoView {
    let UseCalendarReturn { dates, .. } = use_calendar::<MyDate>();
    // ...
    view! { }
}
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

Not tested yet.

Installation

cargo add leptos-use-calendar

Options

UseCalendarOptions

Options for use_calendar_with_options.

Every option is set with a builder method of the same name, e.g. UseCalendarOptions::default().initial_date(...). See also the API docs.

initial_date

Type: MaybeRwSignal<Option<D>>

Date being used to initialize the calendar month to be displayed. Defaults to CalendarDateType::today.

first_day_of_the_week

Type: Signal<usize>

First day of the week as a number from 0 to 6. Defaults to 0 (Monday).

Source

Source • Demo • Docs

watch_debounced

A debounced version of watch.

Demo

Usage

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_watch_debounce_throttle::watch_debounced;

pub fn Demo() -> impl IntoView {
    let (source, set_source) = signal(0);

watch_debounced(
    move || source.get(),
    move |_, _, _| {
        log!("changed!");
    },
    500.0,
);

   view! { }
}

This really is only shorthand shorthand for watch_with_options(deps, callback, WatchOptions::default().debounce(ms)).

Please note that if the current component is cleaned up before the debounced callback is called, the debounced callback will not be called.

There’s also watch_debounced_with_options where you can specify the other watch options (except filter).

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_watch_debounce_throttle::{watch_debounced_with_options, WatchDebouncedOptions};

pub fn Demo() -> impl IntoView {
    let (source, set_source) = signal(0);

watch_debounced_with_options(
    move || source.get(),
    move |_, _, _| {
        log!("changed!");
    },
    500.0,
    WatchDebouncedOptions::default().max_wait(Some(1000.0)),
);

   view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the callback will never be called except if you set immediate to true in which case the callback will be called exactly once.

See also

Installation

cargo add leptos-use-watch-debounce-throttle

Options

WatchDebouncedOptions

Options for watch_debounced_with_options.

Every option is set with a builder method of the same name, e.g. WatchDebouncedOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

If immediate is false, the callback will not run immediately but only after the first change is detected of any signal that is accessed in deps. Defaults to false.

max_wait

Type: Signal<Option<f64>>

The maximum time allowed to be delayed before the callback invoked. In milliseconds. Same as DebounceOptions::max_wait

Source

Source • Demo • Docs

watch_pausable

Pausable watch.

Demo

Usage

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_watch_pausable::{watch_pausable, WatchPausableReturn};

pub fn Demo() -> impl IntoView {
let (source, set_source) = signal("foo".to_string());

let WatchPausableReturn {
    stop,
    pause,
    resume,
    ..
} = watch_pausable(
    move || source.get(),
    |v, _, _| {
        log!("Changed to {}", v);
    },
);

set_source.set("bar".to_string()); // > "Changed to bar"

pause();

set_source.set("foobar".to_string()); // (nothing happens)

resume();

set_source.set("hello".to_string()); // > "Changed to hello"
   view! { }
}

There’s also watch_pausable_with_options which takes the same options as watch.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this works just fine except if you throttle or debounce in which case the callback will never be called except if you set immediate to true in which case the callback will be called exactly once.

See also

  • leptos::watch

Installation

cargo add leptos-use-watch-pausable

Options

WatchOptions

Options for watch_with_options

The filter is a type parameter so that the debounce and throttle code is only compiled into your app if you use it.

Every option is set with a builder method of the same name, e.g. WatchOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

If immediate is true, the callback will run immediately. If it’s false, the callbackwill run only after the first change is detected of any signal that is accessed indeps. Defaults to false`.

filter

Type: F

Allows to debounce or throttle the callback with a FilterOptions. Defaults to no filter.

Source

Source • Demo • Docs

watch_throttled

A throttled version of leptos::watch.

Demo

Usage

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_watch_debounce_throttle::watch_throttled;

pub fn Demo() -> impl IntoView {
    let (source, set_source) = signal(0);

watch_throttled(
    move || source.get(),
    move |_, _, _| {
        log!("changed!");
    },
    500.0,
);

   view! { }
}

This really is only shorthand shorthand for watch_with_options(deps, callback, WatchOptions::default().throttle(ms)).

Please note that if the current component is cleaned up before the throttled callback is called, the throttled callback will not be called.

There’s also watch_throttled_with_options where you can specify the other watch options (except filter).

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_watch_debounce_throttle::{watch_throttled_with_options, WatchThrottledOptions};

pub fn Demo() -> impl IntoView {
    let (source, set_source) = signal(0);

watch_throttled_with_options(
    move || source.get(),
    move |_, _, _| {
        log!("changed!");
    },
    500.0,
    WatchThrottledOptions::default().leading(true).trailing(false),
);

   view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the callback will never be called except if you set immediate to true in which case the callback will be called exactly once.

See also

Installation

cargo add leptos-use-watch-debounce-throttle

Options

WatchThrottledOptions

Options for watch_throttled_with_options.

Every option is set with a builder method of the same name, e.g. WatchThrottledOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

If immediate is false, the callback will not run immediately but only after the first change is detected of any signal that is accessed in deps. Defaults to false.

trailing

Type: bool

Invoke on the trailing edge of the timeout. Defaults to true.

leading

Type: bool

Invoke on the leading edge of the timeout. Defaults to true.

Source

Source • Demo • Docs

watch_with_options

A version of leptos::watch but with additional options.

Immediate

This is the same as for leptos::watch. But you don’t have to specify it. By default its set to false. If immediate is true, the callback will run immediately (this is also true if throttled/debounced). If it’s false, the callback will run only after the first change is detected of any signal that is accessed in deps.

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_watch_with_options::{watch_with_options, WatchOptions};

pub fn Demo() -> impl IntoView {
let (num, set_num) = signal(0);

watch_with_options(
    move || num.get(),
    move |num, _, _| {
        log!("Number {}", num);
    },
    WatchOptions::default().immediate(true),
); // > "Number 0"

set_num.set(1); // > "Number 1"
   view! { }
}

Filters

The callback can be throttled or debounced. Please see watch_throttled and watch_debounced for details.

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_watch_with_options::{watch_with_options, WatchOptions};

pub fn Demo() -> impl IntoView {
let (num, set_num) = signal(0);

watch_with_options(
    move || num.get(),
    move |num, _, _| {
        log!("Number {}", num);
    },
    WatchOptions::default().throttle(100.0), // there's also `throttle_with_options`
);
   view! { }
}
use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_watch_with_options::{watch_with_options, WatchOptions};

pub fn Demo() -> impl IntoView {
let (num, set_num) = signal(0);

watch_with_options(
    move || num.get(),
    move |num, _, _| {
        log!("number {}", num);
    },
    WatchOptions::default().debounce(100.0), // there's also `debounce_with_options`
);
   view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this works just fine except if you throttle or debounce in which case the callback will never be called except if you set immediate to true in which case the callback will be called exactly once when watch() is executed.

See also

Installation

cargo add leptos-use-watch-with-options

Options

WatchOptions

Options for watch_with_options

The filter is a type parameter so that the debounce and throttle code is only compiled into your app if you use it.

Every option is set with a builder method of the same name, e.g. WatchOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

If immediate is true, the callback will run immediately. If it’s false, the callbackwill run only after the first change is detected of any signal that is accessed indeps. Defaults to false`.

filter

Type: F

Allows to debounce or throttle the callback with a FilterOptions. Defaults to no filter.

Source

Source • Docs

whenever

Shorthand for watching a signal to be true.

Usage

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_whenever::whenever;

pub fn Demo() -> impl IntoView {
let (is_ready, set_ready) = signal(false);

whenever(move || is_ready.get(), |v, _, _| log!("{}", v));

    view! { }
}

Callback Function

Same as watch, the callback will be called with callback(input, prev_input, prev_return).

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_whenever::whenever;

pub fn Demo() -> impl IntoView {
let (is_ready, set_ready) = signal(false);
whenever(move || is_ready.get(), |value, prev_value, _| {
    log!("before: {prev_value:?}; now: {value}");
});

    view! { }
}

Computed

Same as watch, you can pass a getter function to calculate on each change.

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_whenever::whenever;

pub fn Demo() -> impl IntoView {
let (counter, set_counter) = signal(0);
whenever(
    move || counter.get() == 7,
    |_, _, _| log!("counter is 7 now!"),
);

    view! { }
}

Options

Options and defaults are same as watch_with_options.

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_watch_with_options::WatchOptions;
use leptos_use_whenever::whenever_with_options;

pub fn Demo() -> impl IntoView {
let (counter, set_counter) = signal(0);
whenever_with_options(
    move || counter.get() == 7,
    |_, _, _| log!("counter is 7 now!"),
    WatchOptions::default().immediate(true),
);

    view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this works just fine except if you throttle or debounce in which case the callback will never be called except if you set immediate to true in which case the callback will be called exactly once.

Installation

cargo add leptos-use-whenever

Options

WatchOptions

Options for watch_with_options

The filter is a type parameter so that the debounce and throttle code is only compiled into your app if you use it.

Every option is set with a builder method of the same name, e.g. WatchOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

If immediate is true, the callback will run immediately. If it’s false, the callbackwill run only after the first change is detected of any signal that is accessed indeps. Defaults to false`.

filter

Type: F

Allows to debounce or throttle the callback with a FilterOptions. Defaults to no filter.

Source

Source • Docs

signal_debounced

Debounce changing of a Signal value.

Use *_local variants for values that are not Send + Sync.

Demo

Usage

use leptos::prelude::*;
use leptos_use_signal_debounce_throttle::{signal_debounced, signal_debounced_local};
use std::cell::RefCell;

#[component]
fn Demo() -> impl IntoView {
let (input, set_input) = signal("");
let debounced: Signal<&'static str> = signal_debounced(input, 1000.0);

let (input_local, set_input_local) = signal_local(RefCell::new(0));
let debounced_local: Signal<RefCell<i32>, _> = signal_debounced_local(input_local, 1000.0);

view! { }
}

Options

The usual debounce option max_wait is available.

use leptos::prelude::*;
use leptos_use_signal_debounce_throttle::{signal_debounced_with_options, signal_debounced_local_with_options};
use leptos_use_filters::DebounceOptions;
use std::cell::RefCell;

#[component]
fn Demo() -> impl IntoView {
let (input, set_input) = signal("");
let debounced: Signal<&'static str> = signal_debounced_with_options(
    input,
    1000.0,
    DebounceOptions::default().max_wait(Some(500.0))
);

let (input_local, set_input_local) = signal_local(RefCell::new(0));
let debounced_local: Signal<RefCell<i32>, _> = signal_debounced_local_with_options(
    input_local,
    1000.0,
    DebounceOptions::default().max_wait(Some(500.0))
);

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

Internally this uses setTimeout which is not supported on the server. So usually a throttled signal on the server will simply be ignored.

Installation

cargo add leptos-use-signal-debounce-throttle

Options

DebounceOptions

Every option is set with a builder method of the same name, e.g. DebounceOptions::default().max_wait(...). See also the API docs.

max_wait

Type: Signal<Option<f64>>

The maximum time allowed to be delayed before it’s invoked. In milliseconds.

Source

Source • Demo • Docs

signal_throttled

Throttle changing of a Signal value.

Use *_local variants for values that are not Send + Sync.

Demo

Usage

use leptos::prelude::*;
use leptos_use_signal_debounce_throttle::{signal_throttled, signal_throttled_local};
use std::cell::RefCell;

#[component]
fn Demo() -> impl IntoView {
let (input, set_input) = signal("");
let throttled: Signal<&'static str> = signal_throttled(input, 1000.0);

let (input_local, set_input_local) = signal_local(RefCell::new(0));
let throttled_local: Signal<RefCell<i32>, _> = signal_throttled_local(input_local, 1000.0);

view! { }
}

Options

The usual throttle options leading and trailing are available.

use leptos::prelude::*;
use leptos_use_signal_debounce_throttle::{signal_throttled_with_options, signal_throttled_local_with_options};
use leptos_use_filters::ThrottleOptions;
use std::cell::RefCell;

#[component]
fn Demo() -> impl IntoView {
let (input, set_input) = signal("");
let throttled: Signal<&'static str> = signal_throttled_with_options(
    input,
    1000.0,
    ThrottleOptions::default().leading(false).trailing(true)
);

let (input_local, set_input_local) = signal_local(RefCell::new(0));
let throttled_local: Signal<RefCell<i32>, _> = signal_throttled_local_with_options(
    input_local,
    1000.0,
    ThrottleOptions::default().leading(false).trailing(true)
);

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

Internally this uses setTimeout which is not supported on the server. So usually a throttled signal on the server will simply be ignored.

Installation

cargo add leptos-use-signal-debounce-throttle

Options

ThrottleOptions

Every option is set with a builder method of the same name, e.g. ThrottleOptions::default().trailing(...). See also the API docs.

trailing

Type: bool

Invoke on the trailing edge of the timeout. Defaults to true.

leading

Type: bool

Invoke on the leading edge of the timeout (=immediately). Defaults to true.

Source

Source • Demo • Docs

sync_signal

Two-way Signals synchronization.

Note: Please consider first if you can achieve your goals with the “Good Options” described in the Leptos book Only if you really have to, use this function. This is, in effect, the “If you really must…” option.

Demo

Usage

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_sync_signal::sync_signal;

#[component]
fn Demo() -> impl IntoView {
let (a, set_a) = signal(1);
let (b, set_b) = signal(2);

let stop = sync_signal((a, set_a), (b, set_b));

log!("a: {}, b: {}", a.get(), b.get()); // a: 1, b: 1

set_b.set(3);

log!("a: {}, b: {}", a.get(), b.get()); // a: 3, b: 3

set_a.set(4);

log!("a: {}, b: {}", a.get(), b.get()); // a: 4, b: 4

view! { }
}

RwSignal

You can mix and match RwSignals and Signal-WriteSignal pairs.

use leptos::prelude::*;
use leptos_use_sync_signal::sync_signal;

#[component]
fn Demo() -> impl IntoView {
let (a, set_a) = signal(1);
let (b, set_b) = signal(2);
let c_rw = RwSignal::new(3);
let d_rw = RwSignal::new(4);

sync_signal((a, set_a), c_rw);
sync_signal(d_rw, (b, set_b));
sync_signal(c_rw, d_rw);


view! { }
}

One directional

You can synchronize a signal only from left to right or right to left.

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_sync_signal::{sync_signal_with_options, SyncSignalOptions, SyncDirection};

#[component]
fn Demo() -> impl IntoView {
let (a, set_a) = signal(1);
let (b, set_b) = signal(2);

let stop = sync_signal_with_options(
    (a, set_a),
    (b, set_b),
    SyncSignalOptions::default().direction(SyncDirection::LeftToRight)
);

set_b.set(3); // doesn't sync

log!("a: {}, b: {}", a.get(), b.get()); // a: 1, b: 3

set_a.set(4);

log!("a: {}, b: {}", a.get(), b.get()); // a: 4, b: 4

view! { }
}

Custom Transform

You can optionally provide custom transforms between the two signals.

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_sync_signal::{sync_signal_with_options, SyncSignalOptions};

#[component]
fn Demo() -> impl IntoView {
let (a, set_a) = signal(10);
let (b, set_b) = signal(2);

let stop = sync_signal_with_options(
    (a, set_a),
    (b, set_b),
    SyncSignalOptions::with_transforms(
        |left| *left * 2,
        |right| *right / 2,
    ),
);

log!("a: {}, b: {}", a.get(), b.get()); // a: 10, b: 20

set_b.set(30);

log!("a: {}, b: {}", a.get(), b.get()); // a: 15, b: 30

view! { }
}

Different Types

SyncSignalOptions::default() is only defined if the two signal types are identical. Otherwise, you have to initialize the options with with_transforms or with_assigns instead of default.

use leptos::prelude::*;
use leptos_use_sync_signal::{sync_signal_with_options, SyncSignalOptions};
use std::str::FromStr;

#[component]
fn Demo() -> impl IntoView {
let (a, set_a) = signal("10".to_string());
let (b, set_b) = signal(2);

let stop = sync_signal_with_options(
    (a, set_a),
    (b, set_b),
    SyncSignalOptions::with_transforms(
        |left: &String| i32::from_str(left).unwrap_or_default(),
        |right: &i32| right.to_string(),
    ),
);

view! { }
}
use leptos::prelude::*;
use leptos_use_sync_signal::{sync_signal_with_options, SyncSignalOptions};
use std::str::FromStr;

#[derive(Clone)]
pub struct Foo {
    bar: i32,
}

#[component]
fn Demo() -> impl IntoView {
let (a, set_a) = signal(Foo { bar: 10 });
let (b, set_b) = signal(2);

let stop = sync_signal_with_options(
    (a, set_a),
    (b, set_b),
    SyncSignalOptions::with_assigns(
        |b: &mut i32, a: &Foo| *b = a.bar,
        |a: &mut Foo, b: &i32| a.bar = *b,
    ),
);

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server the signals are not continuously synced. If the option immediate is true, the signals are synced once initially. If the option immediate is false, then this function does nothing.

Installation

cargo add leptos-use-sync-signal

Options

SyncSignalOptions

Options for sync_signal_with_options.

Every option is set with a builder method of the same name, e.g. SyncSignalOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

If true, the signals will be immediately synced when this function is called. If false, a signal is only updated when the other signal’s value changes. Defaults to true.

direction

Type: SyncDirection

Direction of syncing. Defaults to SyncDirection::Both.

Source

Source • Demo • Docs

use_sorted

Reactive sort of iterable

Demo

Usage

use leptos::prelude::*;
use leptos_use_sorted::use_sorted;

#[component]
fn Demo() -> impl IntoView {
let source = vec![10, 3, 5, 7, 2, 1, 8, 6, 9, 4];
let sorted: Signal<Vec<i32>> = use_sorted(source); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

view! { }
}

You can also sort by key or with a compare function.

use leptos::prelude::*;
use leptos_use_sorted::{use_sorted_by, use_sorted_by_key};

#[derive(Clone, PartialEq)]
pub struct Person {
    pub name: String,
    pub age: u16,
}

#[component]
fn Demo() -> impl IntoView {
let source = vec![
    Person {
        name: "John".to_string(),
        age: 40,
    },
    Person {
        name: "Jane".to_string(),
        age: 20,
    },
    Person {
        name: "Joe".to_string(),
        age: 30,
    },
    Person {
        name: "Jenny".to_string(),
        age: 22,
    },
];

// sort by key
let sorted: Signal<Vec<Person>> = use_sorted_by_key(
    source.clone(),
    |person: &Person| person.age,
);

// sort with compare function
let sorted: Signal<Vec<Person>> = use_sorted_by(
    source,
    |p1: &Person, p2: &Person| p1.age.cmp(&p2.age),
);

view! { }
}

Please note that these two ways of sorting are equivalent.

Installation

cargo add leptos-use-sorted

Source

Source • Demo • Docs

header

Get the value of the header with the given name.

This function is only meant to be used on the server. So it is only defined when the feature "ssr" is enabled together with one of the features "axum" or "actix".

Example

#![allow(unused)]
fn main() {
use leptos_use_header::header;

let content_len = header(http::header::CONTENT_LENGTH);
}

Installation

cargo add leptos-use-header

Source

Source • Docs

is_err

Reactive Result::is_err().

Usage

use leptos::prelude::*;
use leptos_use_is::is_err;

#[component]
fn Demo() -> impl IntoView {
let (example, set_example) = signal(
    if js_sys::Math::random() < 0.5 { Ok("Example") } else { Err(()) }
);

let is_error = is_err(example);

view! { }
}

Installation

cargo add leptos-use-is

Source

Source • Docs

is_none

Reactive Option::is_none().

Usage

use leptos::prelude::*;
use leptos_use_is::is_none;

#[component]
fn Demo() -> impl IntoView {
let (example, set_example) = signal(
    if js_sys::Math::random() < 0.5 { Some("Example") } else { None }
);

let is_empty = is_none::<_, &str>(example);

view! { }
}

Installation

cargo add leptos-use-is

Source

Source • Docs

is_ok

Reactive Result::is_ok().

Usage

use leptos::prelude::*;
use leptos_use_is::is_ok;

#[component]
fn Demo() -> impl IntoView {
let (example, set_example) = signal(
    if js_sys::Math::random() < 0.5 { Ok("Example") } else { Err(()) }
);

let is_ok = is_ok(example);

view! { }
}

Installation

cargo add leptos-use-is

Source

Source • Docs

is_some

Reactive Option::is_some().

Usage

use leptos::prelude::*;
use leptos_use_is::is_some;

#[component]
fn Demo() -> impl IntoView {
let (example, set_example) = signal(
    if js_sys::Math::random() < 0.5 { Some("Example") } else { None }
);

let not_empty = is_some::<_, &str>(example);

view! { }
}

Installation

cargo add leptos-use-is

Source

Source • Docs

use_cycle_list

Cycle through a list of items.

Demo

Usage

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_cycle_list::{use_cycle_list, UseCycleListReturn};

#[component]
fn Demo() -> impl IntoView {
let UseCycleListReturn { state, next, prev, .. } = use_cycle_list(
    vec!["Dog", "Cat", "Lizard", "Shark", "Whale", "Dolphin", "Octopus", "Seal"]
);

log!("{}", state.get()); // "Dog"

prev();

log!("{}", state.get()); // "Seal"

view! { }
}

Installation

cargo add leptos-use-cycle-list

Options

UseCycleListOptions

Options for use_cycle_list_with_options.

Every option is set with a builder method of the same name, e.g. UseCycleListOptions::default().initial_value(...). See also the API docs.

initial_value

Type: Option<MaybeRwSignal<T>>

The initial value of the state. Can be a Signal. If none is provided the first entry of the list will be used.

fallback_index

Type: usize

The default index when the current value is not found in the list. For example when get_index_of returns None.

get_position

Type: fn(&T, &Vec<T>) -> Option<usize>

Custom function to get the index of the current value. Defaults to Iterator::position()

Source

Source • Demo • Docs

use_debounce_fn

Debounce execution of a function.

Debounce is an overloaded waiter: If you keep asking him your requests will be ignored until you stop and give him some time to think about your latest inquiry.

Demo

Usage

use leptos::prelude::*;
use leptos::ev::resize;
use leptos_use_fn_debounce_throttle::use_debounce_fn;

#[component]
fn Demo() -> impl IntoView {
let mut debounced_fn = use_debounce_fn(
    || {
        // do something
    },
    1000.0,
);

window_event_listener(resize, move |_| { debounced_fn(); });
   view! { }
}

Please note that if the current component is cleaned up before the throttled callback is called, the throttled callback will not be called.

You can also pass options to use_debounce_fn_with_options with a maximum wait time, similar to lodash debounce.

use leptos::prelude::*;
use leptos::ev::resize;
use leptos_use_fn_debounce_throttle::use_debounce_fn_with_options;
use leptos_use_filters::DebounceOptions;

#[component]
fn Demo() -> impl IntoView {
let mut debounced_fn = use_debounce_fn_with_options(
    || {
        // do something
    },
    1000.0,
    DebounceOptions::default()
        .max_wait(Some(5000.0)),
);

window_event_listener(resize, move |_| { debounced_fn(); });
   view! { }
}

Currently there is no way to use a function with a return value. Please open an issue if you need this.

If you want to throttle a function that takes an argument there are also the versions use_debounce_fn_with_arg and use_debounce_fn_with_arg_and_options.

SendWrapped Return

The returned closure is a sendwrapped function. It can only be called from the same thread that called use_debounce_....

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

Internally this uses setTimeout which is not supported on the server. So usually calling a debounced function on the server will simply be ignored.

Installation

cargo add leptos-use-fn-debounce-throttle

Options

DebounceOptions

Every option is set with a builder method of the same name, e.g. DebounceOptions::default().max_wait(...). See also the API docs.

max_wait

Type: Signal<Option<f64>>

The maximum time allowed to be delayed before it’s invoked. In milliseconds.

Source

Source • Demo • Docs

use_derive_signal!

Macro to easily create helper functions that derive a signal using a piece of code.

See is_ok or use_to_string as examples.

use_supported

SSR compatibe is_supported

Usage

use leptos::prelude::*;
use leptos_use_supported::use_supported;
use wasm_js_macros::js;
use wasm_bindgen::JsValue;

pub fn Demo() -> impl IntoView {
let is_supported = use_supported(
    || js!("getBattery" in &window().navigator())
);

if is_supported.get() {
    // do something
}
   view! { }
}

Installation

cargo add leptos-use-supported

Source

Source • Docs

use_throttle_fn

Throttle execution of a function. Especially useful for rate limiting execution of handlers on events like resize and scroll.

Throttle is a spring that throws balls: After a ball flies out it needs some time to shrink back, so it cannot throw any more balls until it’s ready.

Demo

Usage

use leptos::prelude::*;
use leptos_use_fn_debounce_throttle::use_throttle_fn;

#[component]
fn Demo() -> impl IntoView {
let mut throttled_fn = use_throttle_fn(
    || {
        // do something, it will be called at most 1 time per second
    },
    1000.0,
);
view! {
    <button on:click=move |_| { throttled_fn(); }>
        "Smash me!"
    </button>
}
}

Please note that if the current component is cleaned up before the throttled callback is called, the throttled callback will not be called.

You can provide options when you use use_throttle_fn_with_options.

use leptos::prelude::*;
use leptos_use_filters::ThrottleOptions;
use leptos_use_fn_debounce_throttle::use_throttle_fn_with_options;
#[component]
fn Demo() -> impl IntoView {
let throttled_fn = use_throttle_fn_with_options(
    || {
        // do something, it will be called at most 1 time per second
    },
    1000.0,
    ThrottleOptions::default()
        .leading(true)
        .trailing(true),
);
   view! { }
}

If you want to throttle a function that takes an argument there are also the versions use_throttle_fn_with_arg and use_throttle_fn_with_arg_and_options.

SendWrapped Return

The returned closure is a sendwrapped function. It can only be called from the same thread that called use_throttle_....

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

Internally this uses setTimeout which is not supported on the server. So usually calling a throttled function on the server will simply be ignored.

Installation

cargo add leptos-use-fn-debounce-throttle

Options

ThrottleOptions

Every option is set with a builder method of the same name, e.g. ThrottleOptions::default().trailing(...). See also the API docs.

trailing

Type: bool

Invoke on the trailing edge of the timeout. Defaults to true.

leading

Type: bool

Invoke on the leading edge of the timeout (=immediately). Defaults to true.

Source

Source • Demo • Docs

use_to_string

Reactive ToString::to_string().

Usage

use leptos::prelude::*;
use leptos_use_to_string::use_to_string;

#[component]
fn Demo() -> impl IntoView {
let (number, set_number) = signal(3.14_f64);
let str = use_to_string::<_, f64>(number);

view! { }
}

Installation

cargo add leptos-use-to-string

Source

Source • Docs

use_toggle

A boolean switcher with utility functions.

Demo

Usage

use leptos::*;
use leptos_use_toggle::{use_toggle, UseToggleReturn};

#[component]
fn Demo() -> impl IntoView {
let UseToggleReturn { toggle, value, set_value } = use_toggle(true);

view! { }
}

See also

Installation

cargo add leptos-use-toggle

Source

Source • Demo • Docs

use_intl_datetime_format

Reactive Intl.DateTimeFormat.

Demo

Usage

Dates are passed in as chrono::DateTime (just like in use_calendar).

In basic use without specifying a locale, a formatted string in the default locale and with default options is returned.

use leptos::prelude::*;
use leptos_use_intl_datetime_format::{use_intl_datetime_format, UseIntlDateTimeFormatOptions};
use chrono::{TimeZone, Utc};

#[component]
fn Demo() -> impl IntoView {
let (date, set_date) = signal(Utc.with_ymd_and_hms(2020, 12, 20, 3, 23, 16).unwrap());

let date_time_format = use_intl_datetime_format(UseIntlDateTimeFormatOptions::default());

let formatted = date_time_format.format(date); // "12/20/2020" if in US English locale

view! { }
}

Using locales

In order to get the format of the language used in the user interface of your application, make sure to specify that language (and possibly some fallback languages) using the locales argument:

use leptos::prelude::*;
use leptos_use_intl_datetime_format::{use_intl_datetime_format, UseIntlDateTimeFormatOptions};
use chrono::{TimeZone, Utc};

#[component]
fn Demo() -> impl IntoView {
let date = Utc.with_ymd_and_hms(2012, 12, 20, 3, 0, 0).unwrap();

// British English uses day-month-year order and 24-hour time without AM/PM
let date_time_format = use_intl_datetime_format(
    UseIntlDateTimeFormatOptions::default().locale("en-GB"),
);
let formatted = date_time_format.format(date); // 20/12/2012

// Korean uses year-month-day order
let date_time_format = use_intl_datetime_format(
    UseIntlDateTimeFormatOptions::default().locale("ko-KR"),
);
let formatted = date_time_format.format(date); // 2012. 12. 20.

// Arabic in most Arabic speaking countries uses real Arabic digits
let date_time_format = use_intl_datetime_format(
    UseIntlDateTimeFormatOptions::default().locale("ar-EG"),
);
let formatted = date_time_format.format(date); // ٢٠‏/١٢‏/٢٠١٢

// when requesting a language that may not be supported, such as
// Balinese, include a fallback language, in this case Indonesian
let date_time_format = use_intl_datetime_format(
    UseIntlDateTimeFormatOptions::default()
        .locales(vec!["ban".to_string(), "id".to_string()]),
);
let formatted = date_time_format.format(date); // 20/12/2012

view! { }
}

Using options

The results can be customized in multiple ways.

use leptos::prelude::*;
use leptos_use_intl_datetime_format::{use_intl_datetime_format, UseIntlDateTimeFormatOptions, WeekdayFormat, EraFormat, YearFormat, MonthFormat, DayFormat, TimeNumericFormat, TimeZoneNameFormat};
use chrono::{TimeZone, Utc};

#[component]
fn Demo() -> impl IntoView {
let date = Utc.with_ymd_and_hms(2012, 12, 20, 3, 0, 0).unwrap();

// request a weekday along with a long date
let date_time_format = use_intl_datetime_format(
    UseIntlDateTimeFormatOptions::default()
        .locale("en-US")
        .weekday(WeekdayFormat::Long)
        .year(YearFormat::Numeric)
        .month(MonthFormat::Long)
        .day(DayFormat::Numeric),
);
let formatted = date_time_format.format(date); // "Thursday, December 20, 2012"

// an application may want to use UTC and make that visible
let date_time_format = use_intl_datetime_format(
    UseIntlDateTimeFormatOptions::default()
        .locale("en-US")
        .hour(TimeNumericFormat::Numeric)
        .minute(TimeNumericFormat::TwoDigit)
        .second(TimeNumericFormat::TwoDigit)
        .time_zone("UTC")
        .time_zone_name(TimeZoneNameFormat::Short),
);
let formatted = date_time_format.format(date); // "3:00:00 AM UTC"

view! { }
}

Instead of specifying the individual date and time components you can use the UseIntlDateTimeFormatOptions::date_style and UseIntlDateTimeFormatOptions::time_style shortcuts.

use leptos::prelude::*;
use leptos_use_intl_datetime_format::{use_intl_datetime_format, UseIntlDateTimeFormatOptions, DateTimeStyle};
use chrono::{TimeZone, Utc};

#[component]
fn Demo() -> impl IntoView {
let date = Utc.with_ymd_and_hms(2012, 12, 20, 3, 0, 0).unwrap();

let date_time_format = use_intl_datetime_format(
    UseIntlDateTimeFormatOptions::default()
        .locale("en-GB")
        .date_style(DateTimeStyle::Full)
        .time_style(DateTimeStyle::Long)
        .time_zone("UTC"),
);
let formatted = date_time_format.format(date); // "Thursday 20 December 2012 at 03:00:00 UTC"

view! { }
}

Note that date_style and time_style cannot be mixed with the individual date-time component options (like weekday, year, hour, …). Doing so makes Intl.DateTimeFormat throw a RangeError which results in an empty string being returned.

For an exhaustive list of options see UseIntlDateTimeFormatOptions.

Formatting ranges

Apart from the format method, the format_range method can be used to format a range of dates. Please see UseIntlDateTimeFormatReturn::format_range for details.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

Since Intl.DateTimeFormat is a JavaScript API it is not available on the server. That’s why it falls back to a simple call to format!() on the server, which is not locale-aware.

Installation

cargo add leptos-use-intl-datetime-format

Options

UseIntlDateTimeFormatOptions

Every option is set with a builder method of the same name, e.g. UseIntlDateTimeFormatOptions::default().locales(...). See also the API docs.

locales

Type: Vec<String>

A vec of strings, each with a BCP 47 language tag. Please refer to the MDN Docs for more info.

locale_matcher

Type: LocaleMatcher

The locale matching algorithm to use. Possible values are Lookup and BestFit; the default is BestFit. For information about this option, see the Intl page.

calendar

Type: Option<String>

The calendar to use, such as "chinese", "gregory", "persian" etc. For a list of the supported calendar types, see the MDN docs.

day_period

Type: Option<DayPeriodFormat>

The way day periods should be expressed. This option only has an effect if a 12-hour clock (hour_cycle H11 or H12, or hour12 is true) is used. Note that the day period may be displayed even if the hour is not set to be displayed.

numbering_system

Type: Option<String>

The numbering system to use. Possible values include: "arab", "arabext", "bali", "beng", "deva", "fullwide", "gujr", "guru", "hanidec", "khmr", "knda", "laoo", "latn", "limb", "mlym", "mong", "mymr", "orya", "tamldec", "telu", "thai", "tibt".

hour12

Type: Option<bool>

Whether to use 12-hour time (as opposed to 24-hour time). The default is locale dependent. This option overrides the hc language tag and/or the hour_cycle option in case both are present.

hour_cycle

Type: Option<HourCycle>

The hour cycle to use. This option overrides the hc language tag, if both are present, and the hour12 option takes precedence in case both options have been specified.

  • H11: hour system using 0–11; corresponds to midnight starting at 0:00 AM.
  • H12: hour system using 1–12; corresponds to midnight starting at 12:00 AM.
  • H23: hour system using 0–23; corresponds to midnight starting at 0:00.
  • H24: hour system using 1–24; corresponds to midnight starting at 24:00.

time_zone

Type: Option<String>

The time zone to use. The only value implementations must recognize is "UTC"; the default is the runtime’s default time zone. Implementations may also recognize the time zone names of the IANA time zone database, such as "Asia/Shanghai", "Asia/Kolkata", "America/New_York".

format_matcher

Type: FormatMatcher

The format matching algorithm to use. Possible values are Basic and BestFit; the default is BestFit. See the MDN docs for details. Only has an effect when using the individual date-time component options (and not UseIntlDateTimeFormatOptions::date_style / UseIntlDateTimeFormatOptions::time_style).

weekday

Type: Option<WeekdayFormat>

The representation of the weekday.

  • Long: e.g., Thursday
  • Short: e.g., Thu
  • Narrow: e.g., T. Two weekdays may have the same narrow style for some locales (e.g. Tuesday’s narrow style is also T).

Cannot be combined with UseIntlDateTimeFormatOptions::date_style / UseIntlDateTimeFormatOptions::time_style.

era

Type: Option<EraFormat>

The representation of the era.

  • Long: e.g., Anno Domini
  • Short: e.g., AD
  • Narrow: e.g., A

Cannot be combined with UseIntlDateTimeFormatOptions::date_style / UseIntlDateTimeFormatOptions::time_style.

year

Type: Option<YearFormat>

The representation of the year.

  • Numeric: e.g., 2012
  • TwoDigit: e.g., 12

Cannot be combined with UseIntlDateTimeFormatOptions::date_style / UseIntlDateTimeFormatOptions::time_style.

month

Type: Option<MonthFormat>

The representation of the month.

  • Numeric: e.g., 3
  • TwoDigit: e.g., 03
  • Long: e.g., March
  • Short: e.g., Mar
  • Narrow: e.g., M. Two months may have the same narrow style for some locales (e.g. May’s narrow style is also M).

Cannot be combined with UseIntlDateTimeFormatOptions::date_style / UseIntlDateTimeFormatOptions::time_style.

day

Type: Option<DayFormat>

The representation of the day.

  • Numeric: e.g., 1
  • TwoDigit: e.g., 01

Cannot be combined with UseIntlDateTimeFormatOptions::date_style / UseIntlDateTimeFormatOptions::time_style.

hour

Type: Option<TimeNumericFormat>

The representation of the hour.

  • Numeric: e.g., 1
  • TwoDigit: e.g., 01

Cannot be combined with UseIntlDateTimeFormatOptions::date_style / UseIntlDateTimeFormatOptions::time_style.

minute

Type: Option<TimeNumericFormat>

The representation of the minute.

  • Numeric: e.g., 1
  • TwoDigit: e.g., 01

Cannot be combined with UseIntlDateTimeFormatOptions::date_style / UseIntlDateTimeFormatOptions::time_style.

second

Type: Option<TimeNumericFormat>

The representation of the second.

  • Numeric: e.g., 1
  • TwoDigit: e.g., 01

Cannot be combined with UseIntlDateTimeFormatOptions::date_style / UseIntlDateTimeFormatOptions::time_style.

fractional_second_digits

Type: Option<u8>

The number of digits used to represent fractions of a second (any additional digits are truncated). Possible values are from 1 to 3.

time_zone_name

Type: Option<TimeZoneNameFormat>

The localized representation of the time zone name.

  • Long: long localized form (e.g., Pacific Standard Time).
  • Short: short localized form (e.g.: PST).
  • ShortOffset: short localized GMT format (e.g., GMT-8).
  • LongOffset: long localized GMT format (e.g., GMT-0800).
  • ShortGeneric: short generic non-location format (e.g.: PT).
  • LongGeneric: long generic non-location format (e.g.: Pacific Time).

date_style

Type: Option<DateTimeStyle>

The date formatting length. Cannot be combined with the individual date-time component options (weekday, era, year, month, day, hour, minute, second, fractional_second_digits, time_zone_name, day_period).

Possible values are Full, Long, Medium and Short.

time_style

Type: Option<DateTimeStyle>

The time formatting length. Cannot be combined with the individual date-time component options (weekday, era, year, month, day, hour, minute, second, fractional_second_digits, time_zone_name, day_period).

Possible values are Full, Long, Medium and Short.

Source

Source • Demo • Docs

use_intl_number_format

Reactive Intl.NumberFormat.

Demo

Usage

In basic use without specifying a locale, a formatted string in the default locale and with default options is returned.

use leptos::prelude::*;
use leptos_use_intl_number_format::{use_intl_number_format, UseIntlNumberFormatOptions};

#[component]
fn Demo() -> impl IntoView {
let (number, set_number) = signal(3500);

let number_format = use_intl_number_format(UseIntlNumberFormatOptions::default());

let formatted = number_format.format::<u16>(number); // "3,500" if in US English locale

view! { }
}

Using locales

This example shows some of the variations in localized number formats. In order to get the format of the language used in the user interface of your application, make sure to specify that language (and possibly some fallback languages) using the locales argument:

use leptos::prelude::*;
use leptos_use_intl_number_format::{use_intl_number_format, UseIntlNumberFormatOptions};

#[component]
fn Demo() -> impl IntoView {
let number = 123456.789_f32;

// German uses comma as decimal separator and period for thousands
let number_format = use_intl_number_format(
    UseIntlNumberFormatOptions::default().locale("de-DE"),
);
let formatted = number_format.format::<f32>(number); // 123.456,789

// Arabic in most Arabic speaking countries uses real Arabic digits
let number_format = use_intl_number_format(
    UseIntlNumberFormatOptions::default().locale("ar-EG"),
);
let formatted = number_format.format::<f32>(number); // ١٢٣٤٥٦٫٧٨٩

// India uses thousands/lakh/crore separators
let number_format = use_intl_number_format(
    UseIntlNumberFormatOptions::default().locale("en-IN"),
);
let formatted = number_format.format::<f32>(number); // 1,23,456.789

// the nu extension key requests a numbering system, e.g. Chinese decimal
let number_format = use_intl_number_format(
    UseIntlNumberFormatOptions::default().locale("zh-Hans-CN-u-nu-hanidec"),
);
let formatted = number_format.format::<f32>(number); // 一二三,四五六.七八九

// when requesting a language that may not be supported, such as
// Balinese, include a fallback language, in this case Indonesian
let number_format = use_intl_number_format(
    UseIntlNumberFormatOptions::default().locales(vec!["ban".to_string(), "id".to_string()]),
);
let formatted = number_format.format::<f32>(number); // 123.456,789


view! { }
}

Using options

The results can be customized in multiple ways.

use leptos::prelude::*;
use leptos_use_intl_number_format::{NumberStyle, UnitDisplay, use_intl_number_format, UseIntlNumberFormatOptions};

#[component]
fn Demo() -> impl IntoView {
let number = 123456.789_f64;

// request a currency format
let number_format = use_intl_number_format(
    UseIntlNumberFormatOptions::default()
        .locale("de-DE")
        .style(NumberStyle::Currency)
        .currency("EUR"),
);
let formatted = number_format.format::<f64>(number); // 123.456,79 €

// the Japanese yen doesn't use a minor unit
let number_format = use_intl_number_format(
    UseIntlNumberFormatOptions::default()
        .locale("ja-JP")
        .style(NumberStyle::Currency)
        .currency("JPY"),
);
let formatted = number_format.format::<f64>(number); // ¥123,457

// limit to three significant digits
let number_format = use_intl_number_format(
    UseIntlNumberFormatOptions::default()
        .locale("en-IN")
        .maximum_significant_digits(3),
);
let formatted = number_format.format::<f64>(number); // 1,23,000

// Formatting with units
let number_format = use_intl_number_format(
    UseIntlNumberFormatOptions::default()
        .locale("pt-PT")
        .style(NumberStyle::Unit)
        .unit("kilometer-per-hour"),
);
let formatted = number_format.format::<i32>(50); // 50 km/h

let number_format = use_intl_number_format(
    UseIntlNumberFormatOptions::default()
        .locale("en-GB")
        .style(NumberStyle::Unit)
        .unit("liter")
        .unit_display(UnitDisplay::Long),
);
let formatted = number_format.format::<i32>(16); // 16 litres

view! { }
}

For an exhaustive list of options see UseIntlNumberFormatOptions.

Formatting ranges

Apart from the format method, the format_range method can be used to format a range of numbers. Please see UseIntlNumberFormatReturn::format_range for details.

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

Since Intl.NumberFormat is a JavaScript API it is not available on the server. That’s why it falls back to a simple call to format!() on the server.

Installation

cargo add leptos-use-intl-number-format

Options

UseIntlNumberFormatOptions

Options for use_intl_number_format.

Every option is set with a builder method of the same name, e.g. UseIntlNumberFormatOptions::default().locales(...). See also the API docs.

locales

Type: Vec<String>

A vec of strings, each with a BCP 47 language tag. Please refer to the MDN Docs for more info.

compact_display

Type: CompactDisplay

Only used when UseIntlNumberFormatOptions::notation is Compact. Takes either Short (default) or Long.

currency

Type: Option<String>

The currency to use in currency formatting. Possible values are the ISO 4217 currency codes, such as “USD” for the US dollar, “EUR” for the euro, or “CNY” for the Chinese RMB — see the Current currency & funds code list. There is no default value; if the style is Currency, the currency property must be provided.

currency_display

Type: CurrencyDisplay

How to display the currency in currency formatting. The default is Symbol.

  • Symbol: use a localized currency symbol such as €.
  • NarrowSymbol: use a narrow format symbol (“$100” rather than “US$100”).
  • Code: use the ISO currency code.
  • Name: use a localized currency name such as "dollar".

currency_sign

Type: CurrencySign

In many locales, accounting format means to wrap the number with parentheses instead of appending a minus sign. You can enable this formatting by setting this option to Accounting. The default value is Standard.

locale_matcher

Type: LocaleMatcher

The locale matching algorithm to use. Possible values are Lookup and BestFit; the default is "BestFit". For information about this option, see the Intl page.

notation

Type: Notation

The formatting that should be displayed for the number. The default is "standard".

  • Standard: plain number formatting.
  • Scientific: order-of-magnitude for formatted number.
  • Engineering: exponent of ten when divisible by three.
  • Compact: string representing exponent; See UseIntlNumberFormatOptions::compact_display.

numbering_system

Type: Option<String>

Numbering System. Possible values include: "arab", "arabext", "bali", "beng", "deva", "fullwide", "gujr", "guru", "hanidec", "khmr", "knda", "laoo", "latn", "limb", "mlym", "mong", "mymr", "orya", "tamldec", "telu", "thai", "tibt".

sign_display

Type: SignDisplay

When to display the sign for the number. The default is Auto.

  • Auto: sign display for negative numbers only, including negative zero.
  • Always: always display sign.
  • ExceptZero: sign display for positive and negative numbers, but not zero.
  • Negative: sign display for negative numbers only, excluding negative zero. Experimental
  • Never: never display sign.

style

Type: NumberStyle

The formatting style to use. The default is Decimal.

  • Decimal for plain number formatting.
  • Currency for currency formatting.
  • Percent for percent formatting.
  • Unit for unit formatting.

unit

Type: Option<String>

The unit to use in unit formatting, Possible values are core unit identifiers, defined in UTS #35, Part 2, Section 6. A subset of units from the full list was selected for use in ECMAScript. Pairs of simple units can be concatenated with “-per-” to make a compound unit. There is no default value; if the style is Unit, the unit property must be provided.

unit_display

Type: UnitDisplay

The unit formatting style to use in unit formatting. The default is Short.

  • Long (e.g., 16 litres).
  • Short (e.g., 16 l).
  • Narrow (e.g., 16l).

use_grouping

Type: NumberGrouping

Experimental. Whether to use grouping separators, such as thousands separators or thousand/lakh/crore separators. The default is Auto.

  • Always: display grouping separators even if the locale prefers otherwise.
  • Auto: display grouping separators based on the locale preference, which may also be dependent on the currency.
  • None: do not display grouping separators.
  • Min2: display grouping separators when there are at least 2 digits in a group.

rounding_mode

Type: RoundingMode

Experimental. Options for rounding modes. The default is HalfExpand.

  • Ceil: round toward +∞. Positive values round up. Negative values round “more positive”.
  • Floor round toward -∞. Positive values round down. Negative values round “more negative”.
  • Expand: round away from 0. The magnitude of the value is always increased by rounding. Positive values round up. Negative values round “more negative”.
  • Trunc: round toward 0. This magnitude of the value is always reduced by rounding. Positive values round down. Negative values round “less negative”.
  • HalfCeil: ties toward +∞. Values above the half-increment round like Ceil (towards +∞), and below like Floor (towards -∞). On the half-increment, values round like Ceil.
  • HalfFloor: ties toward -∞. Values above the half-increment round like Ceil (towards +∞), and below like Floor (towards -∞). On the half-increment, values round like Floor.
  • HalfExpand: ties away from 0. Values above the half-increment round like Expand (away from zero), and below like Trunc (towards 0). On the half-increment, values round like Expand.
  • HalfTrunc: ties toward 0. Values above the half-increment round like Expand (away from zero), and below like Trunc (towards 0). On the half-increment, values round like Trunc.
  • HalfEven: ties towards the nearest even integer. Values above the half-increment round like Expand (away from zero), and below like Trunc (towards 0). On the half-increment values round towards the nearest even digit.

These options reflect the ICU user guide, where Expand and Trunc map to ICU “UP” and “DOWN”, respectively. The rounding modes example demonstrates how each mode works.

rounding_priority

Type: RoundingPriority

Experimental. Specify how rounding conflicts will be resolved if both “FractionDigits” (UseIntlNumberFormatOptions::minimum_fraction_digits/UseIntlNumberFormatOptions::maximum_fraction_digits) and “SignificantDigits” (UseIntlNumberFormatOptions::minimum_significant_digits/UseIntlNumberFormatOptions::maximum_significant_digits) are specified:

  • Auto: the result from the significant digits property is used (default).
  • MorePrecision: the result from the property that results in more precision is used.
  • LessPrecision: the result from the property that results in less precision is used.

Note that for values other than Auto the result with more precision is calculated from the UseIntlNumberFormatOptions::maximum_significant_digits and UseIntlNumberFormatOptions::maximum_fraction_digits (minimum fractional and significant digit settings are ignored).

rounding_increment

Type: u16

Experimental. Specifies the rounding-increment precision. Must be one of the following integers: 1 (default), 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000.

This option controls the rounding increment to be used when formatting numbers:

  • It indicates the increment at which rounding should take place relative to the calculated rounding magnitude.
  • It cannot be mixed with significant-digits rounding or any setting of rounding_priority other than Auto.

For example, if maximum_fraction_digits is 2 and rounding_increment is 5, then the number is rounded to the nearest 0.05 (“nickel rounding”).

use leptos::prelude::*;
use leptos_use_intl_number_format::{use_intl_number_format, UseIntlNumberFormatOptions, NumberStyle};

#[component]
fn Demo() -> impl IntoView {
let nf = use_intl_number_format(
    UseIntlNumberFormatOptions::default()
        .style(NumberStyle::Currency)
        .currency("USD")
        .maximum_fraction_digits(2)
        .rounding_increment(5),
);

let formatted = nf.format::<f64>(11.29); // "$11.30"
let formatted = nf.format::<f64>(11.25); // "$11.25"
let formatted = nf.format::<f64>(11.22); // "$11.20"

view! { }
}

If you set minimum_fraction_digits and maximum_fraction_digits, they must set them to the same value; otherwise a RangeError is thrown.

trailing_zero_display

Type: TrailingZeroDisplay

Experimental. A string expressing the strategy for displaying trailing zeros on whole numbers. The default is "auto".

  • Auto: keep trailing zeros according to minimum_fraction_digits and minimum_significant_digits.
  • StripIfInteger: remove the fraction digits if they are all zero. This is the same as Auto if any of the fraction digits is non-zero.

minimum_integer_digits

Type: u8

These properties fall into two groups: minimum_integer_digits, minimum_fraction_digits, and maximum_fraction_digits in one group, minimum_significant_digits and maximum_significant_digits in the other. If properties from both groups are specified, conflicts in the resulting display format are resolved based on the value of the UseIntlNumberFormatOptions::rounding_priority property.

The minimum number of integer digits to use. A value with a smaller number of integer digits than this number will be left-padded with zeros (to the specified length) when formatted. Possible values are from 1 to 21; the default is 1.

minimum_fraction_digits

Type: Option<u8>

The minimum number of fraction digits to use. Possible values are from 0 to 20; the default for plain number and percent formatting is 0; the default for currency formatting is the number of minor unit digits provided by the ISO 4217 currency code list (2 if the list doesn’t provide that information).

maximum_fraction_digits

Type: Option<u8>

The maximum number of fraction digits to use. Possible values are from 0 to 20; the default for plain number formatting is the larger of minimum_fraction_digits and 3; the default for currency formatting is the larger of minimum_fraction_digits and the number of minor unit digits provided by the ISO 4217 currency code list (2 if the list doesn’t provide that information); the default for percent formatting is minimum_fraction_digits.

minimum_significant_digits

Type: Option<u8>

The minimum number of significant digits to use. Possible values are from 1 to 21; the default is 1.

maximum_significant_digits

Type: Option<u8>

The maximum number of significant digits to use. Possible values are from 1 to 21; the default is 21.

Source

Source • Demo • Docs

use_locale

Reactive locale matching.

Returns the first matching locale given by use_locales that is also found in the supported list. In case there is no match, then the first locale in supported will be returned.

If supported is empty, this function will panic!

Matching is done by using the unic_langid::LanguageIdentifier::matches method.

Demo

Usage

use leptos::*;
use leptos_use_locale::use_locale;
use unic_langid::langid_slice;

#[component]
fn Demo() -> impl IntoView {
let locale = use_locale(langid_slice!["en", "de", "fr"]);

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

See use_locales

Installation

cargo add leptos-use-locale

Options

UseLocalesOptions

Options for use_locales_with_options.

Every option is set with a builder method of the same name, e.g. UseLocalesOptions::default().ssr_lang_header_getter(...). See also the API docs.

ssr_lang_header_getter

Type: Arc<dyn Fn() -> Option<String>>

Getter function to return the string value of the accept languange header. When you use one of the features "axum" or "actix" there’s a valid default implementation provided.

Source

Source • Demo • Docs

use_locales

Reactive locales.

If called on the client-side this function returns the value of navigator.languages and listens for changes to that property.

See “Server-Side Rendering” below.

Demo

Usage

use leptos::*;
use leptos_use_locales::use_locales;

#[component]
fn Demo() -> impl IntoView {
let locales = use_locales();

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in Server-Side Rendering.

On the server this returns the parsed value of the accept-language header.

If you’re using axum you have to enable the "axum" feature in your Cargo.toml. In case it’s actix-web enable the feature "actix".

Bring your own header

In case you’re neither using Axum nor Actix or the default implementation is not to your liking, you can provide your own way of reading the language header value using the option UseLocalesOptions::ssr_lang_header_getter.

Installation

cargo add leptos-use-locales

Options

UseLocalesOptions

Options for use_locales_with_options.

Every option is set with a builder method of the same name, e.g. UseLocalesOptions::default().ssr_lang_header_getter(...). See also the API docs.

ssr_lang_header_getter

Type: Arc<dyn Fn() -> Option<String>>

Getter function to return the string value of the accept languange header. When you use one of the features "axum" or "actix" there’s a valid default implementation provided.

Source

Source • Demo • Docs

use_abs

Reactive abs().

Demo

Usage

use leptos::prelude::*;
use leptos_use_math::use_abs;

#[component]
fn Demo() -> impl IntoView {
let (value, set_value) = signal(-32.25);
let result: Signal<f64> = use_abs(value); // 32.25

assert_eq!(result.get(), 32.25);
view! { }
}

Installation

cargo add leptos-use-math

Source

Source • Demo • Docs

use_and

Reactive AND condition.

Demo

Usage

use leptos::prelude::*;
use leptos_use_math::use_and;

#[component]
fn Demo() -> impl IntoView {
let (a, set_a) = signal(true);
let (b, set_b) = signal(false);

let a_and_b = use_and(a, b);

view! { }
}

Installation

cargo add leptos-use-math

Source

Source • Demo • Docs

use_ceil

Reactive ceil().

Demo

Usage

use leptos::prelude::*;
use leptos_use_math::use_ceil;

#[component]
fn Demo() -> impl IntoView {
let (value, set_value) = signal(44.15);
let result: Signal<f64> = use_ceil(value); // 45

assert_eq!(result.get(), 45.0);
view! { }
}

Installation

cargo add leptos-use-math

Source

Source • Demo • Docs

use_floor

Reactive floor().

Demo

Usage

use leptos::prelude::*;
use leptos_use_math::use_floor;

#[component]
fn Demo() -> impl IntoView {
let (value, set_value) = signal(45.95);
let result: Signal<f64> = use_floor(value); // 45

assert_eq!(result.get(), 45.0);
view! { }
}

Installation

cargo add leptos-use-math

Source

Source • Demo • Docs

use_max

Reactive max().

Works with any container that implements IntoIterator (Vec, HashSet, …) with any elements that implement PartialOrd and Clone (floats, ints, strings, …).

If the container is empty or only contains non comparable values like NaN, it returns None. Otherwise it returns the Some(<largest value>) in the container.

Usage

use leptos::prelude::*;
use leptos_use_math::use_max;

#[component]
fn Demo() -> impl IntoView {
let (values, set_values) = signal(vec![1.0, 2.0, 3.0, f32::NAN, 4.0, 5.0]);
let result = use_max::<Vec<f32>, _, _>(values); // Some(5.0)

assert_eq!(result.get(), Some(5.0));
view! { }
}

Installation

cargo add leptos-use-math

Source

Source • Docs

use_min

Reactive min().

Works with any container that implements IntoIterator (Vec, HashSet, …) with any elements that implement PartialOrd and Clone (floats, ints, strings, …).

If the container is empty or only contains non comparable values like NaN, it returns None. Otherwise it returns the Some(<smallest value>) in the container.

Usage

use leptos::prelude::*;
use leptos_use_math::use_min;

#[component]
fn Demo() -> impl IntoView {
let (values, set_values) = signal(vec![1.0, 2.0, 3.0, f32::NAN, 4.0, 5.0]);
let result = use_min::<Vec<f32>, _, _>(values); // Some(1.0)

assert_eq!(result.get(), Some(1.0));
view! { }
}

Installation

cargo add leptos-use-math

Source

Source • Docs

use_not

Reactive NOT condition.

Demo

Usage

use leptos::prelude::*;
use leptos_use_math::use_not;

#[component]
fn Demo() -> impl IntoView {
let (a, set_a) = signal(true);

let not_a = use_not(a);

view! { }
}

See also

Installation

cargo add leptos-use-math

Source

Source • Demo • Docs

use_or

Reactive OR condition.

Demo

Usage

use leptos::prelude::*;
use leptos_use_math::use_or;

#[component]
fn Demo() -> impl IntoView {
let (a, set_a) = signal(true);
let (b, set_b) = signal(false);

let a_or_b = use_or(a, b);

view! { }
}

Installation

cargo add leptos-use-math

Source

Source • Demo • Docs

use_round

Reactive round().

Demo

Usage

use leptos::prelude::*;
use leptos_use_math::use_round;

#[component]
fn Demo() -> impl IntoView {
let (value, set_value) = signal(45.95);
let result: Signal<f64> = use_round(value); // 46

assert_eq!(result.get(), 46.0);
view! { }
}

Installation

cargo add leptos-use-math

Source

Source • Demo • Docs