finished new functions and release

This commit is contained in:
Maccesch 2023-06-24 01:12:43 +01:00
parent fadfcab1c1
commit 4999313f32
15 changed files with 116 additions and 242 deletions

View file

@ -1,3 +1,3 @@
[build] [unstable]
rustflags = ["--cfg=web_sys_unstable_apis"] rustflags = ["--cfg=web_sys_unstable_apis"]
rustdocflags = ["--cfg=web_sys_unstable_apis"] rustdocflags = ["--cfg=web_sys_unstable_apis"]

View file

@ -3,6 +3,19 @@
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.3.3] - 2023-06-24
### New Functions 🚀
- `use_color_mode`
- `use_cycle_list`
- `use_active_element`
### Changes 🔥
- You can now use this crate with the `stable` toolchain (thanks @lpotthast)
- Set leptos dependency to `default-features = false` in order to enable SSR.
## [0.3.2] - 2023-06-17 ## [0.3.2] - 2023-06-17
### New Functions 🚀 ### New Functions 🚀

View file

@ -1,6 +1,6 @@
[package] [package]
name = "leptos-use" name = "leptos-use"
version = "0.3.2" version = "0.3.3"
edition = "2021" edition = "2021"
authors = ["Marc-Stefan Cassola"] authors = ["Marc-Stefan Cassola"]
categories = ["gui", "web-programming"] categories = ["gui", "web-programming"]
@ -16,7 +16,7 @@ homepage = "https://leptos-use.rs"
leptos = { version = "0.3", default-features = false } leptos = { version = "0.3", default-features = false }
wasm-bindgen = "0.2" wasm-bindgen = "0.2"
js-sys = "0.3" js-sys = "0.3"
default-struct-builder = { path = "../default-struct-builder" } default-struct-builder = "0.3"
num = { version = "0.4", optional = true } num = { version = "0.4", optional = true }
serde = { version = "1", optional = true } serde = { version = "1", optional = true }
serde_json = { version = "1", optional = true } serde_json = { version = "1", optional = true }
@ -64,7 +64,10 @@ math = ["num"]
storage = ["serde", "serde_json", "web-sys/StorageEvent"] storage = ["serde", "serde_json", "web-sys/StorageEvent"]
stable = ["leptos/stable"] stable = ["leptos/stable"]
[package.metadata."docs.rs"] [package.metadata.docs.rs]
all-features = true all-features = true
rustdoc-args = ["--cfg=web_sys_unstable_apis"] rustdoc-args = ["--cfg=web_sys_unstable_apis"]
rustc-args = ["--cfg=web_sys_unstable_apis"] rustc-args = ["--cfg=web_sys_unstable_apis"]
[dev-dependencies]
leptos = "0.3"

View file

@ -12,7 +12,7 @@
<p align="center"> <p align="center">
<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"><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/-35%20functions-%23EF3939" alt="35 Functions" /></a> <a href="https://leptos-use.rs"><img src="https://img.shields.io/badge/-38%20functions-%23EF3939" alt="38 Functions" /></a>
</p> </p>
<br/> <br/>

View file

@ -64,6 +64,9 @@ def main():
print(line) print(line)
elif re.match(r"^//\s?#\[doc\(cfg\(.+?\)\)]", stripped_line):
pass
elif doc_comment_started: elif doc_comment_started:
initial_doc_finished = True initial_doc_finished = True

View file

@ -11,6 +11,6 @@
<p> <p>
<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="./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/-35%20functions-%23EF3939" alt="35 Functions" /></a> <a href="./functions.html"><img src="https://img.shields.io/badge/-38%20functions-%23EF3939" alt="38 Functions" /></a>
</p> </p>
</div> </div>

View file

@ -1,17 +1,26 @@
use leptos::html::Col; use leptos::html::html;
use leptos::*; use leptos::*;
use leptos_use::docs::demo_or_body; use leptos_use::docs::{demo_or_body, Note};
use leptos_use::{ use leptos_use::{
use_color_mode_with_options, use_cycle_list, ColorMode, UseColorModeOptions, use_color_mode_with_options, use_cycle_list_with_options, ColorMode, UseColorModeOptions,
UseColorModeReturn, UseCycleListReturn, UseColorModeReturn, UseCycleListOptions, UseCycleListReturn,
}; };
#[component] #[component]
fn Demo(cx: Scope) -> impl IntoView { fn Demo(cx: Scope) -> impl IntoView {
let UseColorModeReturn { mode, set_mode, .. } = let UseColorModeReturn { mode, set_mode, .. } = use_color_mode_with_options(
use_color_mode_with_options(cx, UseColorModeOptions::default()); cx,
UseColorModeOptions::default()
.custom_modes(vec![
"rust".into(),
"coal".into(),
"navy".into(),
"ayu".into(),
])
.initial_value(ColorMode::from(html(cx).class_name())),
);
let UseCycleListReturn { state, next, .. } = use_cycle_list( let UseCycleListReturn { state, next, .. } = use_cycle_list_with_options(
cx, cx,
vec![ vec![
ColorMode::Light, ColorMode::Light,
@ -20,9 +29,14 @@ fn Demo(cx: Scope) -> impl IntoView {
ColorMode::Custom("navy".into()), ColorMode::Custom("navy".into()),
ColorMode::Custom("ayu".into()), ColorMode::Custom("ayu".into()),
], ],
UseCycleListOptions::default().initial_value(Some((mode, set_mode).into())),
); );
view! { cx, view! { cx,
<button on:click=move |_| next()>
{ move || format!("{}", state.get()) }
</button>
<Note>"Click to change the color mode"</Note>
} }
} }

View file

@ -264,8 +264,8 @@ select {
--tw-backdrop-sepia: ; --tw-backdrop-sepia: ;
} }
.block { .static {
display: block; position: static;
} }
.text-\[--brand-color\] { .text-\[--brand-color\] {

View file

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

View file

@ -1,12 +1,11 @@
use leptos::*; use leptos::*;
use std::pin::Pin;
pub enum MaybeRwSignal<T> pub enum MaybeRwSignal<T>
where where
T: 'static, T: 'static,
{ {
Static(T), Static(T),
DynamicRw(ReadSignal<T>, WriteSignal<T>), DynamicRw(Signal<T>, WriteSignal<T>),
DynamicRead(Signal<T>), DynamicRead(Signal<T>),
} }
@ -14,8 +13,8 @@ impl<T: Clone> Clone for MaybeRwSignal<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
match self { match self {
Self::Static(t) => Self::Static(t.clone()), Self::Static(t) => Self::Static(t.clone()),
Self::DynamicRw(r, w) => Self::DynamicRw(r, w), Self::DynamicRw(r, w) => Self::DynamicRw(*r, *w),
Self::DynamicRead(s) => Self::DynamicRead(s), Self::DynamicRead(s) => Self::DynamicRead(*s),
} }
} }
} }
@ -55,12 +54,18 @@ impl<T> From<Memo<T>> for MaybeRwSignal<T> {
impl<T> From<RwSignal<T>> for MaybeRwSignal<T> { impl<T> From<RwSignal<T>> for MaybeRwSignal<T> {
fn from(s: RwSignal<T>) -> Self { fn from(s: RwSignal<T>) -> Self {
let (r, w) = s.split(); let (r, w) = s.split();
Self::DynamicRw(r, w) Self::DynamicRw(r.into(), w)
} }
} }
impl<T> From<(ReadSignal<T>, WriteSignal<T>)> for MaybeRwSignal<T> { impl<T> From<(ReadSignal<T>, WriteSignal<T>)> for MaybeRwSignal<T> {
fn from(s: (ReadSignal<T>, WriteSignal<T>)) -> Self { fn from(s: (ReadSignal<T>, WriteSignal<T>)) -> Self {
Self::DynamicRw(s.0.into(), s.1)
}
}
impl<T> From<(Signal<T>, WriteSignal<T>)> for MaybeRwSignal<T> {
fn from(s: (Signal<T>, WriteSignal<T>)) -> Self {
Self::DynamicRw(s.0, s.1) Self::DynamicRw(s.0, s.1)
} }
} }
@ -71,187 +76,18 @@ impl From<&str> for MaybeRwSignal<String> {
} }
} }
impl<T: Clone> SignalGet<T> for MaybeRwSignal<T> { impl<T: Clone> MaybeRwSignal<T> {
fn get(&self) -> T { pub fn to_signal(&self, cx: Scope) -> (Signal<T>, WriteSignal<T>) {
match self { match self {
Self::Static(t) => t.clone(), Self::DynamicRead(s) => {
Self::DynamicRw(r, _) => r.get(), // TODO : this feels hacky
Self::DynamicRead(s) => s.get(), let (_, w) = create_signal(cx, s.get_untracked());
(*s, w)
} }
} Self::DynamicRw(r, w) => (*r, *w),
Self::Static(v) => {
fn try_get(&self) -> Option<T> { let (r, w) = create_signal(cx, v.clone());
match self { (Signal::from(r), w)
Self::Static(t) => Some(t.clone()),
Self::DynamicRw(r, _) => r.try_get(),
Self::DynamicRead(s) => s.try_get(),
}
}
}
impl<T> SignalWith<T> for MaybeRwSignal<T> {
fn with<O>(&self, f: impl FnOnce(&T) -> O) -> O {
match self {
Self::Static(t) => f(t),
Self::DynamicRw(r, w) => r.with(f),
Self::DynamicRead(s) => s.with(f),
}
}
fn try_with<O>(&self, f: impl FnOnce(&T) -> O) -> Option<O> {
match self {
Self::Static(t) => Some(f(t)),
Self::DynamicRw(r, _) => r.try_with(f),
Self::DynamicRead(s) => s.try_with(f),
}
}
}
impl<T> SignalWithUntracked<T> for MaybeRwSignal<T> {
fn with_untracked<O>(&self, f: impl FnOnce(&T) -> O) -> O {
match self {
Self::Static(t) => f(t),
Self::DynamicRw(r, _) => r.with_untracked(f),
Self::DynamicRead(s) => s.with_untracked(f),
}
}
fn try_with_untracked<O>(&self, f: impl FnOnce(&T) -> O) -> Option<O> {
match self {
Self::Static(t) => Some(f(t)),
Self::DynamicRw(r, _) => r.try_with_untracked(f),
Self::DynamicRead(s) => s.try_with_untracked(f),
}
}
}
impl<T: Clone> SignalGetUntracked<T> for MaybeRwSignal<T> {
fn get_untracked(&self) -> T {
match self {
Self::Static(t) => t.clone(),
Self::DynamicRw(r, _) => r.get_untracked(),
Self::DynamicRead(s) => s.get_untracked(),
}
}
fn try_get_untracked(&self) -> Option<T> {
match self {
Self::Static(t) => Some(t.clone()),
Self::DynamicRw(r, _) => r.try_get_untracked(),
Self::DynamicRead(s) => s.try_get_untracked(),
}
}
}
impl<T: Clone> SignalStream<T> for MaybeRwSignal<T> {
fn to_stream(&self, cx: Scope) -> Pin<Box<dyn futures::stream::Stream<Item = T>>> {
match self {
Self::Static(t) => {
let t = t.clone();
let stream = futures::stream::once(async move { t });
Box::bin(stream)
}
Self::DynamicRw(r, _) => r.to_stream(cx),
Self::DynamicRead(s) => s.to_stream(cx),
}
}
}
impl<T> MaybeRwSignal<T> {
pub fn derive(cx: Scope, derived_signal: impl Fn() -> T + 'static) -> Self {
Self::DynamicRead(Signal::derive(cx, derived_signal))
}
}
impl<T> SignalSetUntracked<T> for MaybeRwSignal<T> {
fn set_untracked(&self, new_value: T) {
match self {
Self::DynamicRw(_, w) => w.set_untracked(new_value),
_ => {
// do nothing
}
}
}
fn try_set_untracked(&self, new_value: T) -> Option<T> {
match self {
Self::DynamicRw(_, w) => w.try_set_untracked(new_value),
_ => Some(new_value),
}
}
}
impl<T> SignalUpdateUntracked<T> for MaybeRwSignal<T> {
#[inline(always)]
fn update_untracked(&self, f: impl FnOnce(&mut T)) {
match self {
Self::DynamicRw(_, w) => w.update_untracked(f),
_ => {
// do nothing
}
}
}
#[inline(always)]
fn try_update_untracked<O>(&self, f: impl FnOnce(&mut T) -> O) -> Option<O> {
match self {
Self::DynamicRw(_, w) => w.try_update_untracked(f),
_ => Some(f()),
}
}
}
impl<T> SignalUpdate<T> for MaybeRwSignal<T> {
#[inline(always)]
fn update(&self, f: impl FnOnce(&mut T)) {
match self {
Self::DynamicRw(_, w) => w.update(f),
_ => {
// do nothing
}
}
}
#[inline(always)]
fn try_update<O>(&self, f: impl FnOnce(&mut T) -> O) -> Option<O> {
match self {
Self::DynamicRw(_, w) => w.try_update(f),
_ => Some(f()),
}
}
}
impl<T> SignalSet<T> for MaybeRwSignal<T> {
#[inline(always)]
fn set(&self, new_value: T) {
match self {
Self::DynamicRw(_, w) => w.set(new_value),
_ => {
// do nothing
}
}
}
fn try_set(&self, new_value: T) -> Option<T> {
match self {
Self::DynamicRw(_, w) => w.try_set(new_value),
_ => Some(new_value),
}
}
}
impl<T> SignalDispose for MaybeRwSignal<T> {
fn dispose(self) {
match self {
Self::DynamicRw(r, w) => {
r.dispose();
w.dispose();
}
Self::DynamicRead(s) => s.dispose(),
_ => {
// do nothing
} }
} }
} }

View file

@ -2,7 +2,7 @@ use leptos::window;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
/// Local or session storage or a custom store that is a `web_sys::Storage`. /// Local or session storage or a custom store that is a `web_sys::Storage`.
#[doc(cfg(feature = "storage"))] // #[doc(cfg(feature = "storage"))]
#[derive(Default)] #[derive(Default)]
pub enum StorageType { pub enum StorageType {
#[default] #[default]

View file

@ -3,6 +3,7 @@ use crate::core::ElementMaybeSignal;
use crate::storage::{use_storage_with_options, UseStorageOptions}; use crate::storage::{use_storage_with_options, UseStorageOptions};
#[cfg(feature = "storage")] #[cfg(feature = "storage")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter};
use crate::core::StorageType; use crate::core::StorageType;
use crate::use_preferred_dark; use crate::use_preferred_dark;
@ -54,11 +55,11 @@ use wasm_bindgen::JsCast;
/// # fn Demo(cx: Scope) -> impl IntoView { /// # fn Demo(cx: Scope) -> impl IntoView {
/// # let UseColorModeReturn { mode, set_mode, .. } = use_color_mode(cx); /// # let UseColorModeReturn { mode, set_mode, .. } = use_color_mode(cx);
/// # /// #
/// mode(); // ColorMode::Dark or ColorMode::Light /// mode.get(); // ColorMode::Dark or ColorMode::Light
/// ///
/// set_mode(ColorMode::Dark); // change to dark mode and persist (with feature `storage`) /// set_mode.set(ColorMode::Dark); // change to dark mode and persist (with feature `storage`)
/// ///
/// set_mode(ColorMode::Auto); // change to auto mode /// set_mode.set(ColorMode::Auto); // change to auto mode
/// # /// #
/// # view! { cx, } /// # view! { cx, }
/// # } /// # }
@ -182,7 +183,7 @@ where
if attribute == "class" { if attribute == "class" {
for mode in &modes { for mode in &modes {
if value == ColorMode::from_string(mode) { if &value.to_string() == mode {
let _ = el.class_list().add_1(mode); let _ = el.class_list().add_1(mode);
} else { } else {
let _ = el.class_list().remove_1(mode); let _ = el.class_list().remove_1(mode);
@ -231,7 +232,10 @@ where
on_changed(state.get()); on_changed(state.get());
}); });
let mode = Signal::derive(cx, move || if emit_auto { store.get() } else { state() }); let mode = Signal::derive(
cx,
move || if emit_auto { store.get() } else { state.get() },
);
UseColorModeReturn { UseColorModeReturn {
mode, mode,
@ -259,10 +263,10 @@ fn get_store_signal(
cx: Scope, cx: Scope,
initial_value: MaybeSignal<ColorMode>, initial_value: MaybeSignal<ColorMode>,
storage_signal: Option<RwSignal<ColorMode>>, storage_signal: Option<RwSignal<ColorMode>>,
storage_key: &String, _storage_key: &String,
storage_enabled: bool, _storage_enabled: bool,
storage: StorageType, _storage: StorageType,
listen_to_storage_changes: bool, _listen_to_storage_changes: bool,
) -> (ReadSignal<ColorMode>, WriteSignal<ColorMode>) { ) -> (ReadSignal<ColorMode>, WriteSignal<ColorMode>) {
if let Some(storage_signal) = storage_signal { if let Some(storage_signal) = storage_signal {
storage_signal.split() storage_signal.split()
@ -273,7 +277,7 @@ fn get_store_signal(
#[cfg(feature = "storage")] #[cfg(feature = "storage")]
/// Color modes /// Color modes
#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash)] #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash, Debug)]
pub enum ColorMode { pub enum ColorMode {
#[default] #[default]
Auto, Auto,
@ -310,21 +314,21 @@ fn get_store_signal(
} }
} }
impl ToString for ColorMode { impl Display for ColorMode {
fn to_string(&self) -> String { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
use ColorMode::*; use ColorMode::*;
match self { match self {
Auto => "".to_string(), Auto => write!(f, "auto"),
Light => "light".to_string(), Light => write!(f, "light"),
Dark => "dark".to_string(), Dark => write!(f, "dark"),
Custom(v) => v.clone(), Custom(v) => write!(f, "{}", v),
} }
} }
} }
impl ColorMode { impl From<&str> for ColorMode {
pub fn from_string(s: &str) -> ColorMode { fn from(s: &str) -> Self {
match s { match s {
"auto" => ColorMode::Auto, "auto" => ColorMode::Auto,
"" => ColorMode::Auto, "" => ColorMode::Auto,
@ -335,6 +339,12 @@ impl ColorMode {
} }
} }
impl From<String> for ColorMode {
fn from(s: String) -> Self {
ColorMode::from(s.as_str())
}
}
/// Arguments to [`UseColorModeOptions::on_changed`] /// Arguments to [`UseColorModeOptions::on_changed`]
#[derive(Clone)] #[derive(Clone)]
pub struct UseColorModeOnChangeArgs { pub struct UseColorModeOnChangeArgs {

View file

@ -1,3 +1,4 @@
use crate::core::MaybeRwSignal;
use crate::watch; use crate::watch;
use default_struct_builder::DefaultBuilder; use default_struct_builder::DefaultBuilder;
use leptos::*; use leptos::*;
@ -21,11 +22,11 @@ use leptos::*;
/// vec!["Dog", "Cat", "Lizard", "Shark", "Whale", "Dolphin", "Octopus", "Seal"] /// vec!["Dog", "Cat", "Lizard", "Shark", "Whale", "Dolphin", "Octopus", "Seal"]
/// ); /// );
/// ///
/// log!("{}", state()); // "Dog" /// log!("{}", state.get()); // "Dog"
/// ///
/// prev(); /// prev();
/// ///
/// log!("{}", state()); // "Seal" /// log!("{}", state.get()); // "Seal"
/// # /// #
/// # view! { cx, } /// # view! { cx, }
/// # } /// # }
@ -77,14 +78,14 @@ where
move || { move || {
if let Some(initial_value) = initial_value { if let Some(initial_value) = initial_value {
initial_value.get() initial_value
} else { } else {
first.expect("The provided list shouldn't be empty") MaybeRwSignal::from(first.expect("The provided list shouldn't be empty"))
} }
} }
}; };
let (state, set_state) = create_signal(cx, get_initial_value()); let (state, set_state) = get_initial_value().to_signal(cx);
let index = { let index = {
let list = list.clone(); let list = list.clone();
@ -162,7 +163,7 @@ where
}; };
UseCycleListReturn { UseCycleListReturn {
state: state.into(), state,
set_state, set_state,
index: index.into(), index: index.into(),
set_index: set, set_index: set,
@ -181,7 +182,7 @@ where
/// The initial value of the state. Can be a Signal. If none is provided the first entry /// The initial value of the state. Can be a Signal. If none is provided the first entry
/// of the list will be used. /// of the list will be used.
#[builder(keep_type)] #[builder(keep_type)]
initial_value: Option<MaybeSignal<T>>, initial_value: Option<MaybeRwSignal<T>>,
/// The default index when the current value is not found in the list. /// The default index when the current value is not found in the list.
/// For example when `get_index_of` returns `None`. /// For example when `get_index_of` returns `None`.

View file

@ -2,7 +2,7 @@ use crate::use_event_listener;
use crate::utils::CloneableFnMutWithArg; use crate::utils::CloneableFnMutWithArg;
use leptos::ev::change; use leptos::ev::change;
use leptos::*; use leptos::*;
use std::cell::{OnceCell, RefCell}; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
/// Reactive [Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Testing_media_queries). /// Reactive [Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Testing_media_queries).
@ -40,8 +40,8 @@ pub fn use_media_query(cx: Scope, query: impl Into<MaybeSignal<String>>) -> Sign
let media_query: Rc<RefCell<Option<web_sys::MediaQueryList>>> = Rc::new(RefCell::new(None)); let media_query: Rc<RefCell<Option<web_sys::MediaQueryList>>> = Rc::new(RefCell::new(None));
let remove_listener: RemoveListener = Rc::new(RefCell::new(None)); let remove_listener: RemoveListener = Rc::new(RefCell::new(None));
let listener: Rc<OnceCell<Box<dyn CloneableFnMutWithArg<web_sys::Event>>>> = let listener: Rc<RefCell<Box<dyn CloneableFnMutWithArg<web_sys::Event>>>> =
Rc::new(OnceCell::new()); Rc::new(RefCell::new(Box::new(|_| {})));
let cleanup = { let cleanup = {
let remove_listener = Rc::clone(&remove_listener); let remove_listener = Rc::clone(&remove_listener);
@ -70,10 +70,7 @@ pub fn use_media_query(cx: Scope, query: impl Into<MaybeSignal<String>>) -> Sign
cx, cx,
media_query.clone(), media_query.clone(),
change, change,
listener listener.borrow().clone(),
.get()
.expect("cell should be initialized by now")
.clone(),
)))); ))));
} else { } else {
set_matches.set(false); set_matches.set(false);
@ -84,8 +81,7 @@ pub fn use_media_query(cx: Scope, query: impl Into<MaybeSignal<String>>) -> Sign
{ {
let update = update.clone(); let update = update.clone();
listener listener
.set(Box::new(move |_| update()) as Box<dyn CloneableFnMutWithArg<web_sys::Event>>) .replace(Box::new(move |_| update()) as Box<dyn CloneableFnMutWithArg<web_sys::Event>>);
.expect("cell is empty");
} }
create_effect(cx, move |_| update()); create_effect(cx, move |_| update());

View file

@ -20,19 +20,19 @@ use leptos::*;
/// # view! { cx, } /// # view! { cx, }
/// # } /// # }
/// ```{{#if feature}} /// ```{{#if feature}}
#[doc(cfg(feature = "{{feature}}"))]{{/if}} // #[doc(cfg(feature = "{{feature}}"))]{{/if}}
pub fn {{ function_name }}({{#if scope }}cx: Scope{{/if}}) -> {{ to_pascal_case function_name }}Return { pub fn {{ function_name }}({{#if scope }}cx: Scope{{/if}}) -> {{ to_pascal_case function_name }}Return {
{{ function_name }}_with_options({{#if scope }}cx, {{/if}}{{ to_pascal_case function_name }}Options::default()) {{ function_name }}_with_options({{#if scope }}cx, {{/if}}{{ to_pascal_case function_name }}Options::default())
} }
/// Version of [`{{ function_name }}`] that takes a `{{ to_pascal_case function_name }}Options`. See [`{{ function_name }}`] for how to use.{{#if feature}} /// Version of [`{{ function_name }}`] that takes a `{{ to_pascal_case function_name }}Options`. See [`{{ function_name }}`] for how to use.{{#if feature}}
#[doc(cfg(feature = "{{feature}}"))]{{/if}} // #[doc(cfg(feature = "{{feature}}"))]{{/if}}
pub fn {{ function_name }}_with_options({{#if scope }}cx: Scope, {{/if}}options: {{ to_pascal_case function_name }}Options) -> {{ to_pascal_case function_name }}Return { pub fn {{ function_name }}_with_options({{#if scope }}cx: Scope, {{/if}}options: {{ to_pascal_case function_name }}Options) -> {{ to_pascal_case function_name }}Return {
{{ to_pascal_case function_name }}Return {} {{ to_pascal_case function_name }}Return {}
} }
/// Options for [`{{ function_name }}_with_options`].{{#if feature}} /// Options for [`{{ function_name }}_with_options`].{{#if feature}}
#[doc(cfg(feature = "{{feature}}"))]{{/if}} // #[doc(cfg(feature = "{{feature}}"))]{{/if}}
#[derive(DefaultBuilder)] #[derive(DefaultBuilder)]
pub struct {{ to_pascal_case function_name }}Options {} pub struct {{ to_pascal_case function_name }}Options {}
@ -42,6 +42,6 @@ impl Default for {{ to_pascal_case function_name }}Options {
} }
} }
/// Return type of [`{{ function_name }}`]. /// Return type of [`{{ function_name }}`].{{#if feature}}
{{#if feature}}#[doc(cfg(feature = "{{feature}}"))]{{/if}} // #[doc(cfg(feature = "{{feature}}"))]{{/if}}
pub struct {{ to_pascal_case function_name }}Return {} pub struct {{ to_pascal_case function_name }}Return {}