Skip to content

Commit

Permalink
feat: add Radio component
Browse files Browse the repository at this point in the history
  • Loading branch information
Jandiasnow committed Apr 11, 2024
1 parent 1e5a0cf commit dfd0cc7
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/Radio/demos/Playground.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<StoryBook levaStore={store}>
<Radio.Group {...control} options={options} />
</StoryBook>
);
};
37 changes: 37 additions & 0 deletions src/Radio/demos/index.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Space direction="vertical">
<Radio.Group defaultValue={options[0].value} options={options} />
<Radio.Group defaultValue={options[0].value} optionType="button" options={options} />
<Radio.Group
buttonStyle="solid"
defaultValue={options[0].value}
optionType="button"
options={options}
/>
<Radio.Group
buttonBorderRadius={15}
buttonGap={15}
buttonStyle="solid"
defaultValue={options[0].value}
optionType="button"
options={options}
/>
<Radio.Group
buttonBorderRadius={true}
buttonGap={true}
buttonStyle="solid"
defaultValue={options[0].value}
optionType="button"
options={options}
/>
</Space>
);
};
35 changes: 35 additions & 0 deletions src/Radio/index.md
Original file line number Diff line number Diff line change
@@ -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 <Radio.Group options={options} defaultValue={options[0].value} />;
};
```

<code src="./demos/index.tsx" center></code>

## Playground

<code src="./demos/Playground.tsx" nopadding></code>

## APIs

<API></API>
34 changes: 34 additions & 0 deletions src/Radio/index.tsx
Original file line number Diff line number Diff line change
@@ -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<RadioProps & React.RefAttributes<RadioRef>> & {
Group: typeof Group;
Button: typeof AntdRadio.Button;
};
export const Radio = cloneDeep(AntdRadio) as RadioType;

const Group: React.FC<RadioGroupProps> = props => {
const { className, ...otherProps } = props;

const { styles, cx } = useStyles(otherProps);

return <AntdRadio.Group {...otherProps} className={cx(styles.custom, className)} />;
};
Radio.Group = Group;

Radio.Button = AntdRadio.Button;

export default Radio;

export { type RadioChangeEvent, type RadioProps } from 'antd';
65 changes: 65 additions & 0 deletions src/Radio/style.ts
Original file line number Diff line number Diff line change
@@ -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' }
);
81 changes: 81 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export * from './Divider';
export * from './Drawer';
export * from './Modal';
export * from './notification';
export * from './Radio';

// ~ antd
export {
Expand Down Expand Up @@ -45,6 +46,7 @@ export {
ColorPicker,
type ColorPickerProps,
type ColProps, // @todo center style
type CountdownProps,
DatePicker,
type DatePickerProps,
Dropdown,
Expand All @@ -62,6 +64,7 @@ export {
type FormListOperation,
type FormProps,
type FormRule,
type GlobalToken,
Grid,
Image,
ImageProps,
Expand All @@ -74,6 +77,7 @@ export {
type LayoutProps,
List,
type ListProps,
type MappingAlgorithm,
type MentionProps,
Mentions,
Menu,
Expand All @@ -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
Expand Down

0 comments on commit dfd0cc7

Please sign in to comment.