MCPcopy Create free account
hub / github.com/DioxusLabs/dioxus-components / VirtualList

Function VirtualList

primitives/src/virtual_list.rs:75–255  ·  view source on GitHub ↗
(props: VirtualListProps)

Source from the content-addressed store, hash-verified

73/// All user-provided `attributes` are spread onto the container element.
74#[component]
75pub fn VirtualList(props: VirtualListProps) -> Element {
76 let VirtualListProps {
77 count,
78 buffer,
79 estimate_size,
80 render_item,
81 attributes,
82 } = props;
83
84 let container_id = crate::use_unique_id();
85
86 // Create the Store — only holds mutable shared state
87 let state: Store<VirtualizerState> = use_store(|| VirtualizerState {
88 scroll_offset: 0,
89 viewport_size: 0,
90 is_scrolling: false,
91 item_size_cache: HashMap::new(),
92 scroll_adjustments: 0,
93 stable_total_size: None,
94 stable_measurement_count: None,
95 deferred_adjustments: 0,
96 });
97
98 // Measurements as a memo — recomputes when count or item_size_cache change.
99 // Read (not peeked) by the render body so the component re-renders when the
100 // memo invalidates; peeking a dirty memo returns stale data (Memo::peek does
101 // not check the dirty flag), which can yield out-of-bounds indices when
102 // `count` shrinks between renders.
103 let measurements: Memo<Vec<crate::r#virtual::types::VirtualItem>> = use_memo(move || {
104 let count = count();
105 let isc = state.item_size_cache();
106 let item_size_cache = isc.read();
107 let estimate_cb = estimate_size.as_ref().map(|c| move |i: usize| c(i));
108 compute_measurements(
109 count,
110 &item_size_cache,
111 estimate_cb.as_ref().map(|f| f as &dyn Fn(usize) -> u32),
112 )
113 });
114
115 // Subscribe to scroll events via JS bridge
116 use_effect(move || {
117 let script = r#"
118 const container = document.getElementById(await dioxus.recv());
119 if (!container) return;
120
121 let scrollEndTimer = null;
122 let lastOffset = null;
123 let lastViewport = null;
124 let lastIsScrolling = null;
125
126 function publish(isScrolling) {
127 const scroll = Math.round(container.scrollTop);
128 const viewport = Math.min(container.clientHeight, window.innerHeight) || 600;
129 // Deduplicate only if the full scroll state is unchanged.
130 if (
131 scroll === lastOffset &&
132 viewport === lastViewport &&

Callers

nothing calls this directly

Calls 11

use_unique_idFunction · 0.85
compute_measurementsFunction · 0.85
set_scroll_offsetFunction · 0.85
set_viewport_sizeFunction · 0.85
sync_container_scrollFunction · 0.85
resize_itemFunction · 0.85
get_virtual_itemsFunction · 0.85
get_total_sizeFunction · 0.85
as_refMethod · 0.80
firstMethod · 0.80
startMethod · 0.45

Tested by

no test coverage detected