mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-18 14:13:37 +08:00
refactor: cssinjs for segmented (#35134)
* refactor: cssinjs for segmented * fix: disabled styles * feat: sync code from master
This commit is contained in:
parent
89aac84e65
commit
5d66b0ba3f
@ -7,6 +7,7 @@ import type { ComponentToken as EmptyComponentToken } from '../../empty/style';
|
||||
import type { ComponentToken as CascaderComponentToken } from '../../cascader/style';
|
||||
import type { ComponentToken as InputNumberComponentToken } from '../../input-number/style';
|
||||
import type { ComponentToken as MentionsComponentToken } from '../../mentions/style';
|
||||
import type { ComponentToken as SegmentedComponentToken } from '../../segmented/style';
|
||||
import type { ComponentToken as SelectComponentToken } from '../../select/style';
|
||||
import type { ComponentToken as SliderComponentToken } from '../../slider/style';
|
||||
import type { ComponentToken as TypographyComponentToken } from '../../typography/style';
|
||||
@ -79,6 +80,7 @@ export interface OverrideToken {
|
||||
Popover?: {};
|
||||
Rate?: {};
|
||||
Result?: {};
|
||||
Segmented?: SegmentedComponentToken;
|
||||
Select?: SelectComponentToken;
|
||||
Skeleton?: {};
|
||||
Slider?: SliderComponentToken;
|
||||
@ -326,6 +328,7 @@ export interface AliasToken extends Omit<DerivativeToken, OmitDerivativeKey> {
|
||||
|
||||
controlPaddingHorizontal: number;
|
||||
controlPaddingHorizontalSM: number;
|
||||
|
||||
paddingSM: number;
|
||||
paddingXS: number;
|
||||
paddingXXS: number;
|
||||
|
@ -11,6 +11,8 @@ import { ConfigContext } from '../config-provider';
|
||||
import type { SizeType } from '../config-provider/SizeContext';
|
||||
import SizeContext from '../config-provider/SizeContext';
|
||||
|
||||
import useStyle from './style';
|
||||
|
||||
export type { SegmentedValue } from 'rc-segmented';
|
||||
|
||||
interface SegmentedLabeledOptionWithoutIcon extends RcSegmentedLabeledOption {
|
||||
@ -53,6 +55,8 @@ const Segmented = React.forwardRef<HTMLDivElement, SegmentedProps>((props, ref)
|
||||
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls('segmented', customizePrefixCls);
|
||||
// Style
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
|
||||
// ===================== Size =====================
|
||||
const size = React.useContext(SizeContext);
|
||||
@ -79,19 +83,23 @@ const Segmented = React.forwardRef<HTMLDivElement, SegmentedProps>((props, ref)
|
||||
[options, prefixCls],
|
||||
);
|
||||
|
||||
return (
|
||||
return wrapSSR(
|
||||
<RcSegmented
|
||||
{...restProps}
|
||||
className={classNames(className, {
|
||||
[`${prefixCls}-block`]: block,
|
||||
[`${prefixCls}-sm`]: mergedSize === 'small',
|
||||
[`${prefixCls}-lg`]: mergedSize === 'large',
|
||||
})}
|
||||
className={classNames(
|
||||
className,
|
||||
{
|
||||
[`${prefixCls}-block`]: block,
|
||||
[`${prefixCls}-sm`]: mergedSize === 'small',
|
||||
[`${prefixCls}-lg`]: mergedSize === 'large',
|
||||
},
|
||||
hashId,
|
||||
)}
|
||||
options={extendedOptions}
|
||||
ref={ref}
|
||||
prefixCls={prefixCls}
|
||||
direction={direction}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -1,2 +1,215 @@
|
||||
import '../../style/index.less';
|
||||
import './index.less';
|
||||
// deps-lint-skip-all
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
import { TinyColor } from '@ctrl/tinycolor';
|
||||
import type { GenerateStyle, FullToken } from '../../_util/theme';
|
||||
import { resetComponent, genComponentStyleHook, mergeToken } from '../../_util/theme';
|
||||
|
||||
export interface ComponentToken {}
|
||||
|
||||
interface SegmentedToken extends FullToken<'Segmented'> {
|
||||
segmentedBg: string;
|
||||
segmentedHoverBg: string;
|
||||
segmentedSelectedBg: string;
|
||||
segmentedLabelColor: string;
|
||||
segmentedLabelHoverColor: string;
|
||||
segmentedPaddingVertical: number;
|
||||
segmentedPaddingVerticalLG: number;
|
||||
segmentedPaddingVerticalSM: number;
|
||||
segmentedPaddingHorizontal: number;
|
||||
segmentedPaddingHorizontalSM: number;
|
||||
segmentedContainerPadding: number;
|
||||
}
|
||||
|
||||
// ============================== Mixins ==============================
|
||||
function segmentedDisabledItem(cls: string, token: SegmentedToken): CSSObject {
|
||||
return {
|
||||
[`${cls}, ${cls}:hover, ${cls}:focus`]: {
|
||||
color: token.colorTextDisabled,
|
||||
cursor: 'not-allowed',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME: hard code
|
||||
const segmentedSelectedItemBoxShadow = [
|
||||
`0 2px 8px -2px ${new TinyColor('#000').setAlpha(0.05).toRgbString()}`,
|
||||
`0 1px 4px -1px ${new TinyColor('#000').setAlpha(0.07).toRgbString()}`,
|
||||
`0 0 1px 0 ${new TinyColor('#000').setAlpha(0.08).toRgbString()}`,
|
||||
].join(',');
|
||||
|
||||
function getSegmentedItemSelectedStyle(token: SegmentedToken): CSSObject {
|
||||
return {
|
||||
backgroundColor: token.segmentedSelectedBg,
|
||||
borderRadius: token.controlRadius,
|
||||
boxShadow: segmentedSelectedItemBoxShadow,
|
||||
};
|
||||
}
|
||||
|
||||
const segmentedTextEllipsisCss: CSSObject = {
|
||||
overflow: 'hidden',
|
||||
// handle text ellipsis
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
wordBreak: 'keep-all',
|
||||
};
|
||||
|
||||
// ============================== Styles ==============================
|
||||
const genSegmentedStyle: GenerateStyle<SegmentedToken> = (token: SegmentedToken) => {
|
||||
const { componentCls } = token;
|
||||
|
||||
return {
|
||||
[componentCls]: {
|
||||
...resetComponent(token),
|
||||
|
||||
display: 'inline-block',
|
||||
padding: token.segmentedContainerPadding,
|
||||
color: token.segmentedLabelColor,
|
||||
backgroundColor: token.segmentedBg,
|
||||
borderRadius: token.radiusBase,
|
||||
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
||||
|
||||
'&-group': {
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
alignItems: 'stretch',
|
||||
justifyItems: 'flex-start',
|
||||
width: '100%',
|
||||
},
|
||||
|
||||
// RTL styles
|
||||
'&&-rtl': {
|
||||
direction: 'rtl',
|
||||
},
|
||||
|
||||
// hover/focus styles
|
||||
[`&:not(${componentCls}-disabled)`]: {
|
||||
'&:hover, &:focus': {
|
||||
backgroundColor: token.segmentedHoverBg,
|
||||
},
|
||||
},
|
||||
|
||||
// block styles
|
||||
'&&-block': {
|
||||
display: 'flex',
|
||||
},
|
||||
|
||||
'&&-block &-item': {
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
},
|
||||
|
||||
// item styles
|
||||
[`${componentCls}-item`]: {
|
||||
position: 'relative',
|
||||
textAlign: 'center',
|
||||
cursor: 'pointer',
|
||||
transition: `color ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
||||
|
||||
'&-selected': {
|
||||
...getSegmentedItemSelectedStyle(token),
|
||||
color: token.segmentedLabelHoverColor,
|
||||
},
|
||||
|
||||
'&:hover, &:focus': {
|
||||
color: token.segmentedLabelHoverColor,
|
||||
},
|
||||
|
||||
'&-label': {
|
||||
// FIXME: hard code
|
||||
minHeight: token.controlHeight - token.segmentedContainerPadding * 2,
|
||||
lineHeight: `${token.controlHeight - token.segmentedContainerPadding * 2}px`,
|
||||
padding: `0 ${token.segmentedPaddingHorizontal}px`,
|
||||
...segmentedTextEllipsisCss,
|
||||
},
|
||||
|
||||
// syntactic sugar to add `icon` for Segmented Item
|
||||
'&-icon + *': {
|
||||
// FIXME: hard code
|
||||
marginInlineEnd: token.marginSM / 2,
|
||||
},
|
||||
|
||||
'&-input': {
|
||||
position: 'absolute',
|
||||
insetBlockStart: 0,
|
||||
insetInlineStart: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
opacity: 0,
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
},
|
||||
|
||||
// size styles
|
||||
[`&&-lg ${componentCls}-item-label`]: {
|
||||
// FIXME: hard code
|
||||
minHeight: token.controlHeightLG - token.segmentedContainerPadding * 2,
|
||||
lineHeight: `${token.controlHeightLG - token.segmentedContainerPadding * 2}px`,
|
||||
padding: `0 ${token.segmentedPaddingHorizontal}px`,
|
||||
fontSize: token.fontSizeLG,
|
||||
},
|
||||
|
||||
[`&&-sm ${componentCls}-item-label`]: {
|
||||
// FIXME: hard code
|
||||
minHeight: token.controlHeightSM - token.segmentedContainerPadding * 2,
|
||||
lineHeight: `${token.controlHeightSM - token.segmentedContainerPadding * 2}px`,
|
||||
padding: `0 ${token.segmentedPaddingHorizontalSM}px`,
|
||||
},
|
||||
|
||||
// disabled styles
|
||||
...segmentedDisabledItem(`&-disabled ${componentCls}-item`, token),
|
||||
...segmentedDisabledItem(`${componentCls}-item-disabled`, token),
|
||||
|
||||
// thumb styles
|
||||
[`${componentCls}-thumb`]: {
|
||||
...getSegmentedItemSelectedStyle(token),
|
||||
|
||||
position: 'absolute',
|
||||
insetBlockStart: 0,
|
||||
insetInlineStart: 0,
|
||||
width: 0,
|
||||
height: '100%',
|
||||
padding: `${token.paddingXXS}px 0`,
|
||||
},
|
||||
|
||||
// transition effect when `appear-active`
|
||||
[`${componentCls}-thumb-motion-appear-active`]: {
|
||||
transition: `transform ${token.motionDurationSlow} ${token.motionEaseInOut}, width ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
||||
willChange: 'transform, width',
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
export default genComponentStyleHook('Segmented', token => {
|
||||
const segmentedToken = mergeToken<SegmentedToken>(token, {
|
||||
// FIXME: hard code
|
||||
segmentedBg: new TinyColor('#000').setAlpha(0.04).toRgbString(),
|
||||
// FIXME: hard code
|
||||
segmentedHoverBg: new TinyColor('#000').setAlpha(0.06).toRgbString(),
|
||||
// FIXME: hard code
|
||||
segmentedSelectedBg: '#fff',
|
||||
// FIXME: hard code
|
||||
segmentedLabelColor: new TinyColor('#000').setAlpha(0.65).toRgbString(),
|
||||
// FIXME: hard code
|
||||
segmentedLabelHoverColor: '#262626',
|
||||
segmentedPaddingVertical: Math.max(
|
||||
Math.round(((token.controlHeight - token.fontSize * token.lineHeight) / 2) * 10) / 10 -
|
||||
token.controlLineWidth,
|
||||
3,
|
||||
),
|
||||
segmentedPaddingVerticalLG:
|
||||
Math.ceil(((token.controlHeightLG - token.fontSizeLG * token.lineHeight) / 2) * 10) / 10 -
|
||||
token.controlLineWidth,
|
||||
segmentedPaddingVerticalSM: Math.max(
|
||||
Math.round(((token.controlHeightSM - token.fontSize * token.lineHeight) / 2) * 10) / 10 -
|
||||
token.controlLineWidth,
|
||||
0,
|
||||
),
|
||||
segmentedPaddingHorizontal: token.controlPaddingHorizontal - token.controlLineWidth,
|
||||
segmentedPaddingHorizontalSM: token.controlPaddingHorizontalSM - token.controlLineWidth,
|
||||
// FIXME: hard code
|
||||
segmentedContainerPadding: token.paddingXXS / 2,
|
||||
});
|
||||
return [genSegmentedStyle(segmentedToken)];
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user