adobe / adobe/react-spectrum

Use the correct ownerDocument

Open
#4,634 6 comments 3 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
15.9k
Forks
1.6k
Avg merge
3d 9m
Merged PRs (30d)
59

Description

# 🙋 Feature Request

The codebase has a lot of references of `document`. The problem of using `document` is that it causes a lot of issues when the the component is dynamically added to an iframe. This technique is different from loading a separate URL in an iframe. See https://dev.to/graftini/rendering-in-an-iframe-in-a-react-app-2boa for more details about this approach.

This technique is generally useful for libraries because:
- You can keep your styling isolated
- You can keep your events listeners isolated and
- You can accept any JS as a library option which would not have been possible if you loaded a separate HTML.

## 🤔 Expected Behavior

react-aria should accept document from outside.

## 😯 Current Behavior

The codebase doesn't accept a custom ownerDocument

## 💁 Possible Solution

There are three ways to accomplish this:

- **The first option** is to implement it at the hooks level or by passing the document to a `DocumentProvider`, similar to how the `I18nProvider` works.
- **The second option** is to pass the `ownerDocument` in every hook that uses document/window, making the API easier to use without any breaking changes. Additionally, if a custom window is desired, the `ownerDocument.defaultView` can be used.

```ts
usePopover({
// If not passed the default document is used.
ownerDocument?: Document
})
```

- **The third option** is to just deduce the `ownerDocument` using the ref used in the hooks. This means that nothing changes in the public API and correct document is always used. This is the simplest solution.

## 🔦 Context

We have a library with its own user interface (UI) that can be placed within any webpage. To ensure isolation of events and styling, we render the React component inside an iframe. This approach reduces the likelihood of bugs caused by conflicting customer code. Since certain options in the software development kit (SDK) cannot be serialized and passed into an iframe, we cannot load a separate HTML page to handle those options. Consequently, dynamically rendering the React component is the only viable solution for utilizing these options.

## 💻 Examples

Unanswered discussion: https://github.com/adobe/react-spectrum/discussions/2237 similar to this.
Open issue: https://github.com/adobe/react-spectrum/issues/3350

I have opened this issue because the issue is not limited to `FocusScope`

**Popover** suffers similar issue where it calculates the popover positioning related to main window.

https://github.com/adobe/react-spectrum/assets/5389035/8bae630a-8b40-400d-8792-1dec912c317b

## PR

**I will be happy to open a PR and avoid maintaining fork. The API can be gradually implemented and it doesn't have to be one big PR.**

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the hooks that reference document or window, especially FocusScope and Popover, and compare the related discussion 2237 and issue 3350. Evaluate the three proposed approaches—provider, per-hook ownerDocument, or ref-based deduction—and define completion as correct document and positioning behavior for components dynamically rendered inside an iframe.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.