UNPKG

@mozaic-ds/vue

Version:

Mozaic-Vue is the Vue.js implementation of ADEO Design system

147 lines (135 loc) 3.67 kB
import type { Meta, StoryObj } from '@storybook/vue3-vite'; import { defineComponent } from 'vue'; import './Catalog.scss'; type StoryModule = { default?: { title?: string; args?: Record<string, unknown>; parameters?: { docs?: { description?: { component?: string; story?: string; }; }; }; render?: (...args: unknown[]) => unknown; }; [key: string]: unknown; }; const storyModules = import.meta.glob('../components/*/*.stories.ts', { eager: true, }) as Record<string, StoryModule>; const humanizeComponentName = (value: string) => value .replace(/([a-z0-9])([A-Z])/g, '$1 $2') .replace(/[-_]+/g, ' ') .replace(/\b\w/g, (char) => char.toUpperCase()) .trim(); const slugify = (value: string) => value .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, ''); const getStoryHref = (title: string) => `/?path=/docs/${slugify(title)}--docs`; const catalogStories = Object.entries(storyModules) .filter(([, module]) => Boolean(module.default?.title)) .map(([filePath, module]) => { const meta = module.default ?? {}; const storyName = Object.keys(module).find( (name) => name !== 'default' && name !== '__esModule', ); const story = storyName ? (module[storyName] as StoryModule) : undefined; const render = typeof story?.render === 'function' ? story.render : typeof meta.render === 'function' ? meta.render : undefined; const args = { ...(meta.args ?? {}), ...(story?.args ?? {}), }; const componentName = filePath.split('/components/')[1]?.split('/')[0] ?? meta.title ?? 'Component'; const rawTitle = (meta.title ?? componentName).split('/').pop() ?? componentName; return { filePath, title: humanizeComponentName(rawTitle), description: meta.parameters?.docs?.description?.component ?? meta.parameters?.docs?.description?.story ?? 'Component documentation and examples.', storyHref: getStoryHref(meta.title ?? componentName), previewComponent: render && typeof render === 'function' ? defineComponent(render(args as never)) : undefined, }; }) .sort((left, right) => left.title.localeCompare(right.title)); const meta: Meta = { title: 'Catalog', parameters: { controls: { disable: true, }, docs: { controls: { disable: true, }, description: { component: 'A live catalog of the library components.', }, toc: false, canvas: { sourceState: 'none' }, }, }, }; export default meta; type Story = StoryObj; export const Default: Story = { render: () => ({ setup() { return { catalogStories }; }, template: ` <section class="catalog-grid" > <article v-for="entry in catalogStories" :key="entry.filePath" class="catalog-card" > <div class="catalog-preview" > <component :is="entry.previewComponent" v-if="entry.previewComponent" /> <span v-else>{{ entry.title }}</span> </div> <h3 class="catalog-title" > <a class="catalog-link" :href="entry.storyHref">{{ entry.title }}</a> </h3> <p class="catalog-description" > {{ entry.description }} </p> </article> </section> `, }), parameters: { docs: { canvas: { withToolbar: false, }, }, }, };