Rust/UI component that displays an infinite scrolling component that can be used to display text, images, or videos.
- Copy Demo
@jack
1. Just love it
@jack
2. Just love it
@jack
3. Just love it
@jack
4. Just love it
@jack
5. Just love it
@jack
6. Just love it
@jack
7. Just love it
@jack
8. Just love it
@jack
9. Just love it
@jack
10. Just love it
@jack
11. Just love it
@jack
12. Just love it
@jack
[II] 1. Just love it
@jack
[II] 2. Just love it
@jack
[II] 3. Just love it
@jack
[II] 4. Just love it
@jack
[II] 5. Just love it
@jack
[II] 6. Just love it
@jack
[II] 7. Just love it
@jack
[II] 8. Just love it
@jack
[II] 9. Just love it
@jack
[II] 10. Just love it
@jack
[II] 11. Just love it
@jack
[II] 12. Just love it
use leptos::prelude::*;
use crate::components::extensions::marquee::{Marquee, MarqueeRow, MarqueeWrapper};
#[component]
pub fn DemoMarquee() -> impl IntoView {
view! {
<MarqueeWrapper class="max-w-4xl">
<Marquee>
<MarqueeRow>
<CardFigureExample blockquote="1. Just love it".to_string() />
<CardFigureExample blockquote="2. Just love it".to_string() />
<CardFigureExample blockquote="3. Just love it".to_string() />
</MarqueeRow>
<MarqueeRow>
<CardFigureExample blockquote="4. Just love it".to_string() />
<CardFigureExample blockquote="5. Just love it".to_string() />
<CardFigureExample blockquote="6. Just love it".to_string() />
</MarqueeRow>
<MarqueeRow>
<CardFigureExample blockquote="7. Just love it".to_string() />
<CardFigureExample blockquote="8. Just love it".to_string() />
<CardFigureExample blockquote="9. Just love it".to_string() />
</MarqueeRow>
<MarqueeRow>
<CardFigureExample blockquote="10. Just love it".to_string() />
<CardFigureExample blockquote="11. Just love it".to_string() />
<CardFigureExample blockquote="12. Just love it".to_string() />
</MarqueeRow>
</Marquee>
// --------------------------------------
// --------------------------------------
// --------------------------------------
// --------------------------------------
// --------------------------------------
// --------------------------------------
<Marquee>
<MarqueeRow class="[animation-direction:reverse]">
<CardFigureExample blockquote="[II] 1. Just love it".to_string() />
<CardFigureExample blockquote="[II] 2. Just love it".to_string() />
<CardFigureExample blockquote="[II] 3. Just love it".to_string() />
</MarqueeRow>
<MarqueeRow class="[animation-direction:reverse]">
<CardFigureExample blockquote="[II] 4. Just love it".to_string() />
<CardFigureExample blockquote="[II] 5. Just love it".to_string() />
<CardFigureExample blockquote="[II] 6. Just love it".to_string() />
</MarqueeRow>
<MarqueeRow class="[animation-direction:reverse]">
<CardFigureExample blockquote="[II] 7. Just love it".to_string() />
<CardFigureExample blockquote="[II] 8. Just love it".to_string() />
<CardFigureExample blockquote="[II] 9. Just love it".to_string() />
</MarqueeRow>
<MarqueeRow class="[animation-direction:reverse]">
<CardFigureExample blockquote="[II] 10. Just love it".to_string() />
<CardFigureExample blockquote="[II] 11. Just love it".to_string() />
<CardFigureExample blockquote="[II] 12. Just love it".to_string() />
</MarqueeRow>
</Marquee>
</MarqueeWrapper>
}
}
/* ========================================================== */
/* ✨ FUNCTIONS ✨ */
/* ========================================================== */
#[component]
fn CardFigureExample(blockquote: String) -> impl IntoView {
view! {
<figure class="overflow-hidden relative p-4 w-64 rounded-xl border cursor-pointer border-gray-950/[.1] bg-gray-950/[.01] dark:border-gray-50/[.1] dark:bg-gray-50/[.10] dark:hover:bg-gray-50/[.15] hover:bg-gray-950/[.05]">
<div class="flex gap-2 items-center">
<img class="rounded-full" width="32" height="32" alt="" src="https://avatar.vercel.sh/jack" />
<div class="flex flex-col">
<figcaption class="text-sm font-medium dark:text-white">Jack</figcaption>
<p class="text-xs font-medium dark:text-white/40">@jack</p>
</div>
</div>
<blockquote class="mt-2 text-sm">{blockquote}</blockquote>
</figure>
}
}
Installation
You can run either of the following commands:
# cargo install ui-cli --forceui add demo_marqueeui add marquee
Update the imports to match your project setup.
Copy and paste the following code into your project:
components/ui/marquee.rs
use leptos::prelude::*;
use leptos_ui::clx;
use tw_merge::*;
use crate::registry::ui::mask::{Mask, MaskSide};
// TODO UI. Separate the mask from the marquee.
mod components {
use super::*;
clx! {MarqueeRow, div,
"animate__marquee__row",
"flex flex-row justify-around shrink-0 [gap:var(--gap)]"
}
}
pub use components::*;
/* ========================================================== */
/* ✨ FUNCTIONS ✨ */
/* ========================================================== */
#[component]
pub fn Marquee(children: Children) -> impl IntoView {
view! {
<style>
{"@keyframes marquee_horizontal {
from { transform: translateX(0); }
to { transform: translateX(calc(-100% - var(--gap))); }
}
@keyframes marquee_vertical {
from { transform: translateY(0); }
to { transform: translateY(calc(-100% - var(--gap))); }
}
.animate__marquee__row {
animation-name: marquee_horizontal;
animation-duration: var(--duration);
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.group:hover .animate__marquee__row {
animation-play-state: paused;
}
"}
</style>
<div
data-name="Marquee"
class="flex overflow-hidden flex-row p-2 group [--gap:1rem] [gap:var(--gap)] [--duration:20s]"
>
{children()}
</div>
}
}
#[component]
pub fn MarqueeWrapper(#[prop(into, optional)] class: String, children: Children) -> impl IntoView {
let merged_class = tw_merge!(
"flex overflow-hidden relative flex-col justify-center items-center p-20 w-full h-full md:shadow-xl min-h-[300px] bg-background",
class
);
view! { <div class=merged_class>{children()} <Mask side=MaskSide::Left /> <Mask side=MaskSide::Right /></div> }
}
Update the imports to match your project setup.
Usage
// Coming soon 🦀