gemini-uis 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,378 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite'
2
- import { Button } from '@/libs/Button'
3
-
4
- const meta = {
5
- title: 'Components/Button',
6
- component: Button,
7
- parameters: {
8
- layout: 'centered',
9
- docs: {
10
- description: {
11
- component: '一个精简的按钮组件,仅保留基本功能,专为简单项目使用而设计。',
12
- },
13
- },
14
- },
15
- tags: ['autodocs'],
16
- argTypes: {
17
- type: {
18
- control: 'select',
19
- options: ['primary', 'secondary', 'outline', 'ghost', 'text', 'danger', 'default'],
20
- description: '按钮变体',
21
- table: {
22
- type: { summary: 'ButtonType' },
23
- defaultValue: { summary: 'primary' },
24
- },
25
- },
26
- size: {
27
- control: 'select',
28
- options: ['xs', 'sm', 'md', 'lg', 'xl'],
29
- description: '按钮尺寸',
30
- table: {
31
- type: { summary: 'ButtonSize' },
32
- defaultValue: { summary: 'md' },
33
- },
34
- },
35
- rounded: {
36
- control: 'boolean',
37
- description: '是否圆角',
38
- table: {
39
- type: { summary: 'boolean' },
40
- defaultValue: { summary: 'false' },
41
- },
42
- },
43
- disabled: {
44
- control: 'boolean',
45
- description: '是否禁用',
46
- table: {
47
- type: { summary: 'boolean' },
48
- defaultValue: { summary: 'false' },
49
- },
50
- },
51
- loading: {
52
- control: 'boolean',
53
- description: '是否显示加载状态',
54
- table: {
55
- type: { summary: 'boolean' },
56
- defaultValue: { summary: 'false' },
57
- },
58
- },
59
- htmlType: {
60
- control: 'select',
61
- options: ['button', 'submit', 'reset'],
62
- description: 'HTML按钮类型',
63
- table: {
64
- type: { summary: "'button' | 'submit' | 'reset'" },
65
- defaultValue: { summary: 'button' },
66
- },
67
- },
68
- children: {
69
- control: 'text',
70
- description: '按钮内容',
71
- },
72
- },
73
- } satisfies Meta<typeof Button>
74
-
75
- export default meta
76
- type Story = StoryObj<typeof meta>
77
-
78
- /**
79
- * 基础按钮示例
80
- */
81
- export const Default: Story = {
82
- args: {
83
- children: '点击我',
84
- type: 'primary',
85
- size: 'md',
86
- rounded: false,
87
- disabled: false,
88
- loading: false,
89
- },
90
- }
91
-
92
- /**
93
- * 所有变体展示
94
- */
95
- export const Variants: Story = {
96
- render: () => (
97
- <div className="flex flex-wrap gap-4">
98
- <Button type="primary">主要按钮</Button>
99
- <Button type="secondary">次要按钮</Button>
100
- <Button type="outline">轮廓按钮</Button>
101
- <Button type="ghost">幽灵按钮</Button>
102
- <Button type="text">文本按钮</Button>
103
- <Button type="danger">危险按钮</Button>
104
- <Button type="default">默认按钮</Button>
105
- </div>
106
- ),
107
- parameters: {
108
- docs: {
109
- description: {
110
- story: '展示所有可用的按钮变体类型。',
111
- },
112
- },
113
- },
114
- }
115
-
116
- /**
117
- * 所有尺寸展示
118
- */
119
- export const Sizes: Story = {
120
- render: () => (
121
- <div className="flex flex-wrap items-center gap-4">
122
- <Button size="xs">超小按钮</Button>
123
- <Button size="sm">小按钮</Button>
124
- <Button size="md">中等按钮</Button>
125
- <Button size="lg">大按钮</Button>
126
- <Button size="xl">超大按钮</Button>
127
- </div>
128
- ),
129
- parameters: {
130
- docs: {
131
- description: {
132
- story: '展示所有可用的按钮尺寸。',
133
- },
134
- },
135
- },
136
- }
137
-
138
- /**
139
- * 圆角设置
140
- */
141
- export const Rounded: Story = {
142
- render: () => (
143
- <div className="flex flex-wrap gap-4">
144
- <Button rounded={false}>方框按钮</Button>
145
- <Button rounded={true}>圆角按钮</Button>
146
- </div>
147
- ),
148
- parameters: {
149
- docs: {
150
- description: {
151
- story: '展示圆角和方框两种样式。',
152
- },
153
- },
154
- },
155
- }
156
-
157
- /**
158
- * 状态展示
159
- */
160
- export const States: Story = {
161
- render: () => (
162
- <div className="flex flex-wrap gap-4">
163
- <Button>正常状态</Button>
164
- <Button loading>加载中</Button>
165
- <Button disabled>禁用</Button>
166
- <Button loading disabled>加载且禁用</Button>
167
- </div>
168
- ),
169
- parameters: {
170
- docs: {
171
- description: {
172
- story: '展示按钮的不同状态:正常、加载、禁用。',
173
- },
174
- },
175
- },
176
- }
177
-
178
- /**
179
- * 事件处理示例
180
- */
181
- export const WithClickHandler: Story = {
182
- render: () => (
183
- <Button
184
- onClick={(e) => {
185
- e.preventDefault()
186
- alert('按钮被点击了!')
187
- }}
188
- >
189
- 点击我
190
- </Button>
191
- ),
192
- parameters: {
193
- docs: {
194
- description: {
195
- story: '展示如何处理按钮点击事件。',
196
- },
197
- },
198
- },
199
- }
200
-
201
- /**
202
- * 表单集成示例
203
- */
204
- export const FormIntegration: Story = {
205
- render: () => (
206
- <form
207
- onSubmit={(e) => {
208
- e.preventDefault()
209
- alert('表单已提交')
210
- }}
211
- onReset={() => {
212
- alert('表单已重置')
213
- }}
214
- className="flex gap-4"
215
- >
216
- <Button type="primary" htmlType="submit">
217
- 提交表单
218
- </Button>
219
- <Button type="secondary" htmlType="reset">
220
- 重置
221
- </Button>
222
- </form>
223
- ),
224
- parameters: {
225
- docs: {
226
- description: {
227
- story: '展示如何在表单中使用按钮,包括提交和重置功能。',
228
- },
229
- },
230
- },
231
- }
232
-
233
- /**
234
- * 组合示例:不同变体的所有尺寸
235
- */
236
- export const AllVariantsAndSizes: Story = {
237
- render: () => {
238
- const variants: Array<'primary' | 'secondary' | 'outline' | 'ghost' | 'text' | 'danger' | 'default'> = [
239
- 'primary',
240
- 'secondary',
241
- 'outline',
242
- 'ghost',
243
- 'text',
244
- 'danger',
245
- 'default',
246
- ]
247
- const sizes: Array<'xs' | 'sm' | 'md' | 'lg' | 'xl'> = ['xs', 'sm', 'md', 'lg', 'xl']
248
-
249
- return (
250
- <div className="space-y-6">
251
- {variants.map((variant) => (
252
- <div key={variant} className="space-y-2">
253
- <h3 className="text-sm font-semibold text-gray-700 capitalize">{variant}</h3>
254
- <div className="flex flex-wrap items-center gap-2">
255
- {sizes.map((size) => (
256
- <Button key={size} type={variant} size={size}>
257
- {size.toUpperCase()}
258
- </Button>
259
- ))}
260
- </div>
261
- </div>
262
- ))}
263
- </div>
264
- )
265
- },
266
- parameters: {
267
- docs: {
268
- description: {
269
- story: '展示所有变体和尺寸的组合效果。',
270
- },
271
- },
272
- },
273
- }
274
-
275
- /**
276
- * 圆角与方框对比
277
- */
278
- export const RoundedComparison: Story = {
279
- render: () => {
280
- const variants: Array<'primary' | 'secondary' | 'outline'> = ['primary', 'secondary', 'outline']
281
-
282
- return (
283
- <div className="space-y-6">
284
- <div className="space-y-2">
285
- <h3 className="text-sm font-semibold text-gray-700">方框按钮 (rounded=false)</h3>
286
- <div className="flex flex-wrap gap-2">
287
- {variants.map((variant) => (
288
- <Button key={variant} type={variant} rounded={false}>
289
- {variant}
290
- </Button>
291
- ))}
292
- </div>
293
- </div>
294
- <div className="space-y-2">
295
- <h3 className="text-sm font-semibold text-gray-700">圆角按钮 (rounded=true)</h3>
296
- <div className="flex flex-wrap gap-2">
297
- {variants.map((variant) => (
298
- <Button key={variant} type={variant} rounded={true}>
299
- {variant}
300
- </Button>
301
- ))}
302
- </div>
303
- </div>
304
- </div>
305
- )
306
- },
307
- parameters: {
308
- docs: {
309
- description: {
310
- story: '对比不同变体的圆角和方框样式。',
311
- },
312
- },
313
- },
314
- }
315
-
316
- /**
317
- * 加载状态示例
318
- */
319
- export const LoadingStates: Story = {
320
- render: () => (
321
- <div className="flex flex-wrap gap-4">
322
- <Button type="primary" loading>
323
- 加载中
324
- </Button>
325
- <Button type="secondary" loading>
326
- 加载中
327
- </Button>
328
- <Button type="outline" loading>
329
- 加载中
330
- </Button>
331
- <Button type="danger" loading>
332
- 加载中
333
- </Button>
334
- </div>
335
- ),
336
- parameters: {
337
- docs: {
338
- description: {
339
- story: '展示不同变体的加载状态。',
340
- },
341
- },
342
- },
343
- }
344
-
345
- /**
346
- * 禁用状态示例
347
- */
348
- export const DisabledStates: Story = {
349
- render: () => (
350
- <div className="flex flex-wrap gap-4">
351
- <Button type="primary" disabled>
352
- 禁用
353
- </Button>
354
- <Button type="secondary" disabled>
355
- 禁用
356
- </Button>
357
- <Button type="outline" disabled>
358
- 禁用
359
- </Button>
360
- <Button type="ghost" disabled>
361
- 禁用
362
- </Button>
363
- <Button type="text" disabled>
364
- 禁用
365
- </Button>
366
- <Button type="danger" disabled>
367
- 禁用
368
- </Button>
369
- </div>
370
- ),
371
- parameters: {
372
- docs: {
373
- description: {
374
- story: '展示不同变体的禁用状态。',
375
- },
376
- },
377
- },
378
- }
@@ -1,144 +0,0 @@
1
- # Button 组件 - 简化版
2
-
3
- 一个精简的按钮组件,仅保留基本功能,专为简单项目使用而设计。
4
-
5
- ## 特性
6
-
7
- - 🎨 **6种变体**: primary, secondary, outline, ghost, link, danger
8
- - 📏 **5种尺寸**: xs, sm, md, lg, xl
9
- - 🔄 **圆角设置**: 支持方框和圆角两种样式
10
- - 🔄 **加载状态**: 内置加载动画
11
- - 🎯 **简洁设计**: 移除了复杂功能,专注于核心需求
12
- - 📱 **响应式**: 支持基础响应式布局
13
- - ♿ **无障碍**: 完整的键盘导航支持
14
-
15
- ## 安装
16
-
17
- ```tsx
18
- import { Button } from "@/ui/Button";
19
- ```
20
-
21
- ## 基础用法
22
-
23
- ```tsx
24
- // 基础按钮
25
- <Button>点击我</Button>
26
-
27
- // 不同变体
28
- <Button type="primary">主要按钮</Button>
29
- <Button type="secondary">次要按钮</Button>
30
- <Button type="outline">轮廓按钮</Button>
31
- <Button type="ghost">幽灵按钮</Button>
32
- <Button type="link">链接按钮</Button>
33
- <Button type="danger">危险按钮</Button>
34
- ```
35
-
36
- ## 尺寸
37
-
38
- ```tsx
39
- <Button size="xs">超小按钮</Button>
40
- <Button size="sm">小按钮</Button>
41
- <Button size="md">中等按钮</Button>
42
- <Button size="lg">大按钮</Button>
43
- <Button size="xl">超大按钮</Button>
44
- ```
45
-
46
- ## 圆角设置
47
-
48
- ```tsx
49
- <Button rounded={false}>方框按钮</Button>
50
- <Button rounded={true}>圆角按钮</Button>
51
- ```
52
-
53
- ## 状态
54
-
55
- ```tsx
56
- <Button loading>加载中</Button>
57
- <Button disabled>禁用</Button>
58
- ```
59
-
60
- ## 事件处理
61
-
62
- ```tsx
63
- <Button
64
- onClick={(e) => {
65
- e.preventDefault();
66
- console.log("按钮被点击");
67
- }}
68
- >
69
- 点击我
70
- </Button>
71
- ```
72
-
73
- ## 表单集成
74
-
75
- ```tsx
76
- <form>
77
- <Button type="submit" variant="primary">
78
- 提交表单
79
- </Button>
80
- <Button type="reset" variant="secondary">
81
- 重置
82
- </Button>
83
- </form>
84
- ```
85
-
86
- ## API 参考
87
-
88
- ### ButtonProps
89
-
90
- | 属性 | 类型 | 默认值 | 描述 |
91
- | --------- | --------------------------------- | ----------- | ---------------- |
92
- | type | `ButtonType` | `'primary'` | 按钮变体 |
93
- | size | `ButtonSize` | `'md'` | 按钮尺寸 |
94
- | rounded | `boolean` | `false` | 是否圆角 |
95
- | disabled | `boolean` | `false` | 是否禁用 |
96
- | loading | `boolean` | `false` | 是否显示加载状态 |
97
- | className | `string` | - | 自定义类名 |
98
- | children | `ReactNode` | - | 按钮内容 |
99
- | htmlType | `'button' \| 'submit' \| 'reset'` | `'button'` | HTML按钮类型 |
100
- | onClick | `(event: MouseEvent) => void` | - | 点击事件处理器 |
101
-
102
- ### 类型定义
103
-
104
- ```tsx
105
- type ButtonType =
106
- | "primary"
107
- | "secondary"
108
- | "outline"
109
- | "ghost"
110
- | "link"
111
- | "danger";
112
- type ButtonSize = "xs" | "sm" | "md" | "lg" | "xl";
113
- ```
114
-
115
- ## 简化说明
116
-
117
- 相比完整版Button组件,简化版移除了以下功能:
118
-
119
- - ❌ 复杂的形状选项(pill, square等)
120
- - ❌ 多种状态类型(success, error等)
121
- - ❌ 图标支持(leftIcon, rightIcon)
122
- - ❌ 全宽支持
123
- - ❌ 复杂的主题系统
124
-
125
- ## 最佳实践
126
-
127
- 1. **保持简洁**: 使用默认的primary变体作为主要操作
128
- 2. **尺寸一致**: 在同一界面中保持按钮尺寸的一致性
129
- 3. **状态反馈**: 使用loading状态提供用户反馈
130
- 4. **无障碍性**: 确保按钮有适当的标签和键盘导航
131
-
132
- ## 常见问题
133
-
134
- ### Q: 如何自定义按钮颜色?
135
-
136
- A: 可以通过`className`属性添加自定义样式,或者修改`styles.ts`中的样式配置。
137
-
138
- ### Q: 按钮支持哪些事件?
139
-
140
- A: 支持所有标准的HTML button元素事件,如onClick、onMouseOver等。
141
-
142
- ### Q: 如何实现按钮组?
143
-
144
- A: 可以将多个Button组件包装在一个容器中,使用flex布局实现按钮组。
@@ -1,69 +0,0 @@
1
- import { forwardRef } from 'react'
2
- import type { ButtonProps, ButtonRef } from './types'
3
- import { getButtonStyles } from './styles'
4
- import { cn } from '@/utils'
5
- import { LoadingIcon } from '@/icons'
6
-
7
- export const Button = forwardRef<ButtonRef, ButtonProps>(
8
- (
9
- {
10
- type = 'primary',
11
- size = 'md',
12
- rounded = false,
13
- disabled = false,
14
- loading = false,
15
- className,
16
- children,
17
- htmlType = 'button',
18
- onClick,
19
- ...props
20
- },
21
- ref
22
- ) => {
23
- // 计算最终状态
24
- const isDisabled = disabled || loading
25
-
26
- // 获取样式类名
27
- const buttonStyles = getButtonStyles(
28
- type,
29
- size,
30
- rounded,
31
- isDisabled,
32
- loading,
33
- className
34
- )
35
-
36
- // 处理点击事件
37
- const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
38
- if (isDisabled) {
39
- event.preventDefault()
40
- return
41
- }
42
- onClick?.(event)
43
- }
44
-
45
- return (
46
- <button
47
- ref={ref}
48
- type={htmlType}
49
- disabled={isDisabled}
50
- onClick={handleClick}
51
- className={cn(buttonStyles)}
52
- {...props}
53
- >
54
- {loading && <LoadingIcon className="animate-spin w-4 h-4 mr-2" />}
55
- {children}
56
- </button>
57
- )
58
- }
59
- )
60
-
61
- export default Button
62
-
63
- // 导出类型
64
- export type {
65
- ButtonProps,
66
- ButtonRef,
67
- ButtonType,
68
- ButtonSize,
69
- } from './types'
@@ -1,71 +0,0 @@
1
- import type { ButtonType, ButtonSize } from './types'
2
-
3
- /**
4
- * 获取按钮变体样式
5
- */
6
- export const getVariantStyles = (variant: ButtonType): string => {
7
- const variants = {
8
- primary: 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500',
9
- default: 'bg-white text-gray-700 hover:bg-gray-50 focus:ring-gray-500 border border-gray-300',
10
- secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-500 border border-gray-300',
11
- outline: 'bg-transparent text-blue-600 hover:bg-blue-50 focus:ring-blue-500 border border-blue-600',
12
- ghost: 'bg-transparent text-gray-700 hover:bg-gray-100 focus:ring-gray-500',
13
- text: 'bg-transparent text-gray-700 focus:ring-gray-500',
14
- danger: 'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500',
15
- }
16
- return variants[variant] || variants.primary
17
- }
18
-
19
- /**
20
- * 获取按钮尺寸样式
21
- */
22
- export const getSizeStyles = (size: ButtonSize): string => {
23
- const sizes = {
24
- xs: 'px-2 py-1 text-xs min-h-[1.5rem]',
25
- sm: 'px-3 py-1.5 text-sm min-h-[2rem]',
26
- md: 'px-4 py-2 text-sm min-h-[2.5rem]',
27
- lg: 'px-6 py-3 text-base min-h-[3rem]',
28
- xl: 'px-8 py-4 text-lg min-h-[3.5rem]',
29
- }
30
- return sizes[size] || sizes.md
31
- }
32
-
33
- /**
34
- * 获取按钮圆角样式
35
- */
36
- export const getRoundedStyles = (rounded: boolean): string => {
37
- return rounded ? 'rounded-lg' : 'rounded-none'
38
- }
39
-
40
- /**
41
- * 组合所有样式类名
42
- */
43
- export const getButtonStyles = (
44
- variant: ButtonType = 'primary',
45
- size: ButtonSize = 'md',
46
- rounded: boolean = false,
47
- disabled: boolean = false,
48
- loading: boolean = false,
49
- customClassName?: string
50
- ): string => {
51
- const baseStyles = 'inline-flex items-center justify-center font-medium text-center transition-all duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed'
52
- const variantStyles = getVariantStyles(variant)
53
- const sizeStyles = getSizeStyles(size)
54
- const roundedStyles = getRoundedStyles(rounded)
55
- const disabledStyles = disabled ? 'opacity-50 cursor-not-allowed' : ''
56
- const loadingStyles = loading ? 'cursor-wait' : ''
57
-
58
- return [
59
- baseStyles,
60
- variantStyles,
61
- sizeStyles,
62
- roundedStyles,
63
- disabledStyles,
64
- loadingStyles,
65
- customClassName,
66
- ]
67
- .filter(Boolean)
68
- .join(' ')
69
- .replace(/\s+/g, ' ')
70
- .trim()
71
- }
@@ -1,52 +0,0 @@
1
- import type { ReactNode, ButtonHTMLAttributes } from 'react'
2
-
3
- /**
4
- * Button组件的变体类型 - 简化版
5
- */
6
- export type ButtonType =
7
- | 'primary' // 主要按钮
8
- | 'default' // 默认按钮
9
- | 'secondary' // 次要按钮
10
- | 'outline' // 轮廓按钮
11
- | 'ghost' // 幽灵按钮
12
- | 'text' // 文本按钮
13
- | 'danger' // 危险按钮
14
-
15
- /**
16
- * Button组件的尺寸类型 - 简化版
17
- */
18
- export type ButtonSize =
19
- | 'xs' // 超小尺寸
20
- | 'sm' // 小尺寸
21
- | 'md' // 中等尺寸
22
- | 'lg' // 大尺寸
23
- | 'xl' // 超大尺寸
24
-
25
-
26
- /**
27
- * Button组件的基础属性接口 - 简化版
28
- */
29
- export interface ButtonProps
30
- extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'size' | 'children' | 'type'> {
31
- /** 按钮变体 */
32
- type?: ButtonType
33
- /** 按钮尺寸 */
34
- size?: ButtonSize
35
- /** 是否圆角 */
36
- rounded?: boolean
37
- /** 是否禁用 */
38
- disabled?: boolean
39
- /** 是否显示加载状态 */
40
- loading?: boolean
41
- /** 自定义类名 */
42
- className?: string
43
- /** 子元素 */
44
- children?: ReactNode
45
- /** 按钮类型 */
46
- htmlType?: ButtonHTMLAttributes<HTMLButtonElement>['type']
47
- }
48
-
49
- /**
50
- * Button组件的ref类型
51
- */
52
- export type ButtonRef = HTMLButtonElement