mirror of https://github.com/langgenius/dify.git
chore: improve storybook (#27111)
This commit is contained in:
parent
7e9be4d3d9
commit
dc1a380888
|
|
@ -1,19 +1,29 @@
|
|||
import type { StorybookConfig } from '@storybook/nextjs'
|
||||
|
||||
const config: StorybookConfig = {
|
||||
// stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
|
||||
stories: ['../app/components/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
|
||||
addons: [
|
||||
'@storybook/addon-onboarding',
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-docs',
|
||||
'@chromatic-com/storybook',
|
||||
'@storybook/addon-interactions',
|
||||
],
|
||||
framework: {
|
||||
name: '@storybook/nextjs',
|
||||
options: {},
|
||||
options: {
|
||||
builder: {
|
||||
useSWC: true,
|
||||
lazyCompilation: false,
|
||||
},
|
||||
nextConfigPath: undefined,
|
||||
},
|
||||
},
|
||||
staticDirs: ['../public'],
|
||||
core: {
|
||||
disableWhatsNewNotifications: true,
|
||||
},
|
||||
docs: {
|
||||
defaultName: 'Documentation',
|
||||
},
|
||||
}
|
||||
export default config
|
||||
|
|
|
|||
|
|
@ -1,12 +1,21 @@
|
|||
import React from 'react'
|
||||
import type { Preview } from '@storybook/react'
|
||||
import { withThemeByDataAttribute } from '@storybook/addon-themes'
|
||||
import I18nServer from '../app/components/i18n-server'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import I18N from '../app/components/i18n'
|
||||
import { ToastProvider } from '../app/components/base/toast'
|
||||
|
||||
import '../app/styles/globals.css'
|
||||
import '../app/styles/markdown.scss'
|
||||
import './storybook.css'
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
refetchOnWindowFocus: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const decorators = [
|
||||
withThemeByDataAttribute({
|
||||
themes: {
|
||||
|
|
@ -17,9 +26,15 @@ export const decorators = [
|
|||
attributeName: 'data-theme',
|
||||
}),
|
||||
(Story) => {
|
||||
return <I18nServer>
|
||||
<Story />
|
||||
</I18nServer>
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<I18N locale="en-US">
|
||||
<ToastProvider>
|
||||
<Story />
|
||||
</ToastProvider>
|
||||
</I18N>
|
||||
</QueryClientProvider>
|
||||
)
|
||||
},
|
||||
]
|
||||
|
||||
|
|
@ -31,7 +46,11 @@ const preview: Preview = {
|
|||
date: /Date$/i,
|
||||
},
|
||||
},
|
||||
docs: {
|
||||
toc: true,
|
||||
},
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
}
|
||||
|
||||
export default preview
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
import { fn } from '@storybook/test'
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs'
|
||||
|
||||
import { RocketLaunchIcon } from '@heroicons/react/20/solid'
|
||||
import { Button } from '.'
|
||||
|
|
@ -20,8 +19,7 @@ const meta = {
|
|||
},
|
||||
args: {
|
||||
variant: 'ghost',
|
||||
onClick: fn(),
|
||||
children: 'adsf',
|
||||
children: 'Button',
|
||||
},
|
||||
} satisfies Meta<typeof Button>
|
||||
|
||||
|
|
@ -33,6 +31,9 @@ export const Default: Story = {
|
|||
variant: 'primary',
|
||||
loading: false,
|
||||
children: 'Primary Button',
|
||||
styleCss: {},
|
||||
spinnerClassName: '',
|
||||
destructive: false,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs'
|
||||
|
||||
import type { ChatItem } from '../../types'
|
||||
import { mockedWorkflowProcess } from './__mocks__/workflowProcess'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs'
|
||||
|
||||
import type { ChatItem } from '../types'
|
||||
import Question from './question'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,199 @@
|
|||
import type { Meta, StoryObj } from '@storybook/nextjs'
|
||||
import { useState } from 'react'
|
||||
import Confirm from '.'
|
||||
import Button from '../button'
|
||||
|
||||
const meta = {
|
||||
title: 'Base/Confirm',
|
||||
component: Confirm,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
docs: {
|
||||
description: {
|
||||
component: 'Confirmation dialog component that supports warning and info types, with customizable button text and behavior.',
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
type: {
|
||||
control: 'select',
|
||||
options: ['info', 'warning'],
|
||||
description: 'Dialog type',
|
||||
},
|
||||
isShow: {
|
||||
control: 'boolean',
|
||||
description: 'Whether to show the dialog',
|
||||
},
|
||||
title: {
|
||||
control: 'text',
|
||||
description: 'Dialog title',
|
||||
},
|
||||
content: {
|
||||
control: 'text',
|
||||
description: 'Dialog content',
|
||||
},
|
||||
confirmText: {
|
||||
control: 'text',
|
||||
description: 'Confirm button text',
|
||||
},
|
||||
cancelText: {
|
||||
control: 'text',
|
||||
description: 'Cancel button text',
|
||||
},
|
||||
isLoading: {
|
||||
control: 'boolean',
|
||||
description: 'Confirm button loading state',
|
||||
},
|
||||
isDisabled: {
|
||||
control: 'boolean',
|
||||
description: 'Confirm button disabled state',
|
||||
},
|
||||
showConfirm: {
|
||||
control: 'boolean',
|
||||
description: 'Whether to show confirm button',
|
||||
},
|
||||
showCancel: {
|
||||
control: 'boolean',
|
||||
description: 'Whether to show cancel button',
|
||||
},
|
||||
maskClosable: {
|
||||
control: 'boolean',
|
||||
description: 'Whether clicking mask closes dialog',
|
||||
},
|
||||
},
|
||||
} satisfies Meta<typeof Confirm>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
// Interactive demo wrapper
|
||||
const ConfirmDemo = (args: any) => {
|
||||
const [isShow, setIsShow] = useState(false)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button variant="primary" onClick={() => setIsShow(true)}>
|
||||
Open Dialog
|
||||
</Button>
|
||||
<Confirm
|
||||
{...args}
|
||||
isShow={isShow}
|
||||
onConfirm={() => {
|
||||
console.log('✅ User clicked confirm')
|
||||
setIsShow(false)
|
||||
}}
|
||||
onCancel={() => {
|
||||
console.log('❌ User clicked cancel')
|
||||
setIsShow(false)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Basic warning dialog - Delete action
|
||||
export const WarningDialog: Story = {
|
||||
render: args => <ConfirmDemo {...args} />,
|
||||
args: {
|
||||
type: 'warning',
|
||||
title: 'Delete Confirmation',
|
||||
content: 'Are you sure you want to delete this project? This action cannot be undone.',
|
||||
},
|
||||
}
|
||||
|
||||
// Info dialog
|
||||
export const InfoDialog: Story = {
|
||||
render: args => <ConfirmDemo {...args} />,
|
||||
args: {
|
||||
type: 'info',
|
||||
title: 'Notice',
|
||||
content: 'Your changes have been saved. Do you want to proceed to the next step?',
|
||||
},
|
||||
}
|
||||
|
||||
// Custom button text
|
||||
export const CustomButtonText: Story = {
|
||||
render: args => <ConfirmDemo {...args} />,
|
||||
args: {
|
||||
type: 'warning',
|
||||
title: 'Exit Editor',
|
||||
content: 'You have unsaved changes. Are you sure you want to exit?',
|
||||
confirmText: 'Discard Changes',
|
||||
cancelText: 'Continue Editing',
|
||||
},
|
||||
}
|
||||
|
||||
// Loading state
|
||||
export const LoadingState: Story = {
|
||||
render: args => <ConfirmDemo {...args} />,
|
||||
args: {
|
||||
type: 'warning',
|
||||
title: 'Deleting...',
|
||||
content: 'Please wait while we delete the file...',
|
||||
isLoading: true,
|
||||
},
|
||||
}
|
||||
|
||||
// Disabled state
|
||||
export const DisabledState: Story = {
|
||||
render: args => <ConfirmDemo {...args} />,
|
||||
args: {
|
||||
type: 'info',
|
||||
title: 'Verification Required',
|
||||
content: 'Please complete email verification before proceeding.',
|
||||
isDisabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
// Alert style - Confirm button only
|
||||
export const AlertStyle: Story = {
|
||||
render: args => <ConfirmDemo {...args} />,
|
||||
args: {
|
||||
type: 'info',
|
||||
title: 'Success',
|
||||
content: 'Your settings have been updated!',
|
||||
showCancel: false,
|
||||
confirmText: 'Got it',
|
||||
},
|
||||
}
|
||||
|
||||
// Dangerous action - Long content
|
||||
export const DangerousAction: Story = {
|
||||
render: args => <ConfirmDemo {...args} />,
|
||||
args: {
|
||||
type: 'warning',
|
||||
title: 'Permanently Delete Account',
|
||||
content: 'This action will permanently delete your account and all associated data, including: all projects and files, collaboration history, and personal settings. This action cannot be reversed!',
|
||||
confirmText: 'Delete My Account',
|
||||
cancelText: 'Keep My Account',
|
||||
},
|
||||
}
|
||||
|
||||
// Non-closable mask
|
||||
export const NotMaskClosable: Story = {
|
||||
render: args => <ConfirmDemo {...args} />,
|
||||
args: {
|
||||
type: 'warning',
|
||||
title: 'Important Action',
|
||||
content: 'This action requires your explicit choice. Clicking outside will not close this dialog.',
|
||||
maskClosable: false,
|
||||
},
|
||||
}
|
||||
|
||||
// Full feature demo - Playground
|
||||
export const Playground: Story = {
|
||||
render: args => <ConfirmDemo {...args} />,
|
||||
args: {
|
||||
type: 'warning',
|
||||
title: 'This is a title',
|
||||
content: 'This is the dialog content text...',
|
||||
confirmText: undefined,
|
||||
cancelText: undefined,
|
||||
isLoading: false,
|
||||
isDisabled: false,
|
||||
showConfirm: true,
|
||||
showCancel: true,
|
||||
maskClosable: true,
|
||||
},
|
||||
}
|
||||
|
|
@ -142,7 +142,7 @@
|
|||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^5.0.0",
|
||||
"@babel/core": "^7.28.3",
|
||||
"@chromatic-com/storybook": "^3.1.0",
|
||||
"@chromatic-com/storybook": "^4.1.1",
|
||||
"@eslint-react/eslint-plugin": "^1.15.0",
|
||||
"@happy-dom/jest-environment": "^20.0.2",
|
||||
"@mdx-js/loader": "^3.1.0",
|
||||
|
|
@ -151,14 +151,12 @@
|
|||
"@next/eslint-plugin-next": "15.5.4",
|
||||
"@next/mdx": "15.5.4",
|
||||
"@rgrove/parse-xml": "^4.1.0",
|
||||
"@storybook/addon-essentials": "8.5.0",
|
||||
"@storybook/addon-interactions": "8.5.0",
|
||||
"@storybook/addon-links": "8.5.0",
|
||||
"@storybook/addon-onboarding": "8.5.0",
|
||||
"@storybook/addon-themes": "8.5.0",
|
||||
"@storybook/nextjs": "8.5.0",
|
||||
"@storybook/react": "8.5.0",
|
||||
"@storybook/test": "8.5.0",
|
||||
"@storybook/addon-docs": "9.1.13",
|
||||
"@storybook/addon-links": "9.1.13",
|
||||
"@storybook/addon-onboarding": "9.1.13",
|
||||
"@storybook/addon-themes": "9.1.13",
|
||||
"@storybook/nextjs": "9.1.13",
|
||||
"@storybook/react": "9.1.13",
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-dom": "^6.8.0",
|
||||
"@testing-library/react": "^16.0.1",
|
||||
|
|
@ -186,7 +184,7 @@
|
|||
"eslint-plugin-react-hooks": "^5.1.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.19",
|
||||
"eslint-plugin-sonarjs": "^3.0.2",
|
||||
"eslint-plugin-storybook": "^9.0.7",
|
||||
"eslint-plugin-storybook": "^9.1.13",
|
||||
"eslint-plugin-tailwindcss": "^3.18.0",
|
||||
"globals": "^15.11.0",
|
||||
"husky": "^9.1.6",
|
||||
|
|
@ -197,7 +195,7 @@
|
|||
"magicast": "^0.3.4",
|
||||
"postcss": "^8.4.47",
|
||||
"sass": "^1.92.1",
|
||||
"storybook": "8.5.0",
|
||||
"storybook": "9.1.13",
|
||||
"tailwindcss": "^3.4.14",
|
||||
"typescript": "^5.8.3",
|
||||
"uglify-js": "^3.19.3"
|
||||
|
|
@ -243,7 +241,8 @@
|
|||
"object.fromentries": "npm:@nolyfill/object.fromentries@^1",
|
||||
"object.groupby": "npm:@nolyfill/object.groupby@^1",
|
||||
"object.values": "npm:@nolyfill/object.values@^1",
|
||||
"safe-buffer": "npm:@nolyfill/safe-buffer@^1",
|
||||
"safe-buffer": "^5.2.1",
|
||||
"@nolyfill/safe-buffer": "npm:safe-buffer@^5.2.1",
|
||||
"safe-regex-test": "npm:@nolyfill/safe-regex-test@^1",
|
||||
"safer-buffer": "npm:@nolyfill/safer-buffer@^1",
|
||||
"side-channel": "npm:@nolyfill/side-channel@^1",
|
||||
|
|
|
|||
1454
web/pnpm-lock.yaml
1454
web/pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue