Scroll Shadow
A scrollable area with soft fading edges.
use herogpui::components::scroll_shadow::ScrollShadow;ScrollShadow on docs.rsSource at v0.14.0
Usage
Showing Usage, live: HeroGPUI compiled to WebAssembly. The canvas has no accessibility tree; each example's description and code below carry the same information.
An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::ScrollShadow;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
ScrollShadow::new("scroll-shadow")
.max_h(px(180.))
.children((1..=14).map(|n| {
gpui::div().py(px(6.)).child(format!("Row {n} of fourteen"))
}),)An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{ActiveTheme, Orientation, ScrollShadow};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
ScrollShadow::new("scroll-shadow-or-v").max_h(px(140.)).children(
(1..=10).map(|n| gpui::div().py(px(6.)).child(format!("Row {n}"))),
)
.into_any_element(),
ScrollShadow::new("scroll-shadow-or-h")
.orientation(Orientation::Horizontal)
.max_w(px(360.))
.gap(px(12.))
.children((1..=12).map(|n| {
gpui::div()
.flex_shrink_0()
.w(px(90.))
.h(px(60.))
.rounded(px(10.))
.bg(cx.colors().default.color)
.child(format!("{n}"))
}))
.into_any_element(),
])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::ScrollShadow;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
ScrollShadow::new("scroll-shadow-size-sm")
.size(px(8.))
.max_h(px(120.))
.children(
(1..=10)
.map(|n| gpui::div().py(px(6.)).child(format!("Row {n}"))),
)
.into_any_element(),
ScrollShadow::new("scroll-shadow-size-lg")
.size(px(40.))
.max_h(px(120.))
.children(
(1..=10)
.map(|n| gpui::div().py(px(6.)).child(format!("Row {n}"))),
)
.into_any_element(),
])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{Card, CardContent, CardHeader, CardTitle, ScrollShadow};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
Card::new()
.w(px(320.))
.child(
CardHeader::new().child(CardTitle::new().child("Release notes"))
)
.child(CardContent::new().child(
ScrollShadow::new("scroll-shadow-card").max_h(px(140.)).children(
(1..=12).map(|n| {
gpui::div().py(px(6.)).child(format!("Change {n}"))
}),
),
),)`hideScrollBar` omits the painted overlay thumb and leaves the shadows as the only affordance; the first specimen keeps the default bar for contrast. An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::ScrollShadow;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
ScrollShadow::new("scroll-shadow-bar")
.max_h(px(140.))
.children(
(1..=12)
.map(|n| gpui::div().py(px(6.)).child(format!("Row {n}"))),
)
.into_any_element(),
ScrollShadow::new("scroll-shadow-no-bar")
.hide_scroll_bar(true)
.max_h(px(140.))
.children(
(1..=12)
.map(|n| gpui::div().py(px(6.)).child(format!("Row {n}"))),
)
.into_any_element(),
])Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.
use herogpui::prelude::{ScrollShadow, ScrollShadowVisibility};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
gpui::div()
.flex()
.flex_col()
.items_start()
.justify_center()
.gap(px(12.))
.children(vec![
ScrollShadow::new("scroll-shadow-vis-auto")
.visibility(ScrollShadowVisibility::Auto)
// `onVisibilityChange` fires when the shaded
// edges change, which `Auto` does as it scrolls.
.on_visibility_change(cx.listener(
|this, visibility: &ScrollShadowVisibility, _, cx| {
this.set_demo_text_value(
"ss-visibility",
format!("{visibility:?}"),
);
cx.notify();
},
))
.max_h(px(120.))
.children(
(1..=10)
.map(|n| gpui::div().py(px(6.)).child(format!("Row {n}"))),
)
.into_any_element(),
ScrollShadow::new("scroll-shadow-vis-both")
.visibility(ScrollShadowVisibility::Both)
.max_h(px(120.))
.children(
(1..=10)
.map(|n| gpui::div().py(px(6.)).child(format!("Row {n}"))),
)
.into_any_element(),
ScrollShadow::new("scroll-shadow-vis-top")
.visibility(ScrollShadowVisibility::Top)
.max_h(px(120.))
.children(
(1..=10)
.map(|n| gpui::div().py(px(6.)).child(format!("Row {n}"))),
)
.into_any_element(),
])An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::ScrollShadow;
use herogpui::gpui::prelude::*;
use herogpui::gpui::{AnyElement, px};
use herogpui::gpui;
let lines: Vec<AnyElement> = (1..=20)
.map(|i| {
gpui::div()
.py(px(4.))
.child(format!("Row {i}"))
.into_any_element()
})
.collect();
ScrollShadow::new("scroll-shadow-main")
.max_h(px(200.))
.children(lines)Scroll sideways to reveal more cards. Vertical wheel input continues to the page. An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::{ActiveTheme, Orientation, ScrollShadow};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
ScrollShadow::new("scroll-shadow-h")
.orientation(Orientation::Horizontal)
.max_w(px(520.))
.size(px(56.))
.children((1..=14).map(|i| {
gpui::div()
.flex_shrink_0()
.px(px(16.))
.py(px(10.))
.rounded(px(10.))
.bg(cx.colors().surface_secondary)
.child(format!("Card {i}"))
.into_any_element()
}))An element expression with window: &mut Window and cx: &mut App in scope.
use herogpui::prelude::ScrollShadow;
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;
ScrollShadow::new("scroll-shadow-off")
.max_h(px(140.))
.is_enabled(false)
.children((1..=10).map(|i| {
gpui::div()
.py(px(4.))
.child(format!("Row {i}"))
.into_any_element()
}))Anatomy
Rust types
Scroll Shadow is assembled from these builders. The API reference lists each one.
Customization
Shared appearance belongs on ThemeBuilder::components and .recipe("name"). Typed builders change how Scroll Shadow looks at one call site. Every builder also carries sx for placement, width and flex: it takes GPUI's own styling methods and refines them over the component's root after the theme, so an instance override wins. Behaviour builders live in the API reference below.
Styling
| Method | Values | Description |
|---|---|---|
orientation(Orientation) | Orientation::Vertical | Orientation::Horizontal | Axis along which content scrolls and fades appear. |
size(Pixels) | number | Depth of each fade gradient in pixels. |
// The one slot for caller-owned low-level styling: GPUI's
// styling methods, refined over the root element last.
.sx(|el| {
el.bg(gpui::rgba(0xffa500ff)) // background
.text_color(gpui::rgba(0x000000ff)) // text
.w(gpui::px(13.)) // size
.h(gpui::px(12.))
})API reference
Against HeroUI v3.2.6: 11 entries ported, 1 partial, 2 not ported. Partial rows are marked in the tables; entries not ported are listed under each table with the reason.
Builders
| Builder | Values | Default | Description |
|---|---|---|---|
orientation( | Orientation:: | Orientation:: | Axis along which content scrolls and fades appear. |
size( | number | 40 | Depth of each fade gradient in pixels. |
offset( | number | 0 | Scroll distance before the corresponding fade appears. |
hide_scroll_bar( | true | | false | Omits the painted overlay thumb that stands in for the browser scrollbar. |
is_enabled( | true | | true | Turns fade rendering and visibility reporting on or off. |
visibility( | ScrollShadowVisibility:: | ScrollShadowVisibility:: | Controls which edge fades are eligible to render. |
on_visibility_change( | Fn( | โ | Reports resolved visible edges when they change. |
Not ported2 HeroUI entries not ported
| HeroUI v3 | Why it is not ported |
|---|---|
ScrollShadow.variant | The documented API has one visual variant, which is the port's built-in treatment. |
ScrollShadow.className | Browser styles are unavailable. |
Parts
| Part | Description |
|---|---|
ScrollShadow | Scrollable root plus edge-fade overlays. |
States
| State | Builder | Description |
|---|---|---|
Leading edge | ScrollHandle::offset | Leading fade appears after content moves beyond the configured offset. |
Trailing edge | ScrollHandle::max_offset | Trailing fade appears while more content remains after the viewport. |
Both edges | ScrollShadowVisibility::Both | Both fades render when content can scroll in either direction. |