Ref https://github.com/zed-industries/zed/pull/50228
## Summary
- Refactored to share Gallery component between native and web versions
- Fixed WASM compatibility issues with async/threading
- Added web version of the story gallery
## Show case
https://huacnlee.github.io/gpui-component-story-web/
## Key Changes
### 1. Shared Gallery Component
- Extracted Gallery to `crates/story/src/gallery.rs`
- Removed duplicate code (~570 lines) from `main.rs` and
`story-web/lib.rs`
- Both native and web versions now use the same Gallery implementation
### 2. WASM Async Architecture Improvements
**Problem:** WASM main thread cannot use blocking synchronization
primitives (`Mutex`, `RwLock`) that rely on `Atomics.wait`.
**Solution:** Redesigned the async architecture to avoid cross-thread
locks:
- Changed from `Arc<Mutex<ParsedContent>>` to direct storage in
`TextViewState`
- Backend tasks now use pure message-passing instead of shared locks
- All state updates happen on the main thread
**New workflow:**
1. User updates text → Send `UpdateOptions` to background task
2. Background task → Receives copy of current `ParsedContent`, parses
text, returns new `ParsedContent`
3. Main thread → Receives result, directly replaces `parsed_content`
4. Rendering → Reads `parsed_content`, no locks needed
### 3. Cross-platform Time APIs
- Replaced `std::time` with `instant` crate for cross-platform
compatibility
- Updated 11 files to use `instant::{Duration, Instant}`
- Fixed tracing-subscriber initialization for WASM (`.without_time()`)
## Technical Details
### Files Modified
- `crates/story/src/gallery.rs` - **New** shared Gallery module
- `crates/story/src/main.rs` - Simplified to use shared Gallery
- `crates/story-web/src/lib.rs` - Simplified to use shared Gallery (326
lines → 26 lines)
- `crates/ui/src/text/state.rs` - WASM async architecture improvements
- `crates/ui/src/async_util.rs` - Cross-platform async utilities
- `crates/ui/Cargo.toml` - Added `instant` and `parking_lot`
dependencies
### Key Architecture Changes
```rust
// Before: Shared mutable state with locks (blocked on WASM)
pub struct TextViewState {
parsed_content: Arc<Mutex<ParsedContent>>,
}
// After: Direct storage with message-passing (WASM-compatible)
pub struct TextViewState {
parsed_content: ParsedContent,
}
```
## Test Plan
- ✅ Native version compiles and runs
- ✅ WASM version builds successfully
- ✅ All components render correctly in both versions
- ✅ No "Atomics.wait cannot be called in this context" errors
## Benefits
- **Reduced code duplication**: Removed ~570 lines of duplicate code
- **Single source of truth**: Gallery updates only need to happen in one
place
- **WASM compatibility**: Proper async architecture that works on
single-threaded WASM
- **Cross-platform**: Native and Web use identical code paths
## TODO
- [ ] `gpui_web` not have implement the `set_menus`, app menu missing.
- [ ] `tree-sitter` can't compiled for wasm, disabled to without
highlight.
- [ ] Input can't handle any type events.
- [ ] Embed font for CJK.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Closes#1947
## Description
The `Release Docs` action is currently triggered by a tag, but this can
cause it to become unsynchronized with the official package version if
the package fails to publish.
To address this, change the `Release Docs` action to be triggered by the
`Release Crate` workflow. Once that workflow completes successfully, it
will trigger the documentation release, ensuring that the doc version
stays in sync with the official package version.
Initialize a Next.js-based documentation site using Fumadocs framework
to provide comprehensive guides for all GPUI components. The site
includes getting started guides, API references, and documentation for
40+ components including Button, Input, Table, Tree, Chart, and more.
---------
Co-authored-by: Jason Lee <huacnlee@gmail.com>