Skip to content
Closed
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
4d918aa
feat(vue): init storybook
carwack Mar 18, 2025
1cfe1e0
feat(vue): migrate stories to storybook for avatar component
carwack Mar 18, 2025
653cd22
feat(vue): migrate stories to storybook for accordion component
carwack Mar 18, 2025
92f2e9d
feat(vue): migrate stories to storybook for carousel component
carwack Mar 18, 2025
fceb51d
feat(vue): migrate stories to storybook for checkbox
carwack Mar 18, 2025
c95516d
feat(vue): migrate stories to storybook for clipboard
carwack Mar 18, 2025
468c054
feat(vue): migrate stories to storybook for collapsible
carwack Mar 18, 2025
1277abf
feat(vue): migrate stories to storybook for color picker
carwack Mar 18, 2025
126f68d
feat(vue) migrate stories to storybook for combobox
carwack Mar 18, 2025
4b80030
feat(vue): migrate stories to storybook for date picker
carwack Mar 18, 2025
4dc4261
feat(vue): migrate stories to storybook for dialog
carwack Mar 18, 2025
1fb718f
feat(vue): migrate stories to storybook for editable
carwack Mar 18, 2025
05ea86f
feat(vue): migrate stories to storybook for field
carwack Mar 18, 2025
f7df932
feat(vue): migrate stories to storybook for fieldset
carwack Mar 18, 2025
a4d907a
feat(vue): migrate stories to storybook for file upload
carwack Mar 18, 2025
37372a2
feat(vue): migrate stories to storybook for focus trap
carwack Mar 18, 2025
4da62ad
feat(vue): migrate stories to storybook for format
carwack Mar 18, 2025
b09310b
feat(vue): migrate stories to storybook for frame
carwack Mar 18, 2025
dd8dbb1
feat(vue): migrate stories to storybook for highlight
carwack Mar 18, 2025
945f142
feat(vue): migrate stories to storybook for hover card
carwack Mar 18, 2025
483acd3
refactor(vue): add Components / to storybook meta title
carwack Mar 18, 2025
c35b5cc
feat(vue): migrate stories to storybook for menu
carwack Mar 18, 2025
066978d
feat(vue): migrate stories to storybook for number input
carwack Mar 18, 2025
cd598ee
feat(vue): migrate stories to storybook for pagination
carwack Mar 18, 2025
00bccb1
feat(vue): migrate stories to storybook for pin input
carwack Mar 18, 2025
948374a
feat(vue): migrate stories to storybook for popover
carwack Mar 18, 2025
0a4e191
feat(vue): migrate stories to storybook for presence
carwack Mar 18, 2025
0af6c0e
feat(vue): migrate stories to storybook for qr code
carwack Mar 18, 2025
c307f65
feat(vue): migrate stories to storybook for radio group
carwack Mar 18, 2025
6f7e327
feat(vue): migrate stories to storybook for rating group
carwack Mar 18, 2025
8eb0849
feat(vue): migrate stories to storbook for segment group
carwack Mar 18, 2025
4749d5c
feat(vue): migratie stories to storybook for select
carwack Mar 18, 2025
823e390
feat(vue): migrate stories to storybook for signature pad
carwack Mar 18, 2025
16aad1d
feat(vue): migrate stories to storybook for slider
carwack Mar 18, 2025
881fe52
feat(vue): migrate stories to storybook for splitter
carwack Mar 18, 2025
feb0908
feat(vue): migreate stories to storybook for steps
carwack Mar 18, 2025
bb0235e
feat(vue): migrate stories to storybook for switch
carwack Mar 18, 2025
45e1201
feat(vue): migrate stories to storybook for tabs
carwack Mar 18, 2025
3cae345
feat(vue): migrate stories to storybook for tags input
carwack Mar 18, 2025
ee0492b
feat(vue): migrate stories to storybook for time picker
carwack Mar 18, 2025
4c40518
feat(vue): migrate stories to storybook for timer
carwack Mar 18, 2025
b6fc1bf
feat(vue): migrate stories to storybook for toast
carwack Mar 18, 2025
f384a7e
feat(vue): migrate stories to storybook for toggle
carwack Mar 18, 2025
bd27f80
feat(vue): migreate stories to storybook for toggle group
carwack Mar 18, 2025
84c2c53
feat(vue): migrate stories to storybook for tooltip
carwack Mar 18, 2025
09ad3ed
feat(vue): migrate stories to storybook for tour
carwack Mar 18, 2025
abbe472
feat(vue): migrate stories to storybook for tree view
carwack Mar 18, 2025
886d8e0
feat(vue): migrate stories to storybook for environment
carwack Mar 18, 2025
43d5994
feat(vue): migrate stories to storybook for locale
carwack Mar 18, 2025
57e4dd3
feat(vue): migrate stories to storybook for progress
carwack Mar 18, 2025
1d77784
chore(vue): remove histoire from repo
carwack Mar 18, 2025
20627cb
Merge remote-tracking branch 'origin/main' into feat/add-vue-storybook
carwack Jun 6, 2025
debd9e0
refactor(stories): update stories with args and emits for accordion a…
carwack Jun 6, 2025
fd1d80e
feat(storybook): enable addon actions
carwack Jun 6, 2025
7025dec
feat(storybook): create emitHandlers type to format tuple to function…
carwack Jun 6, 2025
8b9e9e4
refactor(storybook): use EmitHandlers type for better TS support
carwack Jun 6, 2025
9b4202a
feat(angle-slider): add storybook stories
carwack Jun 18, 2025
aabca2d
feat(angle-slider): remove histoire stories
carwack Jun 18, 2025
7a60330
refactor(download-trigger): change to storybook stories
carwack Jun 18, 2025
affd868
feat(combobox): update stories
carwack Jun 18, 2025
027f80b
refactor(floating-panel): change to storybook stories
carwack Jun 18, 2025
cb8ce5c
refactor(vue): add space in storybook title
carwack Jun 18, 2025
5291feb
refactor(listbox): change to storybook stories
carwack Jun 18, 2025
ed8ddb2
refactor(password-input): change to storybook stories
carwack Jun 18, 2025
51a470c
feat(toast): add all examples to stories
carwack Jun 18, 2025
a673fff
feat(tour): add all examples to stories
carwack Jun 18, 2025
4ddf23b
feat(tree-view): add all examples to stories
carwack Jun 18, 2025
baa48ef
feat(environment): add all examples to stories
carwack Jun 18, 2025
5e99bbd
feat(locale): add all examples to stories
carwack Jun 18, 2025
212d766
feat(file-upload): add all examples to stories
carwack Jun 18, 2025
9d13c83
feat(format): add all examples to stories
carwack Jun 18, 2025
307359f
feat(presence): add all examples to stories
carwack Jun 18, 2025
dcdbe1d
feat(splitter): add all examples to stories
carwack Jun 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -311,4 +311,5 @@ vite.config.mts.timestamp-*
*.prompt.md

# Solid Start
.vinxi
.vinxi
*storybook.log
Binary file added bun.lockb
Binary file not shown.
41 changes: 40 additions & 1 deletion packages/vue/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
import './main.css'
import type { StorybookConfig } from '@storybook/vue3-vite'

const config: StorybookConfig = {
stories: ['../src/**/*.stories.ts'],
addons: [
{
name: '@storybook/addon-essentials',
options: { backgrounds: false, controls: false, actions: false },
},
'@storybook/addon-a11y',
],
framework: {
name: '@storybook/vue3-vite',
options: {},
},
core: {
disableTelemetry: true,
},
docs: {
autodocs: false,
},


// TODO: fix this when vue-docgen accepts types from other packages in components
// This is a workaround until vue-docgen-plugin is fixed since we also dont use autodocs
// This removes the plugin vue-docgen-plugin so it wont load and throws an error on the use of an type import like
// import { Avatar, type AvatarRootEmits, type AvatarRootProps } from '@ark-ui/vue/avatar'
// using options: { docgen: "vue-component-meta",} throws other errors with node_modules/@zag-js/avatar/dist/index.mjs.vue'
// could not be found. This could be a fix for the vue-docgen-plugin error but it is not working for now
viteFinal(config) {
const vueDocgenIndex = config.plugins?.findIndex((plugin) =>
plugin && typeof plugin === 'object' && 'name' in plugin && plugin.name === 'storybook:vue-docgen-plugin'
) ?? -1
if (vueDocgenIndex !== -1) config.plugins?.splice(vueDocgenIndex, 1)
return config
}
}


export default config
15 changes: 15 additions & 0 deletions packages/vue/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Preview } from '@storybook/vue3'
import './main.css'

const preview: Preview = {
parameters: {
options: {
storySort: {
method: 'alphabetical',
},
},
layout: 'padded',
},
}

export default preview
14 changes: 0 additions & 14 deletions packages/vue/histoire.config.ts

This file was deleted.

18 changes: 14 additions & 4 deletions packages/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@
"test": "vitest",
"test:ci": "vitest --run",
"typecheck": "vue-tsc",
"storybook": "histoire dev",
"storybook": "storybook dev -p 6009",
"release-it": "release-it --config ../../release-it.json",
"prepack": "clean-package",
"postpack": "clean-package restore"
"postpack": "clean-package restore",
"build-storybook": "storybook build"
},
"publishConfig": {
"access": "public"
Expand Down Expand Up @@ -137,23 +138,32 @@
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@histoire/plugin-vue": "0.17.17",
"@chromatic-com/storybook": "^3",
"@release-it/keep-a-changelog": "6.0.0",
"@storybook/addon-essentials": "^8.6.7",
"@storybook/blocks": "^8.6.7",
"@storybook/experimental-addon-test": "^8.6.7",
"@storybook/test": "^8.6.7",
"@storybook/vue3": "^8.6.7",
"@storybook/vue3-vite": "^8.6.7",
"@testing-library/dom": "10.4.0",
"@testing-library/jest-dom": "6.6.3",
"@testing-library/user-event": "14.6.1",
"@testing-library/vue": "8.0.3",
"@types/jsdom": "21.1.7",
"@vitejs/plugin-vue": "5.2.3",
"@vitejs/plugin-vue-jsx": "4.1.2",
"@vitest/browser": "3.0.9",
"@vitest/coverage-v8": "3.0.9",
"@vue/compiler-sfc": "3.5.13",
"clean-package": "2.2.0",
"globby": "14.1.0",
"histoire": "0.17.17",
"jsdom": "26.0.0",
"lucide-vue-next": "0.482.0",
"playwright": "1.51.1",
"release-it": "18.1.2",
"resize-observer-polyfill": "1.5.1",
"storybook": "^8.6.7",
"typescript": "5.8.2",
"vite": "6.2.2",
"vite-plugin-dts": "4.5.3",
Expand Down
120 changes: 120 additions & 0 deletions packages/vue/src/components/accordion/accordion.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import type { Meta } from '@storybook/vue3'

import AccordionExample from './examples/accordion.vue'
import BasicExample from './examples/basic.vue'
import CollapsibleExample from './examples/collapsible.vue'
import ContextFocusedValueExample from './examples/context/focusedValue.vue'
import ContextGetItemStateExample from './examples/context/getItemState.vue'
import ContextSetValueExample from './examples/context/setValue.vue'
import ContextValueExample from './examples/context/value.vue'
import ControlledExample from './examples/controlled.vue'
import DisabledExample from './examples/disabled.vue'
import HorizontalExample from './examples/horizontal.vue'
import MultipleExample from './examples/multiple.vue'
import RenderPropExample from './examples/render-prop.vue'
import RootProviderExample from './examples/root-provider.vue'
import VerticalExample from './examples/vertical.vue'

const meta = {
title: 'Components / Accordion',
} as Meta

export default meta

export const Basic = {
render: () => ({
components: { BasicExample },
template: '<BasicExample />',
}),
}

export const RenderProp = {
render: () => ({
components: { RenderPropExample },
template: '<RenderPropExample />',
}),
}

export const Collapsible = {
render: () => ({
components: { CollapsibleExample },
template: '<CollapsibleExample />',
}),
}

export const Multiple = {
render: () => ({
components: { MultipleExample },
template: '<MultipleExample />',
}),
}

export const Controlled = {
render: () => ({
components: { ControlledExample },
template: '<ControlledExample />',
}),
}

export const Vertical = {
render: () => ({
components: { VerticalExample },
template: '<VerticalExample />',
}),
}

export const Horizontal = {
render: () => ({
components: { HorizontalExample },
template: '<HorizontalExample />',
}),
}

export const Disabled = {
render: () => ({
components: { DisabledExample },
template: '<DisabledExample />',
}),
}

export const Closed = {
render: () => ({
components: { AccordionExample },
template: `<AccordionExample multiple :items="['React', 'Solid', 'Vue']" />`,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carwack

I don't know but having the template as a string feels not great from a DX perspective, as errors can easily happen. Is there an alternative to this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just saw this review, thanks for creating it and sorry for the long wait on a response.
I don't know yet, but I will take a look into it asap and see if there is an alternative!

Copy link
Copy Markdown
Contributor Author

@carwack carwack May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cschroeter
I have been looking into it. Mainly checked the docs of Storybook. For Vue it seems that we either have to set the most complex component of the examples as the reference in the meta and then be able to just set the args for that story. The other stories still need to have the template set.

const meta = {
  title: 'Components / Avatar',
  component: ClosedExample, // Reference component for Storybook docs
  argTypes: {
    name: { control: 'text', description: 'The user name (used for initials fallback)' },
    src: { control: 'text', description: 'URL to the avatar image' },
  },
} satisfies Meta<typeof ClosedExample>

export default meta
type Story = StoryObj<AvatarBaseProps>
...
export const Basic: Story = {
  render: () => ({
    components: { BasicExample },
    template: '<BasicExample />',
  }),
  args: {},
}

export const Closed: Story = {
  args: {
    name: "Christian",
    src: "https://avatars.githubusercontent.com/u/1846056?v=4",
  },
}

Alternative is using the args like this:

export const Closed = {
  render: (args: AvatarProps) => ({
    components: { ClosedExample },
    setup() {
      return {
        args,
        onStatusChange: action('status changed'),
      };
    },
    template: '<ClosedExample v-bind="args" @status-change="onStatusChange" />',
  }),
  args: {
    name: "Christian",
    src: "https://avatars.githubusercontent.com/u/1846056?v=4",
  } satisfies AvatarProps,
}

https://storybook.js.org/docs/api/csf

Altho it's mostly needed like that when we have closed component examples. Other examples are mostly just the template like:

export const Basic = {
  render: () => ({
    components: { BasicExample },
    template: '<BasicExample />',
  }),
}

I feel like the 2nd option is the best here. What do you think of it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will look into implementing the 2nd option in this PR asap. @cschroeter

export const Closed = {
  render: (args: AvatarProps) => ({
    components: { ClosedExample },
    setup() {
      return {
        args,
        onStatusChange: action('status changed'),
      };
    },
    template: '<ClosedExample v-bind="args" @status-change="onStatusChange" />',
  }),
  args: {
    name: "Christian",
    src: "https://avatars.githubusercontent.com/u/1846056?v=4",
  } satisfies AvatarProps,
}
export const Basic = {
  render: () => ({
    components: { BasicExample },
    template: '<BasicExample />',
  }),
}

}),
}

export const RootProvider = {
render: () => ({
components: { RootProviderExample },
template: '<RootProviderExample />',
}),
}

export const ContextFocusedValue = {
render: () => ({
components: { ContextFocusedValueExample },
template: '<ContextFocusedValueExample />',
}),
}

export const ContextValue = {
render: () => ({
components: { ContextValueExample },
template: '<ContextValueExample />',
}),
}

export const ContextSetValue = {
render: () => ({
components: { ContextSetValueExample },
template: '<ContextSetValueExample />',
}),
}

export const ContextGetItemState = {
render: () => ({
components: { ContextGetItemStateExample },
template: '<ContextGetItemStateExample />',
}),
}
62 changes: 0 additions & 62 deletions packages/vue/src/components/accordion/accordion.stories.vue

This file was deleted.

46 changes: 46 additions & 0 deletions packages/vue/src/components/avatar/avatar.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { Meta } from '@storybook/vue3'

import BasicExample from './examples/basic.vue'
import ClosedExample from './examples/closed.vue'
import EventsExample from './examples/events.vue'
import RootProviderExample from './examples/root-provider.vue'

const meta = {
title: 'Components / Avatar',
} as Meta

export default meta

export const Basic = {
render: () => ({
components: { BasicExample },
template: '<BasicExample />',
}),
}

export const Events = {
render: () => ({
components: { EventsExample },
template: '<EventsExample />',
}),
}

export const Closed = {
render: () => ({
components: { ClosedExample },
template: `
<ClosedExample
name="Christian"
src="https://avatars.githubusercontent.com/u/1846056?v=4"
@status-change="(e) => console.log(e.status)"
/>
`,
}),
}

export const RootProvider = {
render: () => ({
components: { RootProviderExample },
template: '<RootProviderExample />',
}),
}
26 changes: 0 additions & 26 deletions packages/vue/src/components/avatar/avatar.stories.vue

This file was deleted.

Loading