Skip to content

Commit

Permalink
Merge branch 'next' into alias-token
Browse files Browse the repository at this point in the history
  • Loading branch information
aojunhao123 authored Jan 16, 2025
2 parents afcf91a + 0b6d56c commit 94ce65e
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 10 deletions.
5 changes: 4 additions & 1 deletion components/config-provider/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import type { TreeSelectProps } from '../tree-select';
import type { RenderEmptyHandler } from './defaultRenderEmpty';
import type { StatisticProps } from '../statistic';
import type { RibbonProps } from '../badge/Ribbon';
import type { SegmentedProps } from '../segmented';
export const defaultPrefixCls = 'ant';
export const defaultIconPrefixCls = 'anticon';

Expand Down Expand Up @@ -201,6 +202,8 @@ export type PopconfirmConfig = Pick<

export type SliderConfig = ComponentStyleConfig & Pick<SliderProps, 'styles' | 'classNames'>;

export type SegmentedConfig = ComponentStyleConfig & Pick<SegmentedProps, 'classNames' | 'styles'>;

export type SpinConfig = ComponentStyleConfig & Pick<SpinProps, 'indicator'>;

export type StatisticConfig = ComponentStyleConfig & Pick<StatisticProps, 'classNames' | 'styles'>;
Expand Down Expand Up @@ -290,7 +293,7 @@ export interface ConfigConsumerProps {
typography?: ComponentStyleConfig;
skeleton?: ComponentStyleConfig;
spin?: SpinConfig;
segmented?: ComponentStyleConfig;
segmented?: SegmentedConfig;
steps?: ComponentStyleConfig;
statistic?: StatisticConfig;
image?: ImageConfig;
Expand Down
2 changes: 1 addition & 1 deletion components/config-provider/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ const {
| result | Set Result common props | { className?: string, style?: React.CSSProperties , classNames?: [ResultProps\["classNames"\]](/components/result#api), styles?: [ResultProps\["styles"\]](/components/result#api)} | - | 5.7.0, `classNames` and `styles`: 6.0.0 |
| ribbon | Set Ribbon common props | { className?: string, style?: React.CSSProperties, , classNames?: [RibbonProps\["classNames"\]](/components/badge#api), styles?: [RibbonProps\["styles"\]](/components/badge#api) } | - | 6.0.0 |
| skeleton | Set Skeleton common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| segmented | Set Segmented common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| segmented | Set Segmented common props | { className?: string, style?: React.CSSProperties, classNames?: [SegmentedProps\["classNames"\]](/components/segmented#api), styles?: [SegmentedProps\["styles"\]](/components/segmented#api) } | - | 5.7.0, `classNames` and `styles`: 6.0.0 |
| select | Set Select common props | { className?: string, showSearch?: boolean, style?: React.CSSProperties } | - | 5.7.0 |
| slider | Set Slider common props | { className?: string, style?: React.CSSProperties, classNames?: [SliderProps\["classNames"\]](/components/slider#api), styles?: [SliderProps\["styles"\]](/components/slider#api) } | - | 5.7.0, `classNames` and `styles`: 5.23.0 |
| switch | Set Switch common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
Expand Down
2 changes: 1 addition & 1 deletion components/config-provider/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const {
| result | 设置 Result 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [ResultProps\["classNames"\]](/components/result-cn#api), styles?: [ResultProps\["styles"\]](/components/result-cn#api) } | - | 5.7.0, `classNames``styles`: 6.0.0 |
| ribbon | 设置 Ribbon 组件的通用属性 | { className?: string, style?: React.CSSProperties, , classNames?: [RibbonProps\["classNames"\]](/components/badge-cn#api), styles?: [RibbonProps\["styles"\]](/components/badge-cn#api) } | - | 6.0.0 |
| skeleton | 设置 Skeleton 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| segmented | 设置 Segmented 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| segmented | 设置 Segmented 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [SegmentedProps\["classNames"\]](/components/segmented-cn#api), styles?: [SegmentedProps\["styles"\]](/components/segmented-cn#api) } | - | 5.7.0, `classNames``styles`: 6.0.0 |
| select | 设置 Select 组件的通用属性 | { className?: string, showSearch?: boolean, style?: React.CSSProperties } | - | 5.7.0 |
| slider | 设置 Slider 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [SliderProps\["classNames"\]](/components/slider-cn#api), styles?: [SliderProps\["styles"\]](/components/slider-cn#api) } | - | 5.7.0, `classNames``styles`: 5.23.0 |
| switch | 设置 Switch 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
Expand Down
40 changes: 40 additions & 0 deletions components/segmented/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -357,4 +357,44 @@ describe('Segmented', () => {
expect(el.name).toEqual(GROUP_NAME);
});
});
it('should apply custom styles to Segmented', () => {
const customClassNames = {
root: 'custom-root',
icon: 'custom-icon',
item: 'custom-item',
label: 'custom-label',
};

const customStyles = {
root: { color: 'red' },
icon: { backgroundColor: 'blue' },
item: { color: 'yellow' },
label: { backgroundColor: 'black' },
};

const { container } = render(
<Segmented
options={[{ label: 'Kanban', value: 'Kanban', icon: <AppstoreOutlined /> }]}
classNames={customClassNames}
styles={customStyles}
/>,
);

const rootElement = container.querySelector('.ant-segmented') as HTMLElement;
const iconElement = container.querySelector('.ant-segmented-item-icon') as HTMLElement;
const itemElement = container.querySelector('.ant-segmented-item') as HTMLElement;
const labelElement = container.querySelector('.ant-segmented-item-label') as HTMLElement;

// check classNames
expect(rootElement.classList).toContain('custom-root');
expect(iconElement.classList).toContain('custom-icon');
expect(itemElement.classList).toContain('custom-item');
expect(labelElement.classList).toContain('custom-label');

// check styles
expect(rootElement.style.color).toBe('red');
expect(iconElement.style.backgroundColor).toBe('blue');
expect(itemElement.style.color).toBe('yellow');
expect(labelElement.style.backgroundColor).toBe('black');
});
});
44 changes: 44 additions & 0 deletions components/segmented/demo/_semantic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
import { Segmented } from 'antd';

import SemanticPreview from '../../../.dumi/components/SemanticPreview';
import useLocale from '../../../.dumi/hooks/useLocale';

const locales = {
cn: {
root: '根元素',
item: '包裹的子组件',
icon: '图标元素',
label: '内容元素',
},
en: {
root: 'Root element',
item: 'Wrapped item element',
icon: 'Icon element',
label: 'Content element',
},
};

const App: React.FC = () => {
const [locale] = useLocale(locales);
return (
<SemanticPreview
semantics={[
{ name: 'root', desc: locale.root, version: '6.0.0' },
{ name: 'item', desc: locale.item, version: '6.0.0' },
{ name: 'label', desc: locale.label, version: '6.0.0' },
{ name: 'icon', desc: locale.icon, version: '6.0.0' },
]}
>
<Segmented
options={[
{ label: 'List', value: 'List', icon: <BarsOutlined /> },
{ label: 'Kanban', value: 'Kanban', icon: <AppstoreOutlined /> },
]}
/>
</SemanticPreview>
);
};

export default App;
4 changes: 4 additions & 0 deletions components/segmented/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ Common props ref:[Common props](/docs/react/common-props)
| disabled | Disabled state of segmented item | boolean | false | |
| className | The additional css class | string | - | |

## Semantic DOM

<code src="./demo/_semantic.tsx" simplify="true"></code>

## Design Token

<ComponentTokenTable component="Segmented"></ComponentTokenTable>
43 changes: 37 additions & 6 deletions components/segmented/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import type {
SegmentedProps as RCSegmentedProps,
SegmentedValue as RcSegmentedValue,
SegmentedRawOption,
} from 'rc-segmented';
import RcSegmented from 'rc-segmented';
} from '@rc-component/segmented';
import RcSegmented from '@rc-component/segmented';

import { ConfigContext } from '../config-provider';
import useSize from '../config-provider/hooks/useSize';
import type { SizeType } from '../config-provider/SizeContext';
import useStyle from './style';

export type { SegmentedValue } from 'rc-segmented';

export type { SegmentedValue } from '@rc-component/segmented';
export type SemanticName = 'root' | 'icon' | 'label' | 'item';
interface SegmentedLabeledOptionWithoutIcon<ValueType = RcSegmentedValue>
extends RcSegmentedLabeledOption<ValueType> {
label: RcSegmentedLabeledOption['label'];
Expand Down Expand Up @@ -49,6 +49,8 @@ export interface SegmentedProps<ValueType = RcSegmentedValue>
/** Option to control the display size */
size?: SizeType;
vertical?: boolean;
classNames?: Partial<Record<SemanticName, string>>;
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
}

const InternalSegmented = React.forwardRef<HTMLDivElement, SegmentedProps>((props, ref) => {
Expand All @@ -64,6 +66,8 @@ const InternalSegmented = React.forwardRef<HTMLDivElement, SegmentedProps>((prop
style,
vertical,
name = defaultName,
styles,
classNames: segmentedClassNames,
...restProps
} = props;

Expand All @@ -85,7 +89,19 @@ const InternalSegmented = React.forwardRef<HTMLDivElement, SegmentedProps>((prop
...restOption,
label: (
<>
<span className={`${prefixCls}-item-icon`}>{icon}</span>
<span
className={classNames(
`${prefixCls}-item-icon`,
segmented?.classNames?.icon,
segmentedClassNames?.icon,
)}
style={{
...segmented?.styles?.icon,
...styles?.icon,
}}
>
{icon}
</span>
{label && <span>{label}</span>}
</>
),
Expand All @@ -100,6 +116,8 @@ const InternalSegmented = React.forwardRef<HTMLDivElement, SegmentedProps>((prop
className,
rootClassName,
segmented?.className,
segmentedClassNames?.root,
segmented?.classNames?.root,
{
[`${prefixCls}-block`]: block,
[`${prefixCls}-sm`]: mergedSize === 'small',
Expand All @@ -110,14 +128,27 @@ const InternalSegmented = React.forwardRef<HTMLDivElement, SegmentedProps>((prop
cssVarCls,
);

const mergedStyle: React.CSSProperties = { ...segmented?.style, ...style };
const mergedStyle: React.CSSProperties = {
...segmented?.styles?.root,
...segmented?.style,
...styles?.root,
...style,
};

return wrapCSSVar(
<RcSegmented
{...restProps}
name={name}
className={cls}
style={mergedStyle}
classNames={{
label: classNames(segmentedClassNames?.label, segmented?.classNames?.label),
item: classNames(segmentedClassNames?.item, segmented?.classNames?.item),
}}
styles={{
item: { ...segmented?.styles?.item, ...styles?.item },
label: { ...segmented?.styles?.label, ...styles?.label },
}}
options={extendedOptions}
ref={ref}
prefixCls={prefixCls}
Expand Down
4 changes: 4 additions & 0 deletions components/segmented/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ demo:
| disabled | 分段项的禁用状态 | boolean | false | |
| className | 自定义类名 | string | - | |

## Semantic DOM

<code src="./demo/_semantic.tsx" simplify="true"></code>

## 主题变量(Design Token)

<ComponentTokenTable component="Segmented"></ComponentTokenTable>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
"@rc-component/color-picker": "~2.0.1",
"@rc-component/mutate-observer": "^1.1.0",
"@rc-component/qrcode": "~1.0.0",
"@rc-component/segmented": "~1.0.0",
"@rc-component/tooltip": "~1.0.0",
"@rc-component/tour": "~1.15.1",
"@rc-component/trigger": "^2.2.6",
Expand All @@ -140,7 +141,6 @@
"rc-progress": "~4.0.0",
"rc-rate": "~2.13.0",
"rc-resize-observer": "^1.4.3",
"rc-segmented": "~2.7.0",
"rc-select": "~14.16.5",
"rc-slider": "~11.1.8",
"rc-steps": "~6.0.1",
Expand Down

0 comments on commit 94ce65e

Please sign in to comment.