-
-
Notifications
You must be signed in to change notification settings - Fork 243
feat: add storybook #1270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sacrosanctic
wants to merge
16
commits into
npmx-dev:main
Choose a base branch
from
sacrosanctic:storybook
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,664
−34
Open
feat: add storybook #1270
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
5f73105
init
sacrosanctic b55d819
modify init
sacrosanctic ad5c030
nuxt+storybook integration workaround
sacrosanctic 2c85494
stub nuxt modules
sacrosanctic c09c374
add toolbar app settings
sacrosanctic 7f67e4c
add test dependency
sacrosanctic 7ce2dde
add story: og images
sacrosanctic 9412300
add story: license
sacrosanctic 439f5c9
add story: `DownloadAnalytics`
sacrosanctic f2fa20f
add story: input
sacrosanctic bece123
Merge pull request #2 from sacrosanctic/improved-storybook-setup
sacrosanctic 9545569
README
sacrosanctic e0b4a22
nit
sacrosanctic 812c3f5
keep 2 stories
sacrosanctic 6fd1da6
clean up story
sacrosanctic 0fd5e03
move md to docsite
sacrosanctic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,3 +45,6 @@ file-tree-sprite.svg | |
|
|
||
| # output | ||
| .vercel | ||
|
|
||
| *storybook.log | ||
| storybook-static | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| # Why Storybook? | ||
|
|
||
| Storybook is a development environment for UI components that helps catch UI changes and provides integrations for various testing types. For testing, Storybook offers: | ||
|
|
||
| - **Accessibility tests** - Built-in a11y checks | ||
| - **Visual tests** - Compare JPG screenshots | ||
| - **Vitest tests** - Use stories directly in your unit tests | ||
|
|
||
| ## Component Categories | ||
|
|
||
| The plan is to organize components into 3 categories. | ||
|
|
||
| ### UI Library Components | ||
|
|
||
| Generic and reusable components used throughout your application. | ||
|
|
||
| - Examples: Button, Input, Modal, Card | ||
| - **Testing focus:** Props, variants, accessibility | ||
| - **Coverage:** All variants and states | ||
|
|
||
| ### Composite Components | ||
|
|
||
| Single-use components that encapsulate one feature. | ||
|
|
||
| - Examples: UserProfile, WeeklyDownloadStats | ||
| - **Testing focus:** Integration patterns, user interactions | ||
| - **Coverage:** Common usage scenarios | ||
|
|
||
| ### Page Components | ||
|
|
||
| **Full-page layouts** should match what the users see. | ||
|
|
||
| - Examples: HomePage, Dashboard, CheckoutPage | ||
| - **Testing focus:** Layout, responsive behavior, integration testing | ||
| - **Coverage:** Critical user flows and breakpoints | ||
|
|
||
| ## Coverage Guidelines | ||
|
|
||
| ### Which Components Need Stories? | ||
|
|
||
| TBD | ||
|
|
||
| ## Project Conventions | ||
|
|
||
| ### Place a `.stories.ts` file next to your component | ||
|
|
||
| ``` | ||
| components/ | ||
| ├── Button.vue | ||
| └── Button.stories.ts | ||
| ``` | ||
|
|
||
| ### Story Template | ||
|
|
||
| ```ts | ||
| // *.stories.ts | ||
| import type { Meta, StoryObj } from '@nuxtjs/storybook' | ||
| import Component from './Button.vue' | ||
|
|
||
| const meta = { | ||
| component: Component, | ||
| // component scope configuration goes here | ||
| } satisfies Meta<typeof Component> | ||
|
|
||
| export default meta | ||
| type Story = StoryObj<typeof meta> | ||
|
|
||
| export const Default: Story = { | ||
| // story scope configuration goes here | ||
| } | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| Stories can be configured at three levels: | ||
|
|
||
| - **Global scope** (`.storybook/preview.ts`) - Applies to all stories | ||
| - **Component scope** - Applies to all stories for a specific component | ||
| - **Story scope** - Applies to individual stories only | ||
|
|
||
| ## Global App Settings | ||
|
|
||
| Global application settings are added to the Storybook toolbar for easy testing and viewing. Configure these in `.storybook/preview.ts` under the `globalTypes` and `decorators` properties. | ||
|
|
||
| ## Known Limitations | ||
|
|
||
| - `autodocs` usage is discouraged as it is buggy. | ||
| - Changing `i18n` in the toolbar doesn't update the language. A manual story reload is required. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import type { StorybookConfig } from '@nuxtjs/storybook' | ||
|
|
||
| const config = { | ||
| stories: ['../app/**/*.stories.@(js|ts|mdx)'], | ||
| addons: ['@storybook/addon-a11y', '@storybook/addon-docs'], | ||
| framework: '@storybook-vue/nuxt', | ||
| features: { | ||
| backgrounds: false, | ||
| }, | ||
| } satisfies StorybookConfig | ||
| export default config | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| import type { Preview } from '@nuxtjs/storybook' | ||
| import { currentLocales } from '../config/i18n' | ||
| import { fn } from 'storybook/test' | ||
| import { ACCENT_COLORS } from '../shared/utils/constants' | ||
|
|
||
| // related: https://github.com/npmx-dev/npmx.dev/blob/1431d24be555bca5e1ae6264434d49ca15173c43/test/nuxt/setup.ts#L12-L26 | ||
| // Stub Nuxt specific globals | ||
| // @ts-expect-error - dynamic global name | ||
| globalThis['__NUXT_COLOR_MODE__'] ??= { | ||
| preference: 'system', | ||
| value: 'dark', | ||
| getColorScheme: fn(() => 'dark'), | ||
| addColorScheme: fn(), | ||
| removeColorScheme: fn(), | ||
| } | ||
| // @ts-expect-error - dynamic global name | ||
| globalThis.defineOgImageComponent = fn() | ||
|
|
||
| const preview: Preview = { | ||
| parameters: { | ||
| controls: { | ||
| matchers: { | ||
| color: /(background|color)$/i, | ||
| date: /Date$/i, | ||
| }, | ||
| }, | ||
| }, | ||
| // Provides toolbars to switch things like theming and language | ||
| globalTypes: { | ||
| locale: { | ||
| name: 'Locale', | ||
| description: 'UI language', | ||
| defaultValue: 'en-US', | ||
| toolbar: { | ||
| icon: 'globe', | ||
| dynamicTitle: true, | ||
| items: [ | ||
| // English is at the top so it's easier to reset to it | ||
| { value: 'en-US', title: 'English (US)' }, | ||
| ...currentLocales | ||
| .filter(locale => locale.code !== 'en-US') | ||
| .map(locale => ({ value: locale.code, title: locale.name })), | ||
| ], | ||
| }, | ||
| }, | ||
| accentColor: { | ||
| name: 'Accent Color', | ||
| description: 'Accent color', | ||
| toolbar: { | ||
| icon: 'paintbrush', | ||
| dynamicTitle: true, | ||
| items: [ | ||
| ...Object.keys(ACCENT_COLORS.light).map(color => ({ | ||
| value: color, | ||
| title: color.charAt(0).toUpperCase() + color.slice(1), | ||
| })), | ||
| { value: undefined, title: 'No Accent' }, | ||
| ], | ||
| }, | ||
| }, | ||
| theme: { | ||
| name: 'Theme', | ||
| description: 'Color mode', | ||
| defaultValue: 'dark', | ||
| toolbar: { | ||
| icon: 'moon', | ||
| dynamicTitle: true, | ||
| items: [ | ||
| { value: 'light', icon: 'sun', title: 'Light' }, | ||
| { value: 'dark', icon: 'moon', title: 'Dark' }, | ||
| ], | ||
| }, | ||
| }, | ||
| }, | ||
| decorators: [ | ||
| (story, context) => { | ||
| const { locale, theme, accentColor } = context.globals as { | ||
| locale: string | ||
| theme: string | ||
| accentColor?: string | ||
| } | ||
|
|
||
| // Set theme from globals | ||
| document.documentElement.setAttribute('data-theme', theme) | ||
|
|
||
| // Set accent color from globals | ||
| if (accentColor) { | ||
| document.documentElement.style.setProperty('--accent-color', `var(--swatch-${accentColor})`) | ||
| } else { | ||
| document.documentElement.style.removeProperty('--accent-color') | ||
| } | ||
|
|
||
| return { | ||
| template: '<story />', | ||
| // Set locale from globals | ||
| created() { | ||
| if (this.$i18n) { | ||
| this.$i18n.setLocale(locale) | ||
| } | ||
| }, | ||
| updated() { | ||
| if (this.$i18n) { | ||
| this.$i18n.setLocale(locale) | ||
| } | ||
| }, | ||
| } | ||
| }, | ||
| ], | ||
| } | ||
|
|
||
| export default preview |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| import type { Meta, StoryObj } from '@nuxtjs/storybook' | ||
| import Component from './Base.vue' | ||
|
|
||
| const meta = { | ||
| component: Component, | ||
| tags: ['autodocs'], | ||
| } satisfies Meta<typeof Component> | ||
|
|
||
| export default meta | ||
| type Story = StoryObj<typeof meta> | ||
|
|
||
| export const Primary: Story = { | ||
| args: { | ||
| variant: 'primary', | ||
| size: 'medium', | ||
| }, | ||
| render: args => ({ | ||
| components: { Component }, | ||
| setup() { | ||
| return { args } | ||
| }, | ||
| template: '<Component v-bind="args">Primary Button</Component>', | ||
| }), | ||
| } | ||
|
|
||
| export const Secondary: Story = { | ||
| args: { | ||
| variant: 'secondary', | ||
| size: 'medium', | ||
| }, | ||
| render: args => ({ | ||
| components: { Component }, | ||
| setup() { | ||
| return { args } | ||
| }, | ||
| template: '<Component v-bind="args">Secondary Button</Component>', | ||
| }), | ||
| } | ||
|
|
||
| export const Small: Story = { | ||
| args: { | ||
| variant: 'secondary', | ||
| size: 'small', | ||
| }, | ||
| render: args => ({ | ||
| components: { Component }, | ||
| setup() { | ||
| return { args } | ||
| }, | ||
| template: '<Component v-bind="args">Small Button</Component>', | ||
| }), | ||
| } | ||
|
|
||
| export const Disabled: Story = { | ||
| args: { | ||
| variant: 'primary', | ||
| size: 'medium', | ||
| disabled: true, | ||
| }, | ||
| render: args => ({ | ||
| components: { Component }, | ||
| setup() { | ||
| return { args } | ||
| }, | ||
| template: '<Component v-bind="args">Disabled Button</Component>', | ||
| }), | ||
| } | ||
|
|
||
| export const WithIcon: Story = { | ||
| args: { | ||
| variant: 'secondary', | ||
| size: 'medium', | ||
| classicon: 'i-carbon:search', | ||
| }, | ||
| render: args => ({ | ||
| components: { Component }, | ||
| setup() { | ||
| return { args } | ||
| }, | ||
| template: '<Component v-bind="args">Search</Component>', | ||
| }), | ||
| } | ||
|
|
||
| export const WithKeyboardShortcut: Story = { | ||
| args: { | ||
| variant: 'secondary', | ||
| size: 'medium', | ||
| ariaKeyshortcuts: '/', | ||
| }, | ||
| render: args => ({ | ||
| components: { Component }, | ||
| setup() { | ||
| return { args } | ||
| }, | ||
| template: '<Component v-bind="args">Search</Component>', | ||
| }), | ||
| } | ||
|
|
||
| export const Block: Story = { | ||
| args: { | ||
| variant: 'primary', | ||
| size: 'medium', | ||
| block: true, | ||
| }, | ||
| render: args => ({ | ||
| components: { Component }, | ||
| setup() { | ||
| return { args } | ||
| }, | ||
| template: '<Component v-bind="args">Full Width Button</Component>', | ||
| }), | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: npmx-dev/npmx.dev
Length of output: 293
🏁 Script executed:
Repository: npmx-dev/npmx.dev
Length of output: 2964
🏁 Script executed:
Repository: npmx-dev/npmx.dev
Length of output: 425
🏁 Script executed:
Repository: npmx-dev/npmx.dev
Length of output: 2355
Add
@storybook-vue/nuxtto knip'signoreDependenciesor explicitly todevDependencies.The dependency
@storybook-vue/nuxtis installed transitively (present inpnpm-lock.yaml), but knip reports it as unlisted because it's not declared inpackage.jsonand is not ignored in the knip configuration. Add it to theignoreDependenciesarray inknip.tsat line 37, or add it explicitly todevDependenciesinpackage.json.🧰 Tools
🪛 GitHub Actions: ci
[error] 1-1: Unlisted dependencies:
@storybook-vue/nuxt. knip step failed with exit code 1 (ELIFECYCLE).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yannbf Is this relevant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.