Merge branch 'main' into leptos-0.7

# Conflicts:
#	Cargo.toml
#	src/core/storage.rs
#	src/lib.rs
#	src/use_clipboard.rs
#	src/use_cookie.rs
#	src/use_mouse.rs
#	src/use_mouse_in_element.rs
#	src/use_preferred_dark.rs
#	src/use_timeout_fn.rs
This commit is contained in:
Maccesch 2024-08-22 13:45:56 +01:00
commit 52d3bf33f8
141 changed files with 2936 additions and 598 deletions

View file

@ -23,20 +23,27 @@ jobs:
components: rustfmt, clippy, rust-src
- name: Cache
uses: Swatinem/rust-cache@v2
- name: Check function count badge
run: python3 docs/generate_count_badge.py --check
- name: Check version in docs
run: python3 docs/add_version_to_docs.py --check
- name: Check formatting
run: cargo fmt --check
- name: Clippy
run: cargo clippy --features docs,math --tests -- -D warnings
- name: Run tests (general)
run: cargo test --features math,docs,ssr
- name: Run tests (axum)
run: cargo test --features math,docs,ssr,axum --doc use_cookie::use_cookie
- name: Run tests (actix)
run: cargo test --features math,docs,ssr,actix --doc use_cookie::use_cookie
- name: Run tests (axum) use_cookie
run: cargo test --features math,docs,ssr,axum --doc use_cookie
- name: Run tests (axum) use_locale
run: cargo test --features math,docs,ssr,axum --doc use_locale
- name: Run tests (actix) use_cookie
run: cargo test --features math,docs,ssr,actix --doc use_cookie
- name: Run tests (actix) use_locale
run: cargo test --features math,docs,ssr,actix --doc use_locale
#### mdbook
- name: Install mdbook I

View file

@ -1,5 +1,11 @@
on:
pull_request:
branches:
- main
paths:
- "**"
- "!/*.md"
- "!/**.md"
workflow_dispatch:
name: Tests
@ -20,13 +26,18 @@ jobs:
components: rustfmt, clippy, rust-src
- name: Cache
uses: Swatinem/rust-cache@v2
- name: Check formatting
run: cargo fmt --check
- name: Clippy
run: cargo clippy --features docs,math --tests -- -D warnings
- name: Run tests (general)
run: cargo test --features math,docs,ssr
- name: Run tests (axum)
run: cargo test --features math,docs,ssr,axum --doc use_cookie::use_cookie
- name: Run tests (actix)
run: cargo test --features math,docs,ssr,actix --doc use_cookie::use_cookie
- name: Run tests (axum) use_cookie
run: cargo test --features math,docs,ssr,axum --doc use_cookie
- name: Run tests (axum) use_locale
run: cargo test --features math,docs,ssr,axum --doc use_locale
- name: Run tests (actix) use_cookie
run: cargo test --features math,docs,ssr,actix --doc use_cookie
- name: Run tests (actix) use_locale
run: cargo test --features math,docs,ssr,actix --doc use_locale

2
.idea/leptos-use.iml generated
View file

@ -78,6 +78,8 @@
<sourceFolder url="file://$MODULE_DIR$/examples/use_event_source/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/sync_signal/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_user_media/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_locale/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples/use_locales/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/examples/use_event_listener/target" />
<excludeFolder url="file://$MODULE_DIR$/target" />
<excludeFolder url="file://$MODULE_DIR$/docs/book/book" />

View file

@ -3,6 +3,56 @@
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased] -
### New Functions 🚀
- `use_prefers_reduced_motion`
## [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
### Breaking Changes 🛠
@ -37,7 +87,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
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.
- 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).
@ -72,7 +122,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- 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`
- Renamed `BreakpointsSematic` to `BreakpointsSemantic` and `breakpoints_sematic` to `breakpoints_semantic`
(note the `n`) (thanks to @mondeja).
### Fixes 🍕

View file

@ -1,10 +1,10 @@
[package]
name = "leptos-use"
version = "0.11.0"
version = "0.12.0"
edition = "2021"
authors = ["Marc-Stefan Cassola"]
categories = ["gui", "web-programming"]
description = "Collection of essential Leptos utilities inspired by SolidJS USE / VueUse"
description = "Collection of essential Leptos utilities inspired by React-Use / VueUse / SolidJS-USE"
exclude = ["examples/", "tests/"]
keywords = ["leptos", "utilities"]
license = "MIT OR Apache-2.0"
@ -14,14 +14,14 @@ homepage = "https://leptos-use.rs"
[dependencies]
actix-web = { version = "4", optional = true, default-features = false }
async-trait = "0.1"
async-trait = { version = "0.1", optional = true }
cfg-if = "1"
codee = "0.1"
cookie = { version = "0.18", features = ["percent-encode"] }
codee = { version = "0.1", optional = true }
cookie = { version = "0.18", features = ["percent-encode"], optional = true }
default-struct-builder = "0.5"
futures-util = "0.3"
gloo-timers = { version = "0.3", features = ["futures"] }
gloo-utils = { version = "0.2" }
futures-util = { version = "0.3", optional = true }
gloo-timers = { version = "0.3", optional = true, features = ["futures"] }
gloo-utils = { version = "0.2", optional = true }
http1 = { version = "1", optional = true, package = "http" }
http0_2 = { version = "0.2", optional = true, package = "http" }
js-sys = "0.3"
@ -34,116 +34,317 @@ num = { version = "0.4", optional = true }
paste = "1"
send_wrapper = "0.6.0"
thiserror = "1"
wasm-bindgen = "0.2.92"
unic-langid = { version = "0.9", optional = true }
wasm-bindgen = "=0.2.93"
wasm-bindgen-futures = "0.4"
[dependencies.web-sys]
version = "0.3"
features = [
"AddEventListenerOptions",
"BinaryType",
"BroadcastChannel",
"Coordinates",
"Clipboard",
"CloseEvent",
"CssStyleDeclaration",
"CustomEvent",
"CustomEventInit",
"DisplayMediaStreamConstraints",
"DomRect",
"DomRectReadOnly",
"DataTransfer",
"DragEvent",
"Element",
"EventListener",
"EventListenerOptions",
"EventSource",
"EventSourceInit",
"EventTarget",
"File",
"FileList",
"Geolocation",
"HtmlDocument",
"HtmlElement",
"HtmlLinkElement",
"HtmlStyleElement",
"IntersectionObserver",
"IntersectionObserverInit",
"IntersectionObserverEntry",
"Location",
"MediaDevices",
"MediaQueryList",
"MediaStream",
"MediaStreamConstraints",
"MediaStreamTrack",
"MessageEvent",
"MouseEvent",
"MutationObserver",
"MutationObserverInit",
"MutationRecord",
"Navigator",
"NodeList",
"Notification",
"NotificationDirection",
"NotificationOptions",
"NotificationPermission",
"Permissions",
"PermissionState",
"PermissionStatus",
"PointerEvent",
"Position",
"PositionError",
"PositionOptions",
"ReadableStream",
"ReadableStreamDefaultReader",
"ReadableStreamGetReaderOptions",
"ReadableStreamReaderMode",
"ResizeObserver",
"ResizeObserverBoxOptions",
"ResizeObserverEntry",
"ResizeObserverOptions",
"ResizeObserverSize",
"ScrollBehavior",
"ScrollToOptions",
"ServiceWorker",
"ServiceWorkerContainer",
"ServiceWorkerRegistration",
"ServiceWorkerState",
"Storage",
"StorageEvent",
"Touch",
"TouchEvent",
"TouchList",
"Url",
"UrlSearchParams",
"VisibilityState",
"WebSocket",
"WebTransport",
"WebTransportOptions",
"WebTransportDatagramDuplexStream",
"WebTransportBidirectionalStream",
"Window",
"WebTransportReceiveStream",
"WebTransportSendStream",
"WritableStream",
"WritableStreamDefaultWriter",
]
web-sys = { version = "=0.3.70", optional = true }
[dev-dependencies]
codee = { version = "0.1", features = ["json_serde", "msgpack_serde", "base64", "prost"] }
getrandom = { version = "0.2", features = ["js"] }
leptos_meta = { git = "https://github.com/leptos-rs/leptos" }
rand = "0.8"
codee = { version = "0.1", features = ["json_serde", "msgpack_serde", "base64", "prost"] }
serde = { version = "1", features = ["derive"] }
unic-langid = { version = "0.9", features = ["macros"] }
[features]
default = [
"is_err",
"is_none",
"is_ok",
"is_some",
"on_click_outside",
"signal_debounced",
"signal_throttled",
"storage",
"sync_signal",
"use_active_element",
"use_breakpoints",
"use_broadcast_channel",
"use_clipboard",
"use_color_mode",
"use_cookie",
"use_css_var",
"use_cycle_list",
"use_debounce_fn",
"use_device_orientation",
"use_device_pixel_ratio",
"use_display_media",
"use_document",
"use_document_visibility",
"use_draggable",
"use_drop_zone",
"use_element_bounding",
"use_element_hover",
"use_element_size",
"use_element_visibility",
"use_event_listener",
"use_event_source",
"use_favicon",
"use_geolocation",
"use_idle",
"use_infinite_scroll",
"use_intersection_observer",
"use_interval",
"use_interval_fn",
"use_intl_number_format",
"use_locale",
"use_locales",
"use_media_query",
"use_mouse",
"use_mouse_in_element",
"use_mutation_observer",
"use_permission",
"use_preferred_contrast",
"use_preferred_dark",
"use_prefers_reduced_motion",
"use_raf_fn",
"use_resize_observer",
"use_scroll",
"use_service_worker",
"use_sorted",
"use_supported",
"use_throttle_fn",
"use_timeout_fn",
"use_timestamp",
"use_to_string",
"use_user_media",
"use_web_notification",
"use_websocket",
"use_window",
"use_window_focus",
"use_window_scroll",
"watch_debounced",
"watch_pausable",
"watch_throttled",
"watch_with_options",
"whenever"
]
actix = ["dep:actix-web", "dep:leptos_actix", "dep:http0_2"]
axum = ["dep:leptos_axum", "dep:http1"]
docs = []
docs = ["dep:web-sys"]
element = ["use_document", "use_window", "dep:web-sys", "web-sys/EventTarget"]
is = ["use_window"]
is_err = []
is_none = []
is_ok = []
is_some = []
math = ["num"]
on_click_outside = ["use_event_listener", "is"]
signal_debounced = ["use_debounce_fn"]
signal_throttled = ["use_throttle_fn"]
spin = ["dep:leptos-spin", "dep:http1"]
ssr = []
storage = [
"use_event_listener",
"use_window",
"watch_with_options",
"dep:web-sys",
"dep:codee",
"web-sys/CustomEventInit",
"web-sys/Storage"
]
sync_signal = []
use_active_element = ["use_event_listener"]
use_breakpoints = ["use_media_query"]
use_broadcast_channel = [
"use_event_listener",
"use_supported",
"dep:codee",
"web-sys/BroadcastChannel",
]
use_clipboard = [
"use_event_listener",
"use_permission",
"use_supported",
"use_timeout_fn",
"web-sys/Clipboard",
]
use_color_mode = [
"use_cookie",
"use_cycle_list",
"use_preferred_dark",
"storage",
"sync_signal"
]
use_cookie = [
"use_broadcast_channel",
"watch_pausable",
"dep:cookie",
"web-sys/HtmlDocument",
]
use_css_var = [
"use_mutation_observer",
"watch_with_options",
]
use_cycle_list = []
use_debounce_fn = []
use_device_orientation = ["use_event_listener", "use_supported"]
use_device_pixel_ratio = ["use_event_listener", "web-sys/MediaQueryList"]
use_display_media = [
"use_window",
"web-sys/DisplayMediaStreamConstraints",
"web-sys/MediaDevices",
"web-sys/MediaStream",
"web-sys/MediaStreamTrack",
]
use_document = [
"dep:web-sys",
"web-sys/VisibilityState",
]
use_document_visibility = ["use_event_listener", "web-sys/VisibilityState"]
use_draggable = ["use_event_listener", "web-sys/DomRect"]
use_drop_zone = [
"use_event_listener",
"web-sys/DataTransfer",
"web-sys/File",
"web-sys/FileList"
]
use_element_bounding = [
"use_event_listener",
"use_resize_observer",
"web-sys/DomRect",
]
use_element_hover = ["use_event_listener"]
use_element_size = [
"use_resize_observer",
"watch_with_options",
"web-sys/ResizeObserverSize",
]
use_element_visibility = [
"use_intersection_observer",
"web-sys/DomRect",
]
use_event_listener = [
"element",
"watch_with_options",
"dep:web-sys",
"web-sys/EventTarget",
"web-sys/EventListenerOptions"
]
use_event_source = [
"use_event_listener",
"web-sys/EventSource",
"web-sys/EventSourceInit",
"dep:codee",
]
use_favicon = []
use_geolocation = [
"use_window",
"web-sys/Coordinates",
"web-sys/Geolocation",
"web-sys/Position",
"web-sys/PositionError",
"web-sys/PositionOptions",
]
use_idle = [
"use_event_listener",
"use_document",
"use_timestamp",
]
use_infinite_scroll = [
"use_element_visibility",
"use_scroll",
"dep:gloo-timers",
"dep:futures-util",
]
use_intersection_observer = [
"element",
"watch_with_options",
"web-sys/IntersectionObserver",
"web-sys/IntersectionObserverEntry",
"web-sys/IntersectionObserverInit",
]
use_interval = ["use_interval_fn"]
use_interval_fn = []
use_intl_number_format = []
use_locale = ["use_locales", "dep:unic-langid"]
use_locales = ["use_event_listener", "use_window"]
use_media_query = ["use_event_listener"]
use_mouse = [
"element",
"use_event_listener",
"use_window",
"web-sys/Touch",
"web-sys/TouchList",
]
use_mouse_in_element = [
"use_mouse",
"web-sys/DomRect",
]
use_mutation_observer = [
"element",
"use_supported",
"web-sys/MutationObserver",
"web-sys/MutationObserverInit",
"web-sys/MutationRecord",
]
use_permission = [
"use_event_listener",
"web-sys/Permissions",
"web-sys/PermissionState",
"web-sys/PermissionStatus",
]
use_preferred_contrast = ["use_media_query"]
use_preferred_dark = ["use_media_query"]
use_prefers_reduced_motion = ["use_media_query"]
use_raf_fn = []
use_resize_observer = [
"element",
"use_supported",
"web-sys/DomRectReadOnly",
"web-sys/ResizeObserver",
"web-sys/ResizeObserverBoxOptions",
"web-sys/ResizeObserverEntry",
"web-sys/ResizeObserverOptions",
]
use_scroll = [
"element",
"use_event_listener",
"use_debounce_fn",
"use_throttle_fn",
"web-sys/ScrollBehavior",
"web-sys/ScrollToOptions",
]
use_service_worker = [
"use_window",
"web-sys/ServiceWorker",
"web-sys/ServiceWorkerContainer",
"web-sys/ServiceWorkerRegistration"
]
use_sorted = []
use_supported = []
use_throttle_fn = []
use_timeout_fn = []
use_timestamp = ["use_interval_fn", "use_raf_fn"]
use_to_string = []
use_user_media = [
"use_window",
"web-sys/MediaDevices",
"web-sys/MediaStream",
"web-sys/MediaStreamConstraints",
"web-sys/MediaStreamTrack",
]
use_web_notification = [
"use_supported",
"use_window",
"use_event_listener",
"web-sys/Notification",
"web-sys/NotificationOptions",
"web-sys/NotificationPermission",
"web-sys/NotificationDirection",
"web-sys/VisibilityState"
]
use_websocket = ["dep:codee"]
use_window = ["use_document", "dep:web-sys", "web-sys/Navigator", "web-sys/MediaQueryList"]
use_window_focus = ["use_event_listener"]
use_window_scroll = ["use_event_listener", "use_window"]
wasm_ssr = []
watch_debounced = ["watch_with_options"]
watch_pausable = ["watch_with_options"]
watch_throttled = ["watch_with_options"]
watch_with_options = []
whenever = []
[package.metadata.docs.rs]
features = ["math", "docs", "ssr"]

View file

@ -13,7 +13,7 @@
<a href="https://crates.io/crates/leptos-use"><img src="https://img.shields.io/crates/v/leptos-use.svg?label=&color=%232C1275" alt="Crates.io"/></a>
<a href="https://leptos-use.rs/server_side_rendering.html"><img src="https://img.shields.io/badge/-SSR-%236a214b" alt="SSR"></a>
<a href="https://leptos-use.rs"><img src="https://img.shields.io/badge/-docs%20%26%20demos-%239A233F" alt="Docs & Demos"></a>
<a href="https://leptos-use.rs"><img src="https://img.shields.io/badge/-79%20functions-%23EF3939" alt="79 Functions" /></a>
<a href="https://leptos-use.rs"><img src="https://img.shields.io/badge/-82%20functions-%23EF3939" alt="82 Functions" /></a>
</p>
<br/>
@ -87,9 +87,9 @@ This will create the function file in the src directory, scaffold an example dir
## Leptos compatibility
| Crate version | Compatible Leptos version |
|---------------|---------------------------|
| <= 0.3 | 0.3 |
| 0.4, 0.5, 0.6 | 0.4 |
| 0.7, 0.8, 0.9 | 0.5 |
| 0.10, 0.11 | 0.6 |
| Crate version | Compatible Leptos version |
|------------------|---------------------------|
| <= 0.3 | 0.3 |
| 0.4, 0.5, 0.6 | 0.4 |
| 0.7, 0.8, 0.9 | 0.5 |
| 0.10, 0.11, 0.12 | 0.6 |

View file

@ -48,6 +48,7 @@
- [use_permission](browser/use_permission.md)
- [use_preferred_contrast](browser/use_preferred_contrast.md)
- [use_preferred_dark](browser/use_preferred_dark.md)
- [use_prefers_reduced_motion](browser/use_prefers_reduced_motion.md)
- [use_service_worker](browser/use_service_worker.md)
- [use_user_media](browser/use_user_media.md)
- [use_web_notification](browser/use_web_notification.md)
@ -99,6 +100,7 @@
# Utilities
- [header](utilities/header.md)
- [is_err](utilities/is_err.md)
- [is_none](utilities/is_none.md)
- [is_ok](utilities/is_ok.md)
@ -113,6 +115,8 @@
# Intl
- [use_intl_number_format](intl/use_intl_number_format.md)
- [use_locale](intl/use_locale.md)
- [use_locales](intl/use_locales.md)
# @Math

View file

@ -0,0 +1,3 @@
# use_prefers_reduced_motion
<!-- cmdrun python3 ../extract_doc_comment.py use_prefers_reduced_motion -->

View file

@ -1,9 +1,9 @@
# Encoding and Decoding Data
Several functions encode and decode data for storing it and/or sending it over the network. To do this, codecs
located at [`src/utils/codecs`](https://github.com/Synphonyte/leptos-use/tree/main/src/utils/codecs) are used. They
implement the traits [`Encoder`](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/mod.rs#L9) with the
method `encode` and [`Decoder`](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/mod.rs#L17) with the
from the crate [`codee`](https://docs.rs/codee/latest/codee/) are used. They
implement the traits [`Encoder`](https://docs.rs/codee/latest/codee/trait.Encoder.html) with the
method `encode` and [`Decoder`](https://docs.rs/codee/latest/codee/trait.Decoder.html) with the
method `decode`.
There are two types of codecs: One that encodes as binary data (`Vec[u8]`) and another type that encodes as
@ -11,26 +11,8 @@ strings (`String`). There is also an adapter
[`Base64`](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/string/base64.rs) that can be used to
wrap a binary codec and make it a string codec by representing the binary data as a base64 string.
## Available Codecs
### String Codecs
- [**`FromToStringCodec`
**](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/string/from_to_string.rs)
- [**`JsonSerdeCodec`**](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/string/json_serde.rs)**
### Binary Codecs
- [**`FromToBytesCodec`**](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/binary/from_to_bytes.rs)
- [**`BincodeSerdeCodec`**](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/binary/bincode_serde.rs)
- [**`MsgpackSerdeCodec`**](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/binary/msgpack_serde.rs)
### Adapters
- [**`Base64`**](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/string/base64.rs) —
Wraps a binary codec and make it a string codec by representing the binary data as a base64 string.
- [**`OptionCodec`**](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/option.rs) —
Wraps a string codec that encodes `T` to create a codec that encodes `Option<T>`.
Please check the documentation of [`codee`](https://docs.rs/codee/latest/codee/) for more details and a list of all
available codecs.
## Example
@ -41,6 +23,7 @@ format. Since cookies can only store strings, we have to use string codecs here.
# use leptos::*;
# use leptos_use::use_cookie;
# use serde::{Deserialize, Serialize};
# use codee::string::JsonCodec;
# #[component]
# pub fn App(cx: Scope) -> impl IntoView {
@ -57,100 +40,13 @@ let (cookie, set_cookie) = use_cookie::<MyState, JsonCodec>("my-state-cookie");
## Custom Codecs
If you don't find a suitable codecs for your needs, you can implement your own; it's straightforward! If you want to
create a string codec, you can look
at [`JsonSerdeCodec`](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/string/json_serde.rs).
In case it's a binary codec, have a look
at [`BincodeSerdeCodec`](https://github.com/Synphonyte/leptos-use/blob/main/src/utils/codecs/binary/bincode_serde.rs).
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`](https://docs.rs/codee/latest/src/codee/string/json_serde.rs.html).
In case it's a binary codec, have a look at
[`BincodeSerdeCodec`](https://docs.rs/codee/latest/src/codee/binary/bincode_serde.rs.html).
## Versioning
Versioning is the process of handling long-term data that can outlive our code.
For example, we could have a settings struct whose members change over time. We might eventually
add timezone support, and we might then remove support for a thousands separator for numbers.
Each change results in a new possible version of the stored data. If we stored these settings
in browser storage, we would need to handle all possible versions of the data format that can
occur. If we don't offer versioning, then all settings could revert to the default every time we
encounter an old format.
How best to handle versioning depends on the codec involved:
- The `FromToStringCodec` can avoid versioning entirely by keeping
to primitive types. In our example above, we could have decomposed the settings struct into
separate timezone and number separator fields. These would be encoded as strings and stored as
two separate key-value fields in the browser rather than a single field. If a field is missing,
then the value intentionally would fall back to the default without interfering with the other
field.
- The `ProstCodec` uses [Protocol buffers](https://protobuf.dev/overview/)
designed to solve the problem of long-term storage. It provides semantics for versioning that
are not present in JSON or other formats.
- The codecs that use serde under the hood can rely on serde or by
providing their own manual version handling. See the next sections for more details.
### Rely on `serde`
A simple way to avoid complex versioning is to rely on serde's [field attributes](https://serde.rs/field-attrs.html)
such as [`serde(default)`](https://serde.rs/field-attrs.html#default)
and [`serde(rename = "...")`](https://serde.rs/field-attrs.html#rename).
### Manual Version Handling
We look at the example of the `JsonSerdeCodec` in this section.
To implement version handling, we parse the JSON generically then transform the
resulting `JsValue` before decoding it into our struct again.
Let's look at an example.
```rust,noplayground
# use leptos::*;
# use leptos_use::storage::{StorageType, use_local_storage, use_session_storage, use_storage, UseStorageOptions};
# use serde::{Deserialize, Serialize};
# use serde_json::json;
# use leptos_use::utils::{Encoder, Decoder};
#
# pub fn Demo() -> impl IntoView {
#[derive(Serialize, Deserialize, Clone, Default, PartialEq)]
pub struct MyState {
pub hello: String,
// This field was added in a later version
pub greeting: String,
}
pub struct MyStateCodec;
impl Encoder<MyState> for MyStateCodec {
type Error = serde_json::Error;
type Encoded = String;
fn encode(val: &MyState) -> Result<Self::Encoded, Self::Error> {
serde_json::to_string(val)
}
}
impl Decoder<MyState> for MyStateCodec {
type Error = serde_json::Error;
type Encoded = str;
fn decode(stored_value: &Self::Encoded) -> Result<MyState, Self::Error> {
let mut val: serde_json::Value = serde_json::from_str(stored_value)?;
// add "greeting": "Hello" to the object if it's missing
if let Some(obj) = val.as_object_mut() {
if !obj.contains_key("greeting") {
obj.insert("greeting".to_string(), json!("Hello"));
}
serde_json::from_value(val)
} else {
Ok(MyState::default())
}
}
}
// Then use it like the following just as any other codec.
let (get, set, remove) = use_local_storage::<MyState, MyStateCodec>("my-struct-key");
# view! { }
# }
```
For a discussion on how to implement versioning please refer to the
[relevant section in the docs for `codee`](https://docs.rs/codee/latest/codee/index.html#versioning).

View file

@ -0,0 +1,3 @@
# use_locale
<!-- cmdrun python3 ../extract_doc_comment.py use_locale -->

View file

@ -0,0 +1,3 @@
# use_locales
<!-- cmdrun python3 ../extract_doc_comment.py use_locales -->

View file

@ -12,6 +12,6 @@
<a href="https://crates.io/crates/leptos-use"><img src="https://img.shields.io/crates/v/leptos-use.svg?label=&color=%232C1275" alt="Crates.io"/></a>
<a href="https://leptos-use.rs/server_side_rendering.html"><img src="https://img.shields.io/badge/-SSR-%236a214b" alt="SSR"></a>
<a href="./get_started.html"><img src="https://img.shields.io/badge/-docs%20%26%20demos-%239A233F" alt="Docs & Demos"></a>
<a href="./functions.html"><img src="https://img.shields.io/badge/-79%20functions-%23EF3939" alt="79 Functions" /></a>
<a href="./functions.html"><img src="https://img.shields.io/badge/-82%20functions-%23EF3939" alt="82 Functions" /></a>
</p>
</div>

View file

@ -0,0 +1,3 @@
# header
<!-- cmdrun python3 ../extract_doc_comment.py utils/header -->

View file

@ -38,6 +38,8 @@ members = [
"use_interval",
"use_interval_fn",
"use_intl_number_format",
"use_locale",
"use_locales",
"use_media_query",
"use_mouse",
"use_mouse_in_element",
@ -45,6 +47,7 @@ members = [
"use_not",
"use_or",
"use_permission",
"use_prefers_reduced_motion",
"use_raf_fn",
"use_resize_observer",
"use_round",

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["on_click_outside", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["signal_debounced", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["signal_throttled", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -16,17 +16,31 @@ leptos = { version = "0.6", features = ["nightly"] }
leptos_axum = { version = "0.6", optional = true }
leptos_meta = { version = "0.6", features = ["nightly"] }
leptos_router = { version = "0.6", features = ["nightly"] }
leptos-use = { path = "../.." }
log = "0.4"
simple_logger = "4"
tokio = { version = "1", features = ["full"], optional = true }
tower = { version = "0.4", optional = true }
tower-default-headers = { git = "https://github.com/banool/tower-default-headers-rs" }
tower-http = { version = "0.5", features = ["fs"], optional = true }
wasm-bindgen = "0.2.92"
wasm-bindgen = "=0.2.93"
thiserror = "1.0.38"
tracing = { version = "0.1.37", optional = true }
http = "1"
[dependencies.leptos-use]
path = "../.."
features = [
"use_cookie",
"use_color_mode",
"use_debounce_fn",
"use_event_listener",
"use_interval",
"use_intl_number_format",
"use_locales",
"use_timestamp",
"storage"
]
[features]
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
ssr = [

View file

@ -1,15 +1,15 @@
use crate::error_template::{AppError, ErrorTemplate};
use codee::string::FromToStringCodec;
use leptos::ev::{keypress, KeyboardEvent};
use leptos::prelude::*;
use leptos_meta::*;
use leptos_router::*;
use leptos_use::storage::{use_local_storage, use_local_storage_with_options, UseStorageOptions};
use codee::string::FromToStringCodec;
use leptos_use::{
use_color_mode_with_options, use_cookie_with_options, use_debounce_fn, use_event_listener,
use_interval, use_intl_number_format, use_preferred_dark, use_timestamp, use_window, ColorMode,
UseColorModeOptions, UseColorModeReturn, UseCookieOptions, UseIntervalReturn,
UseIntlNumberFormatOptions,
use_interval, use_intl_number_format, use_locales, use_preferred_dark, use_timestamp,
use_window, ColorMode, UseColorModeOptions, UseColorModeReturn, UseCookieOptions,
UseIntervalReturn, UseIntlNumberFormatOptions,
};
#[component]
@ -83,12 +83,13 @@ fn HomePage() -> impl IntoView {
.default_value(Some("Bogus string".to_owned())),
);
let locales = use_locales();
view! {
<Html class=move || mode.get().to_string()/>
<h1>Leptos-Use SSR Example</h1>
<button on:click=on_click>Click Me: {count}</button>
<p>Locale zh-Hans-CN-u-nu-hanidec: {zh_count}</p>
<p>Press any key: {key}</p>
<p>Debounced called: {debounce_value}</p>
<p>Color mode: {move || format!("{:?}", mode.get())}</p>
@ -99,7 +100,10 @@ fn HomePage() -> impl IntoView {
<p>Dark preferred: {is_dark_preferred}</p>
<LocalStorageTest/>
<p>Test cookie: {move || test_cookie().unwrap_or("<Expired>".to_string())}</p>
<pre>{move || format!("Locales:\n {}", locales().join("\n "))}</pre>
<p>Locale zh-Hans-CN-u-nu-hanidec: {zh_count}</p>
<Show when={move || count() > 0 }>
<div>Greater than 0 </div>
</Show>

View file

@ -2,11 +2,13 @@
#[tokio::main]
async fn main() {
use axum::{routing::post, Router};
use http::{HeaderMap, HeaderName, HeaderValue};
use leptos::logging::log;
use leptos::prelude::*;
use leptos_axum::{generate_route_list, LeptosRoutes};
use leptos_use_ssr::app::*;
use leptos_use_ssr::fileserv::file_and_error_handler;
use tower_default_headers::DefaultHeadersLayer;
simple_logger::init_with_level(log::Level::Info).expect("couldn't initialize logging");
@ -20,12 +22,19 @@ async fn main() {
let addr = leptos_options.site_addr;
let routes = generate_route_list(|| view! { <App/> });
let mut default_headers = HeaderMap::new();
let color_header = HeaderValue::from_static("Sec-CH-Prefers-Color-Scheme");
default_headers.insert(HeaderName::from_static("accept-ch"), color_header.clone());
default_headers.insert(HeaderName::from_static("vary"), color_header.clone());
default_headers.insert(HeaderName::from_static("critical-ch"), color_header);
// build our application with a route
let app = Router::new()
.route("/api/*fn_name", post(leptos_axum::handle_server_fns))
.leptos_routes(&leptos_options, routes, || view! { <App/> })
.fallback(file_and_error_handler)
.with_state(leptos_options);
.with_state(leptos_options)
.layer(DefaultHeadersLayer::new(default_headers));
let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
log!("listening on http://{}", &addr);

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["sync_signal", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_active_element", "docs"] }
web-sys = { version = "0.3", features = ["HtmlElement", "DomStringMap"] }
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_breakpoints", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -9,7 +9,7 @@ codee = "0.1"
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_broadcast_channel", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -1,2 +0,0 @@
[build]
rustflags = ["--cfg=web_sys_unstable_apis"]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_clipboard", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_color_mode", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -9,7 +9,7 @@ codee = "0.1"
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_cookie", "docs"] }
rand = "0.8"
getrandom = { version = "0.2", features = ["js"] }
web-sys = "0.3"

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_css_var", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_cycle_list", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_debounce_fn", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_device_orientation", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_device_pixel_ratio", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_display_media", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_document_visibility", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_draggable", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_drop_zone", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_element_bounding", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_element_hover", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_element_size", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_element_visibility", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../.." }
leptos-use = { path = "../..", features = ["use_event_listener"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_favicon", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_geolocation", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_idle", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_infinite_scroll", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_intersection_observer", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_interval", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs", "math"] }
leptos-use = { path = "../..", features = ["use_interval_fn", "docs", "math"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_intl_number_format", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -0,0 +1,17 @@
[package]
name = "use_locale"
version = "0.1.0"
edition = "2021"
[dependencies]
leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["use_locale", "docs"] }
unic-langid = { version = "0.9", features = ["macros"] }
web-sys = "0.3"
[dev-dependencies]
wasm-bindgen = "0.2"
wasm-bindgen-test = "0.3.0"

View file

@ -0,0 +1,23 @@
A simple example for `use_locale`.
If you don't have it installed already, install [Trunk](https://trunkrs.dev/) and [Tailwind](https://tailwindcss.com/docs/installation)
as well as the nightly toolchain for Rust and the wasm32-unknown-unknown target:
```bash
cargo install trunk
npm install -D tailwindcss @tailwindcss/forms
rustup toolchain install nightly
rustup target add wasm32-unknown-unknown
```
Then, open two terminals. In the first one, run:
```
npx tailwindcss -i ./input.css -o ./style/output.css --watch
```
In the second one, run:
```bash
trunk serve --open
```

View file

@ -0,0 +1,2 @@
[build]
public_url = "/demo/"

View file

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<link data-trunk rel="css" href="style/output.css">
</head>
<body></body>
</html>

View file

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View file

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

View file

@ -0,0 +1,22 @@
use leptos::*;
use leptos_use::docs::demo_or_body;
use leptos_use::use_locale;
use unic_langid::langid_slice;
#[component]
fn Demo() -> impl IntoView {
let locale = use_locale(langid_slice!["en", "de", "fr"]);
view! {
<p>Locale: <code class="font-bold">{move || locale.get().to_string()}</code></p>
}
}
fn main() {
_ = console_log::init_with_level(log::Level::Debug);
console_error_panic_hook::set_once();
mount_to(demo_or_body(), || {
view! { <Demo/> }
})
}

View file

@ -0,0 +1,330 @@
[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: #fff;
border-color: #6b7280;
border-width: 1px;
border-radius: 0px;
padding-top: 0.5rem;
padding-right: 0.75rem;
padding-bottom: 0.5rem;
padding-left: 0.75rem;
font-size: 1rem;
line-height: 1.5rem;
--tw-shadow: 0 0 #0000;
}
[type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus {
outline: 2px solid transparent;
outline-offset: 2px;
--tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: #2563eb;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
border-color: #2563eb;
}
input::-moz-placeholder, textarea::-moz-placeholder {
color: #6b7280;
opacity: 1;
}
input::placeholder,textarea::placeholder {
color: #6b7280;
opacity: 1;
}
::-webkit-datetime-edit-fields-wrapper {
padding: 0;
}
::-webkit-date-and-time-value {
min-height: 1.5em;
text-align: inherit;
}
::-webkit-datetime-edit {
display: inline-flex;
}
::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field {
padding-top: 0;
padding-bottom: 0;
}
select {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
background-position: right 0.5rem center;
background-repeat: no-repeat;
background-size: 1.5em 1.5em;
padding-right: 2.5rem;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
[multiple],[size]:where(select:not([size="1"])) {
background-image: initial;
background-position: initial;
background-repeat: unset;
background-size: initial;
padding-right: 0.75rem;
-webkit-print-color-adjust: unset;
print-color-adjust: unset;
}
[type='checkbox'],[type='radio'] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding: 0;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
display: inline-block;
vertical-align: middle;
background-origin: border-box;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
flex-shrink: 0;
height: 1rem;
width: 1rem;
color: #2563eb;
background-color: #fff;
border-color: #6b7280;
border-width: 1px;
--tw-shadow: 0 0 #0000;
}
[type='checkbox'] {
border-radius: 0px;
}
[type='radio'] {
border-radius: 100%;
}
[type='checkbox']:focus,[type='radio']:focus {
outline: 2px solid transparent;
outline-offset: 2px;
--tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
--tw-ring-offset-width: 2px;
--tw-ring-offset-color: #fff;
--tw-ring-color: #2563eb;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
[type='checkbox']:checked,[type='radio']:checked {
border-color: transparent;
background-color: currentColor;
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
[type='checkbox']:checked {
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
}
@media (forced-colors: active) {
[type='checkbox']:checked {
-webkit-appearance: auto;
-moz-appearance: auto;
appearance: auto;
}
}
[type='radio']:checked {
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
}
@media (forced-colors: active) {
[type='radio']:checked {
-webkit-appearance: auto;
-moz-appearance: auto;
appearance: auto;
}
}
[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus {
border-color: transparent;
background-color: currentColor;
}
[type='checkbox']:indeterminate {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");
border-color: transparent;
background-color: currentColor;
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
@media (forced-colors: active) {
[type='checkbox']:indeterminate {
-webkit-appearance: auto;
-moz-appearance: auto;
appearance: auto;
}
}
[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus {
border-color: transparent;
background-color: currentColor;
}
[type='file'] {
background: unset;
border-color: inherit;
border-width: 0;
border-radius: 0;
padding: 0;
font-size: unset;
line-height: inherit;
}
[type='file']:focus {
outline: 1px solid ButtonText;
outline: 1px auto -webkit-focus-ring-color;
}
*, ::before, ::after {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
}
::backdrop {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
}
.static {
position: static;
}
.font-bold {
font-weight: 700;
}
.text-\[--brand-color\] {
color: var(--brand-color);
}
.text-green-600 {
--tw-text-opacity: 1;
color: rgb(22 163 74 / var(--tw-text-opacity));
}
.opacity-75 {
opacity: 0.75;
}
@media (prefers-color-scheme: dark) {
.dark\:text-green-500 {
--tw-text-opacity: 1;
color: rgb(34 197 94 / var(--tw-text-opacity));
}
}

View file

@ -0,0 +1,15 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: {
files: ["*.html", "./src/**/*.rs", "../../src/docs/**/*.rs"],
},
theme: {
extend: {},
},
corePlugins: {
preflight: false,
},
plugins: [
require('@tailwindcss/forms'),
],
}

View file

@ -0,0 +1,16 @@
[package]
name = "use_locales"
version = "0.1.0"
edition = "2021"
[dependencies]
leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["use_locales", "docs"] }
web-sys = "0.3"
[dev-dependencies]
wasm-bindgen = "0.2"
wasm-bindgen-test = "0.3.0"

View file

@ -0,0 +1,23 @@
A simple example for `use_locales`.
If you don't have it installed already, install [Trunk](https://trunkrs.dev/) and [Tailwind](https://tailwindcss.com/docs/installation)
as well as the nightly toolchain for Rust and the wasm32-unknown-unknown target:
```bash
cargo install trunk
npm install -D tailwindcss @tailwindcss/forms
rustup toolchain install nightly
rustup target add wasm32-unknown-unknown
```
Then, open two terminals. In the first one, run:
```
npx tailwindcss -i ./input.css -o ./style/output.css --watch
```
In the second one, run:
```bash
trunk serve --open
```

View file

@ -0,0 +1,2 @@
[build]
public_url = "/demo/"

View file

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<link data-trunk rel="css" href="style/output.css">
</head>
<body></body>
</html>

View file

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View file

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

View file

@ -0,0 +1,21 @@
use leptos::*;
use leptos_use::docs::demo_or_body;
use leptos_use::use_locales;
#[component]
fn Demo() -> impl IntoView {
let locales = use_locales();
view! {
<pre>{move || format!("Locales:\n {}", locales().join("\n "))}</pre>
}
}
fn main() {
_ = console_log::init_with_level(log::Level::Debug);
console_error_panic_hook::set_once();
mount_to(demo_or_body(), || {
view! { <Demo/> }
})
}

View file

@ -0,0 +1,289 @@
[type='text'],[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: #fff;
border-color: #6b7280;
border-width: 1px;
border-radius: 0px;
padding-top: 0.5rem;
padding-right: 0.75rem;
padding-bottom: 0.5rem;
padding-left: 0.75rem;
font-size: 1rem;
line-height: 1.5rem;
--tw-shadow: 0 0 #0000;
}
[type='text']:focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus {
outline: 2px solid transparent;
outline-offset: 2px;
--tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: #2563eb;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
border-color: #2563eb;
}
input::-moz-placeholder, textarea::-moz-placeholder {
color: #6b7280;
opacity: 1;
}
input::placeholder,textarea::placeholder {
color: #6b7280;
opacity: 1;
}
::-webkit-datetime-edit-fields-wrapper {
padding: 0;
}
::-webkit-date-and-time-value {
min-height: 1.5em;
}
::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field {
padding-top: 0;
padding-bottom: 0;
}
select {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
background-position: right 0.5rem center;
background-repeat: no-repeat;
background-size: 1.5em 1.5em;
padding-right: 2.5rem;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
[multiple] {
background-image: initial;
background-position: initial;
background-repeat: unset;
background-size: initial;
padding-right: 0.75rem;
-webkit-print-color-adjust: unset;
print-color-adjust: unset;
}
[type='checkbox'],[type='radio'] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding: 0;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
display: inline-block;
vertical-align: middle;
background-origin: border-box;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
flex-shrink: 0;
height: 1rem;
width: 1rem;
color: #2563eb;
background-color: #fff;
border-color: #6b7280;
border-width: 1px;
--tw-shadow: 0 0 #0000;
}
[type='checkbox'] {
border-radius: 0px;
}
[type='radio'] {
border-radius: 100%;
}
[type='checkbox']:focus,[type='radio']:focus {
outline: 2px solid transparent;
outline-offset: 2px;
--tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
--tw-ring-offset-width: 2px;
--tw-ring-offset-color: #fff;
--tw-ring-color: #2563eb;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
[type='checkbox']:checked,[type='radio']:checked {
border-color: transparent;
background-color: currentColor;
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
[type='checkbox']:checked {
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
}
[type='radio']:checked {
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
}
[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus {
border-color: transparent;
background-color: currentColor;
}
[type='checkbox']:indeterminate {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");
border-color: transparent;
background-color: currentColor;
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus {
border-color: transparent;
background-color: currentColor;
}
[type='file'] {
background: unset;
border-color: inherit;
border-width: 0;
border-radius: 0;
padding: 0;
font-size: unset;
line-height: inherit;
}
[type='file']:focus {
outline: 1px solid ButtonText;
outline: 1px auto -webkit-focus-ring-color;
}
*, ::before, ::after {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
::backdrop {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
.block {
display: block;
}
.text-\[--brand-color\] {
color: var(--brand-color);
}
.text-green-600 {
--tw-text-opacity: 1;
color: rgb(22 163 74 / var(--tw-text-opacity));
}
.opacity-75 {
opacity: 0.75;
}
@media (prefers-color-scheme: dark) {
.dark\:text-green-500 {
--tw-text-opacity: 1;
color: rgb(34 197 94 / var(--tw-text-opacity));
}
}

View file

@ -0,0 +1,15 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: {
files: ["*.html", "./src/**/*.rs", "../../src/docs/**/*.rs"],
},
theme: {
extend: {},
},
corePlugins: {
preflight: false,
},
plugins: [
require('@tailwindcss/forms'),
],
}

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_media_query", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_mouse", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_mouse_in_element", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_mutation_observer", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_permission", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -0,0 +1,16 @@
[package]
name = "use_prefers_reduced_motion"
version = "0.1.0"
edition = "2021"
[dependencies]
leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["use_prefers_reduced_motion", "docs"] }
web-sys = "0.3"
[dev-dependencies]
wasm-bindgen = "0.2"
wasm-bindgen-test = "0.3.0"

View file

@ -0,0 +1,23 @@
A simple example for `use_prefers_reduced_motion`.
If you don't have it installed already, install [Trunk](https://trunkrs.dev/) and [Tailwind](https://tailwindcss.com/docs/installation)
as well as the nightly toolchain for Rust and the wasm32-unknown-unknown target:
```bash
cargo install trunk
npm install -D tailwindcss @tailwindcss/forms
rustup toolchain install nightly
rustup target add wasm32-unknown-unknown
```
Then, open two terminals. In the first one, run:
```
npx tailwindcss -i ./input.css -o ./style/output.css --watch
```
In the second one, run:
```bash
trunk serve --open
```

View file

@ -0,0 +1,2 @@
[build]
public_url = "/demo/"

View file

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<link data-trunk rel="css" href="style/output.css">
</head>
<body></body>
</html>

View file

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View file

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

View file

@ -0,0 +1,29 @@
use leptos::*;
use leptos_use::docs::{demo_or_body, BooleanDisplay};
use leptos_use::use_prefers_reduced_motion;
#[component]
fn Demo() -> impl IntoView {
let is_reduced_motion_preferred = use_prefers_reduced_motion();
view! {
<div>
<p>Prefers reduced motions: <BooleanDisplay value=is_reduced_motion_preferred/></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>
}
}
fn main() {
_ = console_log::init_with_level(log::Level::Debug);
console_error_panic_hook::set_once();
mount_to(demo_or_body(), || {
view! { <Demo/> }
})
}

View file

@ -0,0 +1,326 @@
[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: #fff;
border-color: #6b7280;
border-width: 1px;
border-radius: 0px;
padding-top: 0.5rem;
padding-right: 0.75rem;
padding-bottom: 0.5rem;
padding-left: 0.75rem;
font-size: 1rem;
line-height: 1.5rem;
--tw-shadow: 0 0 #0000;
}
[type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus {
outline: 2px solid transparent;
outline-offset: 2px;
--tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: #2563eb;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
border-color: #2563eb;
}
input::-moz-placeholder, textarea::-moz-placeholder {
color: #6b7280;
opacity: 1;
}
input::placeholder,textarea::placeholder {
color: #6b7280;
opacity: 1;
}
::-webkit-datetime-edit-fields-wrapper {
padding: 0;
}
::-webkit-date-and-time-value {
min-height: 1.5em;
text-align: inherit;
}
::-webkit-datetime-edit {
display: inline-flex;
}
::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field {
padding-top: 0;
padding-bottom: 0;
}
select {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
background-position: right 0.5rem center;
background-repeat: no-repeat;
background-size: 1.5em 1.5em;
padding-right: 2.5rem;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
[multiple],[size]:where(select:not([size="1"])) {
background-image: initial;
background-position: initial;
background-repeat: unset;
background-size: initial;
padding-right: 0.75rem;
-webkit-print-color-adjust: unset;
print-color-adjust: unset;
}
[type='checkbox'],[type='radio'] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding: 0;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
display: inline-block;
vertical-align: middle;
background-origin: border-box;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
flex-shrink: 0;
height: 1rem;
width: 1rem;
color: #2563eb;
background-color: #fff;
border-color: #6b7280;
border-width: 1px;
--tw-shadow: 0 0 #0000;
}
[type='checkbox'] {
border-radius: 0px;
}
[type='radio'] {
border-radius: 100%;
}
[type='checkbox']:focus,[type='radio']:focus {
outline: 2px solid transparent;
outline-offset: 2px;
--tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
--tw-ring-offset-width: 2px;
--tw-ring-offset-color: #fff;
--tw-ring-color: #2563eb;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
[type='checkbox']:checked,[type='radio']:checked {
border-color: transparent;
background-color: currentColor;
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
[type='checkbox']:checked {
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
}
@media (forced-colors: active) {
[type='checkbox']:checked {
-webkit-appearance: auto;
-moz-appearance: auto;
appearance: auto;
}
}
[type='radio']:checked {
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
}
@media (forced-colors: active) {
[type='radio']:checked {
-webkit-appearance: auto;
-moz-appearance: auto;
appearance: auto;
}
}
[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus {
border-color: transparent;
background-color: currentColor;
}
[type='checkbox']:indeterminate {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");
border-color: transparent;
background-color: currentColor;
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
@media (forced-colors: active) {
[type='checkbox']:indeterminate {
-webkit-appearance: auto;
-moz-appearance: auto;
appearance: auto;
}
}
[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus {
border-color: transparent;
background-color: currentColor;
}
[type='file'] {
background: unset;
border-color: inherit;
border-width: 0;
border-radius: 0;
padding: 0;
font-size: unset;
line-height: inherit;
}
[type='file']:focus {
outline: 1px solid ButtonText;
outline: 1px auto -webkit-focus-ring-color;
}
*, ::before, ::after {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
}
::backdrop {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
}
.static {
position: static;
}
.text-\[--brand-color\] {
color: var(--brand-color);
}
.text-green-600 {
--tw-text-opacity: 1;
color: rgb(22 163 74 / var(--tw-text-opacity));
}
.opacity-75 {
opacity: 0.75;
}
@media (prefers-color-scheme: dark) {
.dark\:text-green-500 {
--tw-text-opacity: 1;
color: rgb(34 197 94 / var(--tw-text-opacity));
}
}

View file

@ -0,0 +1,15 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: {
files: ["*.html", "./src/**/*.rs", "../../src/docs/**/*.rs"],
},
theme: {
extend: {},
},
corePlugins: {
preflight: false,
},
plugins: [
require('@tailwindcss/forms'),
],
}

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_raf_fn", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_resize_observer", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_scroll", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_service_worker", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_sorted", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ codee = { version = "0.1", features = ["json_serde"] }
console_error_panic_hook = "0.1"
console_log = "1"
leptos = { version = "0.6", features = ["nightly", "csr"] }
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["storage", "docs"] }
log = "0.4"
serde = "1.0.163"
web-sys = "0.3"

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_throttle_fn", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_timeout_fn", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_timestamp", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_user_media", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_web_notification", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -14,7 +14,7 @@ fn Demo() -> impl IntoView {
.title("Hello World from leptos-use")
.direction(NotificationDirection::Auto)
.language("en")
// .renotify(true)
.renotify(true)
.tag("test"),
);

View file

@ -9,7 +9,7 @@ codee = { version = "0.1", features = ["msgpack_serde"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_websocket", "docs"] }
serde = { version = "1", features = ["derive"] }
web-sys = "0.3"

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_web_notification", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_window_focus", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["use_window_scroll", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["watch_debounced", "docs"] }
web-sys = "0.3"
[dev-dependencies]

View file

@ -8,7 +8,7 @@ leptos = { version = "0.6", features = ["nightly", "csr"] }
console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = { path = "../..", features = ["docs"] }
leptos-use = { path = "../..", features = ["watch_pausable", "docs"] }
web-sys = "0.3"
[dev-dependencies]

Some files were not shown because too many files have changed in this diff Show more