Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ import Resolver from 'ember-resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros';

import compatModules from '@embroider/virtual/compat-modules';
import { setConfig } from 'ember-basic-dropdown/config';

if (macroCondition(isDevelopingApp())) {
importSync('./deprecation-workflow');
}

setConfig({
rootElement: config.APP['rootElement'] as string | undefined,
});

export default class App extends Application {
modulePrefix = config.modulePrefix;
podModulePrefix = config.podModulePrefix;
Expand Down
1 change: 1 addition & 0 deletions ember-basic-dropdown/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default [
// See https://github.com/embroider-build/embroider/blob/main/docs/v2-faq.md#how-can-i-define-the-public-exports-of-my-addon
addon.publicEntrypoints([
'index.js',
'config.js',
'styles.js',
'components/**/*.js',
'modifiers/**/*.js',
Expand Down
47 changes: 35 additions & 12 deletions ember-basic-dropdown/src/components/basic-dropdown-wormhole.gts
Original file line number Diff line number Diff line change
@@ -1,26 +1,49 @@
import Component from '@glimmer/component';
import { getOwner } from '@ember/application';
import { config as utilConfig, _configSet, type Config } from '../config.ts';
import { deprecate } from '@ember/debug';

export interface BasicDropdownWormholeSignature {
Element: HTMLElement;
}

export default class BasicDropdownWormholeComponent extends Component<BasicDropdownWormholeSignature> {
get getDestinationId(): string {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const config = getOwner(this).resolveRegistration('config:environment') as {
'ember-basic-dropdown'?: {
destination?: string;
let config = utilConfig;

if (!_configSet) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const configEnvironment = getOwner(this).resolveRegistration(
'config:environment',
) as {
'ember-basic-dropdown'?: Config;
};
};

return (
(config['ember-basic-dropdown'] &&
config['ember-basic-dropdown'].destination) ||
'ember-basic-dropdown-wormhole'
);
if (configEnvironment['ember-basic-dropdown']) {
const legacyConfigString = JSON.stringify(
configEnvironment['ember-basic-dropdown'],
);
deprecate(
`You have configured \`ember-basic-dropdown\` in \`ember-cli-build.js\`. Remove that configuration and instead use \`import { setConfig } from 'ember-basic-dropdown/config'; setConfig(${legacyConfigString});`,
false,
{
for: 'ember-basic-dropdown',
id: 'ember-basic-dropdown.config-environment',
since: {
enabled: '8.9',
available: '8.9',
},
until: '9.0.0',
},
);

config = configEnvironment['ember-basic-dropdown'];
}
}

return config.destination || 'ember-basic-dropdown-wormhole';
}

<template>
Expand Down
85 changes: 61 additions & 24 deletions ember-basic-dropdown/src/components/basic-dropdown.gts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import type {
TRootEventType,
} from '../types.ts';
import { deprecate } from '@ember/debug';
import { isTesting } from '@embroider/macros';
import { config as utilConfig, _configSet, type Config } from '../config.ts';

// To avoid breaking the current types export we need this
export type { Dropdown, DropdownActions, TRootEventType };
Expand Down Expand Up @@ -393,31 +395,70 @@ export default class BasicDropdown extends Component<BasicDropdownSignature> {
}

_getDestinationId(): string {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const config = getOwner(this).resolveRegistration('config:environment') as {
environment: string;
APP: {
rootElement: string;
let config = utilConfig;

if (!_configSet) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const configEnvironment = getOwner(this).resolveRegistration(
'config:environment',
) as {
APP: {
rootElement: string;
};
'ember-basic-dropdown': Config;
};
'ember-basic-dropdown': {
destination: string;
};
};

if (config.environment === 'test') {
if (configEnvironment['ember-basic-dropdown']) {
const legacyConfigString = JSON.stringify(
configEnvironment['ember-basic-dropdown'],
);
deprecate(
`You have configured \`ember-basic-dropdown\` in \`ember-cli-build.js\`. Remove that configuration and instead use \`import { setConfig } from 'ember-basic-dropdown/config'; setConfig(${legacyConfigString});`,
false,
{
for: 'ember-basic-dropdown',
id: 'ember-basic-dropdown.config-environment',
since: {
enabled: '8.9',
available: '8.9',
},
until: '9.0.0',
},
);

config = configEnvironment['ember-basic-dropdown'];
}

if (configEnvironment['APP']?.rootElement) {
deprecate(
`ember-basic-dropdown received the \`APP.rootElement\` value from \`ember-cli-build.js\`. You now need to pass this value using \`import { setConfig } from 'ember-basic-dropdown/config'; setConfig({rootElement: config.APP['rootElement']});`,
false,
{
for: 'ember-basic-dropdown',
id: 'ember-basic-dropdown.config-environment',
since: {
enabled: '8.9',
available: '8.9',
},
until: '9.0.0',
},
);

config.rootElement = configEnvironment['APP']?.rootElement;
}
}

if (isTesting()) {
// document doesn't exist in fastboot apps, for this reason we need this check
if (typeof document === 'undefined') {
return 'ember-basic-dropdown-wormhole';
}

// check if destination exists in tests:
if (
config['ember-basic-dropdown'] &&
config['ember-basic-dropdown'].destination
) {
const destination = config['ember-basic-dropdown'].destination;
if (config.destination) {
const destination = config.destination;
if (document.getElementById(destination) !== null) {
return destination;
}
Expand All @@ -429,18 +470,14 @@ export default class BasicDropdown extends Component<BasicDropdownSignature> {
}

// fall back to rootElement as destination
const rootElement = config['APP']?.rootElement;
const rootElement = config.rootElement;
return (
document.querySelector(rootElement)?.id ??
(rootElement ? document.querySelector(rootElement)?.id : undefined) ??
'ember-basic-dropdown-wormhole'
);
}

return (
(config['ember-basic-dropdown'] &&
config['ember-basic-dropdown'].destination) ||
'ember-basic-dropdown-wormhole'
);
return config.destination || 'ember-basic-dropdown-wormhole';
}

_getDropdownElement(): HTMLElement | null {
Expand Down
16 changes: 16 additions & 0 deletions ember-basic-dropdown/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export interface Config {
destination?: string;
rootElement?: string;
}

let _config: Config = {};

// This will be removed in next major, don't use this outside the package!
let _configSet = false;

export function setConfig(config: Config) {
_config = config;
_configSet = true;
}

export { _config as config, _configSet };
7 changes: 7 additions & 0 deletions test-app/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ import Resolver from 'ember-resolver';
import loadInitializers from 'ember-load-initializers';
import config from 'test-app/config/environment';
import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros';
import { setConfig, type Config } from 'ember-basic-dropdown/config';

if (macroCondition(isDevelopingApp())) {
importSync('./deprecation-workflow');
}

export const defaultBasicDropdownConfig: Config = {
rootElement: config.APP['rootElement'] as string | undefined,
};

setConfig(defaultBasicDropdownConfig);

export default class App extends Application {
modulePrefix = config.modulePrefix;
podModulePrefix = config.podModulePrefix;
Expand Down
5 changes: 5 additions & 0 deletions test-app/app/instance-initializers/shadow-root.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type ApplicationInstance from '@ember/application/instance';
import { setConfig } from 'ember-basic-dropdown/config';
import config from 'test-app/config/environment';

// @ts-expect-error Public property 'isFastBoot' of exported class
Expand Down Expand Up @@ -32,6 +33,10 @@ export function initialize(appInstance: ApplicationInstance) {

config.APP['rootElement'] = '#ember-basic-dropdown-wormhole';
appInstance.set('rootElement', rootElement);

setConfig({
rootElement: '#ember-basic-dropdown-wormhole',
});
}

export default {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { hbs } from 'ember-cli-htmlbars';
import { render } from '@ember/test-helpers';
import config from 'test-app/config/environment';
import { setConfig } from 'ember-basic-dropdown/config';
import { defaultBasicDropdownConfig } from 'test-app/app';
import type { TestContext } from '@ember/test-helpers';

interface ExtendedTestContext extends TestContext {
element: HTMLElement;
originalConfig: Record<string, unknown>;
}

function getRootNode(element: Element): HTMLElement {
Expand All @@ -17,15 +17,8 @@ function getRootNode(element: Element): HTMLElement {
module('Integration | Component | basic-dropdown-wormhole', function (hooks) {
setupRenderingTest(hooks);

hooks.beforeEach(function (this: ExtendedTestContext) {
// Duplicate config to avoid mutating global config
this.originalConfig = JSON.parse(
JSON.stringify(config['ember-basic-dropdown'] || {}),
) as Record<string, unknown>;
});

hooks.afterEach(function (this: ExtendedTestContext) {
config['ember-basic-dropdown'] = this.originalConfig;
setConfig(defaultBasicDropdownConfig);
});

test<ExtendedTestContext>('Is present', async function (assert) {
Expand All @@ -39,9 +32,10 @@ module('Integration | Component | basic-dropdown-wormhole', function (hooks) {
});

test<ExtendedTestContext>('Uses custom destination from config if present', async function (assert) {
config['ember-basic-dropdown'] = {
setConfig({
...defaultBasicDropdownConfig,
destination: 'custom-wormhole-destination',
};
});

await render(hbs`<BasicDropdownWormhole />`);

Expand Down