use dioxus::prelude::*;
use crate::{
cn,
uikit::{SCROLL_AREA_THUMB, SCROLL_AREA_VIEWPORT, SCROLLBAR_BASE, ScrollBarOrientation},
};
#[component]
pub fn ScrollArea(#[props(default)] class: String, children: Element) -> Element {
let cls = cn!("relative", class);
rsx! {
div { class: cls, "data-slot": "scroll-area",
div {
"data-slot": "scroll-area-viewport",
class: SCROLL_AREA_VIEWPORT,
{children}
}
ScrollBar {}
}
}
}
#[component]
pub fn ScrollBar(#[props(default)] orientation: ScrollBarOrientation, #[props(default)] class: String) -> Element {
let cls = cn!(SCROLLBAR_BASE, orientation.as_class(), class);
rsx! {
div {
"data-slot": "scroll-area-scrollbar",
"data-orientation": orientation.as_ref(),
class: cls,
div { "data-slot": "scroll-area-thumb", class: SCROLL_AREA_THUMB }
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::uikit::test_util::render;
#[test]
fn scroll_area_renders_viewport_and_slots() {
fn app() -> Element {
rsx! {
ScrollArea { "body" }
}
}
let html = render(app);
assert!(html.contains("data-slot=\"scroll-area\""), "{html}");
assert!(html.contains("data-slot=\"scroll-area-viewport\""), "{html}");
assert!(html.contains("overflow-auto"), "{html}");
assert!(html.contains("size-full"), "{html}");
assert!(html.contains("body"));
}
#[test]
fn scrollbar_defaults_to_vertical() {
fn app() -> Element {
rsx! { ScrollBar {} }
}
let html = render(app);
assert!(html.contains("data-slot=\"scroll-area-scrollbar\""), "{html}");
assert!(html.contains("data-orientation=\"vertical\""), "{html}");
assert!(html.contains("w-2.5"), "{html}");
assert!(html.contains("data-slot=\"scroll-area-thumb\""), "{html}");
}
#[test]
fn scrollbar_horizontal_orientation() {
fn app() -> Element {
rsx! {
ScrollBar { orientation: ScrollBarOrientation::Horizontal }
}
}
let html = render(app);
assert!(html.contains("data-orientation=\"horizontal\""), "{html}");
assert!(html.contains("flex-col"), "{html}");
}
}