Skip to content

Replace ember-modal-dialog with native <dialog> and Popover API - #1710

Open
andreisebastianc wants to merge 1 commit into
ember-learn:mainfrom
andreisebastianc:replace-ember-modal-dialog-with-native-popover-and-dialog
Open

andreisebastianc wants to merge 1 commit into
ember-learn:mainfrom
andreisebastianc:replace-ember-modal-dialog-with-native-popover-and-dialog

Conversation

@andreisebastianc

Copy link
Copy Markdown

ember-modal-dialog (and its ember-tether/ember-wormhole dependencies) is unmaintained and blocks upgrading consuming apps. The three places that used it now rely on browser primitives instead:

  • Search results and the version selector are popover="manual" elements rendered in the top layer and placed next to their anchor with CSS anchor positioning (position-anchor / position-area, with @position-try fallbacks that pin to the viewport edge or flip, like ember-tether's "pin" constraint did). Browsers that support popovers but not anchor positioning (Safari 17/18, Firefox < 147) fall back to inline top/left styles computed from the anchor's bounding box.
  • The keyboard shortcuts modal is a native <dialog> opened with showModal(): the browser provides the backdrop, focus trapping, inert page content, Escape handling and (where supported) light dismiss via closedby="any"; a click-on-backdrop fallback covers older browsers.

Behavioural fixes that came with this:

  • A long list of versions now scrolls inside the dropdown instead of running off the bottom of the viewport.
  • Clicking the search input no longer closes the results and clears the query (the old click-outside handler did not exclude the anchor).
  • Escape closes the version selector.
  • The dialog close control is a instead of an href="#" link, and the page behind the open dialog no longer scrolls.

ember-modal-dialog (and its ember-tether/ember-wormhole dependencies) is
unmaintained and blocks upgrading consuming apps. The three places that
used it now rely on browser primitives instead:

- Search results and the version selector are `popover="manual"` elements
  rendered in the top layer and placed next to their anchor with CSS
  anchor positioning (`position-anchor` / `position-area`, with
  `@position-try` fallbacks that pin to the viewport edge or flip, like
  ember-tether's "pin" constraint did). Browsers that support popovers but
  not anchor positioning (Safari 17/18, Firefox < 147) fall back to inline
  top/left styles computed from the anchor's bounding box.
- The keyboard shortcuts modal is a native `<dialog>` opened with
  `showModal()`: the browser provides the backdrop, focus trapping, inert
  page content, Escape handling and (where supported) light dismiss via
  `closedby="any"`; a click-on-backdrop fallback covers older browsers.

Behavioural fixes that came with this:
- A long list of versions now scrolls inside the dropdown instead of
  running off the bottom of the viewport.
- Clicking the search input no longer closes the results and clears the
  query (the old click-outside handler did not exclude the anchor).
- Escape closes the version selector.
- The dialog close control is a <button> instead of an `href="#"` link,
  and the page behind the open dialog no longer scrolls.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@andreisebastianc

andreisebastianc commented Oct 12, 2026 •

Copy link
Copy Markdown
Author

What's this:

I use ember-cli-addon-docs at my workplace. For a long time, it's been clear to me that the addon will have trouble moving to newer ember versions because of several abandoned addons like ember-modal-dialog.

I think simply inlining the addon code is not a good idea, even if other deprecated addons like ember-tether would be inlined at the same time.
The browser provides better primitives than those.

I've made sure to use modifiers instead of did-insert hooks.

This implementation maintains feature parity, for better or worse.

P.S.:

  • I couldn't find in the repo a clear stance against contributions done with LLMS
  • I wouldn't have had the time to manually do this, but I did review all the work and made significant changes to LLM output by delegating change requests back to the LLM
  • The model used is in the commit, and I can produce the prompts

@andreisebastianc

Copy link
Copy Markdown
Author

(ai generated text)

Visual parity

Pixel-compared the dummy app at 1440×900 before/after in Chrome 154: keyboard dialog 0 px differ; version selector 0.02%; search dropdown 0.15%; long version list 0.26%; narrow (480px) version selector 0.22%. The non-zero numbers are 1px text anti-aliasing shifts. Also verified in Firefox 156 and with the JS fallback forced on (same alignment).

Intentional differences:

  • A long version list now scrolls inside the dropdown instead of running off the viewport (previously there was no scrollbar).
  • Clicking the search input no longer closes the results and clears the query (the old click-outside handler didn't exclude the anchor).
  • Escape now closes the version selector.
  • The dialog's close control is a <button> instead of an href="#" link, the dialog takes focus when opened (screen readers announce it via aria-labelledby), and the page behind it no longer scrolls.
  • When the dialog is taller than the viewport it scrolls internally rather than the overlay scrolling.
after-keyboard after-search after-version after-version-many after-version-narrow before-keyboard before-search before-version before-version-many before-version-narrow firefox-combined firefox-keyboard firefox-search firefox-version firefox-version-many firefox-version-narrow

This branch has not been deployed

No deployments
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