ember-maybe-in-element
Ember addon that conditionally renders block content in-place or teleports it into another DOM element.
Repository Health
Technical Analysis
ember-maybe-in-element is a small Ember.js addon that wraps the native {{in-element}} keyword with a conditional toggle. Its {{#maybe-in-element}} block helper takes a destination element and a boolean flag: when the flag is true, the block renders in its original location in the template; when false, it’s teleported into the destination element via Ember’s built-in in-element. This spares developers from hand-writing two copies of the same block guarded by an {{if}}, which is easy to let drift out of sync as the markup evolves.
Under the hood, the addon uses an AST transform (registered through Ember CLI’s preprocessor registry) to compile {{#maybe-in-element el renderInPlace}}...{{/maybe-in-element}} into a <MaybeInElement> component invocation, keeping the runtime piece — a tiny Glimmer template that switches between {{yield}} and {{#in-element}} — dead simple. It depends on ember-in-element-polyfill for compatibility back to Ember 2.10.
What You Get
- A
{{#maybe-in-element}}template helper accepting a destination element and a renderInPlace boolean - A compile-time AST transform that expands the helper into native
{{in-element}}usage with zero extra runtime helper cost - Automatic detection of the host app’s Ember version (3.17+) to emit the correct angle-bracket or curly invocation syntax
- Compatibility down to Ember 2.10 by building on top of
ember-in-element-polyfill
Common Use Cases
- Toggling a modal or tooltip between rendering inline (e.g. for SSR/FastBoot) and portalled into a dedicated DOM node
- Building responsive layouts where content needs to move between a sidebar and a mobile drawer depending on a boolean
- Sharing one template block between an in-place preview and a teleported live view without duplicating markup
- Consolidating older
{{if}}/{{in-element}}duplication in legacy codebases into one maintained pattern
Under The Hood
Architecture
The addon registers a single AST transform via setupPreprocessorRegistry in index.js, which builds a Glimmer AST plugin (lib/ast-transform.js) whose visitor matches BlockStatement nodes named maybe-in-element and rewrites them at compile time into a <MaybeInElement> element invocation carrying @destinationElement and @renderInPlace attributes; the runtime side is just app/components/maybe-in-element.js re-exporting a one-line addon/components/maybe-in-element.hbs template that branches between {{yield}} and {{#in-element}}{{yield}}{{/in-element}}. There’s no service layer, no persisted state, and no other moving parts — the whole addon is a compile-time sugar layer over a native primitive.
Tech Stack
It’s a standard Ember CLI addon built with ember-cli-babel, ember-cli-htmlbars, and ember-cli-version-checker as runtime dependencies, developed against a full Ember 4.x toolchain (ember-cli, ember-source, ember-qunit, ember-auto-import/webpack for the dummy test app) with ember-try configured for cross-version compatibility testing. There is no server, database, or build output beyond the standard addon bundle consumed by a host Ember application.
Code Quality
Integration tests in tests/integration/maybe-in-element-test.js use ember-qunit and @ember/test-helpers to cover both branches of the conditional, reactive toggling of the renderInPlace argument, and preservation of action context inside the teleported block — a reasonably thorough suite for the addon’s scope. ESLint and ember-template-lint are configured, but there’s no TypeScript, and CI runs on Travis CI (.travis.yml), a hosted service that has effectively stopped serving open-source projects, which lines up with the repo’s inactive status and last commit in early 2023.
API Design
The public surface is intentionally tiny: one block helper, two positional arguments, and an optional insertBefore, mirroring the native {{in-element}} keyword it wraps so existing Ember knowledge transfers directly. Getting started requires a single ember install and no configuration, though documentation beyond the README’s one code example is minimal.