diff --git a/src/single-spa-css.test.ts b/src/single-spa-css.test.ts index 8d4c5ff..01d6932 100644 --- a/src/single-spa-css.test.ts +++ b/src/single-spa-css.test.ts @@ -17,23 +17,42 @@ describe("single-spa-css", () => { expect(() => singleSpaCss("asdfsdf")).toThrowError(); }); - it(`throws if cssUrls is not an array`, () => { + it(`throws if opts.cssUrls is not an array`, () => { // @ts-ignore expect(() => singleSpaCss({ cssUrls: "/main.css" })).toThrowError(); }); - it(`preloads scripts during the bootstrap lifecycle`, async () => { + it(`throws if customProps.cssUrls is not an array`, () => { const url = "https://example.com/main.css"; const lifecycles = singleSpaCss<{}>({ cssUrls: [url], }); - expect(findPreloadEl(url)).not.toBeInTheDocument(); + expect(() => + lifecycles.bootstrap({ + ...createProps(), + // @ts-ignore + cssUrls: "/main.css", + }) + ).toThrowError(); + }); + + it(`preloads scripts during the bootstrap lifecycle`, async () => { + const url1 = "https://example.com/main_1.css"; + const url2 = "https://example.com/main_2.css"; + + const lifecycles = singleSpaCss<{}>({ + cssUrls: [url1], + }); + + expect(findPreloadEl(url1)).not.toBeInTheDocument(); + expect(findPreloadEl(url2)).not.toBeInTheDocument(); - await lifecycles.bootstrap(createProps()); + await lifecycles.bootstrap({ ...createProps(), cssUrls: [url2] }); - expect(findPreloadEl(url)).toBeInTheDocument(); + expect(findPreloadEl(url1)).toBeInTheDocument(); + expect(findPreloadEl(url2)).toBeInTheDocument(); }); it(`mounts elements and waits for them to load before resolving the mount promise. Then it unmounts them`, async () => { diff --git a/src/single-spa-css.ts b/src/single-spa-css.ts index 0ee2ade..79b583d 100644 --- a/src/single-spa-css.ts +++ b/src/single-spa-css.ts @@ -1,4 +1,4 @@ -import { AppProps, LifeCycleFn } from "single-spa"; +import { AppProps, LifeCycleFn, CustomProps } from "single-spa"; const defaultOptions: Required = { cssUrls: [], @@ -51,9 +51,19 @@ export default function singleSpaCss( const linkElements: LinkElements = {}; let linkElementsToUnmount: ElementsToUnmount[] = []; - function bootstrap(props: AppProps) { + function bootstrap(props: AppProps & CssCustomProps & ExtraProps) { + const cssUrls: CssUrl[] = [...allCssUrls]; + + if (props.cssUrls) { + if (!Array.isArray(props.cssUrls)) { + throw Error("single-spa-css: cssUrls must be an array"); + } + + cssUrls.push(...props.cssUrls); + } + return Promise.all( - allCssUrls.map( + cssUrls.map( (cssUrl) => new Promise((resolve, reject) => { const [url] = extractUrl(cssUrl); @@ -77,9 +87,11 @@ export default function singleSpaCss( ); } - function mount(props: AppProps) { + function mount(props: AppProps & CssCustomProps & ExtraProps) { + const cssUrls = [...(props.cssUrls ?? []), ...allCssUrls]; + return Promise.all( - allCssUrls.map( + cssUrls.map( (cssUrl) => new Promise((resolve, reject) => { const [url, shouldUnmount] = extractUrl(cssUrl); @@ -122,7 +134,7 @@ export default function singleSpaCss( ); } - function unmount(props: AppProps) { + function unmount(props: AppProps & CssCustomProps & ExtraProps) { const elements = linkElementsToUnmount; // reset this array immediately so that only one mounted instance tries to unmount @@ -178,8 +190,12 @@ type LinkElements = { type ElementsToUnmount = [HTMLLinkElement, string]; +type CssCustomProps = { + cssUrls?: CssUrl[]; +}; + type CSSLifecycles = { - bootstrap: LifeCycleFn; - mount: LifeCycleFn; - unmount: LifeCycleFn; + bootstrap: LifeCycleFn; + mount: LifeCycleFn; + unmount: LifeCycleFn; };