Skip to content

feat(ui): Guarantee consuming-app global CSS can't distort Bible components - Shadow DOM - #348

Draft
cameronapak wants to merge 4 commits into
mainfrom
journey-to-the-shadow-dom
Draft

feat(ui): Guarantee consuming-app global CSS can't distort Bible components - Shadow DOM#348
cameronapak wants to merge 4 commits into
mainfrom
journey-to-the-shadow-dom

Conversation

@cameronapak

@cameronapak cameronapak commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

This PR is in progress and will continue to be defined. This PR was created as a feature branch for https://lifechurch.atlassian.net/browse/YPE-4113.

Greptile Summary

The PR prototypes automatic Shadow DOM style isolation for YouVersionAuthButton and documents the resulting compatibility boundaries.

  • Adds a reusable shadow-root host with constructable-stylesheet and fallback style delivery.
  • Wraps the authentication button while preserving its public React props and forwarded ref.
  • Adds hostile-CSS demonstrations, browser stories, lifecycle tests, an ADR, and a coordinated major changeset.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains within the eligible follow-up-review scope.

No blocking failure remains.

Important Files Changed

Filename Overview
packages/ui/src/lib/shadow-root-host.tsx Adds the shadow-root lifecycle, per-document constructed stylesheet cache, fallback style resource, host reset, and React portal.
packages/ui/src/lib/shadow-isolation.tsx Adds a typed higher-order wrapper that preserves component props and forwarded refs while introducing the isolation host.
packages/ui/src/components/YouVersionAuthButton.tsx Moves the existing authentication-button implementation behind automatic Shadow DOM isolation and pins its intended font utility.
packages/ui/src/styles/global.css Adds shadow-host pseudo-element suppression to the generated SDK stylesheet.
packages/ui/src/components/YouVersionAuthButton.shadow-isolation.stories.tsx Adds browser coverage for hostile global selectors, host pseudo-elements, and same-origin iframe stylesheet adoption.
packages/ui/src/lib/shadow-root-host.test.tsx Adds focused unit coverage for Strict Mode attachment, host resets, and fallback stylesheet identity.
docs/adr/0005-prototype-shadow-dom-style-isolation.md Documents the prototype architecture, compatibility impact, verified behavior, and deliberately deferred concerns.
.changeset/prototype-shadow-dom-isolation.md Records the prototype as a coordinated major release across the fixed-version SDK packages.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Consumer[Consumer application] --> Host[Light-DOM shadow host]
  Host --> Root[Open shadow root]
  Styles[Embedded SDK stylesheet] --> Root
  Root --> Portal[React portal]
  Portal --> Button[YouVersionAuthButton implementation]
  HostCSS[Consumer global CSS] -. selector boundary .-> Host
Loading

Reviews (3): Last reviewed commit: "Merge branch 'main' into journey-to-the-..." | Re-trigger Greptile

Context used (3)

* feat(ui)!: prototype automatic Shadow DOM isolation

* docs(examples): add hostile CSS POC demo

* docs(examples): clarify hostile CSS vectors

* docs(ui): align shadow DOM prototype ADR

* test(ui): strengthen shadow isolation proof

* refactor(ui): remove shadow isolation type assertions

* fix(ui): block hostile shadow host pseudo-elements

* docs(ui): clarify shadow isolation trade-offs

* test(ui): align shadow isolation demo conventions

* docs(examples): keep hostile demo labels readable

* fix(ui): use style precedence for shadow fallback stylesheet

Addresses PR review feedback: the non-adoptedStyleSheets fallback
rendered a bare <style> tag inside the shadow-root portal. Use
React 19's <style href precedence> resource form instead so React
hoists and de-duplicates the stylesheet within the shadow root
rather than risking duplicate insertion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: abharms <aharms@works24.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
@cameronapak cameronapak self-assigned this Aug 19, 2026
@changeset-bot

changeset-bot Bot commented Aug 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e8bad1b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@youversion/platform-core Major
@youversion/platform-react-hooks Major
@youversion/platform-react-ui Major
vite-react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cameronapak cameronapak reopened this Aug 25, 2026
@cameronapak
cameronapak marked this pull request as draft August 25, 2026 14:20
abharms and others added 2 commits August 25, 2026 12:45
* feat(ui): prototype shadow-local top-layer popovers

* fix(ui): reconcile shadow portal strategy changes

* fix(ui): narrow shadow portal spike scope

* fix(ui): harden shadow portal lifecycle

---------

Co-authored-by: abharms <aharms@works24.com>
* feat(ui): validate shadow DOM dialog top layer

* docs(ui): separate shadow DOM rollout plan

* refactor(ui): simplify shadow dialog coordination

* test(ui): prove shadow dialog escapes clipping

* refactor(ui): tighten shadow dialog portal behavior

---------

Co-authored-by: abharms <aharms@works24.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants