@visitwonders/assembly
v0.19.1
Published
The default blueprint for Embroider v2 addons.
Downloads
616
Readme
@visitwonders/assembly
[Short description of the addon.]
Compatibility
- Ember.js v4.12 or above
- Embroider or ember-auto-import v2
Installation
ember install @visitwonders/assemblySetup
Overlay components (Popover, Tooltip, Modal, Drawer, Blanket,
Toast) render through ember-primitives' <Portal>. The consuming
app must mount <PortalTargets /> once — typically in the application
template — so that Assembly overlays can find their portal
destinations:
import { PortalTargets } from '@visitwonders/assembly/overlay';
<template>
{{outlet}}
<PortalTargets />
</template><PortalTargets /> renders three empty <div> elements as portal
destinations. Its position in the template is layout-neutral —
overlays use fixed/absolute positioning and don't affect document
flow.
Without this, the first overlay you open will throw an assertion:
Could not find element by the given name: ember-primitives__portal-targets__popover.
Integration tests
setupRenderingTest does not render the application template, so
rendering tests that exercise any component containing an overlay
(directly or transitively — e.g. SelectField, DatePickerField,
MultiSelect, anything that uses a dropdown or a tooltip-on-label)
need portal destinations inside #ember-testing. The cleanest
pattern is to inject them in your shared setupRenderingTest
wrapper so every rendering test gets them automatically — no
per-test boilerplate, no wrapper around render:
// tests/helpers/index.ts
import { setupRenderingTest as upstreamSetupRenderingTest } from 'ember-qunit';
import type { SetupTestOptions } from 'ember-qunit';
const PORTAL_TARGET_NAMES = [
'ember-primitives__portal-targets__popover',
'ember-primitives__portal-targets__tooltip',
'ember-primitives__portal-targets__modal',
] as const;
export function setupRenderingTest(
hooks: NestedHooks,
options?: SetupTestOptions,
) {
upstreamSetupRenderingTest(hooks, options);
hooks.beforeEach(function () {
const root = document.getElementById('ember-testing');
if (!root) return;
for (const name of PORTAL_TARGET_NAMES) {
const target = document.createElement('div');
target.setAttribute('data-portal-name', name);
target.setAttribute('data-test-portal-target', '');
root.appendChild(target);
}
});
hooks.afterEach(function () {
const root = document.getElementById('ember-testing');
if (!root) return;
for (const target of root.querySelectorAll('[data-test-portal-target]')) {
target.remove();
}
});
}This works because @ember/test-helpers' setupRenderingContext
appends (rather than replaces) the Ember outlet view inside
#ember-testing, so sibling elements injected here survive every
render() call and are still reachable by Portal's
findNearestTarget walk. Tests can keep importing render from
@ember/test-helpers unchanged. Application tests
(setupApplicationTest) are unaffected — they pick up
<PortalTargets /> from the application template automatically.
Usage
[Longer description of how to use the addon in apps.]
Migrations
Breaking changes — token retirements, behaviour shifts, and visual-parity diffs that downstream consumers should know about — are documented one-file-per-change under docs/migrations/.
Recent:
- Token Extension and Focus Ring Upgrade (2026-04-27): surface-vs-fill split, two-stop focus ring (WCAG 2.2 non-text-contrast), typography role sub-tokens, action + input matrices populated, halo tokens retired.
Contributing
See the Contributing guide for details.
License
This project is licensed under the MIT License.
