diff --git a/packages/components/.storybook/main.cjs b/packages/components/.storybook/main.cjs index e9886a681..bcf4bd394 100644 --- a/packages/components/.storybook/main.cjs +++ b/packages/components/.storybook/main.cjs @@ -26,10 +26,10 @@ module.exports = { options: {} }, async viteFinal(config) { - return { - ...config, - plugins: [...config.plugins, tsconfigPaths.default()] - }; + if (config.build === undefined) config.build = {}; // fallback if build is not defined + config.build.target = 'esnext'; // to allow top level await + config.plugins = [...config.plugins, tsconfigPaths.default()]; + return config; }, docs: { docs: true, diff --git a/packages/components/.storybook/preview.js b/packages/components/.storybook/preview.js index d58dfcd00..c9fc43c73 100644 --- a/packages/components/.storybook/preview.js +++ b/packages/components/.storybook/preview.js @@ -1,46 +1,9 @@ -import { setCustomElementsManifest } from '@storybook/web-components'; import 'normalize.css'; import '../src/solid-styles.css'; import '../src/styles/tailwind.css'; -import { fetchStyleComponents } from '../scripts/storybook/styles-helper'; import { registerIconLibrary } from '../src/utilities/icon-library'; import { storybookUtilities } from '../scripts/storybook/helper'; -/** - * This loads the custom elements manifest generated on run or on build time. - */ - -async function loadCustomElements() { - let customElements; - - fetch('./custom-elements.json') - .then(() => { - // Use dynamic manifest generated by Vite on runtime - return fetch('./custom-elements.json').then(res => res.json()); - }) - .catch(() => { - console.log('Failed to fetch custom-elements.json. Using local manifest...'); - // Use manifest file generated on build time - return import('../dist/custom-elements.json'); - }) - .then(async customElements => { - // In production, the manifest is optimized and styles are added during the build process. - // However, in development mode, the manifest isn't built with styles, so we add them dynamically. - // In the latter case therefore we have to "fetchStyleComponents", too. - const stylesAreAlreadyIncluded = customElements.modules.some(module => module.styles === true); - if (!stylesAreAlreadyIncluded) { - const styleComponents = await fetchStyleComponents(); - customElements.modules = [...customElements?.modules, ...styleComponents]; - } - - setCustomElementsManifest(customElements); - }); - - console.log('Custom elements manifest loaded'); -} - -loadCustomElements(); - /** * This registers iconLibraries for the sd-icon component */ diff --git a/packages/components/scripts/storybook/fetch-cem.ts b/packages/components/scripts/storybook/fetch-cem.ts new file mode 100644 index 000000000..9143b30a4 --- /dev/null +++ b/packages/components/scripts/storybook/fetch-cem.ts @@ -0,0 +1,22 @@ +import { fetchStyleComponents } from './styles-helper'; +import { setCustomElementsManifest } from '@storybook/web-components'; + +export default async function loadCustomElements() { + await fetch('./custom-elements.json'); + + // Use dynamic manifest generated by Vite on runtime + const response = await fetch('./custom-elements.json'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const customElements = await response.json(); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + const stylesAreAlreadyIncluded = customElements.modules.some((module: { styles: boolean }) => module.styles); + if (!stylesAreAlreadyIncluded) { + const styleComponents = await fetchStyleComponents(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access + customElements.modules = [...customElements.modules, ...styleComponents]; + } + + setCustomElementsManifest(customElements); + console.log('Custom elements manifest loaded'); +} diff --git a/packages/components/scripts/storybook/helper.ts b/packages/components/scripts/storybook/helper.ts index 261c77f3f..013de32b8 100644 --- a/packages/components/scripts/storybook/helper.ts +++ b/packages/components/scripts/storybook/helper.ts @@ -2,6 +2,7 @@ import { classMap } from 'lit/directives/class-map.js'; import { getWcStorybookHelpers } from '@mariohamann/wc-storybook-helpers'; import { html, unsafeStatic } from 'lit/static-html.js'; import format from 'html-format'; +import loadCustomElements from './fetch-cem'; type ArgTypesDefinition = 'attribute' | 'property' | 'slot' | 'cssPart' | 'cssProperty'; @@ -19,6 +20,8 @@ export interface ConstantDefinition { title?: string; } +await loadCustomElements(); + /** * Returns default arguments, events, and argument types for a given custom element tag. * @@ -58,7 +61,7 @@ export const storybookDefaults = (customElementTag: string): any => { // Get the properties that are not defined as attributes const getProperties = () => { const fieldMembers = (manifest?.members as member[])?.filter(member => member.kind === 'field'); - const attributeNames = new Set(manifest.attributes?.map((attr: { fieldName: string }) => attr.fieldName)); + const attributeNames = new Set(manifest?.attributes?.map((attr: { fieldName: string }) => attr.fieldName)); const result = fieldMembers?.filter(member => !attributeNames.has(member.name) && member?.privacy !== 'private'); return result?.map(member => member.name); }; @@ -253,7 +256,7 @@ export const storybookTemplate = (customElementTag: string) => { args: any; }) => { const template = (args: any) => { - if (!manifest.style) { + if (!manifest?.style) { return theTemplate(args); } // Extract class related attributes and transform into an object.