diff --git a/component.json b/component.json index 07e2e65a..26a95e5d 100644 --- a/component.json +++ b/component.json @@ -34,6 +34,7 @@ "preview/src/components/aspect_ratio", "preview/src/components/scroll_area", "preview/src/components/date_picker", + "preview/src/components/skeleton", "preview/src/components/card" ] } diff --git a/preview/src/components/mod.rs b/preview/src/components/mod.rs index 65f9ed37..baf68358 100644 --- a/preview/src/components/mod.rs +++ b/preview/src/components/mod.rs @@ -81,6 +81,7 @@ examples!( scroll_area, select, separator, + skeleton, slider, switch, tabs, diff --git a/preview/src/components/skeleton/component.json b/preview/src/components/skeleton/component.json new file mode 100644 index 00000000..22912942 --- /dev/null +++ b/preview/src/components/skeleton/component.json @@ -0,0 +1,21 @@ +{ + "name": "skeleton", + "description": "A placeholder component for all loading elements.", + "authors": [ + "zhiyanzhaijie" + ], + "exclude": [ + "variants", + "docs.md", + "component.json" + ], + "cargoDependencies": [ + { + "name": "dioxus-primitives", + "git": "https://github.com/DioxusLabs/components" + } + ], + "globalAssets": [ + "../../../assets/dx-components-theme.css" + ] +} diff --git a/preview/src/components/skeleton/component.rs b/preview/src/components/skeleton/component.rs new file mode 100644 index 00000000..d8118890 --- /dev/null +++ b/preview/src/components/skeleton/component.rs @@ -0,0 +1,9 @@ +use dioxus::prelude::*; + +#[component] +pub fn Skeleton(#[props(extends=GlobalAttributes)] attributes: Vec) -> Element { + rsx! { + document::Link { rel: "stylesheet", href: asset!("./style.css") } + div { class: "skeleton", ..attributes } + } +} diff --git a/preview/src/components/skeleton/docs.md b/preview/src/components/skeleton/docs.md new file mode 100644 index 00000000..ba8faccd --- /dev/null +++ b/preview/src/components/skeleton/docs.md @@ -0,0 +1,10 @@ +The Skeleton component is used to display a placeholder preview of content before the data gets loaded. This helps improve perceived performance and provides users with a visual indication that content is being loaded. + +## Component Structure + +```rust +Skeleton { + // Accepts all GlobalAttributes, commonly used with style for sizing + style: "width: 15rem; height: 1rem;", +} +``` diff --git a/preview/src/components/skeleton/mod.rs b/preview/src/components/skeleton/mod.rs new file mode 100644 index 00000000..9a8ae556 --- /dev/null +++ b/preview/src/components/skeleton/mod.rs @@ -0,0 +1,2 @@ +mod component; +pub use component::*; \ No newline at end of file diff --git a/preview/src/components/skeleton/style.css b/preview/src/components/skeleton/style.css new file mode 100644 index 00000000..d3dd708f --- /dev/null +++ b/preview/src/components/skeleton/style.css @@ -0,0 +1,17 @@ +.skeleton { + background-color: var(--primary-color-5); + border-radius: 0.375rem; + animation: skeleton-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; +} + +@keyframes skeleton-pulse { + + 0%, + 100% { + opacity: 1; + } + + 61.8% { + opacity: 0.5; + } +} diff --git a/preview/src/components/skeleton/variants/main/mod.rs b/preview/src/components/skeleton/variants/main/mod.rs new file mode 100644 index 00000000..32aef0be --- /dev/null +++ b/preview/src/components/skeleton/variants/main/mod.rs @@ -0,0 +1,38 @@ +use super::super::component::*; +use dioxus::prelude::*; + +#[component] +pub fn Demo() -> Element { + rsx! { + div { style: "display: flex; flex-direction: column; align-items: center; gap: 2rem;", + SkeletonInfoDemo {} + SkeletonCardDemo {} + } + } +} + +#[component] +fn SkeletonInfoDemo() -> Element { + rsx! { + div { style: "display: flex; align-items: center; gap: 1rem;", + Skeleton { style: "width: 3rem; height: 3rem; border-radius: 50%;" } + div { style: "display: flex; flex-direction: column; gap: 0.5rem;", + Skeleton { style: "width: 11.625rem; height: 1rem;" } + Skeleton { style: "width: 8.5rem; height: 1rem;" } + } + } + } +} + +#[component] +fn SkeletonCardDemo() -> Element { + rsx! { + div { style: "display: flex; flex-direction: column; gap: 0.75rem;", + Skeleton { style: "width: 15rem; height: 8rem; border-radius: 0.75rem;" } + div { style: "display: flex; flex-direction: column; gap: 0.5rem;", + Skeleton { style: "width: 15.625rem; height: 1rem;" } + Skeleton { style: "width: 12.5rem; height: 1rem;" } + } + } + } +}