通用组件开发

This commit is contained in:
juguohong
2025-08-17 00:00:56 +08:00
parent 86e14cb445
commit 4f6ca73148
25 changed files with 2554 additions and 24 deletions

View File

@@ -0,0 +1,208 @@
# Bubble 通用气泡组件
一个高度可配置的气泡选择器组件,支持任何内容的选择,包括但不限于时间、地点、标签、分类等。
## 特性
- 🎯 支持单选和多选模式
- 📱 三种布局方式:水平、垂直、网格
- 🎨 三种尺寸:小、中、大
- ♿ 支持禁用状态和图标描述
- 🔄 支持受控和非受控模式
- 📱 响应式设计,自动适应不同屏幕
- 🎨 可自定义样式和类名
## 基本用法
### 室内外选择示例如UI图所示
```tsx
import React, { useState } from 'react';
import Bubble, { BubbleOption } from './index';
const LocationSelector: React.FC = () => {
const [selectedLocation, setSelectedLocation] = useState<string>('');
const locationOptions: BubbleOption[] = [
{ id: 1, label: '室内', value: 'indoor' },
{ id: 2, label: '室外', value: 'outdoor' },
{ id: 3, label: '半室外', value: 'semi-outdoor' }
];
return (
<Bubble
options={locationOptions}
value={selectedLocation}
onChange={(value) => setSelectedLocation(value as string)}
layout="horizontal"
size="medium"
/>
);
};
```
### 时间选择器示例
```tsx
const TimeSelector: React.FC = () => {
const [selectedTime, setSelectedTime] = useState<string>('');
const timeOptions: BubbleOption[] = [
{ id: 1, label: '晨间 6:00-10:00', value: 'morning' },
{ id: 2, label: '上午 10:00-12:00', value: 'forenoon' },
{ id: 3, label: '中午 12:00-14:00', value: 'noon' },
{ id: 4, label: '下午 14:00-18:00', value: 'afternoon' },
{ id: 5, label: '晚上 18:00-22:00', value: 'evening' },
{ id: 6, label: '夜间 22:00-24:00', value: 'night' }
];
return (
<Bubble
options={timeOptions}
value={selectedTime}
onChange={(value) => setSelectedTime(value as string)}
layout="grid"
columns={3}
size="medium"
/>
);
};
```
### 多选模式
```tsx
const MultiSelectExample: React.FC = () => {
const [selectedValues, setSelectedValues] = useState<string[]>([]);
const options: BubbleOption[] = [
{ id: 1, label: '运动', value: 'sports' },
{ id: 2, label: '音乐', value: 'music' },
{ id: 3, label: '阅读', value: 'reading' },
{ id: 4, label: '旅行', value: 'travel' }
];
return (
<Bubble
options={options}
value={selectedValues}
onChange={(value) => setSelectedValues(value as string[])}
multiple={true}
layout="grid"
columns={2}
size="medium"
/>
);
};
```
### 带图标和描述
```tsx
const IconExample: React.FC = () => {
const [selectedValue, setSelectedValue] = useState<string>('');
const options: BubbleOption[] = [
{
id: 1,
label: '网球',
value: 'tennis',
icon: '🎾',
description: '室内外均可'
},
{
id: 2,
label: '篮球',
value: 'basketball',
icon: '🏀',
description: '室内场地'
}
];
return (
<Bubble
options={options}
value={selectedValue}
onChange={(value) => setSelectedValue(value as string)}
layout="vertical"
size="large"
/>
);
};
```
## API
### BubbleProps
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| options | `BubbleOption[]` | - | 选项数组 |
| value | `string \| number \| (string \| number)[]` | - | 当前选中的值 |
| onChange | `(value, option) => void` | - | 选择变化时的回调 |
| multiple | `boolean` | `false` | 是否支持多选 |
| layout | `'horizontal' \| 'vertical' \| 'grid'` | `'horizontal'` | 布局方式 |
| columns | `number` | `3` | 网格布局的列数 |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | 按钮尺寸 |
| className | `string` | `''` | 自定义类名 |
| style | `React.CSSProperties` | `{}` | 自定义样式 |
| disabled | `boolean` | `false` | 是否禁用整个组件 |
### BubbleOption
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| id | `string \| number` | - | 选项的唯一标识 |
| label | `string` | - | 显示的文本 |
| value | `string \| number` | - | 选项的值 |
| disabled | `boolean` | `false` | 是否禁用 |
| icon | `React.ReactNode` | - | 可选的图标 |
| description | `string` | - | 可选的描述文本 |
## 布局说明
### 水平布局 (horizontal)
- 适合选项较少的情况
- 自动换行,响应式设计
- 适合顶部导航、标签选择等
### 垂直布局 (vertical)
- 适合选项较多的情况
- 每个选项占满一行
- 适合侧边栏、设置页面等
### 网格布局 (grid)
- 适合选项较多且需要整齐排列的情况
- 可自定义列数
- 适合分类选择、时间选择等
## 尺寸说明
### 小尺寸 (small)
- 适合紧凑的界面
- 适合移动端或空间受限的场景
### 中尺寸 (medium)
- 默认尺寸,适合大多数场景
- 平衡了可用性和美观性
### 大尺寸 (large)
- 适合需要突出显示的场景
- 适合触摸设备或重要操作
## 样式定制
组件使用 SCSS 编写,可以通过以下方式自定义样式:
1. 覆盖 CSS 变量
2. 使用 `className``style` 属性
3. 修改 SCSS 源文件
## 注意事项
- 在网格布局中,`columns` 属性控制列数,行数会根据选项数量自动计算
- 多选模式下,`value` 应该是数组类型
- 单选模式下,`value` 可以是字符串或数字类型
- 组件会自动处理选中状态的样式变化
- 支持图标和描述,让选项更加丰富
- 响应式设计,自动适应不同屏幕尺寸