Skip to content

Commit 187002d

Browse files
authored
Add setConfig and deprecate passing config via environment.js (#1020)
* Add `setConfig` and deprecate passing config over `environment` * Fix lint * Fix shadow dom tests * Fix lint * Fix test
1 parent ea7f093 commit 187002d

File tree

8 files changed

+136
-49
lines changed

8 files changed

+136
-49
lines changed

docs/app/app.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ import Resolver from 'ember-resolver';
33
import loadInitializers from 'ember-load-initializers';
44
import config from './config/environment';
55
import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros';
6-
76
import compatModules from '@embroider/virtual/compat-modules';
7+
import { setConfig } from 'ember-basic-dropdown/config';
88

99
if (macroCondition(isDevelopingApp())) {
1010
importSync('./deprecation-workflow');
1111
}
1212

13+
setConfig({
14+
rootElement: config.APP['rootElement'] as string | undefined,
15+
});
16+
1317
export default class App extends Application {
1418
modulePrefix = config.modulePrefix;
1519
podModulePrefix = config.podModulePrefix;

ember-basic-dropdown/rollup.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export default [
5454
// See https://github.com/embroider-build/embroider/blob/main/docs/v2-faq.md#how-can-i-define-the-public-exports-of-my-addon
5555
addon.publicEntrypoints([
5656
'index.js',
57+
'config.js',
5758
'styles.js',
5859
'components/**/*.js',
5960
'modifiers/**/*.js',

ember-basic-dropdown/src/components/basic-dropdown-wormhole.gts

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,49 @@
11
import Component from '@glimmer/component';
22
import { getOwner } from '@ember/application';
3+
import { config as utilConfig, _configSet, type Config } from '../config.ts';
4+
import { deprecate } from '@ember/debug';
35

46
export interface BasicDropdownWormholeSignature {
57
Element: HTMLElement;
68
}
79

810
export default class BasicDropdownWormholeComponent extends Component<BasicDropdownWormholeSignature> {
911
get getDestinationId(): string {
10-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
11-
// @ts-ignore
12-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
13-
const config = getOwner(this).resolveRegistration('config:environment') as {
14-
'ember-basic-dropdown'?: {
15-
destination?: string;
12+
let config = utilConfig;
13+
14+
if (!_configSet) {
15+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
16+
// @ts-ignore
17+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
18+
const configEnvironment = getOwner(this).resolveRegistration(
19+
'config:environment',
20+
) as {
21+
'ember-basic-dropdown'?: Config;
1622
};
17-
};
1823

19-
return (
20-
(config['ember-basic-dropdown'] &&
21-
config['ember-basic-dropdown'].destination) ||
22-
'ember-basic-dropdown-wormhole'
23-
);
24+
if (configEnvironment['ember-basic-dropdown']) {
25+
const legacyConfigString = JSON.stringify(
26+
configEnvironment['ember-basic-dropdown'],
27+
);
28+
deprecate(
29+
`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});`,
30+
false,
31+
{
32+
for: 'ember-basic-dropdown',
33+
id: 'ember-basic-dropdown.config-environment',
34+
since: {
35+
enabled: '8.9',
36+
available: '8.9',
37+
},
38+
until: '9.0.0',
39+
},
40+
);
41+
42+
config = configEnvironment['ember-basic-dropdown'];
43+
}
44+
}
45+
46+
return config.destination || 'ember-basic-dropdown-wormhole';
2447
}
2548

2649
<template>

ember-basic-dropdown/src/components/basic-dropdown.gts

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import type {
2727
TRootEventType,
2828
} from '../types.ts';
2929
import { deprecate } from '@ember/debug';
30+
import { isTesting } from '@embroider/macros';
31+
import { config as utilConfig, _configSet, type Config } from '../config.ts';
3032

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

395397
_getDestinationId(): string {
396-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
397-
// @ts-ignore
398-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
399-
const config = getOwner(this).resolveRegistration('config:environment') as {
400-
environment: string;
401-
APP: {
402-
rootElement: string;
398+
let config = utilConfig;
399+
400+
if (!_configSet) {
401+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
402+
// @ts-ignore
403+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
404+
const configEnvironment = getOwner(this).resolveRegistration(
405+
'config:environment',
406+
) as {
407+
APP: {
408+
rootElement: string;
409+
};
410+
'ember-basic-dropdown': Config;
403411
};
404-
'ember-basic-dropdown': {
405-
destination: string;
406-
};
407-
};
408412

409-
if (config.environment === 'test') {
413+
if (configEnvironment['ember-basic-dropdown']) {
414+
const legacyConfigString = JSON.stringify(
415+
configEnvironment['ember-basic-dropdown'],
416+
);
417+
deprecate(
418+
`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});`,
419+
false,
420+
{
421+
for: 'ember-basic-dropdown',
422+
id: 'ember-basic-dropdown.config-environment',
423+
since: {
424+
enabled: '8.9',
425+
available: '8.9',
426+
},
427+
until: '9.0.0',
428+
},
429+
);
430+
431+
config = configEnvironment['ember-basic-dropdown'];
432+
}
433+
434+
if (configEnvironment['APP']?.rootElement) {
435+
deprecate(
436+
`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']});`,
437+
false,
438+
{
439+
for: 'ember-basic-dropdown',
440+
id: 'ember-basic-dropdown.config-environment',
441+
since: {
442+
enabled: '8.9',
443+
available: '8.9',
444+
},
445+
until: '9.0.0',
446+
},
447+
);
448+
449+
config.rootElement = configEnvironment['APP']?.rootElement;
450+
}
451+
}
452+
453+
if (isTesting()) {
410454
// document doesn't exist in fastboot apps, for this reason we need this check
411455
if (typeof document === 'undefined') {
412456
return 'ember-basic-dropdown-wormhole';
413457
}
414458

415459
// check if destination exists in tests:
416-
if (
417-
config['ember-basic-dropdown'] &&
418-
config['ember-basic-dropdown'].destination
419-
) {
420-
const destination = config['ember-basic-dropdown'].destination;
460+
if (config.destination) {
461+
const destination = config.destination;
421462
if (document.getElementById(destination) !== null) {
422463
return destination;
423464
}
@@ -429,18 +470,14 @@ export default class BasicDropdown extends Component<BasicDropdownSignature> {
429470
}
430471

431472
// fall back to rootElement as destination
432-
const rootElement = config['APP']?.rootElement;
473+
const rootElement = config.rootElement;
433474
return (
434-
document.querySelector(rootElement)?.id ??
475+
(rootElement ? document.querySelector(rootElement)?.id : undefined) ??
435476
'ember-basic-dropdown-wormhole'
436477
);
437478
}
438479

439-
return (
440-
(config['ember-basic-dropdown'] &&
441-
config['ember-basic-dropdown'].destination) ||
442-
'ember-basic-dropdown-wormhole'
443-
);
480+
return config.destination || 'ember-basic-dropdown-wormhole';
444481
}
445482

446483
_getDropdownElement(): HTMLElement | null {

ember-basic-dropdown/src/config.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export interface Config {
2+
destination?: string;
3+
rootElement?: string;
4+
}
5+
6+
let _config: Config = {};
7+
8+
// This will be removed in next major, don't use this outside the package!
9+
let _configSet = false;
10+
11+
export function setConfig(config: Config) {
12+
_config = config;
13+
_configSet = true;
14+
}
15+
16+
export { _config as config, _configSet };

test-app/app/app.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@ import Resolver from 'ember-resolver';
33
import loadInitializers from 'ember-load-initializers';
44
import config from 'test-app/config/environment';
55
import { importSync, isDevelopingApp, macroCondition } from '@embroider/macros';
6+
import { setConfig, type Config } from 'ember-basic-dropdown/config';
67

78
if (macroCondition(isDevelopingApp())) {
89
importSync('./deprecation-workflow');
910
}
1011

12+
export const defaultBasicDropdownConfig: Config = {
13+
rootElement: config.APP['rootElement'] as string | undefined,
14+
};
15+
16+
setConfig(defaultBasicDropdownConfig);
17+
1118
export default class App extends Application {
1219
modulePrefix = config.modulePrefix;
1320
podModulePrefix = config.podModulePrefix;

test-app/app/instance-initializers/shadow-root.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type ApplicationInstance from '@ember/application/instance';
2+
import { setConfig } from 'ember-basic-dropdown/config';
23
import config from 'test-app/config/environment';
34

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

3334
config.APP['rootElement'] = '#ember-basic-dropdown-wormhole';
3435
appInstance.set('rootElement', rootElement);
36+
37+
setConfig({
38+
rootElement: '#ember-basic-dropdown-wormhole',
39+
});
3540
}
3641

3742
export default {

test-app/tests/integration/components/basic-dropdown-wormhole-test.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { module, test } from 'qunit';
22
import { setupRenderingTest } from 'ember-qunit';
33
import { hbs } from 'ember-cli-htmlbars';
44
import { render } from '@ember/test-helpers';
5-
import config from 'test-app/config/environment';
5+
import { setConfig } from 'ember-basic-dropdown/config';
6+
import { defaultBasicDropdownConfig } from 'test-app/app';
67
import type { TestContext } from '@ember/test-helpers';
78

89
interface ExtendedTestContext extends TestContext {
910
element: HTMLElement;
10-
originalConfig: Record<string, unknown>;
1111
}
1212

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

20-
hooks.beforeEach(function (this: ExtendedTestContext) {
21-
// Duplicate config to avoid mutating global config
22-
this.originalConfig = JSON.parse(
23-
JSON.stringify(config['ember-basic-dropdown'] || {}),
24-
) as Record<string, unknown>;
25-
});
26-
2720
hooks.afterEach(function (this: ExtendedTestContext) {
28-
config['ember-basic-dropdown'] = this.originalConfig;
21+
setConfig(defaultBasicDropdownConfig);
2922
});
3023

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

4134
test<ExtendedTestContext>('Uses custom destination from config if present', async function (assert) {
42-
config['ember-basic-dropdown'] = {
35+
setConfig({
36+
...defaultBasicDropdownConfig,
4337
destination: 'custom-wormhole-destination',
44-
};
38+
});
4539

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

0 commit comments

Comments
 (0)