Demo效果:
组件实现:
import React from 'react'; import clsx from 'clsx'; import { makeStyles } from '@material-ui/core/styles'; import { Box, Typography } from '@vvwork/atoms'; const useStyles = makeStyles(() => ({ root: { display: 'inline-flex', color: '#BCC1CD', fontSize: '12px', borderRadius: '4px', '&:hover, &:focus': { color: '#2A2F3C', backgroundColor: 'rgba(246,247,248,0.8)', }, }, outlined: { border: '1px solid rgba(188,193,205,0.6)', }, outlinedPrimary: { border: '1px solid #FFE8CB', }, outlinedSecondary: { border: '1px solid #EEF4FE', }, colorPrimary: { color: '#FFA22D', '&:hover, &:focus': { color: '#FFA22D', backgroundColor: 'rgba(255, 245, 232, 0.8)', }, }, colorSecondary: { color: '#5590F6', '&:hover, &:focus': { color: '#5590F6', backgroundColor: 'rgba(238,244,254, 0.8)', }, }, disabled: { color: 'rgb(188, 193, 205)', }, clickable: { cursor: 'pointer', }, selected: { color: '#2A2F3C', backgroundColor: 'rgba(246,247,248, 1)', }, selectedPrimary: { backgroundColor: 'rgba(255, 245, 232, 1)', }, selectedSecondary: { backgroundColor: 'rgba(238,244,254, 1)', }, })); export interface DataProps { label: string; key: string; } export interface TagProps { children?: null; clickable?: boolean; color?: 'default' | 'primary' | 'secondary'; disabled?: boolean; data?: DataProps[]; value?: string; onClick?: (nowSelect: string) => void; onChange?: React.EventHandler<any>; variant?: 'default' | 'outlined'; className?: string; } export default function ToggleBox(props: TagProps) { const { data = [], variant = 'default', color = 'default', disabled = false, clickable = true, value = '', className = '', onChange = () => {}, ...rest } = props; const classes = useStyles(); const [select, setSelect] = React.useState(value || (data && data[0].label)); const handleToggle = (nowSelect: DataProps) => () => { onChange(nowSelect); setSelect(nowSelect.label); }; return ( <Box> {data && data.map(item => { return ( <Box {...rest} paddingX={1} paddingY={0.5} marginX={0.5} key={item.key} className={clsx( classes.root, { [classes.outlined]: variant === 'outlined', [classes.outlinedPrimary]: variant === 'outlined' && color === 'primary', [classes.outlinedSecondary]: variant === 'outlined' && color === 'secondary', [classes.colorPrimary]: color === 'primary', [classes.colorSecondary]: color === 'secondary', [classes.disabled]: disabled, [classes.clickable]: clickable, [classes.selected]: select === item.label && color === 'default', [classes.selectedPrimary]: select === item.label && color === 'primary', [classes.selectedSecondary]: select === item.label && color === 'secondary', }, className, )} onClick={handleToggle(item)} > <Typography>{item.label}</Typography> </Box> ); })} </Box> ); }
Demo:
import React from 'react'; import Theme from '../../Theme'; import { Box } from '@vvwork/atoms'; import ToggleBox from '../'; export default function Demo() { return ( <Theme> {/* 1 */} <Box pl={2} pt={2}> <ToggleBox data={[ { label: '无线框1-primary', key: 'first' }, { label: '无线框2-primary', key: 'second' }, ]} variant="default" color="primary" disabled={false} clickable={true} value="无线框1-primary" onChange={data => { console.log(data); }} /> </Box> {/* 2 */} <Box pl={2} pt={2}> <ToggleBox data={[ { label: '无线框1-secondary', key: 'first' }, { label: '无线框2-secondary', key: 'second' }, ]} variant="default" color="secondary" disabled={false} clickable={true} onChange={data => { console.log(data); }} /> </Box> {/* 3 */} <Box pl={2} pt={2}> <ToggleBox data={[ { label: '无线框1-default', key: 'first' }, { label: '无线框2-default', key: 'second' }, ]} variant="default" disabled={false} clickable={true} value="无线框2-default" onChange={data => { console.log(data); }} /> </Box> {/* 4 */} <Box pl={2} pt={2}> <ToggleBox data={[ { label: '线框1-secondary', key: 'first' }, { label: '线框2-secondary', key: 'second' }, ]} variant="outlined" color="secondary" disabled={false} clickable={true} onChange={data => { console.log(data); }} /> </Box> {/* 5 */} <Box pl={2} pt={2}> <ToggleBox data={[ { label: '线框1-primary', key: 'first' }, { label: '线框2-primary', key: 'second' }, ]} variant="outlined" color="primary" disabled={false} clickable={true} value="线框1-primary" onChange={data => { console.log(data); }} /> </Box> {/* 6 */} <Box pl={2} pt={2}> <ToggleBox data={[ { label: '线框1-default', key: 'first' }, { label: '线框2-default', key: 'second' }, ]} variant="outlined" color="default" disabled={false} clickable={true} onChange={data => { console.log(data); }} /> </Box> </Theme> ); }
README.md:
# 可切换按钮组组件 用于显示可切换按钮组 ## 基础 API | Name | Type | Default | Description | | :-------- | :-------------------------------- | :-------- | :------------------------------- | | data | Array[{label:string,key:string}] | [] | 文案数组 | | color | 'default','primary','secondary' | 'default' | 颜色 | | disabled | bool | false | 可用 | | selected | string | '' | 当前选中项 | | variant | 'default','outlined' | 'default' | 变体(默认填充) | | className | string | | 样式 | | onChange | func | | 函数,回调为当前选中项的数据对象 |
index.stories.tsx:
import React from 'react'; import { storiesOf } from '@storybook/react'; import README from './README.md'; import Demo from './Demo'; // eslint-disable-next-line import/no-webpack-loader-syntax import DemoRaw from '!!raw-loader!./Demo'; storiesOf('公共组件|ToggleButton', module) .addParameters({ notes: README, }) .add('示例', () => <Demo />, { jsx: { onBeforeRender: () => DemoRaw, }, });