Skip to content

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

Open
cameronapak wants to merge 1 commit into
mainfrom
journey-to-the-shadow-dom
Open

feat(ui): Guarantee consuming-app global CSS can't distort Bible components - Shadow DOM#348
cameronapak wants to merge 1 commit 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 marks the resulting DOM, SSR, and ref changes as breaking.

  • Adds a reusable shadow host and ref-preserving isolation wrapper.
  • Installs the compiled SDK stylesheet inside each shadow root, with constructable and <style> fallback paths.
  • Adds hostile-CSS examples, Storybook coverage, unit tests, an ADR, and a major unified changeset.

Confidence Score: 5/5

The prototype appears safe to merge within its explicitly documented breaking and deferred scope.

The shadow boundary, stylesheet installation paths, ref forwarding, hostile-CSS coverage, and breaking changeset are internally consistent, and no unacknowledged actionable defect was established.

Important Files Changed

Filename Overview
packages/ui/src/lib/shadow-root-host.tsx Adds effect-driven shadow-root creation, host resets, per-document constructable stylesheets, and a fallback style resource.
packages/ui/src/lib/shadow-isolation.tsx Adds a generic forwarded-ref HOC that renders an implementation through the shadow host.
packages/ui/src/components/YouVersionAuthButton.tsx Moves the existing public button behind automatic Shadow DOM isolation and explicitly applies its sans-serif utility.
packages/ui/src/styles/global.css Adds shadow-context rules that suppress generated content on the selectable light-DOM host.
packages/ui/src/components/YouVersionAuthButton.shadow-isolation.stories.tsx Exercises hostile global selectors and same-origin iframe stylesheet adoption.
docs/adr/0005-prototype-shadow-dom-style-isolation.md Documents the prototype architecture, verified scope, breaking compatibility impact, and deliberately deferred limitations.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  App[Consumer application] --> Host[Light-DOM shadow host]
  Host --> Root[Open ShadowRoot]
  Root --> Styles[SDK stylesheet]
  Root --> Wrapper[Internal reset wrapper]
  Wrapper --> Button[YouVersionAuthButton implementation]
  Global[Consumer global CSS] --> Host
  Global -. selector boundary .-> Root
Loading

Reviews (1): Last reviewed commit: "feat(ui): prototype automatic Shadow DOM..." | Re-trigger Greptile

Context used:

* 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: 69841bf

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

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.

1 participant