Skip to content

Commit

Permalink
fix: 🐛 fix CEM loading in Storybook (#427)
Browse files Browse the repository at this point in the history
  • Loading branch information
mariohamann authored Sep 25, 2023
1 parent 316c8ba commit de7368f
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 43 deletions.
8 changes: 4 additions & 4 deletions packages/components/.storybook/main.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
37 changes: 0 additions & 37 deletions packages/components/.storybook/preview.js
Original file line number Diff line number Diff line change
@@ -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
*/
Expand Down
22 changes: 22 additions & 0 deletions packages/components/scripts/storybook/fetch-cem.ts
Original file line number Diff line number Diff line change
@@ -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');
}
7 changes: 5 additions & 2 deletions packages/components/scripts/storybook/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -19,6 +20,8 @@ export interface ConstantDefinition {
title?: string;
}

await loadCustomElements();

/**
* Returns default arguments, events, and argument types for a given custom element tag.
*
Expand Down Expand Up @@ -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);
};
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit de7368f

Please sign in to comment.