Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ version = "0.0.3"

[workspace.dependencies]
leptos = "0.7.0"
log = "0.4.25"
15 changes: 15 additions & 0 deletions packages/leptos-maybe-callback/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "leptos-maybe-callback"
description = "Optional callbacks for Leptos."

authors.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
version.workspace = true

[dependencies]
leptos.workspace = true

[dev-dependencies]
log.workspace = true
104 changes: 104 additions & 0 deletions packages/leptos-maybe-callback/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Leptos Maybe Callback

Optional callbacks for [Leptos](https://leptos.dev/).

## Documentation

Documentation for the crate is available on [Docs.rs](https://docs.rs/):

- [`leptos-node-ref`](https://docs.rs/leptos-maybe-callback/latest/leptos_maybe_callback/)

## Example

### Component with Optional Callback Prop

Define a component that accepts an optional callback using `#[prop(into, optional)]`. This allows passing a closure, a
`Callback`, or omitting the prop.

```rust
use leptos::{ev::MouseEvent, prelude::*};
use leptos_maybe_callback::MaybeCallback;

/// A button component with an optional `onclick` callback.
#[component]
pub fn Button(
#[prop(into, optional)]
onclick: MaybeCallback<MouseEvent>,
) -> impl IntoView {
view! {
<button on:click=onclick.into_handler()>
"Click me"
</button>
}
}
```

### Using the Component with a Closure

Use the `Button` component and provide a closure for the `onclick` prop.

```rust
use leptos::prelude::*;
use leptos_maybe_callback::MaybeCallback;

/// Parent component using `Button` with a closure.
#[component]
pub fn ButtonWithClosure() -> impl IntoView {
view! {
<div>
<Button onclick=|_| log::info!("Clicked via closure!") />
<Button />
</div>
}
}
```

### Using the Component with a `Callback`

Alternatively, pass a `Callback` as the `onclick` prop.

```rust
use leptos::{ev::MouseEvent, prelude::*};
use leptos_maybe_callback::MaybeCallback;

/// Parent component using `Button` with a `Callback`.
#[component]
pub fn ButtonWithCallback() -> impl IntoView {
let on_click = Callback::new(|event: MouseEvent| {
log::info!("Clicked with event: {:?}", event);
});

view! {
<div>
<Button onclick=on_click />
<Button />
</div>
}
}
```

### Omitting the Callback

If no callback is needed, omit the `onclick` prop or pass `None`.

```rust
use leptos::{ev::MouseEvent, prelude::*};
use leptos_maybe_callback::MaybeCallback;

/// Parent component using `Button` without a callback.
#[component]
pub fn ButtonWithoutCallback() -> impl IntoView {
view! {
<div>
<Button />
<Button onclick={None::<Callback<MouseEvent>>} />
</div>
}
}
```

## Rust For Web

The Leptos Maybe Callback project is part of [Rust For Web](https://github.com/RustForWeb).

[Rust For Web](https://github.com/RustForWeb) creates and ports web UI libraries for Rust. All projects are free and open source.
131 changes: 131 additions & 0 deletions packages/leptos-maybe-callback/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
//! Optional callbacks for [Leptos](https://leptos.dev/).
//!
//! # Example
//!
//! ## Component with Optional Callback Prop
//!
//! Define a component that accepts an optional callback using `#[prop(into, optional)]`. This allows passing a closure, a
//! `Callback`, or omitting the prop.
//!
//! ```
//! use leptos::{ev::MouseEvent, prelude::*};
//! use leptos_maybe_callback::MaybeCallback;
//!
//! /// A button component with an optional `onclick` callback.
//! #[component]
//! pub fn Button(
//! #[prop(into, optional)]
//! onclick: MaybeCallback<MouseEvent>,
//! ) -> impl IntoView {
//! view! {
//! <button on:click=onclick.into_handler()>
//! "Click me"
//! </button>
//! }
//! }
//! ```
//!
//! ## Using the Component with a Closure
//!
//! Use the `Button` component and provide a closure for the `onclick` prop.
//!
//! ```
//! # use leptos::ev::MouseEvent;
//! use leptos::prelude::*;
//! use leptos_maybe_callback::MaybeCallback;
//!
//! # #[component]
//! # pub fn Button(
//! # #[prop(into, optional)]
//! # onclick: MaybeCallback<MouseEvent>,
//! # ) -> impl IntoView {
//! # view! {
//! # <button on:click=onclick.into_handler()>
//! # "Click me"
//! # </button>
//! # }
//! # }
//! #
//! /// Parent component using `Button` with a closure.
//! #[component]
//! pub fn ButtonWithClosure() -> impl IntoView {
//! view! {
//! <div>
//! <Button onclick=|_| log::info!("Clicked via closure!") />
//! <Button />
//! </div>
//! }
//! }
//! ```
//!
//! ## Using the Component with a `Callback`
//!
//! Alternatively, pass a `Callback` as the `onclick` prop.
//!
//! ```rust
//! use leptos::{ev::MouseEvent, prelude::*};
//! use leptos_maybe_callback::MaybeCallback;
//!
//! # #[component]
//! # pub fn Button(
//! # #[prop(into, optional)]
//! # onclick: MaybeCallback<MouseEvent>,
//! # ) -> impl IntoView {
//! # view! {
//! # <button on:click=onclick.into_handler()>
//! # "Click me"
//! # </button>
//! # }
//! # }
//! #
//! /// Parent component using `Button` with a `Callback`.
//! #[component]
//! pub fn ButtonWithCallback() -> impl IntoView {
//! let on_click = Callback::new(|event: MouseEvent| {
//! log::info!("Clicked with event: {:?}", event);
//! });
//!
//! view! {
//! <div>
//! <Button onclick=on_click />
//! <Button />
//! </div>
//! }
//! }
//! ```
//!
//! ## Omitting the Callback
//!
//! If no callback is needed, omit the `onclick` prop or pass `None`.
//!
//! ```rust
//! use leptos::{ev::MouseEvent, prelude::*};
//! use leptos_maybe_callback::MaybeCallback;
//!
//! # #[component]
//! # pub fn Button(
//! # #[prop(into, optional)]
//! # onclick: MaybeCallback<MouseEvent>,
//! # ) -> impl IntoView {
//! # view! {
//! # <button on:click=onclick.into_handler()>
//! # "Click me"
//! # </button>
//! # }
//! # }
//! #
//! /// Parent component using `Button` without a callback.
//! #[component]
//! pub fn ButtonWithoutCallback() -> impl IntoView {
//! view! {
//! <div>
//! <Button />
//! <Button onclick={None::<Callback<MouseEvent>>} />
//! </div>
//! }
//! }
//! ```

mod maybe_callback;

pub use maybe_callback::*;
Loading