-
-
Notifications
You must be signed in to change notification settings - Fork 319
docs(ui): add ButtonGroup stories to storybook #1964
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
base: main
Are you sure you want to change the base?
Changes from all commits
ca3ff3f
9e9acdb
98f10f2
b413402
3962167
57becd4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,6 @@ | ||
| import { addons } from 'storybook/manager-api' | ||
| import { create } from 'storybook/theming' | ||
|
|
||
| const npmxTheme = create({ | ||
| brandTitle: 'npmx Storybook', | ||
| brandImage: '/npmx-storybook.svg', | ||
| }) | ||
| import npmxDark from './theme' | ||
|
|
||
| addons.setConfig({ | ||
| theme: npmxTheme, | ||
| theme: npmxDark, | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| <style> | ||
| /* Override docs story canvas background to match npmx theme */ | ||
| .docs-story { | ||
| background-color: var(--bg, oklch(0.171 0 0)) !important; | ||
| } | ||
| </style> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import { create } from 'storybook/theming/create' | ||
|
|
||
| const npmxDark = create({ | ||
| base: 'dark', | ||
|
|
||
| brandTitle: 'npmx Storybook', | ||
| brandImage: '/npmx-storybook.svg', | ||
|
|
||
| // UI | ||
| appContentBg: '#101010', // oklch(0.171 0 0) | ||
| }) | ||
|
|
||
| export default npmxDark |
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,116 @@ | ||||||||||||||||||||||||||||||
| import type { Meta, StoryObj } from '@storybook-vue/nuxt' | ||||||||||||||||||||||||||||||
| import ButtonBase from './Base.vue' | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const meta = { | ||||||||||||||||||||||||||||||
| component: ButtonBase, | ||||||||||||||||||||||||||||||
| parameters: { | ||||||||||||||||||||||||||||||
| docs: { | ||||||||||||||||||||||||||||||
| source: { | ||||||||||||||||||||||||||||||
| type: 'dynamic', | ||||||||||||||||||||||||||||||
| transform: (code: string) => | ||||||||||||||||||||||||||||||
| code.replace(/<Base\b/g, '<ButtonBase').replace(/<\/Base>/g, '</ButtonBase>'), | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| tags: ['autodocs'], | ||||||||||||||||||||||||||||||
| } satisfies Meta<typeof ButtonBase> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export default meta | ||||||||||||||||||||||||||||||
| type Story = StoryObj<typeof meta> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export const Default: Story = { | ||||||||||||||||||||||||||||||
| args: { | ||||||||||||||||||||||||||||||
| default: 'Button Text', | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
Comment on lines
+21
to
+25
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Default story may not render slot content without a render function. All other stories use explicit render functions with templates to handle slot content, but Consider adding a render function for consistency and to ensure the button text displays: Proposed fix export const Default: Story = {
- args: {
- default: 'Button Text',
- },
+ render: args => ({
+ components: { ButtonBase },
+ setup() {
+ return { args }
+ },
+ template: `<ButtonBase v-bind="args">Button Text</ButtonBase>`,
+ }),
}📝 Committable suggestion
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keeping the default story with the default render allow to someone viewing the storybook to change the story to alternative text in place of
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ʕ •`ᴥ´• ʔ ✏️ Learnings added
🧠 Learnings used |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export const Primary: Story = { | ||||||||||||||||||||||||||||||
| args: { | ||||||||||||||||||||||||||||||
| variant: 'primary', | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| render: args => ({ | ||||||||||||||||||||||||||||||
| components: { ButtonBase }, | ||||||||||||||||||||||||||||||
| setup() { | ||||||||||||||||||||||||||||||
| return { args } | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| template: `<ButtonBase v-bind="args">{{ $t("nav.settings") }}</ButtonBase>`, | ||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export const Secondary: Story = { | ||||||||||||||||||||||||||||||
| args: { | ||||||||||||||||||||||||||||||
| variant: 'secondary', | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| render: args => ({ | ||||||||||||||||||||||||||||||
| components: { ButtonBase }, | ||||||||||||||||||||||||||||||
| setup() { | ||||||||||||||||||||||||||||||
| return { args } | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| template: `<ButtonBase v-bind="args">{{ $t("nav.settings") }}</ButtonBase>`, | ||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export const Small: Story = { | ||||||||||||||||||||||||||||||
| args: { | ||||||||||||||||||||||||||||||
| size: 'small', | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| render: args => ({ | ||||||||||||||||||||||||||||||
| components: { ButtonBase }, | ||||||||||||||||||||||||||||||
| setup() { | ||||||||||||||||||||||||||||||
| return { args } | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| template: `<ButtonBase v-bind="args">{{ $t("nav.settings") }}</ButtonBase>`, | ||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export const Disabled: Story = { | ||||||||||||||||||||||||||||||
| args: { | ||||||||||||||||||||||||||||||
| disabled: true, | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| render: args => ({ | ||||||||||||||||||||||||||||||
| components: { ButtonBase }, | ||||||||||||||||||||||||||||||
| setup() { | ||||||||||||||||||||||||||||||
| return { args } | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| template: `<ButtonBase v-bind="args">{{ $t("nav.settings") }}</ButtonBase>`, | ||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export const WithIcon: Story = { | ||||||||||||||||||||||||||||||
| args: { | ||||||||||||||||||||||||||||||
| classicon: 'i-lucide:search', | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| render: args => ({ | ||||||||||||||||||||||||||||||
| components: { ButtonBase }, | ||||||||||||||||||||||||||||||
| setup() { | ||||||||||||||||||||||||||||||
| return { args } | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| template: `<ButtonBase v-bind="args">{{ $t("search.button") }}</ButtonBase>`, | ||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export const WithKeyboardShortcut: Story = { | ||||||||||||||||||||||||||||||
| args: { | ||||||||||||||||||||||||||||||
| ariaKeyshortcuts: '/', | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| render: args => ({ | ||||||||||||||||||||||||||||||
| components: { ButtonBase }, | ||||||||||||||||||||||||||||||
| setup() { | ||||||||||||||||||||||||||||||
| return { args } | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| template: `<ButtonBase v-bind="args">{{ $t("search.button") }}</ButtonBase>`, | ||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export const Block: Story = { | ||||||||||||||||||||||||||||||
| args: { | ||||||||||||||||||||||||||||||
| block: true, | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| render: args => ({ | ||||||||||||||||||||||||||||||
| components: { ButtonBase }, | ||||||||||||||||||||||||||||||
| setup() { | ||||||||||||||||||||||||||||||
| return { args } | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| template: `<ButtonBase v-bind="args">{{ $t("nav.settings") }}</ButtonBase>`, | ||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
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.
The docs canvas background never follows the selected theme.
Line 4 depends on
--bg, but Storybook never sets that variable in the provided setup:.storybook/preview.ts:62-82only updates--accent-color, and.storybook/theme.ts:1-12setsappContentBgfor the manager UI rather than a CSS custom property. As a result, this always falls back to the dark value, so Light theme docs still render on a dark canvas. Please either initialise--bgin Storybook or switch this rule to a selector that keys offdata-themedirectly.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.
The backgrounds in the autodocs pages look correct with this when viewing the light versions of components and removing this makes them not display correctly. Would love to find a way to fix this in the storybook theme overrides instead of needing this preview-head file but at this time have been unsuccessful.
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.
@cylewaitforit, thanks for the context! This is actually a well-known Storybook limitation. The dark theme is applied correctly in the canvas view but not in the Docs tab — the DOM inside Docs has extra wrappers and inline styles that override the background and theme styles. This is a tracked open bug (#30928) in Storybook, so yourpreview-head.htmlworkaround is reasonable and pragmatic.For a cleaner alternative (when you want to revisit), the closest officially-documented approach is:
Use
parameters.docs.themewith anappContentBgvalue. Storybook Docs uses the same theme system as Storybook's UI but is themed independently from the main UI. The default theme for Docs is always the "light" theme, regardless of the main UI theme. You can pass a custom theme specifically to docs in.storybook/preview.ts:However, this styles the docs page background, not the individual
.docs-storycanvas iframes — which is whypreview-head.htmlis still needed for the story canvas itself.Acknowledge the
!importantrisk: Sincepreview-head.htmluses!importantto override.docs-story, it will prevent any future per-story background customisation. If you later need story-specific backgrounds, you'd need to revisit this rule.Given the upstream bug, the current
preview-head.htmlapproach is a valid and widely-used workaround. I'm withdrawing my original concern — the fix is intentional and appropriate for the current state of Storybook.(ミ^ ◡ ^ミ) ✦ noted for future reviews!
✏️ Learnings added
🧠 Learnings used