feat: Segmented value type support generics (#47091)

* feat: Segmented value type support generics

* fix: type

* docs: update demo

* test: update snapshots

* Update components/segmented/demo/basic.tsx

Signed-off-by: afc163 <afc163@gmail.com>

* Revert "test: update snapshots"

This reverts commit 6f95cd674d73564ba4fbfa4865f94eba14e741d7.

---------

Signed-off-by: afc163 <afc163@gmail.com>
Co-authored-by: afc163 <afc163@gmail.com>
This commit is contained in:
章鱼怪 2024-01-27 20:19:10 +08:00 committed by GitHub
parent a62d7ec3db
commit 7e4bca346d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 10 deletions

View File

@ -2,7 +2,12 @@ import React from 'react';
import { Segmented } from 'antd';
const Demo: React.FC = () => (
<Segmented options={['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly']} />
<Segmented<string>
options={['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly']}
onChange={(value) => {
console.log(value); // string
}}
/>
);
export default Demo;

View File

@ -2,6 +2,7 @@ import classNames from 'classnames';
import type {
SegmentedLabeledOption as RcSegmentedLabeledOption,
SegmentedProps as RCSegmentedProps,
SegmentedValue as RcSegmentedValue,
SegmentedRawOption,
} from 'rc-segmented';
import RcSegmented from 'rc-segmented';
@ -13,11 +14,13 @@ import useStyle from './style';
export type { SegmentedValue } from 'rc-segmented';
interface SegmentedLabeledOptionWithoutIcon extends RcSegmentedLabeledOption {
interface SegmentedLabeledOptionWithoutIcon<ValueType = RcSegmentedValue>
extends RcSegmentedLabeledOption<ValueType> {
label: RcSegmentedLabeledOption['label'];
}
interface SegmentedLabeledOptionWithIcon extends Omit<RcSegmentedLabeledOption, 'label'> {
interface SegmentedLabeledOptionWithIcon<ValueType = RcSegmentedValue>
extends Omit<RcSegmentedLabeledOption<ValueType>, 'label'> {
label?: RcSegmentedLabeledOption['label'];
/** Set icon for Segmented item */
icon: React.ReactNode;
@ -29,20 +32,23 @@ function isSegmentedLabeledOptionWithIcon(
return typeof option === 'object' && !!(option as SegmentedLabeledOptionWithIcon)?.icon;
}
export type SegmentedLabeledOption =
| SegmentedLabeledOptionWithIcon
| SegmentedLabeledOptionWithoutIcon;
export type SegmentedLabeledOption<ValueType = RcSegmentedValue> =
| SegmentedLabeledOptionWithIcon<ValueType>
| SegmentedLabeledOptionWithoutIcon<ValueType>;
export interface SegmentedProps extends Omit<RCSegmentedProps, 'size' | 'options'> {
export type SegmentedOptions<T = SegmentedRawOption> = (T | SegmentedLabeledOption<T>)[];
export interface SegmentedProps<ValueType = RcSegmentedValue>
extends Omit<RCSegmentedProps<ValueType>, 'size' | 'options'> {
rootClassName?: string;
options: (SegmentedRawOption | SegmentedLabeledOption)[];
options: SegmentedOptions<ValueType>;
/** Option to fit width to its parent's width */
block?: boolean;
/** Option to control the display size */
size?: SizeType;
}
const Segmented = React.forwardRef<HTMLDivElement, SegmentedProps>((props, ref) => {
const InternalSegmented = React.forwardRef<HTMLDivElement, SegmentedProps>((props, ref) => {
const {
prefixCls: customizePrefixCls,
className,
@ -111,6 +117,11 @@ const Segmented = React.forwardRef<HTMLDivElement, SegmentedProps>((props, ref)
);
});
const Segmented = InternalSegmented as (<ValueType>(
props: SegmentedProps<ValueType> & React.RefAttributes<HTMLDivElement>,
) => ReturnType<typeof InternalSegmented>) &
Pick<React.FC, 'displayName'>;
if (process.env.NODE_ENV !== 'production') {
Segmented.displayName = 'Segmented';
}

View File

@ -148,7 +148,7 @@
"rc-progress": "~3.5.1",
"rc-rate": "~2.12.0",
"rc-resize-observer": "^1.4.0",
"rc-segmented": "~2.2.2",
"rc-segmented": "~2.3.0",
"rc-select": "~14.11.0",
"rc-slider": "~10.5.0",
"rc-steps": "~6.0.1",