diff --git a/src/Radio/demos/Playground.tsx b/src/Radio/demos/Playground.tsx new file mode 100644 index 0000000..c8fa724 --- /dev/null +++ b/src/Radio/demos/Playground.tsx @@ -0,0 +1,37 @@ +import { StoryBook, useControls, useCreateStore } from '@lobehub/ui'; +import { Radio, RadioGroupProps } from '@yuntijs/ui'; + +export default () => { + const store = useCreateStore(); + const options = [ + { label: 'Apple', value: 'Apple' }, + { label: 'Pear', value: 'Pear' }, + { label: 'Orange', value: 'Orange', disabled: true }, + ]; + const control: RadioGroupProps | any = useControls( + { + defaultValue: options[0].value, + disabled: false, + optionType: { + options: ['default', 'button'], + value: 'default', + }, + buttonStyle: { + options: ['outline', 'solid'], + value: 'outline', + }, + buttonBorderRadius: false, + buttonGap: false, + size: { + options: ['large', 'middle', 'small'], + value: 'middle', + }, + }, + { store } + ); + return ( + + + + ); +}; diff --git a/src/Radio/demos/index.tsx b/src/Radio/demos/index.tsx new file mode 100644 index 0000000..11d79ba --- /dev/null +++ b/src/Radio/demos/index.tsx @@ -0,0 +1,37 @@ +import { Radio, Space } from '@yuntijs/ui'; + +export default () => { + const options = [ + { label: 'Apple', value: 'Apple' }, + { label: 'Pear', value: 'Pear' }, + { label: 'Orange', value: 'Orange', disabled: true }, + ]; + return ( + + + + + + + + ); +}; diff --git a/src/Radio/index.md b/src/Radio/index.md new file mode 100644 index 0000000..91cdeab --- /dev/null +++ b/src/Radio/index.md @@ -0,0 +1,35 @@ +--- +nav: Components +group: Data Entry +title: Radio +description: Used to select a single state from multiple options. +--- + +## Usage + +based on antd [Radio](https://ant.design/components/radio-cn/) component. + +### Simple usage + +```jsx | pure +import { Radio } from '@yuntijs/ui'; + +export default () => { + const options = [ + { label: 'Apple', value: 'Apple' }, + { label: 'Pear', value: 'Pear' }, + { label: 'Orange', value: 'Orange', disabled: true }, + ]; + return ; +}; +``` + + + +## Playground + + + +## APIs + + diff --git a/src/Radio/index.tsx b/src/Radio/index.tsx new file mode 100644 index 0000000..6d956e6 --- /dev/null +++ b/src/Radio/index.tsx @@ -0,0 +1,34 @@ +import { Radio as AntdRadio, type RadioGroupProps as AntdRadioGroupProps, RadioProps } from 'antd'; +import type { RadioRef } from 'antd/es/radio/interface'; +import { cloneDeep } from 'lodash-es'; +import React from 'react'; + +import { useStyles } from './style'; + +export interface CustomRadioProps { + buttonGap?: 'small' | 'middle' | 'large' | number | boolean; + buttonBorderRadius?: number | boolean; +} + +export interface RadioGroupProps extends AntdRadioGroupProps, CustomRadioProps {} + +type RadioType = React.ForwardRefExoticComponent> & { + Group: typeof Group; + Button: typeof AntdRadio.Button; +}; +export const Radio = cloneDeep(AntdRadio) as RadioType; + +const Group: React.FC = props => { + const { className, ...otherProps } = props; + + const { styles, cx } = useStyles(otherProps); + + return ; +}; +Radio.Group = Group; + +Radio.Button = AntdRadio.Button; + +export default Radio; + +export { type RadioChangeEvent, type RadioProps } from 'antd'; diff --git a/src/Radio/style.ts b/src/Radio/style.ts new file mode 100644 index 0000000..1a6753c --- /dev/null +++ b/src/Radio/style.ts @@ -0,0 +1,65 @@ +import { createStyles } from 'antd-style'; + +import { RadioGroupProps } from './index'; + +export const useStyles = createStyles( + ({ css, token }, { size, buttonBorderRadius, buttonGap }: RadioGroupProps) => { + const getButtonGapSize = () => { + const buttonGapSizeMap = { + small: token.sizeSM, + middle: token.size, + large: token.sizeLG, + }; + if (typeof buttonGap === 'string') { + return buttonGapSizeMap[buttonGap]; + } + if (buttonGap === true) { + return size ? buttonGapSizeMap[size] : buttonGapSizeMap['middle']; + } + if (!buttonGap) { + return 0; + } + return buttonGap; + }; + + const getButtonBorderRadius = () => { + const buttonBorderRadiusSizeMap = { + small: token.controlHeightSM, + middle: token.controlHeight, + large: token.controlHeightLG, + }; + if (buttonBorderRadius === true) { + return size ? buttonBorderRadiusSizeMap[size] : buttonBorderRadiusSizeMap['middle']; + } + if (buttonBorderRadius || buttonBorderRadius === 0) { + return buttonBorderRadius; + } + }; + const buttonBorderRadiusStyle = + getButtonBorderRadius() && + css` + label { + border-inline-start-width: 1px !important; + border-radius: ${getButtonBorderRadius()}px !important; + } + label::before { + display: none !important; + } + `; + const buttonGapStyle = css` + label { + margin-right: ${getButtonGapSize()}px !important; + } + label:last-child { + margin-right: 0 !important; + } + `; + return { + custom: css` + ${buttonBorderRadiusStyle} + ${buttonGapStyle} + `, + }; + }, + { hashPriority: 'low' } +); diff --git a/src/index.ts b/src/index.ts index 00f6e19..a033760 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,7 @@ export * from './Divider'; export * from './Drawer'; export * from './Modal'; export * from './notification'; +export * from './Radio'; // ~ antd export { @@ -45,6 +46,7 @@ export { ColorPicker, type ColorPickerProps, type ColProps, // @todo center style + type CountdownProps, DatePicker, type DatePickerProps, Dropdown, @@ -62,6 +64,7 @@ export { type FormListOperation, type FormProps, type FormRule, + type GlobalToken, Grid, Image, ImageProps, @@ -74,6 +77,7 @@ export { type LayoutProps, List, type ListProps, + type MappingAlgorithm, type MentionProps, Mentions, Menu, @@ -83,9 +87,86 @@ export { type MenuTheme, message, type MessageArgsProps, + Pagination, + type PaginationProps, + Popconfirm, + type PopconfirmProps, + Popover, + type PopoverProps, + Progress, + type ProgressProps, + QRCode, + type QRCodeProps, + type QRPropsCanvas, + type QRPropsSvg, + Rate, + type RateProps, + type RefSelectProps, + Result, + type ResultProps, + Row, + type RowProps, + Segmented, + type SegmentedProps, + Select, + type SelectProps, + Skeleton, + type SkeletonProps, + Slider, + type SliderSingleProps, Space, type SpaceProps, + Spin, + type SpinProps, + Statistic, + type StatisticProps, + type StepProps, + Steps, + type StepsProps, type SubMenuProps, + Switch, + type SwitchProps, + Table, + type TableColumnGroupType, + type TableColumnProps, + type TableColumnsType, + type TableColumnType, + type TablePaginationConfig, + type TableProps, + type TabPaneProps, + Tabs, + type TabsProps, + Tag, + type TagProps, + type TagType, + theme, + Timeline, + type TimelineItemProps, + type TimelineProps, + TimePicker, + type TimePickerProps, + type TimeRangePickerProps, + Tooltip, + type TooltipProps, + Tour, + type TourProps, + type TourStepProps, + Transfer, + type TransferProps, + Tree, + type TreeDataNode, + type TreeNodeProps, + type TreeProps, + TreeSelect, + type TreeSelectProps, + Typography, + type TypographyProps, + Upload, + type UploadFile, + type UploadProps, + version, + Watermark, + type WatermarkProps, } from 'antd'; // ~ @lobehub/ui