Merge branch 'main' into use_webtransport
# Conflicts: # .cargo/config.toml # .idea/leptos-use.iml # Cargo.toml # src/lib.rs
|
@ -1,3 +0,0 @@
|
||||||
[build]
|
|
||||||
rustflags = ["--cfg=web_sys_unstable_apis"]
|
|
||||||
rustdocflags = ["--cfg=web_sys_unstable_apis"]
|
|
|
@ -3,14 +3,14 @@
|
||||||
{
|
{
|
||||||
"type": "cargo",
|
"type": "cargo",
|
||||||
"name": "Tests",
|
"name": "Tests",
|
||||||
"cargoArgs": ["test", "--features", "math,storage,docs"],
|
"cargoArgs": ["test", "--features", "math,prost,serde,docs"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "cargo",
|
"type": "cargo",
|
||||||
"name": "Clippy",
|
"name": "Clippy",
|
||||||
"cargoArgs": ["+nightly", "clippy", "--features", "math,storage,docs", "--tests", "--", "-D", "warnings"],
|
"cargoArgs": ["+nightly", "clippy", "--features", "math,prost,serde,docs", "--tests", "--", "-D", "warnings"],
|
||||||
"workingDir": "./",
|
"workingDir": "./",
|
||||||
},
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
4
.github/workflows/ci.yml
vendored
|
@ -30,7 +30,7 @@ jobs:
|
||||||
- name: Check formatting
|
- name: Check formatting
|
||||||
run: cargo fmt --check
|
run: cargo fmt --check
|
||||||
- name: Clippy
|
- name: Clippy
|
||||||
run: cargo clippy --features storage,docs,math --tests -- -D warnings
|
run: cargo clippy --features prost,serde,docs,math --tests -- -D warnings
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: cargo test --all-features
|
run: cargo test --all-features
|
||||||
|
|
||||||
|
@ -110,4 +110,4 @@ jobs:
|
||||||
# - name: Publish to Coveralls
|
# - name: Publish to Coveralls
|
||||||
# uses: coverallsapp/github-action@master
|
# uses: coverallsapp/github-action@master
|
||||||
# with:
|
# with:
|
||||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
2
.github/workflows/tests.yml
vendored
|
@ -23,6 +23,6 @@ jobs:
|
||||||
- name: Check formatting
|
- name: Check formatting
|
||||||
run: cargo fmt --check
|
run: cargo fmt --check
|
||||||
- name: Clippy
|
- name: Clippy
|
||||||
run: cargo clippy --features storage,docs,math --tests -- -D warnings
|
run: cargo clippy --features prost,serde,docs,math --tests -- -D warnings
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: cargo test --all-features
|
run: cargo test --all-features
|
||||||
|
|
9
.idea/leptos-use.iml
generated
|
@ -12,6 +12,7 @@
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/examples/use_throttle_fn/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_throttle_fn/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/examples/use_debounce_fn/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_debounce_fn/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_display_media/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/examples/use_scroll/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_scroll/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/examples/use_resize_observer/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_resize_observer/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/examples/use_mouse/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_mouse/src" isTestSource="false" />
|
||||||
|
@ -56,6 +57,10 @@
|
||||||
<sourceFolder url="file://$MODULE_DIR$/examples/use_geolocation/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_geolocation/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/examples/use_idle/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_idle/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/examples/use_timestamp/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_timestamp/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_sorted/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_service_worker/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_infinite_scroll/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_web_notification/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/examples/use_webtransport_with_server/client/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_webtransport_with_server/client/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/examples/use_webtransport_with_server/server/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/examples/use_webtransport_with_server/server/src" isTestSource="false" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/examples/use_event_listener/target" />
|
<excludeFolder url="file://$MODULE_DIR$/examples/use_event_listener/target" />
|
||||||
|
@ -65,7 +70,9 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/examples/use_throttle_fn/dist" />
|
<excludeFolder url="file://$MODULE_DIR$/examples/use_throttle_fn/dist" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/examples/use_throttle_fn/target" />
|
<excludeFolder url="file://$MODULE_DIR$/examples/use_throttle_fn/target" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/examples/use_debounce_fn/dist" />
|
<excludeFolder url="file://$MODULE_DIR$/examples/use_debounce_fn/dist" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/examples/use_display_media/dist" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/examples/use_debounce_fn/target" />
|
<excludeFolder url="file://$MODULE_DIR$/examples/use_debounce_fn/target" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/examples/use_display_media/target" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/examples/use_scroll/target" />
|
<excludeFolder url="file://$MODULE_DIR$/examples/use_scroll/target" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/examples/use_resize_observer/target" />
|
<excludeFolder url="file://$MODULE_DIR$/examples/use_resize_observer/target" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/examples/use_mouse/target" />
|
<excludeFolder url="file://$MODULE_DIR$/examples/use_mouse/target" />
|
||||||
|
@ -126,4 +133,4 @@
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" name="Python 3.9 interpreter library" level="application" />
|
<orderEntry type="library" name="Python 3.9 interpreter library" level="application" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
|
|
74
CHANGELOG.md
|
@ -3,6 +3,80 @@
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [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 `Codec`s 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 `get`ting 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
|
## [0.7.0] - 2023-09-30
|
||||||
|
|
||||||
### New Functions 🚀
|
### New Functions 🚀
|
||||||
|
|
42
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "leptos-use"
|
name = "leptos-use"
|
||||||
version = "0.7.0"
|
version = "0.9.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Marc-Stefan Cassola"]
|
authors = ["Marc-Stefan Cassola"]
|
||||||
categories = ["gui", "web-programming"]
|
categories = ["gui", "web-programming"]
|
||||||
|
@ -13,23 +13,30 @@ repository = "https://github.com/Synphonyte/leptos-use"
|
||||||
homepage = "https://leptos-use.rs"
|
homepage = "https://leptos-use.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
leptos = "0.5"
|
base64 = { version = "0.21", optional = true }
|
||||||
wasm-bindgen = "0.2"
|
cfg-if = "1"
|
||||||
js-sys = "0.3"
|
|
||||||
default-struct-builder = "0.5"
|
default-struct-builder = "0.5"
|
||||||
|
futures-util = "0.3"
|
||||||
|
gloo-timers = { version = "0.3.0", features = ["futures"] }
|
||||||
|
gloo-utils = { version = "0.2.0" }
|
||||||
|
js-sys = "0.3"
|
||||||
|
lazy_static = "1"
|
||||||
|
leptos = "0.5"
|
||||||
num = { version = "0.4", optional = true }
|
num = { version = "0.4", optional = true }
|
||||||
|
paste = "1"
|
||||||
|
prost = { version = "0.12", optional = true }
|
||||||
serde = { version = "1", optional = true }
|
serde = { version = "1", optional = true }
|
||||||
serde_json = { version = "1", optional = true }
|
serde_json = { version = "1", optional = true }
|
||||||
paste = "1"
|
thiserror = "1.0"
|
||||||
lazy_static = "1"
|
wasm-bindgen = "0.2.88"
|
||||||
cfg-if = "1"
|
wasm-bindgen-futures = "0.4"
|
||||||
wasm-bindgen-futures = "0.4"
|
wasm-bindgen-futures = "0.4"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
rmp-serde = { version = "1.1", optional = true }
|
rmp-serde = { version = "1.1", optional = true }
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
|
|
||||||
[dependencies.web-sys]
|
[dependencies.web-sys]
|
||||||
version = "0.3"
|
version = "0.3.65"
|
||||||
features = [
|
features = [
|
||||||
"AddEventListenerOptions",
|
"AddEventListenerOptions",
|
||||||
"BinaryType",
|
"BinaryType",
|
||||||
|
@ -38,6 +45,7 @@ features = [
|
||||||
"CssStyleDeclaration",
|
"CssStyleDeclaration",
|
||||||
"CustomEvent",
|
"CustomEvent",
|
||||||
"CustomEventInit",
|
"CustomEventInit",
|
||||||
|
"DisplayMediaStreamConstraints",
|
||||||
"DomRect",
|
"DomRect",
|
||||||
"DomRectReadOnly",
|
"DomRectReadOnly",
|
||||||
"DataTransfer",
|
"DataTransfer",
|
||||||
|
@ -55,13 +63,20 @@ features = [
|
||||||
"IntersectionObserver",
|
"IntersectionObserver",
|
||||||
"IntersectionObserverInit",
|
"IntersectionObserverInit",
|
||||||
"IntersectionObserverEntry",
|
"IntersectionObserverEntry",
|
||||||
|
"MediaDevices",
|
||||||
"MediaQueryList",
|
"MediaQueryList",
|
||||||
|
"MediaStream",
|
||||||
|
"MediaStreamTrack",
|
||||||
"MouseEvent",
|
"MouseEvent",
|
||||||
"MutationObserver",
|
"MutationObserver",
|
||||||
"MutationObserverInit",
|
"MutationObserverInit",
|
||||||
"MutationRecord",
|
"MutationRecord",
|
||||||
"Navigator",
|
"Navigator",
|
||||||
"NodeList",
|
"NodeList",
|
||||||
|
"Notification",
|
||||||
|
"NotificationDirection",
|
||||||
|
"NotificationOptions",
|
||||||
|
"NotificationPermission",
|
||||||
"PointerEvent",
|
"PointerEvent",
|
||||||
"Position",
|
"Position",
|
||||||
"PositionError",
|
"PositionError",
|
||||||
|
@ -77,7 +92,12 @@ features = [
|
||||||
"ResizeObserverSize",
|
"ResizeObserverSize",
|
||||||
"ScrollBehavior",
|
"ScrollBehavior",
|
||||||
"ScrollToOptions",
|
"ScrollToOptions",
|
||||||
|
"ServiceWorker",
|
||||||
|
"ServiceWorkerContainer",
|
||||||
|
"ServiceWorkerRegistration",
|
||||||
|
"ServiceWorkerState",
|
||||||
"Storage",
|
"Storage",
|
||||||
|
"StorageEvent",
|
||||||
"Touch",
|
"Touch",
|
||||||
"TouchEvent",
|
"TouchEvent",
|
||||||
"TouchList",
|
"TouchList",
|
||||||
|
@ -97,12 +117,10 @@ features = [
|
||||||
[features]
|
[features]
|
||||||
docs = []
|
docs = []
|
||||||
math = ["num"]
|
math = ["num"]
|
||||||
storage = ["dep:serde", "dep:serde_json", "web-sys/StorageEvent"]
|
prost = ["base64", "dep:prost"]
|
||||||
|
serde = ["dep:serde", "serde_json"]
|
||||||
ssr = []
|
ssr = []
|
||||||
msgpack = ["dep:rmp-serde", "dep:serde"]
|
msgpack = ["dep:rmp-serde", "dep:serde"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
rustdoc-args = ["--cfg=web_sys_unstable_apis"]
|
|
||||||
rustc-args = ["--cfg=web_sys_unstable_apis"]
|
|
||||||
|
|
||||||
|
|
12
README.md
|
@ -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://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/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/-docs%20%26%20demos-%239A233F" alt="Docs & Demos"></a>
|
||||||
<a href="https://leptos-use.rs"><img src="https://img.shields.io/badge/-58%20functions-%23EF3939" alt="58 Functions" /></a>
|
<a href="https://leptos-use.rs"><img src="https://img.shields.io/badge/-63%20functions-%23EF3939" alt="63 Functions" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
@ -87,8 +87,8 @@ This will create the function file in the src directory, scaffold an example dir
|
||||||
|
|
||||||
## Leptos compatibility
|
## Leptos compatibility
|
||||||
|
|
||||||
| Crate version | Compatible Leptos version |
|
| Crate version | Compatible Leptos version |
|
||||||
|---------------|---------------------------|
|
|----------------|---------------------------|
|
||||||
| <= 0.3 | 0.3 |
|
| <= 0.3 | 0.3 |
|
||||||
| 0.4, 0.5, 0.6 | 0.4 |
|
| 0.4, 0.5, 0.6 | 0.4 |
|
||||||
| 0.7 | 0.5 |
|
| 0.7, 0.8, 0.9 | 0.5 |
|
||||||
|
|
|
@ -2,6 +2,7 @@ import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -43,7 +44,7 @@ def build_and_copy_demo(category, md_name):
|
||||||
html = f.read()
|
html = f.read()
|
||||||
head_split = html.split("<head>")
|
head_split = html.split("<head>")
|
||||||
target_head = head_split[1].split("</head>")[0]
|
target_head = head_split[1].split("</head>")[0]
|
||||||
body_split = html.split("<body>")[1].split("</body>")
|
body_split = re.split("<body[^>]*>", html)[1].split("</body>")
|
||||||
target_body = body_split[0]
|
target_body = body_split[0]
|
||||||
|
|
||||||
with open(book_html_path, "w") as f:
|
with open(book_html_path, "w") as f:
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
[Changelog](changelog.md)
|
[Changelog](changelog.md)
|
||||||
[Functions](functions.md)
|
[Functions](functions.md)
|
||||||
|
|
||||||
# @Storage
|
# Storage
|
||||||
|
|
||||||
- [use_local_storage](storage/use_local_storage.md)
|
- [use_local_storage](storage/use_local_storage.md)
|
||||||
- [use_session_storage](storage/use_session_storage.md)
|
- [use_session_storage](storage/use_session_storage.md)
|
||||||
|
@ -33,11 +33,14 @@
|
||||||
- [use_breakpoints](browser/use_breakpoints.md)
|
- [use_breakpoints](browser/use_breakpoints.md)
|
||||||
- [use_color_mode](browser/use_color_mode.md)
|
- [use_color_mode](browser/use_color_mode.md)
|
||||||
- [use_css_var](browser/use_css_var.md)
|
- [use_css_var](browser/use_css_var.md)
|
||||||
|
- [use_display_media](browser/use_display_media.md)
|
||||||
- [use_event_listener](browser/use_event_listener.md)
|
- [use_event_listener](browser/use_event_listener.md)
|
||||||
- [use_favicon](browser/use_favicon.md)
|
- [use_favicon](browser/use_favicon.md)
|
||||||
- [use_media_query](browser/use_media_query.md)
|
- [use_media_query](browser/use_media_query.md)
|
||||||
- [use_preferred_contrast](browser/use_preferred_contrast.md)
|
- [use_preferred_contrast](browser/use_preferred_contrast.md)
|
||||||
- [use_preferred_dark](browser/use_preferred_dark.md)
|
- [use_preferred_dark](browser/use_preferred_dark.md)
|
||||||
|
- [use_service_worker](browser/use_service_worker.md)
|
||||||
|
- [use_web_notification](browser/use_web_notification.md)
|
||||||
|
|
||||||
# Sensors
|
# Sensors
|
||||||
|
|
||||||
|
@ -45,6 +48,7 @@
|
||||||
- [use_element_hover](sensors/use_element_hover.md)
|
- [use_element_hover](sensors/use_element_hover.md)
|
||||||
- [use_geolocation](sensors/use_geolocation.md)
|
- [use_geolocation](sensors/use_geolocation.md)
|
||||||
- [use_idle](sensors/use_idle.md)
|
- [use_idle](sensors/use_idle.md)
|
||||||
|
- [use_infinite_scroll](sensors/use_infinite_scroll.md)
|
||||||
- [use_mouse](sensors/use_mouse.md)
|
- [use_mouse](sensors/use_mouse.md)
|
||||||
- [use_scroll](sensors/use_scroll.md)
|
- [use_scroll](sensors/use_scroll.md)
|
||||||
|
|
||||||
|
@ -73,8 +77,11 @@
|
||||||
- [signal_debounced](reactivity/signal_debounced.md)
|
- [signal_debounced](reactivity/signal_debounced.md)
|
||||||
- [signal_throttled](reactivity/signal_throttled.md)
|
- [signal_throttled](reactivity/signal_throttled.md)
|
||||||
|
|
||||||
# Utilities
|
# Iterable
|
||||||
|
|
||||||
|
- [use_sorted](iterable/use_sorted.md)
|
||||||
|
|
||||||
|
# Utilities
|
||||||
- [is_err](utilities/is_err.md)
|
- [is_err](utilities/is_err.md)
|
||||||
- [is_none](utilities/is_none.md)
|
- [is_none](utilities/is_none.md)
|
||||||
- [is_ok](utilities/is_ok.md)
|
- [is_ok](utilities/is_ok.md)
|
||||||
|
|
3
docs/book/src/browser/use_display_media.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# use_display_media
|
||||||
|
|
||||||
|
<!-- cmdrun python3 ../extract_doc_comment.py use_display_media -->
|
3
docs/book/src/browser/use_service_worker.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# use_service_worker
|
||||||
|
|
||||||
|
<!-- cmdrun python3 ../extract_doc_comment.py use_service_worker -->
|
3
docs/book/src/browser/use_web_notification.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# use_web_notification
|
||||||
|
|
||||||
|
<!-- cmdrun python3 ../extract_doc_comment.py use_web_notification -->
|
|
@ -99,4 +99,8 @@ h1 {
|
||||||
|
|
||||||
h2, h3, h4 {
|
h2, h3, h4 {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchbar {
|
||||||
|
font-size: 1.6rem;
|
||||||
}
|
}
|
|
@ -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://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/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="./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/-58%20functions-%23EF3939" alt="58 Functions" /></a>
|
<a href="./functions.html"><img src="https://img.shields.io/badge/-63%20functions-%23EF3939" alt="63 Functions" /></a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
3
docs/book/src/iterable/use_sorted.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# use_sorted
|
||||||
|
|
||||||
|
<!-- cmdrun python3 ../extract_doc_comment.py use_sorted -->
|
3
docs/book/src/sensors/use_infinite_scroll.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# use_infinite_scroll
|
||||||
|
|
||||||
|
<!-- cmdrun python3 ../extract_doc_comment.py use_infinite_scroll -->
|
|
@ -1,3 +1,3 @@
|
||||||
# use_local_storage
|
# use_local_storage
|
||||||
|
|
||||||
<!-- cmdrun python3 ../extract_doc_comment.py storage/use_local_storage storage -->
|
<!-- cmdrun python3 ../extract_doc_comment.py storage/use_local_storage -->
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# use_session_storage
|
# use_session_storage
|
||||||
|
|
||||||
<!-- cmdrun python3 ../extract_doc_comment.py storage/use_session_storage storage -->
|
<!-- cmdrun python3 ../extract_doc_comment.py storage/use_session_storage -->
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# use_storage
|
# use_storage
|
||||||
|
|
||||||
<!-- cmdrun python3 ../extract_doc_comment.py storage/use_storage storage -->
|
<!-- cmdrun python3 ../extract_doc_comment.py storage/use_storage -->
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[build]
|
|
||||||
rustflags = ["--cfg=web_sys_unstable_apis", "--cfg=has_std"]
|
|
|
@ -13,6 +13,7 @@ members = [
|
||||||
"use_css_var",
|
"use_css_var",
|
||||||
"use_cycle_list",
|
"use_cycle_list",
|
||||||
"use_debounce_fn",
|
"use_debounce_fn",
|
||||||
|
"use_display_media",
|
||||||
"use_document_visibility",
|
"use_document_visibility",
|
||||||
"use_draggable",
|
"use_draggable",
|
||||||
"use_drop_zone",
|
"use_drop_zone",
|
||||||
|
@ -24,6 +25,7 @@ members = [
|
||||||
"use_floor",
|
"use_floor",
|
||||||
"use_geolocation",
|
"use_geolocation",
|
||||||
"use_idle",
|
"use_idle",
|
||||||
|
"use_infinite_scroll",
|
||||||
"use_intersection_observer",
|
"use_intersection_observer",
|
||||||
"use_interval",
|
"use_interval",
|
||||||
"use_interval_fn",
|
"use_interval_fn",
|
||||||
|
@ -35,9 +37,12 @@ members = [
|
||||||
"use_resize_observer",
|
"use_resize_observer",
|
||||||
"use_round",
|
"use_round",
|
||||||
"use_scroll",
|
"use_scroll",
|
||||||
|
"use_service_worker",
|
||||||
|
"use_sorted",
|
||||||
"use_storage",
|
"use_storage",
|
||||||
"use_throttle_fn",
|
"use_throttle_fn",
|
||||||
"use_timestamp",
|
"use_timestamp",
|
||||||
|
"use_web_notification",
|
||||||
"use_websocket",
|
"use_websocket",
|
||||||
"use_webtransport",
|
"use_webtransport",
|
||||||
"use_window_focus",
|
"use_window_focus",
|
||||||
|
|
|
@ -15,17 +15,9 @@ fn Demo() -> impl IntoView {
|
||||||
on:input=move |event| set_input(event_target_value(&event))
|
on:input=move |event| set_input(event_target_value(&event))
|
||||||
placeholder="Try to type quickly, then stop..."
|
placeholder="Try to type quickly, then stop..."
|
||||||
/>
|
/>
|
||||||
<Note>
|
<Note>Delay is set to 1000ms for this demo.</Note>
|
||||||
Delay is set to 1000ms for this demo.
|
<p>Input signal: {input}</p>
|
||||||
</Note>
|
<p>Debounced signal: {debounced}</p>
|
||||||
<p>
|
|
||||||
Input signal:
|
|
||||||
{input}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Debounced signal:
|
|
||||||
{debounced}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,17 +15,9 @@ fn Demo() -> impl IntoView {
|
||||||
on:input=move |event| set_input(event_target_value(&event))
|
on:input=move |event| set_input(event_target_value(&event))
|
||||||
placeholder="Try to type quickly..."
|
placeholder="Try to type quickly..."
|
||||||
/>
|
/>
|
||||||
<Note>
|
<Note>Delay is set to 1000ms for this demo.</Note>
|
||||||
Delay is set to 1000ms for this demo.
|
<p>Input signal: {input}</p>
|
||||||
</Note>
|
<p>Throttled signal: {throttled}</p>
|
||||||
<p>
|
|
||||||
Input signal:
|
|
||||||
{input}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Throttled signal:
|
|
||||||
{throttled}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "start-axum"
|
name = "leptos-use-ssr"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
@ -15,13 +15,13 @@ leptos = { version = "0.5", features = ["nightly"] }
|
||||||
leptos_axum = { version = "0.5", optional = true }
|
leptos_axum = { version = "0.5", optional = true }
|
||||||
leptos_meta = { version = "0.5", features = ["nightly"] }
|
leptos_meta = { version = "0.5", features = ["nightly"] }
|
||||||
leptos_router = { version = "0.5", features = ["nightly"] }
|
leptos_router = { version = "0.5", features = ["nightly"] }
|
||||||
leptos-use = { path = "../..", features = ["storage"] }
|
leptos-use = { path = "../.." }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
simple_logger = "4"
|
simple_logger = "4"
|
||||||
tokio = { version = "1.25.0", optional = true }
|
tokio = { version = "1.25.0", optional = true }
|
||||||
tower = { version = "0.4.13", optional = true }
|
tower = { version = "0.4.13", optional = true }
|
||||||
tower-http = { version = "0.4.3", features = ["fs"], optional = true }
|
tower-http = { version = "0.4.3", features = ["fs"], optional = true }
|
||||||
wasm-bindgen = "=0.2.87"
|
wasm-bindgen = "0.2.88"
|
||||||
thiserror = "1.0.38"
|
thiserror = "1.0.38"
|
||||||
tracing = { version = "0.1.37", optional = true }
|
tracing = { version = "0.1.37", optional = true }
|
||||||
http = "0.2.8"
|
http = "0.2.8"
|
||||||
|
|
|
@ -3,10 +3,10 @@ use leptos::ev::{keypress, KeyboardEvent};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_meta::*;
|
use leptos_meta::*;
|
||||||
use leptos_router::*;
|
use leptos_router::*;
|
||||||
use leptos_use::storage::use_local_storage;
|
use leptos_use::storage::{use_local_storage, StringCodec};
|
||||||
use leptos_use::{
|
use leptos_use::{
|
||||||
use_debounce_fn, use_event_listener, use_intl_number_format, use_window,
|
use_color_mode, use_debounce_fn, use_event_listener, use_intl_number_format, use_timestamp,
|
||||||
UseIntlNumberFormatOptions,
|
use_window, ColorMode, UseColorModeReturn, UseIntlNumberFormatOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
@ -37,7 +37,7 @@ pub fn App() -> impl IntoView {
|
||||||
#[component]
|
#[component]
|
||||||
fn HomePage() -> impl IntoView {
|
fn HomePage() -> impl IntoView {
|
||||||
// Creates a reactive value to update the button
|
// Creates a reactive value to update the button
|
||||||
let (count, set_count, _) = use_local_storage("count-state", 0);
|
let (count, set_count, _) = use_local_storage::<i32, StringCodec>("count-state");
|
||||||
let on_click = move |_| set_count.update(|count| *count += 1);
|
let on_click = move |_| set_count.update(|count| *count += 1);
|
||||||
|
|
||||||
let nf = use_intl_number_format(
|
let nf = use_intl_number_format(
|
||||||
|
@ -63,25 +63,20 @@ fn HomePage() -> impl IntoView {
|
||||||
);
|
);
|
||||||
debounced_fn();
|
debounced_fn();
|
||||||
|
|
||||||
|
let UseColorModeReturn { mode, set_mode, .. } = use_color_mode();
|
||||||
|
|
||||||
|
let timestamp = use_timestamp();
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<h1>
|
<h1>Leptos-Use SSR Example</h1>
|
||||||
Leptos-Use SSR Example
|
<button on:click=on_click>Click Me: {count}</button>
|
||||||
</h1>
|
<p>Locale zh-Hans-CN-u-nu-hanidec: {zh_count}</p>
|
||||||
<button on:click=on_click>
|
<p>Press any key: {key}</p>
|
||||||
Click Me:
|
<p>Debounced called: {debounce_value}</p>
|
||||||
{count}
|
<p>Color mode: {move || format!("{:?}", mode.get())}</p>
|
||||||
</button>
|
<button on:click=move |_| set_mode.set(ColorMode::Light)>Change to Light</button>
|
||||||
<p>
|
<button on:click=move |_| set_mode.set(ColorMode::Dark)>Change to Dark</button>
|
||||||
Locale zh-Hans-CN-u-nu-hanidec:
|
<button on:click=move |_| set_mode.set(ColorMode::Auto)>Change to Auto</button>
|
||||||
{zh_count}
|
<p>{timestamp}</p>
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Press any key:
|
|
||||||
{key}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Debounced called:
|
|
||||||
{debounce_value}
|
|
||||||
</p>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ async fn main() {
|
||||||
use leptos::logging::log;
|
use leptos::logging::log;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_axum::{generate_route_list, LeptosRoutes};
|
use leptos_axum::{generate_route_list, LeptosRoutes};
|
||||||
use start_axum::app::*;
|
use leptos_use_ssr::app::*;
|
||||||
use start_axum::fileserv::file_and_error_handler;
|
use leptos_use_ssr::fileserv::file_and_error_handler;
|
||||||
|
|
||||||
simple_logger::init_with_level(log::Level::Debug).expect("couldn't initialize logging");
|
simple_logger::init_with_level(log::Level::Debug).expect("couldn't initialize logging");
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ async fn main() {
|
||||||
let conf = get_configuration(None).await.unwrap();
|
let conf = get_configuration(None).await.unwrap();
|
||||||
let leptos_options = conf.leptos_options;
|
let leptos_options = conf.leptos_options;
|
||||||
let addr = leptos_options.site_addr;
|
let addr = leptos_options.site_addr;
|
||||||
let routes = generate_route_list(|| view! { <App/> }).await;
|
let routes = generate_route_list(|| view! { <App/> });
|
||||||
|
|
||||||
// build our application with a route
|
// build our application with a route
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
body {
|
body {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
}
|
}
|
|
@ -19,11 +19,7 @@ fn Demo() -> impl IntoView {
|
||||||
<Note class="mb-3">"Select the inputs below to see the changes"</Note>
|
<Note class="mb-3">"Select the inputs below to see the changes"</Note>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-2">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-2">
|
||||||
<For
|
<For each=move || (1..7) key=|i| *i let:i>
|
||||||
each=move || (1..7)
|
|
||||||
key=|i| *i
|
|
||||||
let:i
|
|
||||||
>
|
|
||||||
<input type="text" data-id=i class="!my-0 !min-w-0" placeholder=i/>
|
<input type="text" data-id=i class="!my-0 !min-w-0" placeholder=i/>
|
||||||
</For>
|
</For>
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ leptos = { version = "0.5", features = ["nightly", "csr"] }
|
||||||
console_error_panic_hook = "0.1"
|
console_error_panic_hook = "0.1"
|
||||||
console_log = "1"
|
console_log = "1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
leptos-use = { path = "../..", features = ["docs", "storage"] }
|
leptos-use = { path = "../..", features = ["docs"] }
|
||||||
web-sys = "0.3"
|
web-sys = "0.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
16
examples/use_display_media/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "use_display_media"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
leptos = { version = "0.5", features = ["nightly", "csr"] }
|
||||||
|
console_error_panic_hook = "0.1"
|
||||||
|
console_log = "1"
|
||||||
|
log = "0.4"
|
||||||
|
leptos-use = { path = "../..", features = ["docs"] }
|
||||||
|
web-sys = "0.3"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
|
wasm-bindgen-test = "0.3.0"
|
23
examples/use_display_media/README.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
A simple example for `use_display_media`.
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
2
examples/use_display_media/Trunk.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[build]
|
||||||
|
public_url = "/demo/"
|
7
examples/use_display_media/index.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link data-trunk rel="css" href="style/output.css">
|
||||||
|
</head>
|
||||||
|
<body></body>
|
||||||
|
</html>
|
3
examples/use_display_media/input.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
2
examples/use_display_media/rust-toolchain.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
57
examples/use_display_media/src/main.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use leptos::*;
|
||||||
|
use leptos_use::docs::demo_or_body;
|
||||||
|
use leptos_use::{use_display_media, UseDisplayMediaReturn};
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn Demo() -> impl IntoView {
|
||||||
|
let video_ref = create_node_ref::<leptos::html::Video>();
|
||||||
|
|
||||||
|
let UseDisplayMediaReturn {
|
||||||
|
stream,
|
||||||
|
enabled,
|
||||||
|
set_enabled,
|
||||||
|
..
|
||||||
|
} = use_display_media();
|
||||||
|
|
||||||
|
create_effect(move |_| {
|
||||||
|
match stream.get() {
|
||||||
|
Some(Ok(s)) => {
|
||||||
|
video_ref.get().map(|v| v.set_src_object(Some(&s)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Some(Err(e)) => logging::error!("Failed to get media stream: {:?}", e),
|
||||||
|
None => logging::log!("No stream yet"),
|
||||||
|
}
|
||||||
|
|
||||||
|
video_ref.get().map(|v| v.set_src_object(None));
|
||||||
|
});
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div class="flex flex-col gap-4 text-center">
|
||||||
|
<div>
|
||||||
|
<button on:click=move |_| set_enabled(
|
||||||
|
!enabled(),
|
||||||
|
)>{move || if enabled() { "Stop" } else { "Start" }} sharing my screen</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<video
|
||||||
|
node_ref=video_ref
|
||||||
|
controls=false
|
||||||
|
autoplay=true
|
||||||
|
muted=true
|
||||||
|
class="h-96 w-auto"
|
||||||
|
></video>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
_ = console_log::init_with_level(log::Level::Debug);
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
|
mount_to(demo_or_body(), || {
|
||||||
|
view! { <Demo/> }
|
||||||
|
})
|
||||||
|
}
|
342
examples/use_display_media/style/output.css
Normal file
|
@ -0,0 +1,342 @@
|
||||||
|
[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: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
::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: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
.static {
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-96 {
|
||||||
|
height: 24rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-auto {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-col {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gap-4 {
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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));
|
||||||
|
}
|
||||||
|
}
|
15
examples/use_display_media/tailwind.config.js
Normal 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'),
|
||||||
|
],
|
||||||
|
}
|
|
@ -2,13 +2,16 @@ use leptos::html::Div;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_use::core::Position;
|
use leptos_use::core::Position;
|
||||||
use leptos_use::docs::demo_or_body;
|
use leptos_use::docs::demo_or_body;
|
||||||
use leptos_use::{use_draggable_with_options, UseDraggableOptions, UseDraggableReturn};
|
use leptos_use::{use_draggable_with_options, use_window, UseDraggableOptions, UseDraggableReturn};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn Demo() -> impl IntoView {
|
fn Demo() -> impl IntoView {
|
||||||
let el = create_node_ref::<Div>();
|
let el = create_node_ref::<Div>();
|
||||||
|
|
||||||
let inner_width = window().inner_width().unwrap().as_f64().unwrap();
|
let inner_width = use_window()
|
||||||
|
.as_ref()
|
||||||
|
.map(|w| w.inner_width().unwrap().as_f64().unwrap())
|
||||||
|
.unwrap_or(0.0);
|
||||||
|
|
||||||
let UseDraggableReturn { x, y, style, .. } = use_draggable_with_options(
|
let UseDraggableReturn { x, y, style, .. } = use_draggable_with_options(
|
||||||
el,
|
el,
|
||||||
|
@ -21,20 +24,14 @@ fn Demo() -> impl IntoView {
|
||||||
);
|
);
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<p class="italic op50 text-center">
|
<p class="italic op50 text-center">Check the floating box</p>
|
||||||
Check the floating box
|
|
||||||
</p>
|
|
||||||
<div
|
<div
|
||||||
node_ref=el
|
node_ref=el
|
||||||
class="px-4 py-2 border border-gray-400/30 rounded shadow hover:shadow-lg fixed bg-[--bg] select-none cursor-move z-24"
|
class="px-4 py-2 border border-gray-400/30 rounded shadow hover:shadow-lg fixed bg-[--bg] select-none cursor-move z-24"
|
||||||
style=move || format!("touch-action: none; {}", style())
|
style=move || format!("touch-action: none; {}", style())
|
||||||
>
|
>
|
||||||
"👋 Drag me!"
|
"👋 Drag me!"
|
||||||
<div class="text-sm opacity-50">
|
<div class="text-sm opacity-50">I am {move || x().round()} , {move || y().round()}</div>
|
||||||
I am
|
|
||||||
{move || x().round()},
|
|
||||||
{move || y().round()}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,45 +22,21 @@ fn Demo() -> impl IntoView {
|
||||||
view! {
|
view! {
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="w-full h-auto relative">
|
<div class="w-full h-auto relative">
|
||||||
<p>
|
<p>Drop files into dropZone</p>
|
||||||
Drop files into dropZone
|
|
||||||
</p>
|
|
||||||
<img width="64" src="use_drop_zone/demo/img/leptos-use-logo.svg" alt="Drop me"/>
|
<img width="64" src="use_drop_zone/demo/img/leptos-use-logo.svg" alt="Drop me"/>
|
||||||
<div
|
<div
|
||||||
node_ref=drop_zone_el
|
node_ref=drop_zone_el
|
||||||
class="flex flex-col w-full min-h-[200px] h-auto bg-gray-400/10 justify-center items-center pt-6"
|
class="flex flex-col w-full min-h-[200px] h-auto bg-gray-400/10 justify-center items-center pt-6"
|
||||||
>
|
>
|
||||||
<div>
|
<div>is_over_drop_zone: <BooleanDisplay value=is_over_drop_zone/></div>
|
||||||
is_over_drop_zone:
|
<div>dropped: <BooleanDisplay value=dropped/></div>
|
||||||
<BooleanDisplay value=is_over_drop_zone/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
dropped:
|
|
||||||
<BooleanDisplay value=dropped/>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-wrap justify-center items-center">
|
<div class="flex flex-wrap justify-center items-center">
|
||||||
<For
|
<For each=files key=|f| f.name() let:file>
|
||||||
each=files
|
|
||||||
key=|f| f.name()
|
|
||||||
let:file
|
|
||||||
>
|
|
||||||
<div class="w-200px bg-black-200/10 ma-2 pa-6">
|
<div class="w-200px bg-black-200/10 ma-2 pa-6">
|
||||||
<p>
|
<p>Name: {file.name()}</p>
|
||||||
Name:
|
<p>Size: {file.size()}</p>
|
||||||
{file.name()}
|
<p>Type: {file.type_()}</p>
|
||||||
</p>
|
<p>Last modified: {file.last_modified()}</p>
|
||||||
<p>
|
|
||||||
Size:
|
|
||||||
{file.size()}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Type:
|
|
||||||
{file.type_()}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Last modified:
|
|
||||||
{file.last_modified()}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</For>
|
</For>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[build]
|
|
||||||
rustflags = ["--cfg=web_sys_unstable_apis"]
|
|
|
@ -2,11 +2,11 @@ use leptos::ev::{click, keydown};
|
||||||
use leptos::html::A;
|
use leptos::html::A;
|
||||||
use leptos::logging::log;
|
use leptos::logging::log;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_use::use_event_listener;
|
use leptos_use::{use_event_listener, use_window};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn Demo() -> impl IntoView {
|
fn Demo() -> impl IntoView {
|
||||||
let _ = use_event_listener(window(), keydown, |evt| {
|
let _ = use_event_listener(use_window(), keydown, |evt| {
|
||||||
log!("window keydown: '{}'", evt.key());
|
log!("window keydown: '{}'", evt.key());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -27,20 +27,22 @@ fn Demo() -> impl IntoView {
|
||||||
heading: {:?},
|
heading: {:?},
|
||||||
speed: {:?},
|
speed: {:?},
|
||||||
}}"#,
|
}}"#,
|
||||||
coords.accuracy(), coords.latitude(), coords.longitude(), coords.altitude(),
|
coords.accuracy(),
|
||||||
coords.altitude_accuracy(), coords.heading(), coords.speed()
|
coords.latitude(),
|
||||||
|
coords.longitude(),
|
||||||
|
coords.altitude(),
|
||||||
|
coords.altitude_accuracy(),
|
||||||
|
coords.heading(),
|
||||||
|
coords.speed(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
"None".to_string()
|
"None".to_string()
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
,
|
,
|
||||||
located_at:
|
located_at: {located_at} ,
|
||||||
{located_at}
|
|
||||||
,
|
|
||||||
error:
|
error:
|
||||||
{move || if let Some(error) = error() { error.message() } else { "None".to_string() }}
|
{move || if let Some(error) = error() { error.message() } else { "None".to_string() }} ,
|
||||||
,
|
|
||||||
</pre>
|
</pre>
|
||||||
<button on:click=move |_| pause()>"Pause watch"</button>
|
<button on:click=move |_| pause()>"Pause watch"</button>
|
||||||
<button on:click=move |_| resume()>"Resume watch"</button>
|
<button on:click=move |_| resume()>"Resume watch"</button>
|
||||||
|
|
|
@ -14,20 +14,11 @@ fn Demo() -> impl IntoView {
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<Note class="mb-2">
|
<Note class="mb-2">
|
||||||
For demonstration purpose, the idle timeout is set to
|
For demonstration purpose, the idle timeout is set to <b>5s</b>
|
||||||
<b>
|
|
||||||
5s
|
|
||||||
</b>
|
|
||||||
in this demo (default 1min).
|
in this demo (default 1min).
|
||||||
</Note>
|
</Note>
|
||||||
<div class="mb-2">
|
<div class="mb-2">Idle: <BooleanDisplay value=idle/></div>
|
||||||
Idle:
|
<div>Inactive: <b>{idled_for} s</b></div>
|
||||||
<BooleanDisplay value=idle/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Inactive:
|
|
||||||
<b>{idled_for} s</b>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
examples/use_infinite_scroll/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "use_infinite_scroll"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
leptos = { version = "0.5", features = ["nightly", "csr"] }
|
||||||
|
console_error_panic_hook = "0.1"
|
||||||
|
console_log = "1"
|
||||||
|
log = "0.4"
|
||||||
|
leptos-use = { path = "../..", features = ["docs"] }
|
||||||
|
web-sys = "0.3"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
|
wasm-bindgen-test = "0.3.0"
|
23
examples/use_infinite_scroll/README.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
A simple example for `use_infinite_scroll`.
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
2
examples/use_infinite_scroll/Trunk.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[build]
|
||||||
|
public_url = "/demo/"
|
7
examples/use_infinite_scroll/index.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link data-trunk rel="css" href="style/output.css">
|
||||||
|
</head>
|
||||||
|
<body></body>
|
||||||
|
</html>
|
3
examples/use_infinite_scroll/input.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
2
examples/use_infinite_scroll/rust-toolchain.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
40
examples/use_infinite_scroll/src/main.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
use leptos::html::Div;
|
||||||
|
use leptos::*;
|
||||||
|
use leptos_use::docs::demo_or_body;
|
||||||
|
use leptos_use::{use_infinite_scroll_with_options, UseInfiniteScrollOptions};
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn Demo() -> impl IntoView {
|
||||||
|
let el = create_node_ref::<Div>();
|
||||||
|
|
||||||
|
let (data, set_data) = create_signal(vec![1, 2, 3, 4, 5, 6]);
|
||||||
|
|
||||||
|
let _ = use_infinite_scroll_with_options(
|
||||||
|
el,
|
||||||
|
move |_| async move {
|
||||||
|
let len = data.with_untracked(|d| d.len());
|
||||||
|
set_data.update(|data| *data = (1..len + 6).collect());
|
||||||
|
},
|
||||||
|
UseInfiniteScrollOptions::default().distance(10.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div
|
||||||
|
node_ref=el
|
||||||
|
class="flex flex-col gap-2 p-4 w-[300px] h-[300px] m-auto overflow-y-scroll bg-gray-500/5 rounded"
|
||||||
|
>
|
||||||
|
<For each=move || data.get() key=|i| *i let:item>
|
||||||
|
<div class="h-15 bg-gray-500/5 rounded p-3">{item}</div>
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
_ = console_log::init_with_level(log::Level::Debug);
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
|
mount_to(demo_or_body(), || {
|
||||||
|
view! { <Demo/> }
|
||||||
|
})
|
||||||
|
}
|
338
examples/use_infinite_scroll/style/output.css
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
[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");
|
||||||
|
}
|
||||||
|
|
||||||
|
[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: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
.static {
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-auto {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-\[300px\] {
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-\[300px\] {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-col {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gap-2 {
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overflow-y-scroll {
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounded {
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-500\/5 {
|
||||||
|
background-color: rgb(107 114 128 / 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-3 {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-4 {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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));
|
||||||
|
}
|
||||||
|
}
|
15
examples/use_infinite_scroll/tailwind.config.js
Normal 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'),
|
||||||
|
],
|
||||||
|
}
|
|
@ -42,8 +42,10 @@ fn Demo() -> impl IntoView {
|
||||||
r#" x: {}
|
r#" x: {}
|
||||||
y: {}
|
y: {}
|
||||||
source_type: {:?}
|
source_type: {:?}
|
||||||
"#, mouse_default.x.get(),
|
"#,
|
||||||
mouse_default.y.get(), mouse_default.source_type.get()
|
mouse_default.x.get(),
|
||||||
|
mouse_default.y.get(),
|
||||||
|
mouse_default.source_type.get(),
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -56,8 +58,10 @@ fn Demo() -> impl IntoView {
|
||||||
r#" x: {}
|
r#" x: {}
|
||||||
y: {}
|
y: {}
|
||||||
source_type: {:?}
|
source_type: {:?}
|
||||||
"#, mouse_with_extractor.x
|
"#,
|
||||||
.get(), mouse_with_extractor.y.get(), mouse_with_extractor.source_type.get()
|
mouse_with_extractor.x.get(),
|
||||||
|
mouse_with_extractor.y.get(),
|
||||||
|
mouse_with_extractor.source_type.get(),
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,7 @@ fn Demo() -> impl IntoView {
|
||||||
});
|
});
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div>
|
<div>Count: {count}</div>
|
||||||
Count:
|
|
||||||
{count}
|
|
||||||
</div>
|
|
||||||
<button on:click=move |_| pause() disabled=move || !is_active()>
|
<button on:click=move |_| pause() disabled=move || !is_active()>
|
||||||
Pause
|
Pause
|
||||||
</button>
|
</button>
|
||||||
|
|
16
examples/use_service_worker/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "use_service_worker"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
leptos = { version = "0.5", features = ["nightly", "csr"] }
|
||||||
|
console_error_panic_hook = "0.1"
|
||||||
|
console_log = "1"
|
||||||
|
log = "0.4"
|
||||||
|
leptos-use = { path = "../..", features = ["docs"] }
|
||||||
|
web-sys = "0.3"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
|
wasm-bindgen-test = "0.3.0"
|
23
examples/use_service_worker/README.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
A simple example for `use_service_worker`.
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
7
examples/use_service_worker/Trunk.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[build]
|
||||||
|
public_url = "/demo/"
|
||||||
|
|
||||||
|
[[hooks]]
|
||||||
|
stage = "post_build"
|
||||||
|
command = "bash"
|
||||||
|
command_arguments = ["post_build.sh"]
|
10
examples/use_service_worker/index.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="version" content="{{buildVersion}}">
|
||||||
|
<link data-trunk rel="css" href="style/output.css">
|
||||||
|
<link data-trunk rel="copy-file" href="manifest.json" />
|
||||||
|
<link data-trunk rel="copy-file" href="service-worker.js" />
|
||||||
|
</head>
|
||||||
|
<body></body>
|
||||||
|
</html>
|
3
examples/use_service_worker/input.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
54
examples/use_service_worker/manifest.json
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"name": "Demo",
|
||||||
|
"short_name": "Demo",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "./res/icon/maskable_icon_x48.png",
|
||||||
|
"sizes": "48x48",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "./res/icon/maskable_icon_x72.png",
|
||||||
|
"sizes": "72x72",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "./res/icon/maskable_icon_x96.png",
|
||||||
|
"sizes": "96x96",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "./res/icon/maskable_icon_x128.png",
|
||||||
|
"sizes": "128x128",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "./res/icon/maskable_icon_x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "./res/icon/maskable_icon_x384.png",
|
||||||
|
"sizes": "384x384",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "./res/icon/maskable_icon_x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lang": "en-US",
|
||||||
|
"id": "/demo/",
|
||||||
|
"start_url": "/demo/",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#e52320",
|
||||||
|
"theme_color": "#e52320"
|
||||||
|
}
|
56
examples/use_service_worker/post_build.sh
Executable file
|
@ -0,0 +1,56 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
appName="use_service_worker"
|
||||||
|
stylePrefix="output"
|
||||||
|
styleFormat="css"
|
||||||
|
|
||||||
|
# Extract build version
|
||||||
|
indexJsFile=$(find ./dist/.stage -iname "${appName}-*.js")
|
||||||
|
echo "Extracting build version from file: ${indexJsFile}"
|
||||||
|
regex="(.*)${appName}-(.*).js"
|
||||||
|
_src="${indexJsFile}"
|
||||||
|
while [[ "${_src}" =~ ${regex} ]]; do
|
||||||
|
buildVersion="${BASH_REMATCH[2]}"
|
||||||
|
_i=${#BASH_REMATCH}
|
||||||
|
_src=${_src:_i}
|
||||||
|
done
|
||||||
|
if [ -z "${buildVersion}" ]; then
|
||||||
|
echo "Could not determine build version!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Build-Version is: ${buildVersion}"
|
||||||
|
|
||||||
|
# Replace placeholder in service-worker.js
|
||||||
|
serviceWorkerJsFile=$(find ./dist/.stage -iname "service-worker.js")
|
||||||
|
echo "Replacing {{buildVersion}} placeholder in: ${serviceWorkerJsFile}"
|
||||||
|
sed "s/{{buildVersion}}/${buildVersion}/g" "${serviceWorkerJsFile}" > "${serviceWorkerJsFile}.modified"
|
||||||
|
mv -f "${serviceWorkerJsFile}.modified" "${serviceWorkerJsFile}"
|
||||||
|
|
||||||
|
# Replace placeholder in index.html
|
||||||
|
indexHtmlFile=$(find ./dist/.stage -iname "index.html")
|
||||||
|
echo "Replacing {{buildVersion}} placeholder in: ${indexHtmlFile}"
|
||||||
|
sed "s/{{buildVersion}}/${buildVersion}/g" "${indexHtmlFile}" > "${indexHtmlFile}.modified"
|
||||||
|
mv -f "${indexHtmlFile}.modified" "${indexHtmlFile}"
|
||||||
|
|
||||||
|
# Extract CSS build version
|
||||||
|
indexJsFile=$(find ./dist/.stage -iname "${stylePrefix}-*.${styleFormat}")
|
||||||
|
echo "Extracting style build version from file: ${indexJsFile}"
|
||||||
|
regex="(.*)${stylePrefix}-(.*).${styleFormat}"
|
||||||
|
_src="${indexJsFile}"
|
||||||
|
while [[ "${_src}" =~ ${regex} ]]; do
|
||||||
|
cssBuildVersion="${BASH_REMATCH[2]}"
|
||||||
|
_i=${#BASH_REMATCH}
|
||||||
|
_src=${_src:_i}
|
||||||
|
done
|
||||||
|
if [ -z "${cssBuildVersion}" ]; then
|
||||||
|
echo "Could not determine style build version!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "CSS Build-Version is: ${cssBuildVersion}"
|
||||||
|
|
||||||
|
# Replace placeholder in service-worker.js
|
||||||
|
serviceWorkerJsFile=$(find ./dist/.stage -iname "service-worker.js")
|
||||||
|
echo "Replacing {{cssBuildVersion}} placeholder in: ${serviceWorkerJsFile}"
|
||||||
|
sed "s/{{cssBuildVersion}}/${cssBuildVersion}/g" "${serviceWorkerJsFile}" > "${serviceWorkerJsFile}.modified"
|
||||||
|
mv -f "${serviceWorkerJsFile}.modified" "${serviceWorkerJsFile}"
|
BIN
examples/use_service_worker/res/icon/maskable_icon_x128.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
examples/use_service_worker/res/icon/maskable_icon_x192.png
Normal file
After Width: | Height: | Size: 6 KiB |
BIN
examples/use_service_worker/res/icon/maskable_icon_x384.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
examples/use_service_worker/res/icon/maskable_icon_x48.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/use_service_worker/res/icon/maskable_icon_x512.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
examples/use_service_worker/res/icon/maskable_icon_x72.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
examples/use_service_worker/res/icon/maskable_icon_x96.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
examples/use_service_worker/res/icon/pwa.png
Normal file
After Width: | Height: | Size: 49 KiB |
9
examples/use_service_worker/res/icon/pwa.svg
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="1952" height="734.935" viewBox="0 0 1952.00 734.93" enable-background="new 0 0 1952.00 734.93" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path fill="#3D3D3D" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 1436.62,603.304L 1493.01,460.705L 1655.83,460.705L 1578.56,244.39L 1675.2,0.000528336L 1952,734.933L 1747.87,734.933L 1700.57,603.304L 1436.62,603.304 Z "/>
|
||||||
|
<path fill="#5A0FC8" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 1262.47,734.935L 1558.79,0.00156593L 1362.34,0.0025425L 1159.64,474.933L 1015.5,0.00351906L 864.499,0.00351906L 709.731,474.933L 600.585,258.517L 501.812,562.819L 602.096,734.935L 795.427,734.935L 935.284,309.025L 1068.63,734.935L 1262.47,734.935 Z "/>
|
||||||
|
<path fill="#3D3D3D" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 186.476,482.643L 307.479,482.643C 344.133,482.643 376.772,478.552 405.396,470.37L 436.689,373.962L 524.148,104.516C 517.484,93.9535 509.876,83.9667 501.324,74.5569C 456.419,24.852 390.719,0.000406265 304.222,0.000406265L -3.8147e-006,0.000406265L -3.8147e-006,734.933L 186.476,734.933L 186.476,482.643 Z M 346.642,169.079C 364.182,186.732 372.951,210.355 372.951,239.95C 372.951,269.772 365.238,293.424 349.813,310.906C 332.903,330.331 301.766,340.043 256.404,340.043L 186.476,340.043L 186.476,142.598L 256.918,142.598C 299.195,142.598 329.103,151.425 346.642,169.079 Z "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
2
examples/use_service_worker/rust-toolchain.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
82
examples/use_service_worker/service-worker.js
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
var buildVersion = "{{buildVersion}}"
|
||||||
|
var cssBuildVersion = "{{cssBuildVersion}}"
|
||||||
|
var cacheName = "demo";
|
||||||
|
var filesToCache = [
|
||||||
|
'./',
|
||||||
|
'./index.html',
|
||||||
|
'./manifest.json',
|
||||||
|
'./use_service_worker-' + buildVersion + '_bg.wasm',
|
||||||
|
'./use_service_worker-' + buildVersion + '.js',
|
||||||
|
'./output-' + cssBuildVersion + '.css',
|
||||||
|
'./res/icon/maskable_icon_x48.png',
|
||||||
|
'./res/icon/maskable_icon_x72.png',
|
||||||
|
'./res/icon/maskable_icon_x96.png',
|
||||||
|
'./res/icon/maskable_icon_x128.png',
|
||||||
|
'./res/icon/maskable_icon_x192.png',
|
||||||
|
'./res/icon/maskable_icon_x384.png',
|
||||||
|
'./res/icon/maskable_icon_x512.png',
|
||||||
|
|
||||||
|
// TODO: Add files you want the SW to cache. Rename entries to match your build output!
|
||||||
|
];
|
||||||
|
|
||||||
|
/* Start the service worker and cache all of the app's content */
|
||||||
|
self.addEventListener('install', function (event) {
|
||||||
|
console.log("Installing service-worker for build", buildVersion);
|
||||||
|
const preCache = async () => {
|
||||||
|
get_cache().then(function (cache) {
|
||||||
|
// We clear the whole cache, as we do not know which resources were updated!
|
||||||
|
cache.keys().then(function (requests) {
|
||||||
|
for (let request of requests) {
|
||||||
|
cache.delete(request);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cache.addAll(filesToCache.map(url => new Request(url, { credentials: 'same-origin' })));
|
||||||
|
})
|
||||||
|
};
|
||||||
|
event.waitUntil(preCache);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('message', function (messageEvent) {
|
||||||
|
if (messageEvent.data === "skipWaiting") {
|
||||||
|
console.log("Service-worker received skipWaiting event", buildVersion);
|
||||||
|
self.skipWaiting();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', function (e) {
|
||||||
|
e.respondWith(cache_then_network(e.request));
|
||||||
|
});
|
||||||
|
|
||||||
|
async function get_cache() {
|
||||||
|
return caches.open(cacheName);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cache_then_network(request) {
|
||||||
|
const cache = await get_cache();
|
||||||
|
return cache.match(request).then(
|
||||||
|
(cache_response) => {
|
||||||
|
if (!cache_response) {
|
||||||
|
return fetch_from_network(request, cache);
|
||||||
|
} else {
|
||||||
|
return cache_response;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(reason) => {
|
||||||
|
return fetch_from_network(request, cache);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetch_from_network(request, cache) {
|
||||||
|
return fetch(request).then(
|
||||||
|
(net_response) => {
|
||||||
|
return net_response;
|
||||||
|
},
|
||||||
|
(reason) => {
|
||||||
|
console.error("Network fetch rejected. Falling back to ./index.html. Reason: ", reason);
|
||||||
|
return cache.match("./index.html").then(function (cache_root_response) {
|
||||||
|
return cache_root_response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
59
examples/use_service_worker/src/main.rs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
use leptos::*;
|
||||||
|
use leptos_use::docs::{demo_or_body, BooleanDisplay};
|
||||||
|
use leptos_use::{use_document, use_service_worker, UseServiceWorkerReturn};
|
||||||
|
use web_sys::HtmlMetaElement;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn Demo() -> impl IntoView {
|
||||||
|
let build = load_meta_element("version")
|
||||||
|
.map(|meta| meta.content())
|
||||||
|
.expect("'version' meta element");
|
||||||
|
|
||||||
|
let UseServiceWorkerReturn {
|
||||||
|
registration,
|
||||||
|
installing,
|
||||||
|
waiting,
|
||||||
|
active,
|
||||||
|
skip_waiting,
|
||||||
|
..
|
||||||
|
} = use_service_worker();
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<p>"Current build: " {build}</p>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<p>"registration: " {move || format!("{:#?}", registration())}</p>
|
||||||
|
<p>"installing: " <BooleanDisplay value=installing/></p>
|
||||||
|
<p>"waiting: " <BooleanDisplay value=waiting/></p>
|
||||||
|
<p>"active: " <BooleanDisplay value=active/></p>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<button on:click=move |_| { skip_waiting() }>"Send skip_waiting event"</button>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
_ = console_log::init_with_level(log::Level::Debug);
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
|
mount_to(demo_or_body(), || {
|
||||||
|
view! { <Demo/> }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_meta_element(name: &str) -> Result<web_sys::HtmlMetaElement, String> {
|
||||||
|
use wasm_bindgen::JsCast;
|
||||||
|
if let Some(document) = &*use_document() {
|
||||||
|
document
|
||||||
|
.query_selector(format!("meta[name=\"{name}\"]").as_str())
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
.ok_or_else(|| format!("Unable to find meta element with name '{name}'."))?
|
||||||
|
.dyn_into::<HtmlMetaElement>()
|
||||||
|
.map_err(|err| format!("Unable to cast element to HtmlMetaElement. Err: '{err:?}'."))
|
||||||
|
} else {
|
||||||
|
Err("Unable to find document.".into())
|
||||||
|
}
|
||||||
|
}
|
294
examples/use_service_worker/style/output.css
Normal file
|
@ -0,0 +1,294 @@
|
||||||
|
[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");
|
||||||
|
}
|
||||||
|
|
||||||
|
[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: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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));
|
||||||
|
}
|
||||||
|
}
|
15
examples/use_service_worker/tailwind.config.js
Normal 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'),
|
||||||
|
],
|
||||||
|
}
|
16
examples/use_sorted/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "use_sorted"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
leptos = { version = "0.5", features = ["nightly", "csr"] }
|
||||||
|
console_error_panic_hook = "0.1"
|
||||||
|
console_log = "1"
|
||||||
|
log = "0.4"
|
||||||
|
leptos-use = { path = "../..", features = ["docs"] }
|
||||||
|
web-sys = "0.3"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
|
wasm-bindgen-test = "0.3.0"
|
23
examples/use_sorted/README.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
A simple example for `use_sorted`.
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
2
examples/use_sorted/Trunk.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[build]
|
||||||
|
public_url = "/demo/"
|
7
examples/use_sorted/index.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link data-trunk rel="css" href="style/output.css">
|
||||||
|
</head>
|
||||||
|
<body></body>
|
||||||
|
</html>
|
3
examples/use_sorted/input.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
2
examples/use_sorted/rust-toolchain.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
44
examples/use_sorted/src/main.rs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
use leptos::*;
|
||||||
|
use leptos_use::docs::demo_or_body;
|
||||||
|
use leptos_use::use_sorted;
|
||||||
|
|
||||||
|
fn string_list(list: &[i32]) -> String {
|
||||||
|
list.into_iter()
|
||||||
|
.map(i32::to_string)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(",")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn Demo() -> impl IntoView {
|
||||||
|
let (list, set_list) = create_signal::<Vec<i32>>(vec![4, 2, 67, 34, 76, 22, 2, 4, 65, 23]);
|
||||||
|
|
||||||
|
let sorted: Signal<Vec<i32>> = use_sorted(list);
|
||||||
|
|
||||||
|
let on_input = move |evt| {
|
||||||
|
set_list.update(|list| {
|
||||||
|
*list = event_target_value(&evt)
|
||||||
|
.split(",")
|
||||||
|
.map(|n| n.parse::<i32>().unwrap_or(0))
|
||||||
|
.collect::<Vec<i32>>()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let input_text = move || string_list(&list());
|
||||||
|
let sorted_text = move || string_list(&sorted());
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div>Input:</div>
|
||||||
|
<input prop:value=input_text on:input=on_input type="text"/>
|
||||||
|
<p>Output: {sorted_text}</p>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
_ = console_log::init_with_level(log::Level::Debug);
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
|
mount_to(demo_or_body(), || {
|
||||||
|
view! { <Demo/> }
|
||||||
|
})
|
||||||
|
}
|
289
examples/use_sorted/style/output.css
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
15
examples/use_sorted/tailwind.config.js
Normal 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'),
|
||||||
|
],
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ leptos = { version = "0.5", features = ["nightly", "csr"] }
|
||||||
console_error_panic_hook = "0.1"
|
console_error_panic_hook = "0.1"
|
||||||
console_log = "1"
|
console_log = "1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
leptos-use = { path = "../..", features = ["docs", "storage"] }
|
leptos-use = { path = "../..", features = ["docs", "prost", "serde"] }
|
||||||
web-sys = "0.3"
|
web-sys = "0.3"
|
||||||
serde = "1.0.163"
|
serde = "1.0.163"
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,31 @@
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_use::docs::{demo_or_body, Note};
|
use leptos_use::docs::{demo_or_body, Note};
|
||||||
use leptos_use::storage::use_storage;
|
use leptos_use::storage::{use_local_storage, JsonCodec};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||||
pub struct BananaState {
|
pub struct BananaState {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub color: String,
|
pub wearing: String,
|
||||||
pub size: String,
|
pub descending: String,
|
||||||
pub count: u32,
|
pub count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for BananaState {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
name: "Bananas".to_string(),
|
||||||
|
wearing: "pyjamas".to_string(),
|
||||||
|
descending: "stairs".to_string(),
|
||||||
|
count: 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn Demo() -> impl IntoView {
|
fn Demo() -> impl IntoView {
|
||||||
let the_default = BananaState {
|
let (state, set_state, reset) = use_local_storage::<BananaState, JsonCodec>("banana-state");
|
||||||
name: "Banana".to_string(),
|
let (state2, _, _) = use_local_storage::<BananaState, JsonCodec>("banana-state");
|
||||||
color: "Yellow".to_string(),
|
|
||||||
size: "Medium".to_string(),
|
|
||||||
count: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
let (state, set_state, _) = use_storage("banana-state", the_default.clone());
|
|
||||||
|
|
||||||
let (state2, ..) = use_storage("banana-state", the_default.clone());
|
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<input
|
<input
|
||||||
|
@ -33,14 +36,14 @@ fn Demo() -> impl IntoView {
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
class="block"
|
class="block"
|
||||||
prop:value=move || state.get().color
|
prop:value=move || state.get().wearing
|
||||||
on:input=move |e| set_state.update(|s| s.color = event_target_value(&e))
|
on:input=move |e| set_state.update(|s| s.wearing = event_target_value(&e))
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
class="block"
|
class="block"
|
||||||
prop:value=move || state.get().size
|
prop:value=move || state.get().descending
|
||||||
on:input=move |e| set_state.update(|s| s.size = event_target_value(&e))
|
on:input=move |e| set_state.update(|s| s.descending = event_target_value(&e))
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
|
@ -57,6 +60,7 @@ fn Demo() -> impl IntoView {
|
||||||
step="1"
|
step="1"
|
||||||
max="1000"
|
max="1000"
|
||||||
/>
|
/>
|
||||||
|
<button on:click=move |_| reset()>"Delete from storage"</button>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
"Second " <b>
|
"Second " <b>
|
||||||
|
@ -67,7 +71,9 @@ fn Demo() -> impl IntoView {
|
||||||
<pre>{move || format!("{:#?}", state2.get())}</pre>
|
<pre>{move || format!("{:#?}", state2.get())}</pre>
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
"The values are persistent. When you reload the page the values will be the same."
|
"The values are persistent. When you reload the page or "
|
||||||
|
<a href="#" target="_blank">"open a second window"</a>
|
||||||
|
", the values will be the same."
|
||||||
</Note>
|
</Note>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,7 @@ use leptos_use::use_timestamp;
|
||||||
fn Demo() -> impl IntoView {
|
fn Demo() -> impl IntoView {
|
||||||
let timestamp = use_timestamp();
|
let timestamp = use_timestamp();
|
||||||
|
|
||||||
view! {
|
view! { <div>Timestamp: {timestamp}</div> }
|
||||||
<div>
|
|
||||||
Timestamp:
|
|
||||||
{timestamp}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
16
examples/use_web_notification/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "use_web_notification"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
leptos = { version = "0.5", features = ["nightly", "csr"] }
|
||||||
|
console_error_panic_hook = "0.1"
|
||||||
|
console_log = "1"
|
||||||
|
log = "0.4"
|
||||||
|
leptos-use = { path = "../..", features = ["docs"] }
|
||||||
|
web-sys = "0.3"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
|
wasm-bindgen-test = "0.3.0"
|
23
examples/use_web_notification/README.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
A simple example for `use_web_notification`.
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
2
examples/use_web_notification/Trunk.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[build]
|
||||||
|
public_url = "/demo/"
|
7
examples/use_web_notification/index.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link data-trunk rel="css" href="style/output.css">
|
||||||
|
</head>
|
||||||
|
<body></body>
|
||||||
|
</html>
|
3
examples/use_web_notification/input.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
2
examples/use_web_notification/rust-toolchain.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
52
examples/use_web_notification/src/main.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
use leptos::*;
|
||||||
|
use leptos_use::docs::{demo_or_body, BooleanDisplay};
|
||||||
|
use leptos_use::{
|
||||||
|
use_web_notification_with_options, NotificationDirection, ShowOptions,
|
||||||
|
UseWebNotificationOptions, UseWebNotificationReturn,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn Demo() -> impl IntoView {
|
||||||
|
let UseWebNotificationReturn {
|
||||||
|
is_supported, show, ..
|
||||||
|
} = use_web_notification_with_options(
|
||||||
|
UseWebNotificationOptions::default()
|
||||||
|
.title("Hello World from leptos-use")
|
||||||
|
.direction(NotificationDirection::Auto)
|
||||||
|
.language("en")
|
||||||
|
// .renotify(true)
|
||||||
|
.tag("test"),
|
||||||
|
);
|
||||||
|
|
||||||
|
let show = move || {
|
||||||
|
show(ShowOptions::default());
|
||||||
|
};
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div>
|
||||||
|
<p>Supported: <BooleanDisplay value=is_supported/></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Show
|
||||||
|
when=is_supported
|
||||||
|
fallback=|| {
|
||||||
|
view! { <div>The Notification Web API is not supported in your browser.</div> }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
|
||||||
|
<button on:click={
|
||||||
|
let show = show.clone();
|
||||||
|
move |_| show()
|
||||||
|
}>Show Notification</button>
|
||||||
|
</Show>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
_ = console_log::init_with_level(log::Level::Debug);
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
|
mount_to(demo_or_body(), || {
|
||||||
|
view! { <Demo/> }
|
||||||
|
})
|
||||||
|
}
|
289
examples/use_web_notification/style/output.css
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
15
examples/use_web_notification/tailwind.config.js
Normal 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'),
|
||||||
|
],
|
||||||
|
}
|
24
examples/use_webtransport_with_server/server/cert.crt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEEDCCAvigAwIBAgIUM7q41K5+wQF+tIUZVVjHRLVP8WYwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwgZAxCzAJBgNVBAYTAkVTMREwDwYDVQQIDAhUZW5lcmlmZTETMBEGA1UEBwwK
|
||||||
|
R3JhbmFkaWxsYTETMBEGA1UECgwKU3lucGhvbnl0ZTEcMBoGA1UEAwwTUm9vdCBD
|
||||||
|
ZXJ0IEF1dGhvcml0eTEmMCQGCSqGSIb3DQEJARYXbWFjY2VzY2hAc3lucGhvbnl0
|
||||||
|
ZS5jb20wHhcNMjMwOTE3MjI0NDExWhcNMjUxMjIwMjI0NDExWjCBgDELMAkGA1UE
|
||||||
|
BhMCRVMxETAPBgNVBAgMCFRlbmVyaWZlMRMwEQYDVQQHDApHcmFuYWRpbGxhMRMw
|
||||||
|
EQYDVQQKDApTeW5waG9ueXRlMQwwCgYDVQQDDANCbGExJjAkBgkqhkiG9w0BCQEW
|
||||||
|
F21hY2Nlc2NoQHN5bnBob255dGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||||
|
MIIBCgKCAQEAvDj30GptcuZcTnYZxSULMQqU1csp/54kRM7Emdpsf21es16rRoUO
|
||||||
|
xXfvxGnbGgWb6F2lAG8Gmv7YoliOAliPpFTrmquGhAO/4pMGPsEWVa35/jPIZEpl
|
||||||
|
oi3p9ouoDi3LIqgNFE3BlnW0Xf3ThnMw3P9pndA5+2NnJDKYKHp0tPZwGph6qgOf
|
||||||
|
2nqp0UXZ9U5AqUdjxh7/rAec8NDmAz6TXPSDT2Tc7Xb5bUfWPf2IjxZvcdttjhlf
|
||||||
|
8CyYVZPGWSWClc7R0yaydubnOH0uOYdQhwwQdGnYA+hca+esWoT8IejmD3oup0KE
|
||||||
|
tRFFg7oCmD7H4v/r3jZb5XAvyqXTzzxwdwIDAQABo3AwbjAfBgNVHSMEGDAWgBS1
|
||||||
|
MicRfZi+HsV8udux5h1T1EWDZTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE8DAUBgNV
|
||||||
|
HREEDTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFJFXRB1VgjrDhxU287mxGisg+MzV
|
||||||
|
MA0GCSqGSIb3DQEBCwUAA4IBAQCXBIKF8ylDhq80OxAe1EaRZKEwVKoVtoXEQLQy
|
||||||
|
0voiIx00AjfMjUC16+8rAhDDLL5PWi56zonH/2hCfJyVec/oF059MghzCPAALv1G
|
||||||
|
3koaU+4Tp9S17zLbmlExQN72LOGYs9hswWdrtqpWPeeLxzoYn+LMxANVzhBMz66y
|
||||||
|
KwnwP/BFyeVKYIVTOZfH67j3PYCLizHCOoPOh0m9/ub8QIgFzKhYl4tWKRzJBug1
|
||||||
|
wGYoMIbBasU9N4UoeeWC4OP6YA9MDmpy5D2xFDM0DKW7qYP/KsQSAgPbKKd0a//S
|
||||||
|
xKv6DFpBeEhh6+d+MAHBYu+m7nTHeO90PCtVSohtTH7fSk0r
|
||||||
|
-----END CERTIFICATE-----
|
28
examples/use_webtransport_with_server/server/cert.key
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC8OPfQam1y5lxO
|
||||||
|
dhnFJQsxCpTVyyn/niREzsSZ2mx/bV6zXqtGhQ7Fd+/EadsaBZvoXaUAbwaa/tii
|
||||||
|
WI4CWI+kVOuaq4aEA7/ikwY+wRZVrfn+M8hkSmWiLen2i6gOLcsiqA0UTcGWdbRd
|
||||||
|
/dOGczDc/2md0Dn7Y2ckMpgoenS09nAamHqqA5/aeqnRRdn1TkCpR2PGHv+sB5zw
|
||||||
|
0OYDPpNc9INPZNztdvltR9Y9/YiPFm9x222OGV/wLJhVk8ZZJYKVztHTJrJ25uc4
|
||||||
|
fS45h1CHDBB0adgD6Fxr56xahPwh6OYPei6nQoS1EUWDugKYPsfi/+veNlvlcC/K
|
||||||
|
pdPPPHB3AgMBAAECggEADj4FSmjzNTGHJIy9MHS4HxLc5jyERgpSVj6LE9U6Rn4h
|
||||||
|
H1N3hFOHJZwIsYUNBjAMdw228Yx1JH9KJyaqQDUxUU73sPFvsUeTWnKjk1YK+Zq7
|
||||||
|
gueqLySOAjKVNImmwsPmTg4HR1UG4/quFjqhqdfHh8Fv3XgnGwWPhWaqqs1xTUwD
|
||||||
|
DgatljfrjTt8Nx2RHtwgUQ8ZrAgrb4arQk6WjGqN4smg7n0oszmwmpRtB+9m6aNw
|
||||||
|
CXULF+qxFSWVb/5fiV4B0D2US7aNHNcrSG4yg3FYgW1HsGdFhGhnUCAGpvrzenmm
|
||||||
|
7bkijuQgkmcpd0+KMXM7rcayUCcW6wt2/ZTVL0BJ+QKBgQD09Vuymz5SBAkwbjPB
|
||||||
|
YD4JJFl8ffhW4JiXRa2q5+BwKjesk2nBLUncC8Y+lL9T8tp4+NGGujKjd/EcM03r
|
||||||
|
viq+Bh3ZZqo0WwFAQscQ9iHncf783JxSfkx60LrKpaSd7GQkvuifRizkZR0z3bde
|
||||||
|
pMcueNtGTE3hQGxSvZYWHPCqWwKBgQDEtOs8k6yxDL/DfK/ldAL+AFbQ3tj+Zt22
|
||||||
|
r6MBi/PuyGsvasXSyX/6n92a8kSC67dOwQyOwquTb/1nTMTErctD2gIyo8hjS9cw
|
||||||
|
+DdUkgaUxG0xcpWeHHTRHGwu70hqu0SRBw3AURj1NI4eohYt/gcoNEfZaFSgUprB
|
||||||
|
sDNFGZ8VFQKBgDcpQVr5BpGlgwQ67MCxEYcxfk1AeLnnnbUC5dbEnI/lkd/02i28
|
||||||
|
KxO4Ow5ApM0ctQHk1hoGt/yDt/Hnw7ZAfpOIARTBv7ZGgAOehgFVy9C4pPkAHNue
|
||||||
|
wU4uzsFvh6BgaTS1IOEtBlLwSiEx3mcbqBbY9FfiOu9seHgxZSjZn4BdAoGALNLl
|
||||||
|
P9qO4ZF8KTnCg1DaVbMSFWqSm/Yo07ZWOMYBggodkqKMDappBV1kjChkwEiibsnC
|
||||||
|
6M0nd+NvJRjzRbYsuXt2QL/dq/LeSIRnZ1gXM9NG5puryGnHnNcTN+bC479ksn+e
|
||||||
|
/JH+U/Hz6LsavsRCMUEoljwV/KqWJUjXhgl+nLkCgYA4D8lWtsMkKMh4d6iA4tR3
|
||||||
|
93VdUYZG+nwJ0Cj6fgXCapWZ/ncRXlrUzD616W4poT+R9qG1dhNnUiaw81NsbjFj
|
||||||
|
YK/sBHRTPnm8LbTGZ9WUOPcdQ+T2VNj0DLekiZ6RICazGZLTnj/RaJmJRb1w+ej1
|
||||||
|
yNaquFcA6XZ3WLDYrrcvRA==
|
||||||
|
-----END PRIVATE KEY-----
|