DioxusLabs / DioxusLabs/blitz

Expose BaseDocumentHandle in Root Context for Dioxus Native applications

Open
#900 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
4.1k
Forks
203
Avg merge
8h 58m
Merged PRs (30d)
112

Description

## Problem Description

In `dioxus-native`, the runtime already exposes several key platform capabilities to the VirtualDom root scope (`ScopeId::ROOT`) during window initialization in `dioxus_application.rs`:

- `winit_window: Arc`
- `renderer: Renderer`
- `shell_provider: Arc`
- `history_provider: Rc`
- `document: Rc` (for page title and `` tags)

However, the underlying authority for native DOM operations — **`BaseDocument`** (which manages the node tree, layout geometry, Stylo styling, focus, and scrolling) — is currently inaccessible to components inside the `VirtualDom`.

Components and ecosystem UI libraries that need to perform DOM-level operations on Native (such as measuring bounding client rects for tooltips/popovers/selects, controlling node focus, or querying scroll offsets) currently have no standardized way to obtain a reference to the active native DOM authority without constructing custom window wrappers, engine forks, or ad-hoc workarounds.

## The Web vs. Native Ambient Acquisition Gap

When authoring cross-platform DOM abstractions and UI primitives:

- **On Web (`wasm32`)**: components and hooks can access the ambient document via `web_sys::window()?.document()`.
- **On Blitz Native**: the equivalent authority (`BaseDocument`) is owned by `DioxusDocument.inner`, but it is not exposed to the component tree.

This creates an asymmetry where native libraries must introduce extra platform-specific setup even when the underlying runtime already owns the needed document object.

## Proposed Solution: `BaseDocumentHandle`

Rather than exposing raw `Rc>` directly in Dioxus's type-based context system, introduce a neutral wrapper/newtype such as:

```rust
// packages/dioxus-native/src/contexts.rs
use blitz_dom::BaseDocument;
use std::cell::RefCell;
use std::rc::Rc;

#[derive(Clone)]
pub struct BaseDocumentHandle(Rc>);

impl BaseDocumentHandle {
pub fn new(inner: Rc>) -> Self {
Self(inner)
}

// Exact accessor surface intentionally left open to maintainer preference.
}
```

Then inject it into `ScopeId::ROOT` during native window creation:

```rust
let base_document_handle = BaseDocumentHandle::new(doc.inner.clone());
doc.vdom
.in_scope(ScopeId::ROOT, move || provide_context(base_document_handle));
```

thanks for reading

Contributor guide

Open the contributing guide

Research direction

Start with packages/dioxus-native/src/contexts.rs and the native window initialization in dioxus_application.rs. Trace how DioxusDocument.inner is owned and how existing values enter ScopeId::ROOT, then verify that a BaseDocumentHandle is available to native components without exposing the raw document directly.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
desktop
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.