@servicetitan/web-components 36.4.0 → 37.0.1
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/anvil1-providers.d.ts +6 -0
- package/dist/anvil1-providers.d.ts.map +1 -0
- package/dist/anvil1-providers.js +23 -0
- package/dist/anvil1-providers.js.map +1 -0
- package/dist/anvil2-providers.d.ts +5 -0
- package/dist/anvil2-providers.d.ts.map +1 -0
- package/dist/anvil2-providers.js +13 -0
- package/dist/anvil2-providers.js.map +1 -0
- package/dist/get-style-urls.d.ts +2 -0
- package/dist/get-style-urls.d.ts.map +1 -0
- package/dist/get-style-urls.js +21 -0
- package/dist/get-style-urls.js.map +1 -0
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +4 -51
- package/dist/register.js.map +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +3 -11
- package/dist/render.js.map +1 -1
- package/dist/utils/get-ld-service-token.d.ts +2 -3
- package/dist/utils/get-ld-service-token.d.ts.map +1 -1
- package/dist/utils/get-ld-service-token.js +2 -7
- package/dist/utils/get-ld-service-token.js.map +1 -1
- package/package.json +25 -14
- package/src/__tests__/register-anvil2-optional.test.tsx +32 -0
- package/src/__tests__/register-anvil2.test.tsx +5 -23
- package/src/anvil1-providers.tsx +28 -0
- package/src/anvil2-providers.tsx +13 -0
- package/src/get-style-urls.ts +23 -0
- package/src/register.tsx +4 -66
- package/src/render.ts +3 -13
- package/src/utils/get-ld-service-token.ts +2 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anvil1-providers.d.ts","sourceRoot":"","sources":["../src/anvil1-providers.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAe,MAAM,OAAO,CAAC;AAE3D,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAAG,iBAAiB,CAwB5F,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as Anvil1 from '@servicetitan/design-system';
|
|
3
|
+
import { useCallback } from 'react';
|
|
4
|
+
export const Anvil1Providers = ({ root, portal, children })=>{
|
|
5
|
+
const getTablePopupProps = useCallback((props)=>({
|
|
6
|
+
...props,
|
|
7
|
+
appendTo: root
|
|
8
|
+
}), [
|
|
9
|
+
root
|
|
10
|
+
]);
|
|
11
|
+
if (Anvil1.DefaultPortalContext === undefined || Anvil1.TablePopupPropsContext === undefined) {
|
|
12
|
+
return children;
|
|
13
|
+
}
|
|
14
|
+
return /*#__PURE__*/ _jsx(Anvil1.DefaultPortalContext.Provider, {
|
|
15
|
+
value: portal,
|
|
16
|
+
children: /*#__PURE__*/ _jsx(Anvil1.TablePopupPropsContext.Provider, {
|
|
17
|
+
value: getTablePopupProps,
|
|
18
|
+
children: children
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=anvil1-providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/anvil1-providers.tsx"],"sourcesContent":["import * as Anvil1 from '@servicetitan/design-system';\nimport { FC, PropsWithChildren, useCallback } from 'react';\n\nexport const Anvil1Providers: FC<{ root: ShadowRoot; portal: ShadowRoot } & PropsWithChildren> = ({\n root,\n portal,\n children,\n}) => {\n const getTablePopupProps = useCallback(\n (props: object) => ({\n ...props,\n appendTo: root as unknown as HTMLElement,\n }),\n [root]\n );\n\n if (Anvil1.DefaultPortalContext === undefined || Anvil1.TablePopupPropsContext === undefined) {\n return children;\n }\n\n return (\n <Anvil1.DefaultPortalContext.Provider value={portal as unknown as HTMLElement}>\n <Anvil1.TablePopupPropsContext.Provider value={getTablePopupProps}>\n {children}\n </Anvil1.TablePopupPropsContext.Provider>\n </Anvil1.DefaultPortalContext.Provider>\n );\n};\n"],"names":["Anvil1","useCallback","Anvil1Providers","root","portal","children","getTablePopupProps","props","appendTo","DefaultPortalContext","undefined","TablePopupPropsContext","Provider","value"],"mappings":";AAAA,YAAYA,YAAY,8BAA8B;AACtD,SAAgCC,WAAW,QAAQ,QAAQ;AAE3D,OAAO,MAAMC,kBAAoF,CAAC,EAC9FC,IAAI,EACJC,MAAM,EACNC,QAAQ,EACX;IACG,MAAMC,qBAAqBL,YACvB,CAACM,QAAmB,CAAA;YAChB,GAAGA,KAAK;YACRC,UAAUL;QACd,CAAA,GACA;QAACA;KAAK;IAGV,IAAIH,OAAOS,oBAAoB,KAAKC,aAAaV,OAAOW,sBAAsB,KAAKD,WAAW;QAC1F,OAAOL;IACX;IAEA,qBACI,KAACL,OAAOS,oBAAoB,CAACG,QAAQ;QAACC,OAAOT;kBACzC,cAAA,KAACJ,OAAOW,sBAAsB,CAACC,QAAQ;YAACC,OAAOP;sBAC1CD;;;AAIjB,EAAE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anvil2-providers.d.ts","sourceRoot":"","sources":["../src/anvil2-providers.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE9C,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC;IAAE,oBAAoB,EAAE,cAAc,CAAA;CAAE,GAAG,iBAAiB,CAS5F,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as Anvil2 from '@servicetitan/anvil2';
|
|
3
|
+
export const Anvil2Providers = ({ portalAnvilContainer, children })=>{
|
|
4
|
+
if (Anvil2.PortalProvider === undefined) {
|
|
5
|
+
return children;
|
|
6
|
+
}
|
|
7
|
+
return /*#__PURE__*/ _jsx(Anvil2.PortalProvider, {
|
|
8
|
+
root: portalAnvilContainer,
|
|
9
|
+
children: children
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=anvil2-providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/anvil2-providers.tsx"],"sourcesContent":["import * as Anvil2 from '@servicetitan/anvil2';\nimport { FC, PropsWithChildren } from 'react';\n\nexport const Anvil2Providers: FC<{ portalAnvilContainer: HTMLDivElement } & PropsWithChildren> = ({\n portalAnvilContainer,\n children,\n}) => {\n if (Anvil2.PortalProvider === undefined) {\n return children;\n }\n\n return <Anvil2.PortalProvider root={portalAnvilContainer}>{children}</Anvil2.PortalProvider>;\n};\n"],"names":["Anvil2","Anvil2Providers","portalAnvilContainer","children","PortalProvider","undefined","root"],"mappings":";AAAA,YAAYA,YAAY,uBAAuB;AAG/C,OAAO,MAAMC,kBAAoF,CAAC,EAC9FC,oBAAoB,EACpBC,QAAQ,EACX;IACG,IAAIH,OAAOI,cAAc,KAAKC,WAAW;QACrC,OAAOF;IACX;IAEA,qBAAO,KAACH,OAAOI,cAAc;QAACE,MAAMJ;kBAAuBC;;AAC/D,EAAE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-style-urls.d.ts","sourceRoot":"","sources":["../src/get-style-urls.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,WAAW,SAsB9F"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function getStyleUrls(light, sharedDependenciesNames, el) {
|
|
2
|
+
function getCssUrl(dependencyName, cssFileRegEx) {
|
|
3
|
+
if (light && sharedDependenciesNames.includes(dependencyName)) {
|
|
4
|
+
var _Array_from_find;
|
|
5
|
+
return (_Array_from_find = Array.from(document.getElementsByTagName('link')).find(({ href })=>href && cssFileRegEx.test(href))) === null || _Array_from_find === void 0 ? void 0 : _Array_from_find.href;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
const designSystemUrl = getCssUrl('@servicetitan/design-system', /design-system(\..+)?\.bundle\.css/);
|
|
9
|
+
const anvil2CssUrl = getCssUrl('@servicetitan/anvil2', /anvil2(\..+)?\.bundle\.css/);
|
|
10
|
+
return [
|
|
11
|
+
...designSystemUrl ? [
|
|
12
|
+
designSystemUrl
|
|
13
|
+
] : [],
|
|
14
|
+
...anvil2CssUrl ? [
|
|
15
|
+
anvil2CssUrl
|
|
16
|
+
] : [],
|
|
17
|
+
...el.hasAttribute('style-urls') ? JSON.parse(decodeURIComponent(el.getAttribute('style-urls'))) : []
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=get-style-urls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/get-style-urls.ts"],"sourcesContent":["export function getStyleUrls(light: boolean, sharedDependenciesNames: string[], el: HTMLElement) {\n function getCssUrl(dependencyName: string, cssFileRegEx: RegExp) {\n if (light && sharedDependenciesNames.includes(dependencyName)) {\n return Array.from(document.getElementsByTagName('link')).find(\n ({ href }) => href && cssFileRegEx.test(href)\n )?.href;\n }\n }\n\n const designSystemUrl = getCssUrl(\n '@servicetitan/design-system',\n /design-system(\\..+)?\\.bundle\\.css/\n );\n const anvil2CssUrl = getCssUrl('@servicetitan/anvil2', /anvil2(\\..+)?\\.bundle\\.css/);\n\n return [\n ...(designSystemUrl ? [designSystemUrl] : []),\n ...(anvil2CssUrl ? [anvil2CssUrl] : []),\n ...(el.hasAttribute('style-urls')\n ? JSON.parse(decodeURIComponent(el.getAttribute('style-urls')!))\n : []),\n ];\n}\n"],"names":["getStyleUrls","light","sharedDependenciesNames","el","getCssUrl","dependencyName","cssFileRegEx","includes","Array","from","document","getElementsByTagName","find","href","test","designSystemUrl","anvil2CssUrl","hasAttribute","JSON","parse","decodeURIComponent","getAttribute"],"mappings":"AAAA,OAAO,SAASA,aAAaC,KAAc,EAAEC,uBAAiC,EAAEC,EAAe;IAC3F,SAASC,UAAUC,cAAsB,EAAEC,YAAoB;QAC3D,IAAIL,SAASC,wBAAwBK,QAAQ,CAACF,iBAAiB;gBACpDG;YAAP,QAAOA,mBAAAA,MAAMC,IAAI,CAACC,SAASC,oBAAoB,CAAC,SAASC,IAAI,CACzD,CAAC,EAAEC,IAAI,EAAE,GAAKA,QAAQP,aAAaQ,IAAI,CAACD,oBADrCL,uCAAAA,iBAEJK,IAAI;QACX;IACJ;IAEA,MAAME,kBAAkBX,UACpB,+BACA;IAEJ,MAAMY,eAAeZ,UAAU,wBAAwB;IAEvD,OAAO;WACCW,kBAAkB;YAACA;SAAgB,GAAG,EAAE;WACxCC,eAAe;YAACA;SAAa,GAAG,EAAE;WAClCb,GAAGc,YAAY,CAAC,gBACdC,KAAKC,KAAK,CAACC,mBAAmBjB,GAAGkB,YAAY,CAAC,kBAC9C,EAAE;KACX;AACL"}
|
package/dist/register.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAA+
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAA+B,MAAM,OAAO,CAAC;AAqCnE,MAAM,WAAW,eAAe;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;CACtC;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,QAmN3F"}
|
package/dist/register.js
CHANGED
|
@@ -14,12 +14,15 @@ function _define_property(obj, key, value) {
|
|
|
14
14
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
15
|
import { Log } from '@servicetitan/log-service';
|
|
16
16
|
import { Provider } from '@servicetitan/react-ioc';
|
|
17
|
-
import {
|
|
17
|
+
import { useEffect } from 'react';
|
|
18
|
+
import { Anvil1Providers } from './anvil1-providers';
|
|
19
|
+
import { Anvil2Providers } from './anvil2-providers';
|
|
18
20
|
import { BASENAME_TOKEN, EXPOSED_DEPENDENCIES_TOKEN, EXPOSED_INSTANCE_DEPENDENCIES_TOKEN, IS_WEB_COMPONENT_TOKEN, RENDER_ROOT_TOKEN } from './common';
|
|
19
21
|
import { MFEDataContext } from './contexts/mfe-data-context';
|
|
20
22
|
import { MFEMetadataContext } from './contexts/mfe-metadata-context';
|
|
21
23
|
import { withCssInjector } from './css-injector';
|
|
22
24
|
import { EVENT_BUS_TOKEN } from './event-bus';
|
|
25
|
+
import { getStyleUrls } from './get-style-urls';
|
|
23
26
|
import { WEB_COMPONENT_NAME } from './globals';
|
|
24
27
|
import { HistoryManager } from './history-manager';
|
|
25
28
|
import { render } from './render';
|
|
@@ -38,37 +41,6 @@ const Placeholder = ()=>/*#__PURE__*/ _jsx("div", {
|
|
|
38
41
|
display: 'none'
|
|
39
42
|
}
|
|
40
43
|
});
|
|
41
|
-
const Anvil1Providers = ({ root, portal, children })=>{
|
|
42
|
-
const getTablePopupProps = useCallback((props)=>({
|
|
43
|
-
...props,
|
|
44
|
-
appendTo: root
|
|
45
|
-
}), [
|
|
46
|
-
root
|
|
47
|
-
]);
|
|
48
|
-
try {
|
|
49
|
-
const { DefaultPortalContext, TablePopupPropsContext } = require('@servicetitan/design-system');
|
|
50
|
-
return /*#__PURE__*/ _jsx(DefaultPortalContext.Provider, {
|
|
51
|
-
value: portal,
|
|
52
|
-
children: /*#__PURE__*/ _jsx(TablePopupPropsContext.Provider, {
|
|
53
|
-
value: getTablePopupProps,
|
|
54
|
-
children: children
|
|
55
|
-
})
|
|
56
|
-
});
|
|
57
|
-
} catch (unused) {
|
|
58
|
-
return children;
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
const Anvil2Providers = ({ portalAnvilContainer, children })=>{
|
|
62
|
-
try {
|
|
63
|
-
const { PortalProvider } = require('@servicetitan/anvil2');
|
|
64
|
-
return /*#__PURE__*/ _jsx(PortalProvider, {
|
|
65
|
-
root: portalAnvilContainer,
|
|
66
|
-
children: children
|
|
67
|
-
});
|
|
68
|
-
} catch (unused) {
|
|
69
|
-
return children;
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
44
|
export function register(Component, light, options) {
|
|
73
45
|
const WrappedComponent = withCssInjector(Component);
|
|
74
46
|
class WebComponent extends HTMLElement {
|
|
@@ -262,25 +234,6 @@ export function register(Component, light, options) {
|
|
|
262
234
|
}
|
|
263
235
|
window.customElements.define(WEB_COMPONENT_NAME, WebComponent);
|
|
264
236
|
}
|
|
265
|
-
function getStyleUrls(light, sharedDependenciesNames, el) {
|
|
266
|
-
function getCssUrl(dependencyName, cssFileRegEx) {
|
|
267
|
-
if (light && sharedDependenciesNames.includes(dependencyName)) {
|
|
268
|
-
var _Array_from_find;
|
|
269
|
-
return (_Array_from_find = Array.from(document.getElementsByTagName('link')).find(({ href })=>href && cssFileRegEx.test(href))) === null || _Array_from_find === void 0 ? void 0 : _Array_from_find.href;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
const designSystemUrl = getCssUrl('@servicetitan/design-system', /design-system(\..+)?\.bundle\.css/);
|
|
273
|
-
const anvil2CssUrl = getCssUrl('@servicetitan/anvil2', /anvil2(\..+)?\.bundle\.css/);
|
|
274
|
-
return [
|
|
275
|
-
...designSystemUrl ? [
|
|
276
|
-
designSystemUrl
|
|
277
|
-
] : [],
|
|
278
|
-
...anvil2CssUrl ? [
|
|
279
|
-
anvil2CssUrl
|
|
280
|
-
] : [],
|
|
281
|
-
...el.hasAttribute('style-urls') ? JSON.parse(decodeURIComponent(el.getAttribute('style-urls'))) : []
|
|
282
|
-
];
|
|
283
|
-
}
|
|
284
237
|
function RenderCallback({ callback }) {
|
|
285
238
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
286
239
|
useEffect(()=>callback(), []);
|
package/dist/register.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/register.tsx"],"sourcesContent":["import { type LDService } from '@servicetitan/launchdarkly-service';\nimport { Log } from '@servicetitan/log-service';\nimport { Provider } from '@servicetitan/react-ioc';\nimport { ExposedDependencies } from '@servicetitan/startup-utils';\nimport { ComponentType, FC, PropsWithChildren, ReactElement, useCallback, useEffect } from 'react';\nimport {\n BASENAME_TOKEN,\n Entries,\n EXPOSED_DEPENDENCIES_TOKEN,\n EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,\n ExposedInstanceDependencies,\n IS_WEB_COMPONENT_TOKEN,\n IWebComponent,\n RENDER_ROOT_TOKEN,\n} from './common';\nimport { MFEDataContext } from './contexts/mfe-data-context';\nimport { MFEMetadataContext } from './contexts/mfe-metadata-context';\nimport { withCssInjector } from './css-injector';\nimport { EVENT_BUS_TOKEN, EventBus } from './event-bus';\nimport { WEB_COMPONENT_NAME } from './globals';\nimport { HistoryManager } from './history-manager';\nimport { render } from './render';\nimport { getElementName, getLDServiceToken } from './utils';\n\nfunction createLink(url: string, onLoad: () => void) {\n const element = document.createElement('link');\n\n element.href = url;\n element.rel = 'stylesheet';\n element.crossOrigin = 'anonymous';\n element.onload = onLoad;\n element.onerror = onLoad;\n\n return element;\n}\n\nconst Placeholder: FC = () => <div style={{ display: 'none' }} />;\n\nexport interface RegisterOptions {\n legacyRoot?: boolean;\n sharedDependenciesNames?: string[];\n}\n\nconst Anvil1Providers: FC<{ root: ShadowRoot; portal: ShadowRoot } & PropsWithChildren> = ({\n root,\n portal,\n children,\n}) => {\n const getTablePopupProps = useCallback(\n (props: object) => ({\n ...props,\n appendTo: root as unknown as HTMLElement,\n }),\n [root]\n );\n\n try {\n const { DefaultPortalContext, TablePopupPropsContext } =\n require('@servicetitan/design-system') as typeof import('@servicetitan/design-system');\n return (\n <DefaultPortalContext.Provider value={portal as unknown as HTMLElement}>\n <TablePopupPropsContext.Provider value={getTablePopupProps}>\n {children}\n </TablePopupPropsContext.Provider>\n </DefaultPortalContext.Provider>\n );\n } catch {\n return children;\n }\n};\n\nconst Anvil2Providers: FC<{ portalAnvilContainer: HTMLDivElement } & PropsWithChildren> = ({\n portalAnvilContainer,\n children,\n}) => {\n try {\n const { PortalProvider } =\n require('@servicetitan/anvil2') as typeof import('@servicetitan/anvil2');\n return <PortalProvider root={portalAnvilContainer}>{children}</PortalProvider>;\n } catch {\n return children;\n }\n};\n\nexport function register(Component: ComponentType, light: boolean, options?: RegisterOptions) {\n const WrappedComponent = withCssInjector(Component);\n\n class WebComponent extends HTMLElement implements IWebComponent {\n private root?: ShadowRoot;\n private portal?: ShadowRoot;\n private portalAnvilContainer?: HTMLDivElement;\n\n private styles: {\n total: number;\n loaded: number;\n elements: HTMLElement[];\n } = { total: 0, loaded: 0, elements: [] };\n\n private ldService?: LDService;\n private logService?: Log;\n private historyManager?: HistoryManager;\n private exposedDependencies?: ExposedDependencies;\n private exposedInstanceDependencies?: ExposedInstanceDependencies;\n private eventBus?: EventBus;\n private basename?: string;\n private onReady?: () => void;\n private onDispose?: () => void;\n private view?: ReturnType<typeof render>;\n\n connectedCallback() {\n /*\n * connectedCallback can be called when DOM element has moved\n * check that root is still connected to the DOM\n * if that's the case we don't need to reconnect MFE\n */\n if (this.root?.isConnected) {\n return;\n }\n const sharedDependenciesNames = options?.sharedDependenciesNames ?? [];\n const styleUrls = getStyleUrls(light, sharedDependenciesNames, this);\n\n this.styles = {\n total: styleUrls.length * 2,\n loaded: 0,\n elements: [],\n };\n\n this.root = this.shadowRoot ?? this.attachShadow({ mode: 'open' });\n /*\n * Portal shadow dom is created at the bottom of the body in order to be used as\n * the element for the design system components to attach modals and popups to.\n * This element is passed down the tree through context, and used within\n * the design system components.\n */\n const portalElement = document.createElement('div');\n portalElement.setAttribute(\n 'data-mfe-portal-name',\n getElementName({ WebComponent: WEB_COMPONENT_NAME! })\n );\n this.portal = document.body.appendChild(portalElement).attachShadow({ mode: 'open' });\n /*\n * Add element inside of portal so that Anvil 2 can attach modals and popups to it\n * since floating-ui does not support attaching straight to shadow dom\n */\n this.portalAnvilContainer = document.createElement('div');\n this.portal.appendChild(this.portalAnvilContainer);\n\n this.view = render(<Placeholder />, this.root, options);\n\n this.styles.elements.push(\n ...this.attachStyles(this.root, styleUrls),\n ...this.attachStyles(this.portal, styleUrls)\n );\n }\n\n disconnectedCallback() {\n if (!this.root || this.root.isConnected) {\n return;\n }\n for (const element of this.styles.elements) {\n element.remove();\n }\n\n this.view?.unmount();\n document.body?.removeChild(this.portal!.host);\n this.root = undefined;\n this.portal = undefined;\n this.portalAnvilContainer = undefined;\n\n this.onDispose?.();\n }\n\n // Observe changes to the data-mfe-data attribute so that we can re-render when it changes\n static get observedAttributes() {\n return ['data-mfe-data'];\n }\n\n attributeChangedCallback() {\n this.render();\n }\n\n provide = (entries: Entries) => {\n for (const [key, value] of Object.entries(entries)) {\n this[key as keyof IWebComponent] = value;\n }\n\n if (this.styles.loaded === this.styles.total) {\n this.render();\n }\n };\n\n private handleLoad = () => {\n this.styles.loaded++;\n\n if (this.styles.loaded === this.styles.total) {\n this.render();\n }\n };\n\n private attachStyles = (node: ShadowRoot, urls: string[]) => {\n const elements: HTMLElement[] = [];\n\n for (const url of urls) {\n const element = createLink(url, this.handleLoad);\n node.appendChild(element);\n elements.push(element);\n }\n\n return elements;\n };\n\n private withProviders(children: ReactElement) {\n return (\n <Anvil2Providers portalAnvilContainer={this.portalAnvilContainer!}>\n <Anvil1Providers root={this.root!} portal={this.portal!}>\n {children}\n </Anvil1Providers>\n </Anvil2Providers>\n );\n }\n\n private render = () => {\n /*\n * Check for this.root first, otherwise we get error when\n * attributeChangedCallback happens on load\n */\n if (this.root) {\n const mfeData = this.dataset.mfeData\n ? /*\n * Data was stringified in order to come through the data-mfe-data attribute\n * So we must JSON.parse it here to get an object back\n */\n JSON.parse(this.dataset.mfeData)\n : /*\n * If mfeData isn't there, then the Host may not be up to date with web-components\n * and is instead passing data through separate data-attributes, so we want to\n * spread all of those instead\n */\n { ...this.dataset };\n\n const metadata = {\n shadowRoot: this.root,\n portalShadowRoot: this.portal!,\n };\n\n this.view?.rerender(\n <Provider\n singletons={[\n { provide: IS_WEB_COMPONENT_TOKEN, useValue: true },\n { provide: RENDER_ROOT_TOKEN, useValue: this.root },\n ]}\n >\n <Provider\n singletons={[\n { provide: Log, useValue: this.logService },\n {\n provide: HistoryManager,\n useValue: this.historyManager,\n },\n {\n provide: EXPOSED_DEPENDENCIES_TOKEN,\n useValue: this.exposedDependencies,\n },\n {\n provide: EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,\n useValue: this.exposedInstanceDependencies,\n },\n { provide: BASENAME_TOKEN, useValue: this.basename },\n { provide: EVENT_BUS_TOKEN, useValue: this.eventBus },\n { provide: getLDServiceToken(), useValue: this.ldService },\n ].filter(\n ({ provide, useValue }) =>\n useValue !== undefined && provide !== undefined\n )}\n >\n <MFEDataContext.Provider value={{ ...mfeData }}>\n <MFEMetadataContext.Provider value={metadata}>\n {this.withProviders(<WrappedComponent {...mfeData} />)}\n {this.onReady && <RenderCallback callback={this.onReady} />}\n </MFEMetadataContext.Provider>\n </MFEDataContext.Provider>\n </Provider>\n </Provider>\n );\n }\n };\n }\n\n if (!WEB_COMPONENT_NAME) {\n // eslint-disable-next-line no-console\n console.error('\"WEB_COMPONENT_NAME\" is not defined!');\n return;\n }\n\n window.customElements.define(WEB_COMPONENT_NAME, WebComponent);\n}\n\nfunction getStyleUrls(light: boolean, sharedDependenciesNames: string[], el: HTMLElement) {\n function getCssUrl(dependencyName: string, cssFileRegEx: RegExp) {\n if (light && sharedDependenciesNames.includes(dependencyName)) {\n return Array.from(document.getElementsByTagName('link')).find(\n ({ href }) => href && cssFileRegEx.test(href)\n )?.href;\n }\n }\n\n const designSystemUrl = getCssUrl(\n '@servicetitan/design-system',\n /design-system(\\..+)?\\.bundle\\.css/\n );\n const anvil2CssUrl = getCssUrl('@servicetitan/anvil2', /anvil2(\\..+)?\\.bundle\\.css/);\n\n return [\n ...(designSystemUrl ? [designSystemUrl] : []),\n ...(anvil2CssUrl ? [anvil2CssUrl] : []),\n ...(el.hasAttribute('style-urls')\n ? JSON.parse(decodeURIComponent(el.getAttribute('style-urls')!))\n : []),\n ];\n}\n\nfunction RenderCallback({ callback }: { callback: () => void }) {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => callback(), []);\n return null;\n}\n"],"names":["Log","Provider","useCallback","useEffect","BASENAME_TOKEN","EXPOSED_DEPENDENCIES_TOKEN","EXPOSED_INSTANCE_DEPENDENCIES_TOKEN","IS_WEB_COMPONENT_TOKEN","RENDER_ROOT_TOKEN","MFEDataContext","MFEMetadataContext","withCssInjector","EVENT_BUS_TOKEN","WEB_COMPONENT_NAME","HistoryManager","render","getElementName","getLDServiceToken","createLink","url","onLoad","element","document","createElement","href","rel","crossOrigin","onload","onerror","Placeholder","div","style","display","Anvil1Providers","root","portal","children","getTablePopupProps","props","appendTo","DefaultPortalContext","TablePopupPropsContext","require","value","Anvil2Providers","portalAnvilContainer","PortalProvider","register","Component","light","options","WrappedComponent","WebComponent","HTMLElement","connectedCallback","isConnected","sharedDependenciesNames","styleUrls","getStyleUrls","styles","total","length","loaded","elements","shadowRoot","attachShadow","mode","portalElement","setAttribute","body","appendChild","view","push","attachStyles","disconnectedCallback","remove","unmount","removeChild","host","undefined","onDispose","observedAttributes","attributeChangedCallback","withProviders","ldService","logService","historyManager","exposedDependencies","exposedInstanceDependencies","eventBus","basename","onReady","provide","entries","key","Object","handleLoad","node","urls","mfeData","dataset","JSON","parse","metadata","portalShadowRoot","rerender","singletons","useValue","filter","RenderCallback","callback","console","error","window","customElements","define","el","getCssUrl","dependencyName","cssFileRegEx","includes","Array","from","getElementsByTagName","find","test","designSystemUrl","anvil2CssUrl","hasAttribute","decodeURIComponent","getAttribute"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/register.tsx"],"sourcesContent":["import { type LDService } from '@servicetitan/launchdarkly-service';\nimport { Log } from '@servicetitan/log-service';\nimport { Provider } from '@servicetitan/react-ioc';\nimport { ExposedDependencies } from '@servicetitan/startup-utils';\nimport { ComponentType, FC, ReactElement, useEffect } from 'react';\nimport { Anvil1Providers } from './anvil1-providers';\nimport { Anvil2Providers } from './anvil2-providers';\nimport {\n BASENAME_TOKEN,\n Entries,\n EXPOSED_DEPENDENCIES_TOKEN,\n EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,\n ExposedInstanceDependencies,\n IS_WEB_COMPONENT_TOKEN,\n IWebComponent,\n RENDER_ROOT_TOKEN,\n} from './common';\nimport { MFEDataContext } from './contexts/mfe-data-context';\nimport { MFEMetadataContext } from './contexts/mfe-metadata-context';\nimport { withCssInjector } from './css-injector';\nimport { EVENT_BUS_TOKEN, EventBus } from './event-bus';\nimport { getStyleUrls } from './get-style-urls';\nimport { WEB_COMPONENT_NAME } from './globals';\nimport { HistoryManager } from './history-manager';\nimport { render } from './render';\nimport { getElementName, getLDServiceToken } from './utils';\n\nfunction createLink(url: string, onLoad: () => void) {\n const element = document.createElement('link');\n\n element.href = url;\n element.rel = 'stylesheet';\n element.crossOrigin = 'anonymous';\n element.onload = onLoad;\n element.onerror = onLoad;\n\n return element;\n}\n\nconst Placeholder: FC = () => <div style={{ display: 'none' }} />;\n\nexport interface RegisterOptions {\n legacyRoot?: boolean;\n sharedDependenciesNames?: string[];\n}\n\nexport function register(Component: ComponentType, light: boolean, options?: RegisterOptions) {\n const WrappedComponent = withCssInjector(Component);\n\n class WebComponent extends HTMLElement implements IWebComponent {\n private root?: ShadowRoot;\n private portal?: ShadowRoot;\n private portalAnvilContainer?: HTMLDivElement;\n\n private styles: {\n total: number;\n loaded: number;\n elements: HTMLElement[];\n } = { total: 0, loaded: 0, elements: [] };\n\n private ldService?: LDService;\n private logService?: Log;\n private historyManager?: HistoryManager;\n private exposedDependencies?: ExposedDependencies;\n private exposedInstanceDependencies?: ExposedInstanceDependencies;\n private eventBus?: EventBus;\n private basename?: string;\n private onReady?: () => void;\n private onDispose?: () => void;\n private view?: ReturnType<typeof render>;\n\n connectedCallback() {\n /*\n * connectedCallback can be called when DOM element has moved\n * check that root is still connected to the DOM\n * if that's the case we don't need to reconnect MFE\n */\n if (this.root?.isConnected) {\n return;\n }\n const sharedDependenciesNames = options?.sharedDependenciesNames ?? [];\n const styleUrls = getStyleUrls(light, sharedDependenciesNames, this);\n\n this.styles = {\n total: styleUrls.length * 2,\n loaded: 0,\n elements: [],\n };\n\n this.root = this.shadowRoot ?? this.attachShadow({ mode: 'open' });\n /*\n * Portal shadow dom is created at the bottom of the body in order to be used as\n * the element for the design system components to attach modals and popups to.\n * This element is passed down the tree through context, and used within\n * the design system components.\n */\n const portalElement = document.createElement('div');\n portalElement.setAttribute(\n 'data-mfe-portal-name',\n getElementName({ WebComponent: WEB_COMPONENT_NAME! })\n );\n this.portal = document.body.appendChild(portalElement).attachShadow({ mode: 'open' });\n /*\n * Add element inside of portal so that Anvil 2 can attach modals and popups to it\n * since floating-ui does not support attaching straight to shadow dom\n */\n this.portalAnvilContainer = document.createElement('div');\n this.portal.appendChild(this.portalAnvilContainer);\n\n this.view = render(<Placeholder />, this.root, options);\n\n this.styles.elements.push(\n ...this.attachStyles(this.root, styleUrls),\n ...this.attachStyles(this.portal, styleUrls)\n );\n }\n\n disconnectedCallback() {\n if (!this.root || this.root.isConnected) {\n return;\n }\n for (const element of this.styles.elements) {\n element.remove();\n }\n\n this.view?.unmount();\n document.body?.removeChild(this.portal!.host);\n this.root = undefined;\n this.portal = undefined;\n this.portalAnvilContainer = undefined;\n\n this.onDispose?.();\n }\n\n // Observe changes to the data-mfe-data attribute so that we can re-render when it changes\n static get observedAttributes() {\n return ['data-mfe-data'];\n }\n\n attributeChangedCallback() {\n this.render();\n }\n\n provide = (entries: Entries) => {\n for (const [key, value] of Object.entries(entries)) {\n this[key as keyof IWebComponent] = value;\n }\n\n if (this.styles.loaded === this.styles.total) {\n this.render();\n }\n };\n\n private handleLoad = () => {\n this.styles.loaded++;\n\n if (this.styles.loaded === this.styles.total) {\n this.render();\n }\n };\n\n private attachStyles = (node: ShadowRoot, urls: string[]) => {\n const elements: HTMLElement[] = [];\n\n for (const url of urls) {\n const element = createLink(url, this.handleLoad);\n node.appendChild(element);\n elements.push(element);\n }\n\n return elements;\n };\n\n private withProviders(children: ReactElement) {\n return (\n <Anvil2Providers portalAnvilContainer={this.portalAnvilContainer!}>\n <Anvil1Providers root={this.root!} portal={this.portal!}>\n {children}\n </Anvil1Providers>\n </Anvil2Providers>\n );\n }\n\n private render = () => {\n /*\n * Check for this.root first, otherwise we get error when\n * attributeChangedCallback happens on load\n */\n if (this.root) {\n const mfeData = this.dataset.mfeData\n ? /*\n * Data was stringified in order to come through the data-mfe-data attribute\n * So we must JSON.parse it here to get an object back\n */\n JSON.parse(this.dataset.mfeData)\n : /*\n * If mfeData isn't there, then the Host may not be up to date with web-components\n * and is instead passing data through separate data-attributes, so we want to\n * spread all of those instead\n */\n { ...this.dataset };\n\n const metadata = {\n shadowRoot: this.root,\n portalShadowRoot: this.portal!,\n };\n\n this.view?.rerender(\n <Provider\n singletons={[\n { provide: IS_WEB_COMPONENT_TOKEN, useValue: true },\n { provide: RENDER_ROOT_TOKEN, useValue: this.root },\n ]}\n >\n <Provider\n singletons={[\n { provide: Log, useValue: this.logService },\n {\n provide: HistoryManager,\n useValue: this.historyManager,\n },\n {\n provide: EXPOSED_DEPENDENCIES_TOKEN,\n useValue: this.exposedDependencies,\n },\n {\n provide: EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,\n useValue: this.exposedInstanceDependencies,\n },\n { provide: BASENAME_TOKEN, useValue: this.basename },\n { provide: EVENT_BUS_TOKEN, useValue: this.eventBus },\n { provide: getLDServiceToken(), useValue: this.ldService },\n ].filter(\n ({ provide, useValue }) =>\n useValue !== undefined && provide !== undefined\n )}\n >\n <MFEDataContext.Provider value={{ ...mfeData }}>\n <MFEMetadataContext.Provider value={metadata}>\n {this.withProviders(<WrappedComponent {...mfeData} />)}\n {this.onReady && <RenderCallback callback={this.onReady} />}\n </MFEMetadataContext.Provider>\n </MFEDataContext.Provider>\n </Provider>\n </Provider>\n );\n }\n };\n }\n\n if (!WEB_COMPONENT_NAME) {\n // eslint-disable-next-line no-console\n console.error('\"WEB_COMPONENT_NAME\" is not defined!');\n return;\n }\n\n window.customElements.define(WEB_COMPONENT_NAME, WebComponent);\n}\n\nfunction RenderCallback({ callback }: { callback: () => void }) {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => callback(), []);\n return null;\n}\n"],"names":["Log","Provider","useEffect","Anvil1Providers","Anvil2Providers","BASENAME_TOKEN","EXPOSED_DEPENDENCIES_TOKEN","EXPOSED_INSTANCE_DEPENDENCIES_TOKEN","IS_WEB_COMPONENT_TOKEN","RENDER_ROOT_TOKEN","MFEDataContext","MFEMetadataContext","withCssInjector","EVENT_BUS_TOKEN","getStyleUrls","WEB_COMPONENT_NAME","HistoryManager","render","getElementName","getLDServiceToken","createLink","url","onLoad","element","document","createElement","href","rel","crossOrigin","onload","onerror","Placeholder","div","style","display","register","Component","light","options","WrappedComponent","WebComponent","HTMLElement","connectedCallback","root","isConnected","sharedDependenciesNames","styleUrls","styles","total","length","loaded","elements","shadowRoot","attachShadow","mode","portalElement","setAttribute","portal","body","appendChild","portalAnvilContainer","view","push","attachStyles","disconnectedCallback","remove","unmount","removeChild","host","undefined","onDispose","observedAttributes","attributeChangedCallback","withProviders","children","ldService","logService","historyManager","exposedDependencies","exposedInstanceDependencies","eventBus","basename","onReady","provide","entries","key","value","Object","handleLoad","node","urls","mfeData","dataset","JSON","parse","metadata","portalShadowRoot","rerender","singletons","useValue","filter","RenderCallback","callback","console","error","window","customElements","define"],"mappings":"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"}
|
package/dist/render.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAIrC,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
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
/* eslint-disable react/no-deprecated */ import ReactDOM from 'react-dom';
|
|
2
|
-
|
|
3
|
-
try {
|
|
4
|
-
/**
|
|
5
|
-
* Note, bundlers must be configured to ignore this dependency.
|
|
6
|
-
* @see {@link file://./../../startup/src/core/check-resource/is-managed-react-dom-client-dependency.ts}
|
|
7
|
-
*/ createRoot = require('react-dom/client').createRoot;
|
|
8
|
-
} catch (unused) {
|
|
9
|
-
// ignore
|
|
10
|
-
}
|
|
2
|
+
import * as ReactDOMClient from 'react-dom/client';
|
|
11
3
|
export function render(element, container, options) {
|
|
12
|
-
if (typeof createRoot !== 'function' || (options === null || options === void 0 ? void 0 : options.legacyRoot)) {
|
|
4
|
+
if (typeof ReactDOMClient.createRoot !== 'function' || (options === null || options === void 0 ? void 0 : options.legacyRoot)) {
|
|
13
5
|
return renderLegacyRoot(element, container);
|
|
14
6
|
}
|
|
15
|
-
const root = createRoot(container);
|
|
7
|
+
const root = ReactDOMClient.createRoot(container);
|
|
16
8
|
root.render(element);
|
|
17
9
|
return {
|
|
18
10
|
rerender (element) {
|
package/dist/render.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render.ts"],"sourcesContent":["/* eslint-disable react/no-deprecated */\nimport { ReactElement } from 'react';\nimport ReactDOM from 'react-dom';\nimport
|
|
1
|
+
{"version":3,"sources":["../src/render.ts"],"sourcesContent":["/* eslint-disable react/no-deprecated */\nimport { ReactElement } from 'react';\nimport ReactDOM from 'react-dom';\nimport * as ReactDOMClient from 'react-dom/client';\n\ninterface RenderOptions {\n legacyRoot?: boolean;\n}\n\ninterface RenderResult {\n rerender(element: ReactElement): void;\n unmount(): void;\n}\n\nexport function render(\n element: ReactElement,\n container: Element | DocumentFragment,\n options?: RenderOptions\n): RenderResult {\n if (typeof ReactDOMClient.createRoot !== 'function' || options?.legacyRoot) {\n return renderLegacyRoot(element, container);\n }\n\n const root = ReactDOMClient.createRoot(container);\n root.render(element);\n\n return {\n rerender(element: ReactElement) {\n root.render(element);\n },\n unmount() {\n root.unmount();\n },\n };\n}\n\nfunction renderLegacyRoot(\n element: ReactElement,\n container: Element | DocumentFragment\n): RenderResult {\n ReactDOM.render(element, container);\n\n return {\n rerender(element: ReactElement) {\n ReactDOM.render(element, container);\n },\n unmount() {\n ReactDOM.unmountComponentAtNode(container);\n },\n };\n}\n"],"names":["ReactDOM","ReactDOMClient","render","element","container","options","createRoot","legacyRoot","renderLegacyRoot","root","rerender","unmount","unmountComponentAtNode"],"mappings":"AAAA,sCAAsC,GAEtC,OAAOA,cAAc,YAAY;AACjC,YAAYC,oBAAoB,mBAAmB;AAWnD,OAAO,SAASC,OACZC,OAAqB,EACrBC,SAAqC,EACrCC,OAAuB;IAEvB,IAAI,OAAOJ,eAAeK,UAAU,KAAK,eAAcD,oBAAAA,8BAAAA,QAASE,UAAU,GAAE;QACxE,OAAOC,iBAAiBL,SAASC;IACrC;IAEA,MAAMK,OAAOR,eAAeK,UAAU,CAACF;IACvCK,KAAKP,MAAM,CAACC;IAEZ,OAAO;QACHO,UAASP,OAAqB;YAC1BM,KAAKP,MAAM,CAACC;QAChB;QACAQ;YACIF,KAAKE,OAAO;QAChB;IACJ;AACJ;AAEA,SAASH,iBACLL,OAAqB,EACrBC,SAAqC;IAErCJ,SAASE,MAAM,CAACC,SAASC;IAEzB,OAAO;QACHM,UAASP,OAAqB;YAC1BH,SAASE,MAAM,CAACC,SAASC;QAC7B;QACAO;YACIX,SAASY,sBAAsB,CAACR;QACpC;IACJ;AACJ"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export declare function getLDServiceToken(): SymbolToken<LDService>;
|
|
1
|
+
import * as LDService from '@servicetitan/launchdarkly-service';
|
|
2
|
+
export declare function getLDServiceToken(): import("@servicetitan/react-ioc").SymbolToken<LDService.LDService>;
|
|
4
3
|
//# sourceMappingURL=get-ld-service-token.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-ld-service-token.d.ts","sourceRoot":"","sources":["../../src/utils/get-ld-service-token.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"get-ld-service-token.d.ts","sourceRoot":"","sources":["../../src/utils/get-ld-service-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,oCAAoC,CAAC;AAEhE,wBAAgB,iBAAiB,uEAEhC"}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
try {
|
|
3
|
-
token = require('@servicetitan/launchdarkly-service').LD_SERVICE_TOKEN;
|
|
4
|
-
} catch (unused) {
|
|
5
|
-
// ignore
|
|
6
|
-
}
|
|
1
|
+
import * as LDService from '@servicetitan/launchdarkly-service';
|
|
7
2
|
export function getLDServiceToken() {
|
|
8
|
-
return
|
|
3
|
+
return LDService.LD_SERVICE_TOKEN;
|
|
9
4
|
}
|
|
10
5
|
|
|
11
6
|
//# sourceMappingURL=get-ld-service-token.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/get-ld-service-token.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../src/utils/get-ld-service-token.ts"],"sourcesContent":["import * as LDService from '@servicetitan/launchdarkly-service';\n\nexport function getLDServiceToken() {\n return LDService.LD_SERVICE_TOKEN;\n}\n"],"names":["LDService","getLDServiceToken","LD_SERVICE_TOKEN"],"mappings":"AAAA,YAAYA,eAAe,qCAAqC;AAEhE,OAAO,SAASC;IACZ,OAAOD,UAAUE,gBAAgB;AACrC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/web-components",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "37.0.1",
|
|
4
4
|
"description": "Framework to build, register, and load Microfrontends into host applications",
|
|
5
5
|
"homepage": "https://docs.st.dev/docs/frontend/uikit/web-components",
|
|
6
6
|
"repository": {
|
|
@@ -27,18 +27,18 @@
|
|
|
27
27
|
"src"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@servicetitan/error-boundary": "
|
|
31
|
-
"@servicetitan/startup-utils": "
|
|
30
|
+
"@servicetitan/error-boundary": "37.0.1",
|
|
31
|
+
"@servicetitan/startup-utils": "37.0.1",
|
|
32
32
|
"lodash.get": "~4.4.2",
|
|
33
33
|
"mitt": "~3.0.1",
|
|
34
|
-
"semver": "~7.8.
|
|
34
|
+
"semver": "~7.8.5"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@servicetitan/anvil2": "^3.0
|
|
37
|
+
"@servicetitan/anvil2": "^3.4.0",
|
|
38
38
|
"@servicetitan/design-system": "~14.5.3",
|
|
39
|
-
"@servicetitan/launchdarkly-service": "
|
|
40
|
-
"@servicetitan/log-service": "
|
|
41
|
-
"@servicetitan/react-ioc": "
|
|
39
|
+
"@servicetitan/launchdarkly-service": "37.0.1",
|
|
40
|
+
"@servicetitan/log-service": "37.0.1",
|
|
41
|
+
"@servicetitan/react-ioc": "37.0.1",
|
|
42
42
|
"@testing-library/dom": "^10.4.1",
|
|
43
43
|
"@testing-library/jest-dom": "^6.9.1",
|
|
44
44
|
"@testing-library/react": "^16.3.2",
|
|
@@ -51,14 +51,14 @@
|
|
|
51
51
|
"launchdarkly-react-client-sdk": "3.6.1",
|
|
52
52
|
"react": "~18.3.1",
|
|
53
53
|
"react-dom": "~18.3.1",
|
|
54
|
-
"shadow-dom-testing-library": "^1.
|
|
54
|
+
"shadow-dom-testing-library": "^1.14.0"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"@servicetitan/anvil2": ">=1.5.0",
|
|
58
58
|
"@servicetitan/design-system": ">=14.5.3",
|
|
59
|
-
"@servicetitan/launchdarkly-service": "
|
|
60
|
-
"@servicetitan/log-service": "
|
|
61
|
-
"@servicetitan/react-ioc": "
|
|
59
|
+
"@servicetitan/launchdarkly-service": "37.0.1",
|
|
60
|
+
"@servicetitan/log-service": "37.0.1",
|
|
61
|
+
"@servicetitan/react-ioc": "37.0.1",
|
|
62
62
|
"history": "~4.10.1",
|
|
63
63
|
"react": ">=17.0.2",
|
|
64
64
|
"react-dom": ">=17.0.2"
|
|
@@ -78,7 +78,18 @@
|
|
|
78
78
|
"access": "public"
|
|
79
79
|
},
|
|
80
80
|
"cli": {
|
|
81
|
-
"webpack": false
|
|
81
|
+
"webpack": false,
|
|
82
|
+
"peerDependenciesMeta": {
|
|
83
|
+
"@servicetitan/anvil2": {
|
|
84
|
+
"fallback": "empty"
|
|
85
|
+
},
|
|
86
|
+
"@servicetitan/design-system": {
|
|
87
|
+
"fallback": "empty"
|
|
88
|
+
},
|
|
89
|
+
"@servicetitan/launchdarkly-service": {
|
|
90
|
+
"fallback": "empty"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
82
93
|
},
|
|
83
|
-
"gitHead": "
|
|
94
|
+
"gitHead": "9a2e5579f88cf9895fd2948ce5d5810e976d20b0"
|
|
84
95
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Split from register-anvil2.test.tsx because register.tsx changed from
|
|
3
|
+
* dynamic require() to static `import * as` for Vite/ESM compatibility.
|
|
4
|
+
* The previous approach used jest.resetModules() mid-file to re-mock
|
|
5
|
+
* modules between tests, but static imports are resolved once at module
|
|
6
|
+
* load time and aren't affected by resetModules. Separate files give
|
|
7
|
+
* each test suite its own jest.mock declarations.
|
|
8
|
+
*/
|
|
9
|
+
import '@testing-library/jest-dom';
|
|
10
|
+
import { within } from '@testing-library/react';
|
|
11
|
+
import {
|
|
12
|
+
createRegisterHarness,
|
|
13
|
+
optionalLibraryWrappers,
|
|
14
|
+
} from '../__mocks__/register-anvil2-harness';
|
|
15
|
+
|
|
16
|
+
jest.mock('@servicetitan/anvil2', () => ({}));
|
|
17
|
+
jest.mock('@servicetitan/design-system', () => ({}));
|
|
18
|
+
|
|
19
|
+
describe('[web-components] register', () => {
|
|
20
|
+
const { Page, subject } = createRegisterHarness('mock-no-optional-deps');
|
|
21
|
+
|
|
22
|
+
for (const [library, wrappers] of Object.entries(optionalLibraryWrappers)) {
|
|
23
|
+
describe(`when ${library} is not present`, () => {
|
|
24
|
+
test.each(wrappers)('does not wrap component within %s', name => {
|
|
25
|
+
subject();
|
|
26
|
+
|
|
27
|
+
const element = within(Page.componentShadowRoot as any).queryByText(`<${name}>`);
|
|
28
|
+
expect(element).not.toBeInTheDocument();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
});
|
|
@@ -71,28 +71,10 @@ describe('[web-components] register', () => {
|
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
subject();
|
|
77
|
-
|
|
78
|
-
const element = within(Page.componentShadowRoot as any).queryByText(`<${name}>`);
|
|
79
|
-
expect(element).toBeInTheDocument();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe(`when ${library} is not present`, () => {
|
|
83
|
-
beforeAll(() => {
|
|
84
|
-
jest.resetModules();
|
|
85
|
-
jest.mock(library, () => {
|
|
86
|
-
throw new Error('Cannot find module');
|
|
87
|
-
});
|
|
88
|
-
});
|
|
74
|
+
test.each(Object.values(optionalLibraryWrappers).flat())('wraps component within %s', name => {
|
|
75
|
+
subject();
|
|
89
76
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const element = within(Page.componentShadowRoot as any).queryByText(`<${name}>`);
|
|
94
|
-
expect(element).not.toBeInTheDocument();
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
}
|
|
77
|
+
const element = within(Page.componentShadowRoot as any).queryByText(`<${name}>`);
|
|
78
|
+
expect(element).toBeInTheDocument();
|
|
79
|
+
});
|
|
98
80
|
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as Anvil1 from '@servicetitan/design-system';
|
|
2
|
+
import { FC, PropsWithChildren, useCallback } from 'react';
|
|
3
|
+
|
|
4
|
+
export const Anvil1Providers: FC<{ root: ShadowRoot; portal: ShadowRoot } & PropsWithChildren> = ({
|
|
5
|
+
root,
|
|
6
|
+
portal,
|
|
7
|
+
children,
|
|
8
|
+
}) => {
|
|
9
|
+
const getTablePopupProps = useCallback(
|
|
10
|
+
(props: object) => ({
|
|
11
|
+
...props,
|
|
12
|
+
appendTo: root as unknown as HTMLElement,
|
|
13
|
+
}),
|
|
14
|
+
[root]
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
if (Anvil1.DefaultPortalContext === undefined || Anvil1.TablePopupPropsContext === undefined) {
|
|
18
|
+
return children;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Anvil1.DefaultPortalContext.Provider value={portal as unknown as HTMLElement}>
|
|
23
|
+
<Anvil1.TablePopupPropsContext.Provider value={getTablePopupProps}>
|
|
24
|
+
{children}
|
|
25
|
+
</Anvil1.TablePopupPropsContext.Provider>
|
|
26
|
+
</Anvil1.DefaultPortalContext.Provider>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as Anvil2 from '@servicetitan/anvil2';
|
|
2
|
+
import { FC, PropsWithChildren } from 'react';
|
|
3
|
+
|
|
4
|
+
export const Anvil2Providers: FC<{ portalAnvilContainer: HTMLDivElement } & PropsWithChildren> = ({
|
|
5
|
+
portalAnvilContainer,
|
|
6
|
+
children,
|
|
7
|
+
}) => {
|
|
8
|
+
if (Anvil2.PortalProvider === undefined) {
|
|
9
|
+
return children;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return <Anvil2.PortalProvider root={portalAnvilContainer}>{children}</Anvil2.PortalProvider>;
|
|
13
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function getStyleUrls(light: boolean, sharedDependenciesNames: string[], el: HTMLElement) {
|
|
2
|
+
function getCssUrl(dependencyName: string, cssFileRegEx: RegExp) {
|
|
3
|
+
if (light && sharedDependenciesNames.includes(dependencyName)) {
|
|
4
|
+
return Array.from(document.getElementsByTagName('link')).find(
|
|
5
|
+
({ href }) => href && cssFileRegEx.test(href)
|
|
6
|
+
)?.href;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const designSystemUrl = getCssUrl(
|
|
11
|
+
'@servicetitan/design-system',
|
|
12
|
+
/design-system(\..+)?\.bundle\.css/
|
|
13
|
+
);
|
|
14
|
+
const anvil2CssUrl = getCssUrl('@servicetitan/anvil2', /anvil2(\..+)?\.bundle\.css/);
|
|
15
|
+
|
|
16
|
+
return [
|
|
17
|
+
...(designSystemUrl ? [designSystemUrl] : []),
|
|
18
|
+
...(anvil2CssUrl ? [anvil2CssUrl] : []),
|
|
19
|
+
...(el.hasAttribute('style-urls')
|
|
20
|
+
? JSON.parse(decodeURIComponent(el.getAttribute('style-urls')!))
|
|
21
|
+
: []),
|
|
22
|
+
];
|
|
23
|
+
}
|
package/src/register.tsx
CHANGED
|
@@ -2,7 +2,9 @@ import { type LDService } from '@servicetitan/launchdarkly-service';
|
|
|
2
2
|
import { Log } from '@servicetitan/log-service';
|
|
3
3
|
import { Provider } from '@servicetitan/react-ioc';
|
|
4
4
|
import { ExposedDependencies } from '@servicetitan/startup-utils';
|
|
5
|
-
import { ComponentType, FC,
|
|
5
|
+
import { ComponentType, FC, ReactElement, useEffect } from 'react';
|
|
6
|
+
import { Anvil1Providers } from './anvil1-providers';
|
|
7
|
+
import { Anvil2Providers } from './anvil2-providers';
|
|
6
8
|
import {
|
|
7
9
|
BASENAME_TOKEN,
|
|
8
10
|
Entries,
|
|
@@ -17,6 +19,7 @@ import { MFEDataContext } from './contexts/mfe-data-context';
|
|
|
17
19
|
import { MFEMetadataContext } from './contexts/mfe-metadata-context';
|
|
18
20
|
import { withCssInjector } from './css-injector';
|
|
19
21
|
import { EVENT_BUS_TOKEN, EventBus } from './event-bus';
|
|
22
|
+
import { getStyleUrls } from './get-style-urls';
|
|
20
23
|
import { WEB_COMPONENT_NAME } from './globals';
|
|
21
24
|
import { HistoryManager } from './history-manager';
|
|
22
25
|
import { render } from './render';
|
|
@@ -41,47 +44,6 @@ export interface RegisterOptions {
|
|
|
41
44
|
sharedDependenciesNames?: string[];
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
const Anvil1Providers: FC<{ root: ShadowRoot; portal: ShadowRoot } & PropsWithChildren> = ({
|
|
45
|
-
root,
|
|
46
|
-
portal,
|
|
47
|
-
children,
|
|
48
|
-
}) => {
|
|
49
|
-
const getTablePopupProps = useCallback(
|
|
50
|
-
(props: object) => ({
|
|
51
|
-
...props,
|
|
52
|
-
appendTo: root as unknown as HTMLElement,
|
|
53
|
-
}),
|
|
54
|
-
[root]
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
const { DefaultPortalContext, TablePopupPropsContext } =
|
|
59
|
-
require('@servicetitan/design-system') as typeof import('@servicetitan/design-system');
|
|
60
|
-
return (
|
|
61
|
-
<DefaultPortalContext.Provider value={portal as unknown as HTMLElement}>
|
|
62
|
-
<TablePopupPropsContext.Provider value={getTablePopupProps}>
|
|
63
|
-
{children}
|
|
64
|
-
</TablePopupPropsContext.Provider>
|
|
65
|
-
</DefaultPortalContext.Provider>
|
|
66
|
-
);
|
|
67
|
-
} catch {
|
|
68
|
-
return children;
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const Anvil2Providers: FC<{ portalAnvilContainer: HTMLDivElement } & PropsWithChildren> = ({
|
|
73
|
-
portalAnvilContainer,
|
|
74
|
-
children,
|
|
75
|
-
}) => {
|
|
76
|
-
try {
|
|
77
|
-
const { PortalProvider } =
|
|
78
|
-
require('@servicetitan/anvil2') as typeof import('@servicetitan/anvil2');
|
|
79
|
-
return <PortalProvider root={portalAnvilContainer}>{children}</PortalProvider>;
|
|
80
|
-
} catch {
|
|
81
|
-
return children;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
47
|
export function register(Component: ComponentType, light: boolean, options?: RegisterOptions) {
|
|
86
48
|
const WrappedComponent = withCssInjector(Component);
|
|
87
49
|
|
|
@@ -295,30 +257,6 @@ export function register(Component: ComponentType, light: boolean, options?: Reg
|
|
|
295
257
|
window.customElements.define(WEB_COMPONENT_NAME, WebComponent);
|
|
296
258
|
}
|
|
297
259
|
|
|
298
|
-
function getStyleUrls(light: boolean, sharedDependenciesNames: string[], el: HTMLElement) {
|
|
299
|
-
function getCssUrl(dependencyName: string, cssFileRegEx: RegExp) {
|
|
300
|
-
if (light && sharedDependenciesNames.includes(dependencyName)) {
|
|
301
|
-
return Array.from(document.getElementsByTagName('link')).find(
|
|
302
|
-
({ href }) => href && cssFileRegEx.test(href)
|
|
303
|
-
)?.href;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const designSystemUrl = getCssUrl(
|
|
308
|
-
'@servicetitan/design-system',
|
|
309
|
-
/design-system(\..+)?\.bundle\.css/
|
|
310
|
-
);
|
|
311
|
-
const anvil2CssUrl = getCssUrl('@servicetitan/anvil2', /anvil2(\..+)?\.bundle\.css/);
|
|
312
|
-
|
|
313
|
-
return [
|
|
314
|
-
...(designSystemUrl ? [designSystemUrl] : []),
|
|
315
|
-
...(anvil2CssUrl ? [anvil2CssUrl] : []),
|
|
316
|
-
...(el.hasAttribute('style-urls')
|
|
317
|
-
? JSON.parse(decodeURIComponent(el.getAttribute('style-urls')!))
|
|
318
|
-
: []),
|
|
319
|
-
];
|
|
320
|
-
}
|
|
321
|
-
|
|
322
260
|
function RenderCallback({ callback }: { callback: () => void }) {
|
|
323
261
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
324
262
|
useEffect(() => callback(), []);
|
package/src/render.ts
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
/* eslint-disable react/no-deprecated */
|
|
2
2
|
import { ReactElement } from 'react';
|
|
3
3
|
import ReactDOM from 'react-dom';
|
|
4
|
-
import
|
|
4
|
+
import * as ReactDOMClient from 'react-dom/client';
|
|
5
5
|
|
|
6
|
-
let createRoot: typeof ReactDOMClient.createRoot;
|
|
7
|
-
try {
|
|
8
|
-
/**
|
|
9
|
-
* Note, bundlers must be configured to ignore this dependency.
|
|
10
|
-
* @see {@link file://./../../startup/src/core/check-resource/is-managed-react-dom-client-dependency.ts}
|
|
11
|
-
*/
|
|
12
|
-
createRoot = require('react-dom/client').createRoot;
|
|
13
|
-
} catch {
|
|
14
|
-
// ignore
|
|
15
|
-
}
|
|
16
6
|
interface RenderOptions {
|
|
17
7
|
legacyRoot?: boolean;
|
|
18
8
|
}
|
|
@@ -27,11 +17,11 @@ export function render(
|
|
|
27
17
|
container: Element | DocumentFragment,
|
|
28
18
|
options?: RenderOptions
|
|
29
19
|
): RenderResult {
|
|
30
|
-
if (typeof createRoot !== 'function' || options?.legacyRoot) {
|
|
20
|
+
if (typeof ReactDOMClient.createRoot !== 'function' || options?.legacyRoot) {
|
|
31
21
|
return renderLegacyRoot(element, container);
|
|
32
22
|
}
|
|
33
23
|
|
|
34
|
-
const root = createRoot(container);
|
|
24
|
+
const root = ReactDOMClient.createRoot(container);
|
|
35
25
|
root.render(element);
|
|
36
26
|
|
|
37
27
|
return {
|
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { SymbolToken } from '@servicetitan/react-ioc';
|
|
3
|
-
|
|
4
|
-
let token: SymbolToken<LDService>;
|
|
5
|
-
try {
|
|
6
|
-
token = require('@servicetitan/launchdarkly-service').LD_SERVICE_TOKEN;
|
|
7
|
-
} catch {
|
|
8
|
-
// ignore
|
|
9
|
-
}
|
|
1
|
+
import * as LDService from '@servicetitan/launchdarkly-service';
|
|
10
2
|
|
|
11
3
|
export function getLDServiceToken() {
|
|
12
|
-
return
|
|
4
|
+
return LDService.LD_SERVICE_TOKEN;
|
|
13
5
|
}
|