@servicetitan/web-components 23.1.0 → 23.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.
@@ -0,0 +1,3 @@
1
+ export * from './register-component';
2
+ export * from './test-component';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/__mocks__/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './register-component';
2
+ export * from './test-component';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/__mocks__/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { FunctionComponent } from 'react';
2
+ import { RegisterOptions } from '../register';
3
+ export declare function registerComponent(TestComponent: FunctionComponent, componentName: string | undefined, options?: RegisterOptions): void;
4
+ //# sourceMappingURL=register-component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-component.d.ts","sourceRoot":"","sources":["../../src/__mocks__/register-component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,wBAAgB,iBAAiB,CAC7B,aAAa,EAAE,iBAAiB,EAChC,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,OAAO,CAAC,EAAE,eAAe,QAa5B"}
@@ -0,0 +1,14 @@
1
+ export function registerComponent(TestComponent, componentName, options) {
2
+ /*
3
+ * This register can only happen once, unfortunately. So the TestComponent needs to
4
+ * work for all tests. If ran more than once, window.customElements.define will throw
5
+ * the error: "NotSupportedError: This name has already been registered in the registry."
6
+ *
7
+ * Also note that there is not way to "unregister" a web component, so an afterAll
8
+ * cannot be used.
9
+ */
10
+ global.WEB_COMPONENT_NAME = componentName;
11
+ const { register } = require('../register');
12
+ register(TestComponent, true, options);
13
+ }
14
+ //# sourceMappingURL=register-component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-component.js","sourceRoot":"","sources":["../../src/__mocks__/register-component.tsx"],"names":[],"mappings":"AAGA,MAAM,UAAU,iBAAiB,CAC7B,aAAgC,EAChC,aAAiC,EACjC,OAAyB;IAEzB;;;;;;;OAOG;IACF,MAAc,CAAC,kBAAkB,GAAG,aAAa,CAAC;IACnD,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5C,QAAQ,CAAC,aAAa,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { FC } from 'react';
2
+ export declare const MockComponent: FC<Record<string, any>>;
3
+ //# sourceMappingURL=test-component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-component.d.ts","sourceRoot":"","sources":["../../src/__mocks__/test-component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAc,MAAM,OAAO,CAAC;AAIvC,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAmBjD,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useContext } from 'react';
3
+ import { TablePopupPropsContext } from '@servicetitan/design-system';
4
+ import { useMFEDataContext, useMFEMetadataContext } from '../contexts';
5
+ export const MockComponent = props => {
6
+ const data = useMFEDataContext();
7
+ const metadata = useMFEMetadataContext();
8
+ const popupProps = useContext(TablePopupPropsContext);
9
+ return (_jsxs("div", { children: [Object.entries(props).map(([name, value]) => (_jsx("span", { children: `Prop: ${name}, Value: ${stringifyValue(value)}` }, name))), Object.entries(data).map(([name, value]) => (_jsx("span", { children: `Data: ${name}, Value: ${stringifyValue(value)}` }, name))), Object.entries(metadata).map(([name, value]) => (_jsx("span", { children: `Metadata: ${name}, Value: ${stringifyValue(value)}` }, name))), _jsxs("span", { children: ["TablePopupPropsContext appendTo: ", String(popupProps({}).appendTo)] })] }));
10
+ };
11
+ function stringifyValue(value) {
12
+ return JSON.stringify(value, (_key, value) => value instanceof ShadowRoot ? 'ShadowRoot' : value);
13
+ }
14
+ //# sourceMappingURL=test-component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-component.js","sourceRoot":"","sources":["../../src/__mocks__/test-component.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAM,UAAU,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,CAAC,MAAM,aAAa,GAA4B,KAAK,CAAC,EAAE;IAC1D,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,UAAU,CAAC,sBAAsB,CAAC,CAAC;IAEtD,OAAO,CACH,0BACK,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAC1C,yBAAkB,SAAS,IAAI,YAAY,cAAc,CAAC,KAAK,CAAC,EAAE,IAAvD,IAAI,CAA2D,CAC7E,CAAC,EACD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CACzC,yBAAkB,SAAS,IAAI,YAAY,cAAc,CAAC,KAAK,CAAC,EAAE,IAAvD,IAAI,CAA2D,CAC7E,CAAC,EACD,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAC7C,yBAAkB,aAAa,IAAI,YAAY,cAAc,CAAC,KAAK,CAAC,EAAE,IAA3D,IAAI,CAA+D,CACjF,CAAC,EACF,gEAAwC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAQ,IAC7E,CACT,CAAC;AACN,CAAC,CAAC;AAEF,SAAS,cAAc,CAAC,KAAU;IAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACzC,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CACrD,CAAC;AACN,CAAC"}
@@ -1,3 +1,6 @@
1
1
  import { ComponentType } from 'react';
2
- export declare function register(Component: ComponentType, light: boolean): void;
2
+ export interface RegisterOptions {
3
+ legacyRoot?: boolean;
4
+ }
5
+ export declare function register(Component: ComponentType, light: boolean, options?: RegisterOptions): void;
3
6
  //# sourceMappingURL=register.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAM,aAAa,EAAE,MAAM,OAAO,CAAC;AAqC1C,wBAAgB,QAAQ,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,QAoMhE"}
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAM,aAAa,EAAa,MAAM,OAAO,CAAC;AAmCrD,MAAM,WAAW,eAAe;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,QAsM3F"}
package/dist/register.js CHANGED
@@ -1,15 +1,15 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- // eslint-disable-next-line react/no-deprecated
3
- import { render, unmountComponentAtNode } from 'react-dom';
4
- import { Log } from '@servicetitan/log-service';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect } from 'react';
5
3
  import { DefaultPortalContext, TablePopupPropsContext } from '@servicetitan/design-system';
4
+ import { Log } from '@servicetitan/log-service';
6
5
  import { Provider } from '@servicetitan/react-ioc';
7
6
  import { EXPOSED_DEPENDENCIES_TOKEN, BASENAME_TOKEN, IS_WEB_COMPONENT_TOKEN, RENDER_ROOT_TOKEN, } from './common';
8
- import { EVENT_BUS_TOKEN } from './event-bus';
9
- import { HistoryManager } from './history-manager';
10
- import { WEB_COMPONENT_NAME } from './globals';
11
7
  import { MFEDataContext } from './contexts/mfe-data-context';
12
8
  import { MFEMetadataContext } from './contexts/mfe-metadata-context';
9
+ import { EVENT_BUS_TOKEN } from './event-bus';
10
+ import { WEB_COMPONENT_NAME } from './globals';
11
+ import { HistoryManager } from './history-manager';
12
+ import { render } from './render';
13
13
  function createLink(url, onLoad) {
14
14
  const element = document.createElement('link');
15
15
  element.href = url;
@@ -20,7 +20,7 @@ function createLink(url, onLoad) {
20
20
  return element;
21
21
  }
22
22
  const Placeholder = () => _jsx("div", { style: { display: 'none' } });
23
- export function register(Component, light) {
23
+ export function register(Component, light, options) {
24
24
  class WebComponent extends HTMLElement {
25
25
  constructor() {
26
26
  super(...arguments);
@@ -84,6 +84,12 @@ export function register(Component, light) {
84
84
  writable: true,
85
85
  value: void 0
86
86
  });
87
+ Object.defineProperty(this, "view", {
88
+ enumerable: true,
89
+ configurable: true,
90
+ writable: true,
91
+ value: void 0
92
+ });
87
93
  Object.defineProperty(this, "provide", {
88
94
  enumerable: true,
89
95
  configurable: true,
@@ -129,6 +135,7 @@ export function register(Component, light) {
129
135
  configurable: true,
130
136
  writable: true,
131
137
  value: () => {
138
+ var _a;
132
139
  /*
133
140
  * Check for this.root first, otherwise we get error when
134
141
  * attributeChangedCallback happens on load
@@ -149,7 +156,7 @@ export function register(Component, light) {
149
156
  shadowRoot: this.root,
150
157
  portalShadowRoot: this.portal,
151
158
  };
152
- render(_jsx(Provider, Object.assign({ singletons: [
159
+ (_a = this.view) === null || _a === void 0 ? void 0 : _a.rerender(_jsx(Provider, Object.assign({ singletons: [
153
160
  { provide: IS_WEB_COMPONENT_TOKEN, useValue: true },
154
161
  { provide: RENDER_ROOT_TOKEN, useValue: this.root },
155
162
  ] }, { children: _jsx(DefaultPortalContext.Provider, Object.assign({ value: this.portal }, { children: _jsx(TablePopupPropsContext.Provider, Object.assign({ value: props => (Object.assign(Object.assign({}, props), { appendTo: this.root })) }, { children: _jsx(Provider, Object.assign({ singletons: [
@@ -161,7 +168,7 @@ export function register(Component, light) {
161
168
  },
162
169
  { provide: EVENT_BUS_TOKEN, useValue: this.eventBus },
163
170
  { provide: BASENAME_TOKEN, useValue: this.basename },
164
- ].filter(({ useValue }) => useValue !== undefined) }, { children: _jsx(MFEDataContext.Provider, Object.assign({ value: Object.assign({}, mfeData) }, { children: _jsx(MFEMetadataContext.Provider, Object.assign({ value: metadata }, { children: _jsx(Component, Object.assign({}, mfeData)) })) })) })) })) })) })), this.root, this.onReady);
171
+ ].filter(({ useValue }) => useValue !== undefined) }, { children: _jsx(MFEDataContext.Provider, Object.assign({ value: Object.assign({}, mfeData) }, { children: _jsxs(MFEMetadataContext.Provider, Object.assign({ value: metadata }, { children: [_jsx(Component, Object.assign({}, mfeData)), this.onReady && (_jsx(RenderCallback, { callback: this.onReady }))] })) })) })) })) })) })));
165
172
  }
166
173
  }
167
174
  });
@@ -200,23 +207,23 @@ export function register(Component, light) {
200
207
  this.portal = document.body
201
208
  .appendChild(document.createElement('div'))
202
209
  .attachShadow({ mode: 'open' });
203
- render(_jsx(Placeholder, {}), this.root);
210
+ this.view = render(_jsx(Placeholder, {}), this.root, options);
204
211
  this.styles.elements.push(...this.attachStyles(this.root, styleUrls));
205
212
  this.styles.elements.push(...this.attachStyles(this.portal, styleUrls));
206
213
  }
207
214
  disconnectedCallback() {
208
- var _a, _b;
215
+ var _a, _b, _c;
209
216
  if (!this.root || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.isConnected)) {
210
217
  return;
211
218
  }
212
219
  for (const element of this.styles.elements) {
213
220
  element.remove();
214
221
  }
215
- unmountComponentAtNode(this.root);
222
+ (_b = this.view) === null || _b === void 0 ? void 0 : _b.unmount();
216
223
  document.body.removeChild(this.portal.host);
217
224
  this.root = undefined;
218
225
  this.portal = undefined;
219
- (_b = this.onDispose) === null || _b === void 0 ? void 0 : _b.call(this);
226
+ (_c = this.onDispose) === null || _c === void 0 ? void 0 : _c.call(this);
220
227
  }
221
228
  // Observe changes to the data-mfe-data attribute so that we can re-render when it changes
222
229
  static get observedAttributes() {
@@ -233,4 +240,9 @@ export function register(Component, light) {
233
240
  }
234
241
  window.customElements.define(WEB_COMPONENT_NAME, WebComponent);
235
242
  }
243
+ function RenderCallback({ callback }) {
244
+ // eslint-disable-next-line react-hooks/exhaustive-deps
245
+ useEffect(() => callback(), []);
246
+ return null;
247
+ }
236
248
  //# sourceMappingURL=register.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { ReactElement } from 'react';
2
+ interface RenderOptions {
3
+ legacyRoot?: boolean;
4
+ }
5
+ interface RenderResult {
6
+ rerender(element: ReactElement): void;
7
+ unmount(): void;
8
+ }
9
+ export declare function render(element: ReactElement, container: Element | DocumentFragment, options?: RenderOptions): RenderResult;
10
+ export {};
11
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAerC,UAAU,aAAa;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,UAAU,YAAY;IAClB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACtC,OAAO,IAAI,IAAI,CAAC;CACnB;AAED,wBAAgB,MAAM,CAClB,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,OAAO,GAAG,gBAAgB,EACrC,OAAO,CAAC,EAAE,aAAa,GACxB,YAAY,CAgBd"}
package/dist/render.js ADDED
@@ -0,0 +1,39 @@
1
+ import ReactDOM from 'react-dom';
2
+ let createRoot;
3
+ try {
4
+ /**
5
+ * Note, the webpack.IgnorePlugin must be configured to ignore this dependency.
6
+ * @see {@link file://./../../startup/src/webpack/configs/plugins/ignore-plugin/ignore-plugin.ts}
7
+ */
8
+ createRoot = require('react-dom/client').createRoot;
9
+ }
10
+ catch (e) {
11
+ // ignore
12
+ }
13
+ export function render(element, container, options) {
14
+ if (typeof createRoot !== 'function' || (options === null || options === void 0 ? void 0 : options.legacyRoot)) {
15
+ return renderLegacyRoot(element, container);
16
+ }
17
+ const root = createRoot(container);
18
+ root.render(element);
19
+ return {
20
+ rerender(element) {
21
+ root.render(element);
22
+ },
23
+ unmount() {
24
+ root.unmount();
25
+ },
26
+ };
27
+ }
28
+ function renderLegacyRoot(element, container) {
29
+ ReactDOM.render(element, container);
30
+ return {
31
+ rerender(element) {
32
+ ReactDOM.render(element, container);
33
+ },
34
+ unmount() {
35
+ ReactDOM.unmountComponentAtNode(container);
36
+ },
37
+ };
38
+ }
39
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,WAAW,CAAC;AAGjC,IAAI,UAA4C,CAAC;AACjD,IAAI;IACA;;;OAGG;IACH,UAAU,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,UAAU,CAAC;CACvD;AAAC,OAAO,CAAC,EAAE;IACR,SAAS;CACZ;AAWD,MAAM,UAAU,MAAM,CAClB,OAAqB,EACrB,SAAqC,EACrC,OAAuB;IAEvB,IAAI,OAAO,UAAU,KAAK,UAAU,KAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,CAAA,EAAE;QACzD,OAAO,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;KAC/C;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAErB,OAAO;QACH,QAAQ,CAAC,OAAqB;YAC1B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QACD,OAAO;YACH,IAAI,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;KACJ,CAAC;AACN,CAAC;AAED,SAAS,gBAAgB,CACrB,OAAqB,EACrB,SAAqC;IAErC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAEpC,OAAO;QACH,QAAQ,CAAC,OAAqB;YAC1B,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACxC,CAAC;QACD,OAAO;YACH,QAAQ,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC;KACJ,CAAC;AACN,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/web-components",
3
- "version": "23.1.0",
3
+ "version": "23.2.0",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,16 +15,16 @@
15
15
  "src"
16
16
  ],
17
17
  "dependencies": {
18
- "@servicetitan/error-boundary": "23.1.0",
18
+ "@servicetitan/error-boundary": "23.2.0",
19
19
  "lodash.get": "~4.4.2",
20
20
  "mitt": "~3.0.1",
21
21
  "semver": "~7.5.4"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@servicetitan/design-system": "~14.0.0",
25
- "@servicetitan/log-service": "23.1.0",
26
- "@servicetitan/react-ioc": "23.1.0",
27
- "@testing-library/dom": "^8.20.1",
25
+ "@servicetitan/log-service": "23.2.0",
26
+ "@servicetitan/react-ioc": "23.2.0",
27
+ "@testing-library/dom": "^9.0.0",
28
28
  "@testing-library/jest-dom": "^6.4.2",
29
29
  "@testing-library/react": "^14.2.1",
30
30
  "@types/history": "~4.7.10",
@@ -39,8 +39,8 @@
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@servicetitan/design-system": ">=12.6.2",
42
- "@servicetitan/log-service": "23.1.0",
43
- "@servicetitan/react-ioc": "23.1.0",
42
+ "@servicetitan/log-service": "23.2.0",
43
+ "@servicetitan/react-ioc": "23.2.0",
44
44
  "history": "~4.10.1",
45
45
  "react": ">=17.0.2",
46
46
  "react-dom": ">=17.0.2"
@@ -51,5 +51,5 @@
51
51
  "cli": {
52
52
  "webpack": false
53
53
  },
54
- "gitHead": "7267270e54cdb3a2926f61feb4939d057e82adb3"
54
+ "gitHead": "4b72bab5ab6cb52a688d9329c7fbaa702ae6780c"
55
55
  }
@@ -0,0 +1,2 @@
1
+ export * from './register-component';
2
+ export * from './test-component';
@@ -0,0 +1,20 @@
1
+ import { FunctionComponent } from 'react';
2
+ import { RegisterOptions } from '../register';
3
+
4
+ export function registerComponent(
5
+ TestComponent: FunctionComponent,
6
+ componentName: string | undefined,
7
+ options?: RegisterOptions
8
+ ) {
9
+ /*
10
+ * This register can only happen once, unfortunately. So the TestComponent needs to
11
+ * work for all tests. If ran more than once, window.customElements.define will throw
12
+ * the error: "NotSupportedError: This name has already been registered in the registry."
13
+ *
14
+ * Also note that there is not way to "unregister" a web component, so an afterAll
15
+ * cannot be used.
16
+ */
17
+ (global as any).WEB_COMPONENT_NAME = componentName;
18
+ const { register } = require('../register');
19
+ register(TestComponent, true, options);
20
+ }
@@ -0,0 +1,30 @@
1
+ import { FC, useContext } from 'react';
2
+ import { TablePopupPropsContext } from '@servicetitan/design-system';
3
+ import { useMFEDataContext, useMFEMetadataContext } from '../contexts';
4
+
5
+ export const MockComponent: FC<Record<string, any>> = props => {
6
+ const data = useMFEDataContext();
7
+ const metadata = useMFEMetadataContext();
8
+ const popupProps = useContext(TablePopupPropsContext);
9
+
10
+ return (
11
+ <div>
12
+ {Object.entries(props).map(([name, value]) => (
13
+ <span key={name}>{`Prop: ${name}, Value: ${stringifyValue(value)}`}</span>
14
+ ))}
15
+ {Object.entries(data).map(([name, value]) => (
16
+ <span key={name}>{`Data: ${name}, Value: ${stringifyValue(value)}`}</span>
17
+ ))}
18
+ {Object.entries(metadata).map(([name, value]) => (
19
+ <span key={name}>{`Metadata: ${name}, Value: ${stringifyValue(value)}`}</span>
20
+ ))}
21
+ <span>TablePopupPropsContext appendTo: {String(popupProps({}).appendTo)}</span>
22
+ </div>
23
+ );
24
+ };
25
+
26
+ function stringifyValue(value: any) {
27
+ return JSON.stringify(value, (_key, value) =>
28
+ value instanceof ShadowRoot ? 'ShadowRoot' : value
29
+ );
30
+ }
@@ -0,0 +1,36 @@
1
+ import '@testing-library/jest-dom';
2
+ import { render } from '@testing-library/react';
3
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4
+ // @ts-ignore because Jest mistakenly complains that "'shadow-dom-testing-library' cannot be imported using this construct".
5
+ import { screen } from 'shadow-dom-testing-library';
6
+
7
+ import { MockComponent, registerComponent } from '../__mocks__';
8
+
9
+ describe('[web-components] register', () => {
10
+ const componentName = 'mock-legacy-root-app';
11
+
12
+ beforeAll(() => {
13
+ registerComponent(MockComponent, componentName, { legacyRoot: true });
14
+ });
15
+
16
+ const subject = () => {
17
+ const Component: any = componentName;
18
+ return render(<Component />);
19
+ };
20
+
21
+ describe('when the web component data attribute is changed', () => {
22
+ const setup = () => {
23
+ subject();
24
+
25
+ const webComponent = document.getElementsByTagName(componentName);
26
+ webComponent[0]?.setAttribute('data-mfe-data', JSON.stringify({ string: 'baz' }));
27
+ };
28
+
29
+ test('useMFEDataContext provides updated data', () => {
30
+ setup();
31
+
32
+ expect(screen.getByShadowText(`Prop: string, Value: "baz"`)).toBeInTheDocument();
33
+ expect(screen.getByShadowText(`Data: string, Value: "baz"`)).toBeInTheDocument();
34
+ });
35
+ });
36
+ });
@@ -1,16 +1,13 @@
1
- import { FC, useContext } from 'react';
2
- import { TablePopupPropsContext } from '@servicetitan/design-system';
3
- import { render } from '@testing-library/react';
1
+ import '@testing-library/jest-dom';
2
+ import { act, render } from '@testing-library/react';
4
3
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5
4
  // @ts-ignore because Jest mistakenly complains that "'shadow-dom-testing-library' cannot be imported using this construct".
6
5
  import { screen } from 'shadow-dom-testing-library';
7
- import '@testing-library/jest-dom';
8
6
 
9
7
  import { IWebComponent } from '../common';
10
- import { useMFEDataContext, useMFEMetadataContext } from '../contexts';
8
+ import { MockComponent, registerComponent } from '../__mocks__';
11
9
 
12
10
  describe('[web-components] register', () => {
13
- let onloadRefs: Function[];
14
11
  const componentName = 'mock-app';
15
12
  const handleRef = (webComponent: IWebComponent | null) => {
16
13
  webComponent?.provide({
@@ -18,31 +15,7 @@ describe('[web-components] register', () => {
18
15
  onDispose: jest.fn(),
19
16
  });
20
17
  };
21
- function stringifyValue(value: any) {
22
- return JSON.stringify(value, (_key, value) =>
23
- value instanceof ShadowRoot ? 'ShadowRoot' : value
24
- );
25
- }
26
- const TestComponent: FC<Record<string, any>> = props => {
27
- const data = useMFEDataContext();
28
- const metadata = useMFEMetadataContext();
29
- const popupProps = useContext(TablePopupPropsContext);
30
-
31
- return (
32
- <div>
33
- {Object.entries(props).map(([name, value]) => (
34
- <span key={name}>{`Prop: ${name}, Value: ${stringifyValue(value)}`}</span>
35
- ))}
36
- {Object.entries(data).map(([name, value]) => (
37
- <span key={name}>{`Data: ${name}, Value: ${stringifyValue(value)}`}</span>
38
- ))}
39
- {Object.entries(metadata).map(([name, value]) => (
40
- <span key={name}>{`Metadata: ${name}, Value: ${stringifyValue(value)}`}</span>
41
- ))}
42
- <span>TablePopupPropsContext appendTo: {String(popupProps({}).appendTo)}</span>
43
- </div>
44
- );
45
- };
18
+ let onloadRefs: Function[];
46
19
 
47
20
  class Page {
48
21
  static get componentShadowRoot() {
@@ -55,18 +28,7 @@ describe('[web-components] register', () => {
55
28
  }
56
29
 
57
30
  beforeAll(() => {
58
- /*
59
- * This register can only happen once, unfortunately. So the TestComponent needs to
60
- * work for all tests. If ran more than once, window.customElements.define will throw
61
- * the error: "NotSupportedError: This name has already been registered in the registry."
62
- *
63
- * Also note that there is not way to "unregister" a web component, so an afterAll
64
- * cannot be used.
65
- */
66
- (global as any).WEB_COMPONENT_NAME = componentName;
67
- const { register } = require('../register');
68
- register(TestComponent, true);
69
-
31
+ registerComponent(MockComponent, componentName);
70
32
  /*
71
33
  * mock <link>'s onload so that we can call it directly from the test,
72
34
  * because it won't call itself in the test environment
@@ -91,9 +53,11 @@ describe('[web-components] register', () => {
91
53
  const Component: any = componentName;
92
54
  const renderResult = render(<Component ref={handleRef} {...data} {...dataAttrs} />);
93
55
 
94
- for (const onload of onloadRefs) {
95
- onload();
96
- }
56
+ act(() => {
57
+ for (const onload of onloadRefs) {
58
+ onload();
59
+ }
60
+ });
97
61
 
98
62
  return renderResult;
99
63
  };
@@ -200,49 +164,20 @@ describe('[web-components] register', () => {
200
164
  ).toBeInTheDocument()
201
165
  );
202
166
  });
203
-
204
- describe('when the web component data attr is changed', () => {
205
- const setup = () => {
206
- subject(props);
207
-
208
- const webComponent = document.getElementsByTagName(componentName);
209
- webComponent[0]?.setAttribute(
210
- 'data-mfe-data',
211
- JSON.stringify({ ...props, string: 'baz' })
212
- );
213
- };
214
-
215
- test('useMFEDataContext provides updated data', () => {
216
- setup();
217
-
218
- expect(screen.getByShadowText(`Prop: string, Value: "baz"`)).toBeInTheDocument();
219
- expect(screen.getByShadowText(`Data: string, Value: "baz"`)).toBeInTheDocument();
220
- });
221
- });
222
167
  });
223
168
 
224
- describe('when WEB_COMPONENT_NAME is not set', () => {
225
- let register: typeof import('../register').register;
226
-
227
- beforeEach(() => {
228
- jest.isolateModules(() => {
229
- (global as any).WEB_COMPONENT_NAME = undefined;
230
- register = require('../register').register;
231
- });
232
- jest.spyOn(console, 'error').mockImplementation(jest.fn());
233
- });
234
-
235
- test('logs an error', () => {
236
- register(TestComponent, true);
237
- // eslint-disable-next-line no-console
238
- expect(console.error).toHaveBeenCalledWith('"WEB_COMPONENT_NAME" is not defined!');
169
+ test('logs an error when WEB_COMPONENT_NAME is not set', () => {
170
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn());
171
+ jest.isolateModules(() => {
172
+ registerComponent(MockComponent, undefined);
239
173
  });
174
+ expect(consoleSpy).toHaveBeenCalledWith('"WEB_COMPONENT_NAME" is not defined!');
240
175
  });
241
176
 
242
177
  test('configures the shadow root in PopupPropsContext', () => {
243
178
  subject();
244
179
  expect(screen.getByShadowText(/TablePopupPropsContext appendTo:/)).toHaveTextContent(
245
- /[object ShadowRoot]/
180
+ /\[object ShadowRoot\]/
246
181
  );
247
182
  });
248
183
  });
package/src/register.tsx CHANGED
@@ -1,9 +1,6 @@
1
- import { FC, ComponentType } from 'react';
2
- // eslint-disable-next-line react/no-deprecated
3
- import { render, unmountComponentAtNode } from 'react-dom';
4
-
5
- import { Log } from '@servicetitan/log-service';
1
+ import { FC, ComponentType, useEffect } from 'react';
6
2
  import { DefaultPortalContext, TablePopupPropsContext } from '@servicetitan/design-system';
3
+ import { Log } from '@servicetitan/log-service';
7
4
  import { Provider } from '@servicetitan/react-ioc';
8
5
 
9
6
  import {
@@ -15,11 +12,12 @@ import {
15
12
  IS_WEB_COMPONENT_TOKEN,
16
13
  RENDER_ROOT_TOKEN,
17
14
  } from './common';
18
- import { EventBus, EVENT_BUS_TOKEN } from './event-bus';
19
- import { HistoryManager } from './history-manager';
20
- import { WEB_COMPONENT_NAME } from './globals';
21
15
  import { MFEDataContext } from './contexts/mfe-data-context';
22
16
  import { MFEMetadataContext } from './contexts/mfe-metadata-context';
17
+ import { EventBus, EVENT_BUS_TOKEN } from './event-bus';
18
+ import { WEB_COMPONENT_NAME } from './globals';
19
+ import { HistoryManager } from './history-manager';
20
+ import { render } from './render';
23
21
 
24
22
  function createLink(url: string, onLoad: () => void) {
25
23
  const element = document.createElement('link');
@@ -35,7 +33,11 @@ function createLink(url: string, onLoad: () => void) {
35
33
 
36
34
  const Placeholder: FC = () => <div style={{ display: 'none' }} />;
37
35
 
38
- export function register(Component: ComponentType, light: boolean) {
36
+ export interface RegisterOptions {
37
+ legacyRoot?: boolean;
38
+ }
39
+
40
+ export function register(Component: ComponentType, light: boolean, options?: RegisterOptions) {
39
41
  class WebComponent extends HTMLElement implements IWebComponent {
40
42
  private root?: ShadowRoot;
41
43
  private portal?: ShadowRoot;
@@ -53,6 +55,7 @@ export function register(Component: ComponentType, light: boolean) {
53
55
  private basename?: string;
54
56
  private onReady?: () => void;
55
57
  private onDispose?: () => void;
58
+ private view?: ReturnType<typeof render>;
56
59
 
57
60
  connectedCallback() {
58
61
  /*
@@ -93,7 +96,7 @@ export function register(Component: ComponentType, light: boolean) {
93
96
  .appendChild(document.createElement('div'))
94
97
  .attachShadow({ mode: 'open' });
95
98
 
96
- render(<Placeholder />, this.root);
99
+ this.view = render(<Placeholder />, this.root, options);
97
100
 
98
101
  this.styles.elements.push(...this.attachStyles(this.root, styleUrls));
99
102
  this.styles.elements.push(...this.attachStyles(this.portal, styleUrls));
@@ -107,7 +110,7 @@ export function register(Component: ComponentType, light: boolean) {
107
110
  element.remove();
108
111
  }
109
112
 
110
- unmountComponentAtNode(this.root);
113
+ this.view?.unmount();
111
114
  document.body.removeChild(this.portal!.host);
112
115
  this.root = undefined;
113
116
  this.portal = undefined;
@@ -180,7 +183,7 @@ export function register(Component: ComponentType, light: boolean) {
180
183
  portalShadowRoot: this.portal!,
181
184
  };
182
185
 
183
- render(
186
+ this.view?.rerender(
184
187
  <Provider
185
188
  singletons={[
186
189
  { provide: IS_WEB_COMPONENT_TOKEN, useValue: true },
@@ -211,14 +214,15 @@ export function register(Component: ComponentType, light: boolean) {
211
214
  <MFEDataContext.Provider value={{ ...mfeData }}>
212
215
  <MFEMetadataContext.Provider value={metadata}>
213
216
  <Component {...mfeData} />
217
+ {this.onReady && (
218
+ <RenderCallback callback={this.onReady} />
219
+ )}
214
220
  </MFEMetadataContext.Provider>
215
221
  </MFEDataContext.Provider>
216
222
  </Provider>
217
223
  </TablePopupPropsContext.Provider>
218
224
  </DefaultPortalContext.Provider>
219
- </Provider>,
220
- this.root!,
221
- this.onReady
225
+ </Provider>
222
226
  );
223
227
  }
224
228
  };
@@ -232,3 +236,9 @@ export function register(Component: ComponentType, light: boolean) {
232
236
 
233
237
  window.customElements.define(WEB_COMPONENT_NAME, WebComponent);
234
238
  }
239
+
240
+ function RenderCallback({ callback }: { callback: () => void }) {
241
+ // eslint-disable-next-line react-hooks/exhaustive-deps
242
+ useEffect(() => callback(), []);
243
+ return null;
244
+ }
package/src/render.ts ADDED
@@ -0,0 +1,62 @@
1
+ /* eslint-disable react/no-deprecated */
2
+ import { ReactElement } from 'react';
3
+ import ReactDOM from 'react-dom';
4
+ import type ReactDOMClient from 'react-dom/client';
5
+
6
+ let createRoot: typeof ReactDOMClient.createRoot;
7
+ try {
8
+ /**
9
+ * Note, the webpack.IgnorePlugin must be configured to ignore this dependency.
10
+ * @see {@link file://./../../startup/src/webpack/configs/plugins/ignore-plugin/ignore-plugin.ts}
11
+ */
12
+ createRoot = require('react-dom/client').createRoot;
13
+ } catch (e) {
14
+ // ignore
15
+ }
16
+
17
+ interface RenderOptions {
18
+ legacyRoot?: boolean;
19
+ }
20
+
21
+ interface RenderResult {
22
+ rerender(element: ReactElement): void;
23
+ unmount(): void;
24
+ }
25
+
26
+ export function render(
27
+ element: ReactElement,
28
+ container: Element | DocumentFragment,
29
+ options?: RenderOptions
30
+ ): RenderResult {
31
+ if (typeof createRoot !== 'function' || options?.legacyRoot) {
32
+ return renderLegacyRoot(element, container);
33
+ }
34
+
35
+ const root = createRoot(container);
36
+ root.render(element);
37
+
38
+ return {
39
+ rerender(element: ReactElement) {
40
+ root.render(element);
41
+ },
42
+ unmount() {
43
+ root.unmount();
44
+ },
45
+ };
46
+ }
47
+
48
+ function renderLegacyRoot(
49
+ element: ReactElement,
50
+ container: Element | DocumentFragment
51
+ ): RenderResult {
52
+ ReactDOM.render(element, container);
53
+
54
+ return {
55
+ rerender(element: ReactElement) {
56
+ ReactDOM.render(element, container);
57
+ },
58
+ unmount() {
59
+ ReactDOM.unmountComponentAtNode(container);
60
+ },
61
+ };
62
+ }