diff --git a/components/segmented/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/segmented/__tests__/__snapshots__/demo-extend.test.ts.snap index d9d5a2f1180d..76c58f48c2f6 100644 --- a/components/segmented/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/segmented/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -644,6 +644,84 @@ Array [ ] `; +exports[`renders ./components/segmented/demo/icon-only.md extend context correctly 1`] = ` +
+ + +
+`; + exports[`renders ./components/segmented/demo/size.md extend context correctly 1`] = ` Array [
+ + +
+`; + exports[`renders ./components/segmented/demo/size.md correctly 1`] = ` Array [
`; +exports[`Segmented render with icons 1`] = ` +
+ + +
+`; + exports[`Segmented rtl render component should be rendered correctly in RTL direction 1`] = `
{ it('render segmented with string options', () => { const handleValueChange = jest.fn(); const wrapper = mount( - , + , ); expect(wrapper.render()).toMatchSnapshot(); @@ -356,4 +355,25 @@ describe('Segmented', () => { expect(wrapper.find(`.${prefixCls}`).at(0).hasClass(`${prefixCls}-lg`)).toBeTruthy(); }); + + it('render with icons', () => { + const wrapper = mount( + , + }, + { + value: 'Kanban', + label: 'KanbanYes', + icon: , + }, + ]} + />, + ); + expect(wrapper.render()).toMatchSnapshot(); + expect(wrapper.find(`span.${prefixCls}-item-icon`).length).toBe(2); + expect(wrapper.find(`div.${prefixCls}-item-label`).at(1).contains('KanbanYes')).toBeTruthy(); + }); }); diff --git a/components/segmented/demo/block.md b/components/segmented/demo/block.md index ab2bdced3e29..16335a173ac3 100644 --- a/components/segmented/demo/block.md +++ b/components/segmented/demo/block.md @@ -1,5 +1,5 @@ --- -order: 10 +order: 1 title: zh-CN: Block 分段选择器 en-US: Block Segmented diff --git a/components/segmented/demo/controlled.md b/components/segmented/demo/controlled.md index 48092ecd193f..0f051d366e23 100644 --- a/components/segmented/demo/controlled.md +++ b/components/segmented/demo/controlled.md @@ -1,5 +1,5 @@ --- -order: 0 +order: 3 title: zh-CN: 受控模式 en-US: Controlled mode diff --git a/components/segmented/demo/custom.md b/components/segmented/demo/custom.md index e88b41d1c876..21c488008013 100644 --- a/components/segmented/demo/custom.md +++ b/components/segmented/demo/custom.md @@ -1,5 +1,5 @@ --- -order: 1 +order: 4 title: zh-CN: 自定义渲染 en-US: Custom Render diff --git a/components/segmented/demo/disabled.md b/components/segmented/demo/disabled.md index df9699a2794c..cc0875bd4e91 100644 --- a/components/segmented/demo/disabled.md +++ b/components/segmented/demo/disabled.md @@ -1,5 +1,5 @@ --- -order: 0 +order: 2 title: zh-CN: 不可用 en-US: Basic diff --git a/components/segmented/demo/dynamic.md b/components/segmented/demo/dynamic.md index 47ecdf217363..f03475e036d9 100644 --- a/components/segmented/demo/dynamic.md +++ b/components/segmented/demo/dynamic.md @@ -1,5 +1,5 @@ --- -order: 0 +order: 5 title: zh-CN: 动态数据 en-US: Dynamic diff --git a/components/segmented/demo/icon-only.md b/components/segmented/demo/icon-only.md new file mode 100644 index 000000000000..62cd10e0c939 --- /dev/null +++ b/components/segmented/demo/icon-only.md @@ -0,0 +1,34 @@ +--- +order: 8 +title: + zh-CN: 只设置图标 + en-US: With Icon only +--- + +## zh-CN + +在 Segmented Item 选项中只设置 Icon。 + +## en-US + +Set `icon` without `label` for Segmented Item. + +```jsx +import { Segmented } from 'antd'; +import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons'; + +export default () => ( + , + }, + { + value: 'Kanban', + icon: , + }, + ]} + /> +); +``` diff --git a/components/segmented/demo/size.md b/components/segmented/demo/size.md index 92fe41dfc0a5..d9fa0cb76094 100644 --- a/components/segmented/demo/size.md +++ b/components/segmented/demo/size.md @@ -1,5 +1,5 @@ --- -order: 1 +order: 6 title: zh-CN: 三种大小 en-US: Three sizes of Segmented diff --git a/components/segmented/demo/with-icon.md b/components/segmented/demo/with-icon.md index 7d4855c3e865..20214c7e223d 100644 --- a/components/segmented/demo/with-icon.md +++ b/components/segmented/demo/with-icon.md @@ -1,5 +1,5 @@ --- -order: 0 +order: 7 title: zh-CN: 设置图标 en-US: With Icon diff --git a/components/segmented/index.tsx b/components/segmented/index.tsx index da17860bcb71..5ea98b9cc75d 100644 --- a/components/segmented/index.tsx +++ b/components/segmented/index.tsx @@ -12,12 +12,27 @@ import SizeContext, { SizeType } from '../config-provider/SizeContext'; export type { SegmentedValue } from 'rc-segmented'; -export interface SegmentedLabeledOption extends RcSegmentedLabeledOption { +interface SegmentedLabeledOptionWithoutIcon extends RcSegmentedLabeledOption { + label: RcSegmentedLabeledOption['label']; +} + +interface SegmentedLabeledOptionWithIcon extends Omit { + label?: RcSegmentedLabeledOption['label']; /** Set icon for Segmented item */ - icon?: React.ReactNode; + icon: React.ReactNode; } -export interface SegmentedProps extends Omit { +function isSegmentedLabeledOptionWithIcon( + option: SegmentedRawOption | SegmentedLabeledOptionWithIcon | SegmentedLabeledOptionWithoutIcon, +): option is SegmentedLabeledOptionWithIcon { + return typeof option === 'object' && !!(option as SegmentedLabeledOptionWithIcon)?.icon; +} + +export type SegmentedLabeledOption = + | SegmentedLabeledOptionWithIcon + | SegmentedLabeledOptionWithoutIcon; + +export interface SegmentedProps extends Omit { options: (SegmentedRawOption | SegmentedLabeledOption)[]; /** Option to fit width to its parent's width */ block?: boolean; @@ -46,14 +61,14 @@ const Segmented = React.forwardRef((props, ref) const extendedOptions = React.useMemo( () => options.map(option => { - if (typeof option === 'object' && option?.icon) { + if (isSegmentedLabeledOptionWithIcon(option)) { const { icon, label, ...restOption } = option; return { ...restOption, label: ( <> {icon} - {label} + {label && {label}} ), }; diff --git a/components/segmented/style/index.less b/components/segmented/style/index.less index c3d83b726afc..06b393613552 100644 --- a/components/segmented/style/index.less +++ b/components/segmented/style/index.less @@ -61,8 +61,8 @@ } // syntactic sugar to add `icon` for Segmented Item - &-icon { - margin-right: 6px; + &-icon + * { + margin-left: 6px; } &-input {