@servicetitan/web-components 36.1.1-beta.1 → 36.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/globals.d.ts +3 -3
- package/dist/globals.d.ts.map +1 -1
- package/dist/globals.js +4 -19
- package/dist/globals.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/register-headless.d.ts.map +1 -1
- package/dist/register-headless.js +0 -1
- package/dist/register-headless.js.map +1 -1
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +36 -38
- package/dist/register.js.map +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +11 -3
- package/dist/render.js.map +1 -1
- package/dist/utils/get-bundle-info.d.ts.map +1 -1
- package/dist/utils/get-bundle-info.js +4 -10
- package/dist/utils/get-bundle-info.js.map +1 -1
- package/dist/utils/get-entry-points.d.ts +0 -1
- package/dist/utils/get-entry-points.d.ts.map +1 -1
- package/dist/utils/get-entry-points.js.map +1 -1
- package/dist/utils/get-ld-service-token.d.ts +3 -2
- package/dist/utils/get-ld-service-token.d.ts.map +1 -1
- package/dist/utils/get-ld-service-token.js +7 -2
- package/dist/utils/get-ld-service-token.js.map +1 -1
- package/package.json +12 -21
- package/src/__mocks__/test-component.tsx +2 -9
- package/src/__tests__/event-bus-types.test.ts +2 -1
- package/src/__tests__/register-anvil2.test.tsx +64 -11
- package/src/globals.ts +10 -30
- package/src/index.ts +0 -1
- package/src/register-headless.ts +0 -1
- package/src/register.tsx +42 -48
- package/src/render.ts +14 -3
- package/src/utils/get-bundle-info.ts +5 -11
- package/src/utils/get-entry-points.ts +0 -1
- package/src/utils/get-ld-service-token.ts +10 -2
- package/dist/with-css-injector.d.ts +0 -3
- package/dist/with-css-injector.d.ts.map +0 -1
- package/dist/with-css-injector.js +0 -52
- package/dist/with-css-injector.js.map +0 -1
- package/src/__mocks__/register-anvil2-harness.tsx +0 -49
- package/src/__tests__/register-anvil2-optional.test.tsx +0 -32
- package/src/__tests__/with-css-injector.test.tsx +0 -152
- package/src/with-css-injector.tsx +0 -45
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { act, render } from '@testing-library/react';
|
|
2
|
-
import { FC } from 'react';
|
|
3
|
-
import { useMFEMetadataContext } from '../contexts/mfe-metadata-context';
|
|
4
|
-
import { WEB_COMPONENT_NAME } from '../globals';
|
|
5
|
-
import { withCssInjector } from '../with-css-injector';
|
|
6
|
-
|
|
7
|
-
jest.mock('../contexts/mfe-metadata-context');
|
|
8
|
-
jest.mock('../globals', () => ({
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
10
|
-
WEB_COMPONENT_NAME: 'test-mfe',
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
describe(`[web-components] ${withCssInjector.name}`, () => {
|
|
14
|
-
const innerTestId = 'inner';
|
|
15
|
-
const innerLabel = 'foo';
|
|
16
|
-
const InnerComponent: FC<{ label: string }> = ({ label }) => (
|
|
17
|
-
<div data-testid={innerTestId}>{label}</div>
|
|
18
|
-
);
|
|
19
|
-
const WrappedComponent = withCssInjector(InnerComponent);
|
|
20
|
-
|
|
21
|
-
const componentName = WEB_COMPONENT_NAME as string;
|
|
22
|
-
|
|
23
|
-
let shadowRoot: ShadowRoot;
|
|
24
|
-
let portalShadowRoot: ShadowRoot;
|
|
25
|
-
|
|
26
|
-
beforeEach(() => {
|
|
27
|
-
jest.clearAllMocks();
|
|
28
|
-
delete window.__mfeStyles__;
|
|
29
|
-
delete window.__mfeSelfHosted__;
|
|
30
|
-
shadowRoot = document.createElement('div').attachShadow({ mode: 'open' });
|
|
31
|
-
portalShadowRoot = document.createElement('span').attachShadow({ mode: 'open' });
|
|
32
|
-
document.adoptedStyleSheets = [];
|
|
33
|
-
shadowRoot.adoptedStyleSheets = [];
|
|
34
|
-
portalShadowRoot.adoptedStyleSheets = [];
|
|
35
|
-
jest.mocked(useMFEMetadataContext).mockImplementation(() => ({
|
|
36
|
-
shadowRoot,
|
|
37
|
-
portalShadowRoot,
|
|
38
|
-
}));
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
const subject = () => render(<WrappedComponent label={innerLabel} />);
|
|
42
|
-
|
|
43
|
-
const getEmitter = () => window.__mfeStyles__?.[componentName];
|
|
44
|
-
|
|
45
|
-
test('renders the wrapped component with its props', () => {
|
|
46
|
-
const { getByTestId } = subject();
|
|
47
|
-
|
|
48
|
-
expect(getByTestId(innerTestId).textContent).toBe(innerLabel);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test('initializes the styles registry on window', () => {
|
|
52
|
-
subject();
|
|
53
|
-
|
|
54
|
-
expect(window.__mfeStyles__).toBeDefined();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test('registers an emitter for the component', () => {
|
|
58
|
-
subject();
|
|
59
|
-
|
|
60
|
-
expect(getEmitter()?.sheets).toBeInstanceOf(Map);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe('with a preexisting sheet in the emitter', () => {
|
|
64
|
-
const sheetId = 'sheet-1';
|
|
65
|
-
let sheet: CSSStyleSheet;
|
|
66
|
-
|
|
67
|
-
beforeEach(() => {
|
|
68
|
-
sheet = new CSSStyleSheet();
|
|
69
|
-
const emitter = Object.assign(new EventTarget(), {
|
|
70
|
-
sheets: new Map([[sheetId, sheet]]),
|
|
71
|
-
});
|
|
72
|
-
window.__mfeStyles__ = { [componentName]: emitter };
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test('adopts the sheet into the shadow root', () => {
|
|
76
|
-
subject();
|
|
77
|
-
|
|
78
|
-
expect(shadowRoot.adoptedStyleSheets).toContain(sheet);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test('adopts the sheet into the portal shadow root', () => {
|
|
82
|
-
subject();
|
|
83
|
-
|
|
84
|
-
expect(portalShadowRoot!.adoptedStyleSheets).toContain(sheet);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
test('reuses the existing emitter', () => {
|
|
88
|
-
const existingEmitter = getEmitter();
|
|
89
|
-
|
|
90
|
-
subject();
|
|
91
|
-
|
|
92
|
-
expect(getEmitter()).toBe(existingEmitter);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
describe('when self-hosted in standalone development', () => {
|
|
96
|
-
beforeEach(() => {
|
|
97
|
-
window.__mfeSelfHosted__ = true;
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test('adopts the sheet into document', () => {
|
|
101
|
-
subject();
|
|
102
|
-
|
|
103
|
-
expect(document.adoptedStyleSheets).toContain(sheet);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
describe('when already mounted', () => {
|
|
109
|
-
let unmount: ReturnType<typeof subject>['unmount'];
|
|
110
|
-
let emitter: NonNullable<ReturnType<typeof getEmitter>>;
|
|
111
|
-
|
|
112
|
-
beforeEach(() => {
|
|
113
|
-
unmount = subject().unmount;
|
|
114
|
-
emitter = getEmitter()!;
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
function emit(sheet: CSSStyleSheet) {
|
|
118
|
-
const id = Math.floor(Math.random() * 1e6).toString(36);
|
|
119
|
-
|
|
120
|
-
emitter.sheets.set(id, sheet);
|
|
121
|
-
act(() => {
|
|
122
|
-
emitter.dispatchEvent(new CustomEvent<string>('new-sheet', { detail: id }));
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
describe('when a new-sheet event is dispatched', () => {
|
|
127
|
-
const sheet = new CSSStyleSheet();
|
|
128
|
-
|
|
129
|
-
beforeEach(() => emit(sheet));
|
|
130
|
-
|
|
131
|
-
test('adopts the newly added sheet into the shadow root', () => {
|
|
132
|
-
expect(shadowRoot.adoptedStyleSheets).toContain(sheet);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
test('adopts the newly added sheet into the portal shadow root', () => {
|
|
136
|
-
expect(portalShadowRoot!.adoptedStyleSheets).toContain(sheet);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
describe('when unmounted', () => {
|
|
141
|
-
beforeEach(() => unmount());
|
|
142
|
-
|
|
143
|
-
test('stops adopting newly added sheets', () => {
|
|
144
|
-
const sheet = new CSSStyleSheet();
|
|
145
|
-
|
|
146
|
-
emit(sheet);
|
|
147
|
-
|
|
148
|
-
expect(shadowRoot.adoptedStyleSheets).not.toContain(sheet);
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { ComponentType, useEffect } from 'react';
|
|
2
|
-
import { useMFEMetadataContext } from './contexts/mfe-metadata-context';
|
|
3
|
-
import { WEB_COMPONENT_NAME } from './globals';
|
|
4
|
-
|
|
5
|
-
export function withCssInjector<P extends object>(Component: ComponentType<P>): ComponentType<P> {
|
|
6
|
-
return function CssInjectorWrapper(props: P) {
|
|
7
|
-
const { shadowRoot, portalShadowRoot } = useMFEMetadataContext();
|
|
8
|
-
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
window.__mfeStyles__ ??= {};
|
|
11
|
-
const mfeStyles = window.__mfeStyles__;
|
|
12
|
-
mfeStyles[WEB_COMPONENT_NAME] ??= Object.assign(new EventTarget(), {
|
|
13
|
-
sheets: new Map<string, CSSStyleSheet>(),
|
|
14
|
-
});
|
|
15
|
-
const emitter = mfeStyles[WEB_COMPONENT_NAME];
|
|
16
|
-
/*
|
|
17
|
-
* In self-hosted standalone dev mode (set by index.html), also adopt sheets
|
|
18
|
-
* into document so host-only CSS vars and fonts propagate to the page.
|
|
19
|
-
*/
|
|
20
|
-
const roots = [
|
|
21
|
-
shadowRoot,
|
|
22
|
-
portalShadowRoot,
|
|
23
|
-
...(window.__mfeSelfHosted__ ? [document] : []),
|
|
24
|
-
];
|
|
25
|
-
function adoptSheet(sheet: CSSStyleSheet) {
|
|
26
|
-
for (const root of roots) {
|
|
27
|
-
root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
for (const sheet of emitter.sheets.values()) {
|
|
32
|
-
adoptSheet(sheet);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const handleNewSheet = ({ detail: sheetId }: CustomEvent<string>) => {
|
|
36
|
-
adoptSheet(emitter.sheets.get(sheetId)!);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
emitter.addEventListener('new-sheet', handleNewSheet);
|
|
40
|
-
return () => emitter.removeEventListener('new-sheet', handleNewSheet);
|
|
41
|
-
}, [shadowRoot, portalShadowRoot]);
|
|
42
|
-
|
|
43
|
-
return <Component {...props} />;
|
|
44
|
-
};
|
|
45
|
-
}
|