From dfd0cc7e1ed919e469ef8c10be06960d7df48361 Mon Sep 17 00:00:00 2001
From: Jandiasnow <88074479@qq.com>
Date: Thu, 11 Apr 2024 18:03:18 +0800
Subject: [PATCH] feat: add Radio component
---
src/Radio/demos/Playground.tsx | 37 ++++++++++++++++
src/Radio/demos/index.tsx | 37 ++++++++++++++++
src/Radio/index.md | 35 +++++++++++++++
src/Radio/index.tsx | 34 ++++++++++++++
src/Radio/style.ts | 65 +++++++++++++++++++++++++++
src/index.ts | 81 ++++++++++++++++++++++++++++++++++
6 files changed, 289 insertions(+)
create mode 100644 src/Radio/demos/Playground.tsx
create mode 100644 src/Radio/demos/index.tsx
create mode 100644 src/Radio/index.md
create mode 100644 src/Radio/index.tsx
create mode 100644 src/Radio/style.ts
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