Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Avatar to Leptos 0.7 #422

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
110 changes: 87 additions & 23 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,34 +1,57 @@
[workspace]
# Temporarily disabled to upgrade individual packages to Leptos 0.7.
# members = [
# "book-examples/*/*",
# "packages/colors",
# "packages/icons/*",
# "packages/primitives/*/*",
# "packages/themes/*",
# "scripts",
# "stories/*",
# ]
# Temporarily disabled subcrates to be upgraded individually to Leptos 0.7.
# Once a crate is ready, uncomment it here.
members = [
"book-examples/*/*",
"packages/colors",
"packages/icons/*",
"packages/primitives/leptos/accessible-icon",
"packages/primitives/leptos/arrow",
"packages/primitives/leptos/aspect-ratio",
"packages/primitives/leptos/direction",
"packages/primitives/leptos/id",
"packages/primitives/leptos/label",
"packages/primitives/leptos/use-controllable-state",
"packages/primitives/leptos/use-escape-keydown",
"packages/primitives/leptos/use-previous",
"packages/primitives/leptos/use-size",
"packages/primitives/leptos/visually-hidden",
"packages/icons/dioxus",
"packages/icons/yew",

# -- Leptos Primitives (commented until they're upgraded) --
# "packages/primitives/leptos/accessible-icon",
# "packages/primitives/leptos/arrow",
# "packages/primitives/leptos/aspect-ratio",
# "packages/primitives/leptos/avatar",
# "packages/primitives/leptos/checkbox",
"packages/primitives/leptos/context",
# "packages/primitives/leptos/collection",
# "packages/primitives/leptos/compose-refs",
# "packages/primitives/leptos/direction",
# "packages/primitives/leptos/dismissable-layer",
# "packages/primitives/leptos/dropdown-menu",
# "packages/primitives/leptos/focus-guards",
# "packages/primitives/leptos/focus-scope",
# "packages/primitives/leptos/id",
# "packages/primitives/leptos/label",
# "packages/primitives/leptos/menu",
# "packages/primitives/leptos/popover",
# "packages/primitives/leptos/popper",
# "packages/primitives/leptos/portal",
# "packages/primitives/leptos/presence",
"packages/primitives/leptos/primitive",
# "packages/primitives/leptos/progress",
# "packages/primitives/leptos/roving-focus",
# "packages/primitives/leptos/select",
# "packages/primitives/leptos/separator",
# "packages/primitives/leptos/slot",
# "packages/primitives/leptos/switch",
# "packages/primitives/leptos/tabs",
# "packages/primitives/leptos/toggle",
# "packages/primitives/leptos/use-controllable-state",
# "packages/primitives/leptos/use-escape-keydown",
# "packages/primitives/leptos/use-previous",
# "packages/primitives/leptos/use-size",
# "packages/primitives/leptos/visually-hidden",

# -- Yew Primitives --
"packages/primitives/yew/*",

# -- Themes, Scripts, and Stories --
"packages/themes/yew",
"scripts",
"stories/*",
]

resolver = "2"

[workspace.package]
Expand All @@ -39,14 +62,17 @@ repository = "https://github.com/RustForWeb/radix"
version = "0.0.2"

[workspace.dependencies]
console_log = "1.0.0"
console_error_panic_hook = "0.1.7"
console_log = "1.0.0"
dioxus = "0.6.1"
leptos = "0.7.2"
leptos_dom = "0.7.2"
leptos_router = "0.7.2"
leptos-node-ref = "0.0.3"
leptos-maybe-callback = "0.0.3"
leptos-style = "0.0.3"
leptos-typed-fallback-show = "0.0.3"
leptos-use = "0.15.2"
log = "0.4.22"
send_wrapper = "0.6.0"
serde = "1.0.198"
Expand All @@ -58,6 +84,44 @@ yew-router = "0.18.0"
yew-struct-component = "0.1.4"
yew-style = "0.1.4"

# Subcrate packages (paths remain the same; you can comment out any subcrate not yet upgraded).
# We centralize shared dependencies in [workspace.dependencies] for a single source of truth,
# reducing duplication, preventing version drift, and keeping the Cargo.lock consistent.
#radix-leptos-arrow.path = "./packages/primitives/leptos/arrow"
#radix-leptos-aspect-ratio.path = "./packages/primitives/leptos/aspect-ratio"
#radix-leptos-accessible-icon.path = "./packages/primitives/leptos/accessible-icon"
radix-leptos-avatar.path = "./packages/primitives/leptos/avatar"
#radix-leptos-checkbox.path = "./packages/primitives/leptos/checkbox"
radix-leptos-context.path = "./packages/primitives/leptos/context"
#radix-leptos-collection.path = "./packages/primitives/leptos/collection"
#radix-leptos-compose-refs.path = "./packages/primitives/leptos/compose-refs"
#radix-leptos-direction.path = "./packages/primitives/leptos/direction"
#radix-leptos-dismissable-layer.path = "./packages/primitives/leptos/dismissable-layer"
#radix-leptos-dropdown-menu.path = "./packages/primitives/leptos/dropdown-menu"
#radix-leptos-focus-guards.path = "./packages/primitives/leptos/focus-guards"
#radix-leptos-focus-scope.path = "./packages/primitives/leptos/focus-scope"
#radix-leptos-id.path = "./packages/primitives/leptos/id"
#radix-leptos-label.path = "./packages/primitives/leptos/label"
#radix-leptos-menu.path = "./packages/primitives/leptos/menu"
#radix-leptos-popper.path = "./packages/primitives/leptos/popper"
#radix-leptos-portal.path = "./packages/primitives/leptos/portal"
#radix-leptos-presence.path = "./packages/primitives/leptos/presence"
radix-leptos-primitive.path = "./packages/primitives/leptos/primitive"
#radix-leptos-progress.path = "./packages/primitives/leptos/progress"
#radix-leptos-roving-focus.path = "./packages/primitives/leptos/roving-focus"
#radix-leptos-select.path = "./packages/primitives/leptos/select"
#radix-leptos-separator.path = "./packages/primitives/leptos/separator"
#radix-leptos-slot.path = "./packages/primitives/leptos/slot"
#radix-leptos-switch.path = "./packages/primitives/leptos/switch"
#radix-leptos-tabs.path = "./packages/primitives/leptos/tabs"
#radix-leptos-toggle.path = "./packages/primitives/leptos/toggle"
#radix-leptos-use-controllable-state.path = "./packages/primitives/leptos/use-controllable-state"
#radix-leptos-use-escape-keydown.path = "./packages/primitives/leptos/use-escape-keydown"
#radix-leptos-use-previous.path = "./packages/primitives/leptos/use-previous"
#radix-leptos-use-size.path = "./packages/primitives/leptos/use-size"
#radix-leptos-visually-hidden.path = "./packages/primitives/leptos/visually-hidden"

[patch.crates-io]
yew = { git = "https://github.com/RustForWeb/yew.git", branch = "feature/use-composed-ref" }
yew-router = { git = "https://github.com/RustForWeb/yew.git", branch = "feature/use-composed-ref" }
leptos-node-ref = { git = "https://github.com/geoffreygarrett/leptos-utils", branch = "feature/any-node-ref" }
146 changes: 113 additions & 33 deletions book/src/primitives/components/avatar.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ files = ["src/avatar.rs"]

## Features

- Automatic and manual control over when the image renders.
- Fallback part accepts any children.
- Optionally delay fallback rendering to avoid content flashing.
- Automatic and manual control over when the image renders.
- Fallback part accepts any children.
- Optionally delay fallback rendering to avoid content flashing.

## Installation

Expand All @@ -40,9 +40,9 @@ Install the component from your command line.
cargo add radix-leptos-avatar
```

- [View on crates.io](https://crates.io/crates/radix-leptos-avatar)
- [View on docs.rs](https://docs.rs/radix-leptos-avatar/latest/radix_leptos_avatar/)
- [View source](https://github.com/RustForWeb/radix/tree/main/packages/primitives/leptos/avatar)
- [View on crates.io](https://crates.io/crates/radix-leptos-avatar)
- [View on docs.rs](https://docs.rs/radix-leptos-avatar/latest/radix_leptos_avatar/)
- [View source](https://github.com/RustForWeb/radix/tree/main/packages/primitives/leptos/avatar)

{{#endtab }}
{{#tab name="Yew" }}
Expand All @@ -51,9 +51,9 @@ cargo add radix-leptos-avatar
cargo add radix-yew-avatar
```

- [View on crates.io](https://crates.io/crates/radix-yew-avatar)
- [View on docs.rs](https://docs.rs/radix-yew-avatar/latest/radix_yew_avatar/)
- [View source](https://github.com/RustForWeb/radix/tree/main/packages/primitives/yew/avatar)
- [View on crates.io](https://crates.io/crates/radix-yew-avatar)
- [View on docs.rs](https://docs.rs/radix-yew-avatar/latest/radix_yew_avatar/)
- [View source](https://github.com/RustForWeb/radix/tree/main/packages/primitives/yew/avatar)

{{#endtab }}
{{#endtabs }}
Expand All @@ -67,15 +67,17 @@ Import all parts and piece them together.

```rust,ignore
use leptos::*;
use radix_leptos_avatar::*;
use radix_leptos_avatar::primitive as Avatar;

#[component]
fn Anatomy() -> impl IntoView {
view! {
<Avatar>
<AvatarImage />
<AvatarFallback />
</Avatar>
<Avatar::Root>
<Avatar::Image src="https://example.com/avatar.png" />
<Avatar::Fallback delay_ms=500>
{"AB"}
</Avatar::Fallback>
</Avatar::Root>
}
}
```
Expand Down Expand Up @@ -110,60 +112,70 @@ Contains all the parts of an avatar.
{{#tabs global="framework" }}
{{#tab name="Leptos" }}

| Prop | Type | Default |
| ---------- | ----------------- | ------- |
| `as_child` | `MaybeProp<bool>` | `false` |
| Prop | Type | Default | Description |
|------------|-------------------|---------|------------------------------------------------------------------------------------------|
| `as_child` | `MaybeProp<bool>` | `false` | If `true`, renders only its children without a `<span>` wrapper. |
| `node_ref` | `AnyNodeRef` | - | Optional reference to the underlying `<span>` element. |
| `children` | `TypedChildrenFn` | - | The content of the `Avatar` component (commonly `Avatar::Image` and `Avatar::Fallback`). |

{{#endtab }}
{{#tab name="Yew" }}

| Prop | Type | Default |
| ---------- | ------------------------------------------ | ------- |
|------------|--------------------------------------------|---------|
| `as_child` | `Option<Callback<AvatarChildProps, Html>>` | - |

{{#endtab }}
{{#endtabs }}

### Image
### AvatarImage

The image to render. By default it will only render when it has loaded. You can use the `on_loading_status_change` handler if you need more control.
Displays the image. By default, it only renders if the image successfully loads.
Use the `on_loading_status_change` callback or check the context (see `use_avatar_context`) if you need more control.

{{#tabs global="framework" }}
{{#tab name="Leptos" }}

| Prop | Type | Default |
| -------------------------- | -------------------------------------- | ------- |
| `as_child` | `MaybeProp<bool>` | `false` |
| `on_loading_status_change` | `Option<Callback<ImageLoadingStatus>>` | - |
| Prop | Type | Default | Description |
|----------------------------|-------------------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------|
| `src` | `MaybeProp<String>` | - | The source URL for the avatar image. |
| `referrer_policy` | `MaybeProp<String>` | - | Sets the `referrerpolicy` attribute of the `<img>` tag if needed. |
| `as_child` | `MaybeProp<bool>` | `false` | If `true`, renders only its children without an `<img>` tag. |
| `on_loading_status_change` | `MaybeCallback<ImageLoadingStatus>` | - | Callback to be fired when the image loading status changes. Receives an `ImageLoadingStatus` enum value (`Idle`, `Loading`, `Loaded`, `Error`). |
| `node_ref` | `AnyNodeRef` | - | Optional reference to the underlying `<img>` element. |
| `children` | `Option<ChildrenFn>` | - | If `as_child = true`, can pass child elements to be used instead of an `<img>`. |

{{#endtab }}
{{#tab name="Yew" }}

| Prop | Type | Default |
| -------------------------- | ----------------------------------------------- | ------- |
|----------------------------|-------------------------------------------------|---------|
| `as_child` | `Option<Callback<AvatarImageChildProps, Html>>` | - |
| `on_loading_status_change` | `Callback<ImageLoadingStatus>` | - |

{{#endtab }}
{{#endtabs }}

### Fallback
### AvatarFallback

An element that renders when the image hasn't loaded. This means whilst it's loading, or if there was an error. If you notice a flash during loading, you can provide a `delay_ms` prop to delay its rendering so it only renders for those with slower connections. For more control, use the `on_loading_status_change` handler on `AvatarImage`.
Renders its children while the image is loading or if it fails to load.
Use `delay_ms` to avoid flashing the fallback for users with a fast connection.

{{#tabs global="framework" }}
{{#tab name="Leptos" }}

| Prop | Type | Default |
| ---------- | ----------------- | ------- |
| `as_child` | `MaybeProp<bool>` | `false` |
| `delay_ms` | `MaybeProp<i32>` | - |
| Prop | Type | Default | Description |
|------------|-------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------|
| `delay_ms` | `MaybeProp<i32>` | - | Delay (in milliseconds) before showing the fallback content. If none is provided, fallback shows up immediately if the image isn't loaded. |
| `as_child` | `MaybeProp<bool>` | `false` | If `true`, renders only its children without a `<span>` wrapper. |
| `node_ref` | `AnyNodeRef` | - | Optional reference to the `<span>` element. |
| `children` | `TypedChildrenFn` | - | Typically, initials or an icon to display in place of the image. |

{{#endtab }}
{{#tab name="Yew" }}

| Prop | Type | Default |
| ---------- | -------------------------------------------------- | ------- |
|------------|----------------------------------------------------|---------|
| `as_child` | `Option<Callback<AvatarFallbackChildProps, Html>>` | - |
| `delay_ms` | `Option<i32>` | - |

Expand All @@ -172,8 +184,76 @@ An element that renders when the image hasn't loaded. This means whilst it's loa

## Examples

**Basic Usage**

{{#tabs global="framework" }}
{{#tab name="Leptos" }}

```rust,ignore
use leptos::*;
use radix_leptos_avatar::primitive as Avatar;

#[component]
fn DemoAvatar() -> impl IntoView {
view! {
<Avatar::Root>
<Avatar::Image src="https://example.com/my-avatar.png" />
<Avatar::Fallback delay_ms=300>
{"JD"}
</Avatar::Fallback>
</Avatar::Root>
}
}
```

{{#endtab }}
{{#tab name="Yew" }}
TODO
{{#endtab }}
{{#endtabs }}

**Custom Callback**

{{#tabs global="framework" }}
{{#tab name="Leptos" }}

```rust,ignore
use leptos::*;
use radix_leptos_avatar::primitive as Avatar;
use radix_leptos_avatar::ImageLoadingStatus;

#[component]
fn AvatarWithCallback() -> impl IntoView {
let on_status_change = move |status: ImageLoadingStatus| {
match status {
ImageLoadingStatus::Idle => log!("Avatar Image: Idle"),
ImageLoadingStatus::Loading => log!("Avatar Image: Loading"),
ImageLoadingStatus::Loaded => log!("Avatar Image: Loaded"),
ImageLoadingStatus::Error => log!("Avatar Image: Failed to load"),
}
};

view! {
<Avatar::Root>
<Avatar::Image
src="https://example.com/my-avatar.png"
on_loading_status_change=on_status_change
/>
<Avatar::Fallback>
{"Fallback"}
</Avatar::Fallback>
</Avatar::Root>
}
}
```

{{#endtab }}
{{#tab name="Yew" }}
TODO
{{#endtab }}
{{#endtabs }}

## See Also

- [Radix documentation](https://www.radix-ui.com/primitives/docs/components/avatar)
- [Radix UI documentation](https://www.radix-ui.com/primitives/docs/components/avatar)
- [Repository and more examples](https://github.com/RustForWeb/radix)
5 changes: 5 additions & 0 deletions packages/primitives/leptos/avatar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ version.workspace = true

[dependencies]
leptos.workspace = true
leptos-node-ref.workspace = true
leptos-maybe-callback.workspace = true
leptos-use.workspace = true
radix-leptos-primitive.workspace = true
radix-leptos-context.workspace = true
web-sys.workspace = true
2 changes: 1 addition & 1 deletion packages/primitives/leptos/avatar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ See [the Rust Radix book](https://radix.rustforweb.org/) for documentation.

## Rust For Web

The Rust Radix project is part of [Rust For Web](https://github.com/RustForWeb).
The Rust Radix project is part of the [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.
Loading