Files
shanghai-residences/src/components/quiz/drag-fill/drag-fill.stories.tsx
T
zhongyidian 76c67b492e feat: 更新 ESLint 和 Prettier 配置,增强代码质量管理
- 在 .gitignore 中添加 public/audio/* 以忽略音频文件。
- 更新 bun.lock,添加 eslint-config-prettier 和 eslint-plugin-prettier 依赖,确保 ESLint 与 Prettier 的兼容性。
- 修改 eslint.config.ts,整合 Prettier 规则,优化代码风格一致性。
- 在 package.json 中添加 lint:fix 和 format 脚本,简化代码格式化和修复流程。
- 更新 tailwind.config.ts 和其他组件文件,统一代码风格,提升可读性。
2026-03-05 13:50:47 +08:00

198 lines
5.4 KiB
TypeScript

import type { Meta, StoryObj } from '@storybook/react'
import { useState } from 'react'
import DragFill from './drag-fill'
import type { DragFillProps } from './drag-fill.types'
import { cn } from '@/lib/utils'
const meta: Meta<typeof DragFill> = {
title: 'Components/Quiz/DragFill',
component: DragFill,
tags: ['autodocs'],
argTypes: {
options: {
control: { type: 'object' },
description: '可拖拽的选项列表',
},
blanks: {
control: { type: 'object' },
description: '空白区域列表',
},
value: {
control: { type: 'object' },
description: '当前填充结果(受控模式)',
},
defaultValue: {
control: { type: 'object' },
description: '默认填充结果',
},
disabled: {
control: { type: 'boolean' },
description: '是否禁用整个组件',
},
allowDuplicate: {
control: { type: 'boolean' },
description: '是否允许重复选择同一选项',
},
showSubmitButton: {
control: { type: 'boolean' },
description: '是否显示提交按钮',
},
submitText: {
control: { type: 'text' },
description: '提交按钮文本',
},
},
}
export default meta
type Story = StoryObj<typeof DragFill>
// 基础示例
export const Default: Story = {
args: {
options: ['选项A', '选项B', '选项C', '选项D'],
blanks: ['空白1', '空白2', '空白3'],
onSubmit: (results) => {
console.log('填充结果:', results)
},
},
}
// 使用选项和空白对象
export const WithObjects: Story = {
args: {
options: [
{ value: 'opt1', label: '选项一' },
{ value: 'opt2', label: '选项二' },
{ value: 'opt3', label: '选项三(禁用)', disabled: true },
{ value: 'opt4', label: '选项四' },
],
blanks: [
{ id: 'blank1', label: '第一个空白', required: true },
{ id: 'blank2', label: '第二个空白' },
{ id: 'blank3', label: '第三个空白(必填)', required: true },
],
onSubmit: (results) => {
console.log('填充结果:', results)
},
},
}
// 受控模式
export const Controlled: Story = {
render: () => {
const [value, setValue] = useState<any[]>([])
return (
<div className="space-y-4">
<DragFill
options={['选项A', '选项B', '选项C']}
blanks={['空白1', '空白2']}
value={value}
onChange={setValue}
onSubmit={(results) => {
alert(`提交的结果: ${JSON.stringify(results)}`)
}}
/>
<div className="text-sm text-gray-600">当前填充: {JSON.stringify(value)}</div>
</div>
)
},
}
// 允许重复选择
export const AllowDuplicate: Story = {
args: {
options: ['选项A', '选项B', '选项C'],
blanks: ['空白1', '空白2', '空白3'],
allowDuplicate: true,
onSubmit: (results) => {
console.log('填充结果:', results)
},
},
}
// 禁用状态
export const Disabled: Story = {
args: {
options: ['选项A', '选项B', '选项C'],
blanks: ['空白1', '空白2'],
disabled: true,
defaultValue: [{ blankId: 'blank1', optionValue: '选项A' }],
},
}
// 不显示提交按钮
export const WithoutSubmitButton: Story = {
args: {
options: ['选项A', '选项B', '选项C'],
blanks: ['空白1', '空白2'],
showSubmitButton: false,
onChange: (results) => {
console.log('填充变化:', results)
},
},
}
// 自定义样式
export const CustomStyled: Story = {
args: {
options: ['选项A', '选项B', '选项C', '选项D'],
blanks: ['空白1', '空白2'],
className: 'max-w-2xl mx-auto p-6 bg-gray-50 rounded-xl',
optionClassName: 'text-lg font-semibold',
blankClassName: 'min-h-[100px]',
submitText: '确认答案',
onSubmit: (results) => {
console.log('填充结果:', results)
},
},
}
// 自定义渲染
export const CustomRender: Story = {
render: () => {
return (
<DragFill
options={['选项A', '选项B', '选项C']}
blanks={['空白1', '空白2']}
renderOption={(option, isUsed) => (
<div
className={cn(
'p-4 rounded-lg border-2 transition-all cursor-move',
isUsed
? 'border-gray-200 bg-gray-100 opacity-50'
: 'border-blue-300 bg-blue-50 hover:border-blue-500'
)}
draggable={!isUsed}
>
<div className="flex items-center gap-2">
<span className="text-2xl">📦</span>
<span className="font-medium">{option.label}</span>
</div>
</div>
)}
renderBlank={(blank, filledValue) => (
<div
className={cn(
'min-h-[100px] p-6 rounded-lg border-2 border-dashed flex items-center justify-center',
filledValue ? 'border-green-400 bg-green-50' : 'border-purple-300 bg-purple-50'
)}
>
{filledValue ? (
<div className="text-green-700 font-bold text-lg">✓ {filledValue}</div>
) : (
<div className="text-purple-500 text-center">
<div className="text-3xl mb-2">⬇️</div>
<div>{blank.label || '拖拽到这里'}</div>
</div>
)}
</div>
)}
onSubmit={(results) => {
console.log('填充结果:', results)
}}
/>
)
},
}