|
2 | 2 | import json |
3 | 3 | import inspect |
4 | 4 |
|
5 | | -from sprag import Component, Module, browser, imports, ui |
| 5 | +from sprag import Component, Module, browser, imports, ui, virtual_scroll |
6 | 6 | from sprag.dev.codegen.components import compile_component_artifact, compile_component_class |
7 | 7 | from sprag.dev.codegen.modules import compile_module_artifact, compile_module_class |
8 | 8 | from sprag.dev.codegen.mappings import JSCodegenError |
@@ -99,6 +99,29 @@ def render(self, props=None): |
99 | 99 | ) |
100 | 100 |
|
101 | 101 |
|
| 102 | +@virtual_scroll(chunk=20, axis="horizontal", root=".rail", container_class="rail-inner") |
| 103 | +class VirtualScrollCallbacksComponent(Component): |
| 104 | + def render(self, props=None): |
| 105 | + return ui.div(class_="rail") |
| 106 | + |
| 107 | + def total(self): |
| 108 | + return 1000 |
| 109 | + |
| 110 | + async def chunk(self, i, load_ctx): |
| 111 | + if load_ctx and not load_ctx.is_current(): |
| 112 | + return None |
| 113 | + return ui.div("chunk " + str(i), class_="chunk") |
| 114 | + |
| 115 | + def measure(self, el, i): |
| 116 | + return el.offset_width |
| 117 | + |
| 118 | + def placeholder(self, i, px): |
| 119 | + return ui.div(class_="placeholder") |
| 120 | + |
| 121 | + def evicted(self, i): |
| 122 | + return i |
| 123 | + |
| 124 | + |
102 | 125 | class InvalidComponentSubscription(Component): |
103 | 126 | def render(self, props=None): |
104 | 127 | return ui.button("Subscribe") |
@@ -197,6 +220,17 @@ def test_compile_component_supports_set_metadata_helper(self): |
197 | 220 | self.assertIn("window.__SPRAG_SET_METADATA__", compiled) |
198 | 221 | self.assertIn('this.setMetadata({ "og:title": "Updated OG title" });', compiled) |
199 | 222 |
|
| 223 | + def test_compile_component_supports_virtual_scroll_callbacks(self): |
| 224 | + compiled = compile_component_class(VirtualScrollCallbacksComponent) |
| 225 | + self.assertIn("VirtualScroller", compiled) |
| 226 | + self.assertIn('axis: "horizontal"', compiled) |
| 227 | + self.assertIn("renderChunk: (i, loadCtx) => this.chunk(i, loadCtx)", compiled) |
| 228 | + self.assertIn("measureChunk: (el, i) => this.measure(el, i)", compiled) |
| 229 | + self.assertIn("buildPlaceholder: (i, px) => this.placeholder(i, px)", compiled) |
| 230 | + self.assertIn("onChunkEvicted: (i) => this.evicted(i)", compiled) |
| 231 | + self.assertIn("async chunk(i, load_ctx)", compiled) |
| 232 | + self.assertIn("load_ctx.isCurrent()", compiled) |
| 233 | + |
200 | 234 | def test_compile_module_artifact_emits_source_map_metadata(self): |
201 | 235 | artifact = compile_module_artifact(SupportedModule) |
202 | 236 | payload = json.loads(artifact.source_map) |
|
0 commit comments