diff --git a/src/Radio/demos/Playground.tsx b/src/Radio/demos/Playground.tsx
new file mode 100644
index 0000000..5e89660
--- /dev/null
+++ b/src/Radio/demos/Playground.tsx
@@ -0,0 +1,36 @@
+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',
+ },
+ segmented: false,
+ size: {
+ options: ['large', 'middle', 'small'],
+ value: 'middle',
+ },
+ },
+ { store }
+ );
+ return (
+
+
+
+ );
+};
diff --git a/src/Radio/demos/Segmented.tsx b/src/Radio/demos/Segmented.tsx
new file mode 100644
index 0000000..ecce9e2
--- /dev/null
+++ b/src/Radio/demos/Segmented.tsx
@@ -0,0 +1,47 @@
+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/demos/index.tsx b/src/Radio/demos/index.tsx
new file mode 100644
index 0000000..7f6cbec
--- /dev/null
+++ b/src/Radio/demos/index.tsx
@@ -0,0 +1,21 @@
+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..88f5bf5
--- /dev/null
+++ b/src/Radio/index.md
@@ -0,0 +1,41 @@
+---
+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 ;
+};
+```
+
+
+
+### Segmented usage
+
+**Set the button style is similar to the Segmented component, Generally used for in-page navigation**
+
+
+
+## Playground
+
+
+
+## APIs
+
+
diff --git a/src/Radio/index.tsx b/src/Radio/index.tsx
new file mode 100644
index 0000000..e3d0529
--- /dev/null
+++ b/src/Radio/index.tsx
@@ -0,0 +1,55 @@
+import { Radio as AntdRadio, type RadioGroupProps as AntdRadioGroupProps, RadioProps } from 'antd';
+import AntdGroup from 'antd/es/radio/group';
+import type { RadioRef } from 'antd/es/radio/interface';
+import React from 'react';
+
+import { useStyles } from './style';
+
+export interface CustomRadioProps {
+ /**
+ * @description Set the button style is similar to the Segmented component
+ * @default 'false'
+ */
+ segmented?:
+ | {
+ /**
+ * @description Set the spacing between buttons
+ * @default 'true'
+ */
+ gap?: 'small' | 'middle' | 'large' | number | boolean;
+ /**
+ * @description Set border-radius of buttons
+ * @default 'true'
+ */
+ borderRadius?: number | boolean;
+ /**
+ * @description Sets whether the button's border is displayed
+ * @default 'false'
+ */
+ bordered?: boolean;
+ }
+ | boolean;
+}
+
+export interface RadioGroupProps extends AntdRadioGroupProps, CustomRadioProps {}
+
+type RadioType = React.ForwardRefExoticComponent> & {
+ Group: typeof Group;
+ Button: typeof AntdRadio.Button;
+};
+export const Radio = AntdRadio as RadioType;
+
+const Group: React.FC = props => {
+ const { className, ...otherProps } = props;
+ if (otherProps.segmented) {
+ otherProps.optionType = 'button';
+ }
+ const { styles, cx } = useStyles(otherProps);
+
+ return ;
+};
+Radio.Group = Group;
+
+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..e018e68
--- /dev/null
+++ b/src/Radio/style.ts
@@ -0,0 +1,95 @@
+import { createStyles } from 'antd-style';
+
+import { RadioGroupProps } from './index';
+
+export const useStyles = createStyles(
+ ({ css, token, prefixCls }, { size, segmented }: RadioGroupProps) => {
+ const gap = (() => {
+ if (!segmented) {
+ return 0;
+ }
+ if (segmented !== true) {
+ return segmented.gap;
+ }
+ return true;
+ })();
+
+ const borderRadius = (() => {
+ if (!segmented) {
+ return;
+ }
+ if (segmented !== true) {
+ return segmented.borderRadius;
+ }
+ return true;
+ })();
+
+ const getGapSize = () => {
+ const gapSizeMap = {
+ small: token.sizeSM,
+ middle: token.size,
+ large: token.sizeLG,
+ };
+ if (typeof gap === 'string') {
+ return gapSizeMap[gap];
+ }
+ if (gap === true) {
+ return size ? gapSizeMap[size] : gapSizeMap['middle'];
+ }
+ if (!gap) {
+ return 0;
+ }
+ return gap;
+ };
+
+ const getBorderRadius = () => {
+ const borderRadiusSizeMap = {
+ small: token.controlHeightSM,
+ middle: token.controlHeight,
+ large: token.controlHeightLG,
+ };
+ if (borderRadius === true) {
+ return size ? borderRadiusSizeMap[size] : borderRadiusSizeMap['middle'];
+ }
+ if (borderRadius || borderRadius === 0) {
+ return borderRadius;
+ }
+ };
+ const borderRadiusStyle =
+ getBorderRadius() &&
+ css`
+ label {
+ border-inline-start-width: 1px !important;
+ border-radius: ${getBorderRadius()}px !important;
+ }
+ label::before {
+ display: none !important;
+ }
+ `;
+ const gapStyle = css`
+ label {
+ margin-right: ${getGapSize()}px !important;
+ }
+ label:last-child {
+ margin-right: 0 !important;
+ }
+ `;
+ const noBorderd = segmented === true || (segmented && !segmented.bordered);
+ return {
+ custom: css`
+ ${borderRadiusStyle}
+ ${gapStyle}
+ ${noBorderd &&
+ css`
+ .${prefixCls}-radio-button-wrapper {
+ border: none !important;
+ }
+ .${prefixCls}-radio-button-wrapper-checked {
+ border: 1px solid ${token.colorPrimary} !important;
+ }
+ `}
+ `,
+ };
+ },
+ { 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