refactor(hooks): replace lock_scroll.js with Rust web_sys implementation#21
Conversation
Resolves rust-ui#1. Rewrites the scroll lock utility in pure Rust using web_sys, eliminating the vanilla JS dependency. - Add scroll_lock.rs with lock(), unlock(delay), is_locked() API - Register window.ScrollLock via wasm_bindgen closures at app init - Add CssStyleDeclaration to web-sys features for getComputedStyle - Remove <script src="/hooks/lock_scroll.js"> from shell and 8 components - Delete public/hooks/lock_scroll.js (254 lines of JS)
Also fixes #23 (Safari tab buttons)While testing this PR I discovered it incidentally fixes #23 as well. The inline Verified by A/B testing — clean Full root cause analysis in #23. |
The init() call is already wrapped with #[cfg(target_arch = "wasm32")], but the use statement was unconditional, causing an unused-import warning on the SSR build.
|
Thanks for the contribution @mp-c0de! Really clean port — the read-before-write batching, per-element scrollbar compensation, and exclusion lists are all faithfully preserved. Will follow up with registry regeneration and a minor body/documentElement exclusion guard. |
Summary
Resolves #1.
Replaces
public/hooks/lock_scroll.js(254 lines of vanilla JS) with a pure Rust implementation usingweb_sys. The new module lives inapp_crates/registry/src/hooks/scroll_lock.rsand exposes the same API:lock()— locks scroll on body + all scrollable containers, compensates scrollbar widthunlock(delay_ms)— restores scroll after optional delay (for exit animations)is_locked()— returns current lock stateThe Rust implementation:
window.ScrollLockviawasm_bindgenclosures so existing inline scripts work unchangedthread_local! { RefCell }for state (wasm is single-threaded)ScrollArea,CommandList,SelectContent, etc.)Changes
app_crates/registry/src/hooks/scroll_lock.rs— full Rust implementationCargo.toml— addedCssStyleDeclarationto web-sys featuresapp/src/app.rs— callsscroll_lock::init()at app startup (wasm-only via#[cfg])app/src/shell.rs— removed global<script async src="/hooks/lock_scroll.js"><script src="/hooks/lock_scroll.js">fromSheet,Dialog,Select,DropdownMenu,MultiSelect,Command,Menubar,ContextMenupublic/hooks/lock_scroll.jsNot included (follow-up work)
public/registry/files (tree.md, component markdown)crates/ui-cli/test fixtures that referencelock_scroll.jsTest plan
cargo checkcompiles with zero errors onscroll_lock.rscargo leptos watch— server starts without panicswindow.ScrollLockis registered andisLocked()returns correct stateuse-lock-body-scroll.spec.tshook test