2022-05-11 19:35:00 +08:00
|
|
|
// deps-lint-skip-all
|
|
|
|
import type { CSSObject } from '@ant-design/cssinjs';
|
|
|
|
import { TinyColor } from '@ctrl/tinycolor';
|
2022-05-26 09:14:09 +08:00
|
|
|
import type { FullToken, GenerateStyle } from '../../_util/theme';
|
|
|
|
import { genComponentStyleHook, mergeToken, resetComponent } from '../../_util/theme';
|
2022-05-11 19:35:00 +08:00
|
|
|
|
2022-06-17 18:47:47 +08:00
|
|
|
export interface ComponentToken {
|
|
|
|
// FIXME: need to be removed
|
|
|
|
bgColor: string;
|
|
|
|
bgColorHover: string;
|
|
|
|
bgColorSelected: string;
|
|
|
|
labelColor: string;
|
|
|
|
labelColorHover: string;
|
|
|
|
}
|
2022-05-11 19:35:00 +08:00
|
|
|
|
|
|
|
interface SegmentedToken extends FullToken<'Segmented'> {
|
|
|
|
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',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function getSegmentedItemSelectedStyle(token: SegmentedToken): CSSObject {
|
|
|
|
return {
|
2022-06-17 18:47:47 +08:00
|
|
|
backgroundColor: token.bgColorSelected,
|
2022-05-11 19:35:00 +08:00
|
|
|
borderRadius: token.controlRadius,
|
2022-06-24 10:45:29 +08:00
|
|
|
boxShadow: token.boxShadowSegmentedSelectedItem,
|
2022-05-11 19:35:00 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
2022-06-17 18:47:47 +08:00
|
|
|
color: token.labelColor,
|
|
|
|
backgroundColor: token.bgColor,
|
2022-05-11 19:35:00 +08:00
|
|
|
borderRadius: token.radiusBase,
|
|
|
|
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
|
|
|
|
2022-05-26 09:14:09 +08:00
|
|
|
[`${componentCls}-group`]: {
|
2022-05-11 19:35:00 +08:00
|
|
|
position: 'relative',
|
|
|
|
display: 'flex',
|
|
|
|
alignItems: 'stretch',
|
|
|
|
justifyItems: 'flex-start',
|
|
|
|
width: '100%',
|
|
|
|
},
|
|
|
|
|
|
|
|
// RTL styles
|
|
|
|
'&&-rtl': {
|
|
|
|
direction: 'rtl',
|
|
|
|
},
|
|
|
|
|
|
|
|
// hover/focus styles
|
|
|
|
[`&:not(${componentCls}-disabled)`]: {
|
|
|
|
'&:hover, &:focus': {
|
2022-06-17 18:47:47 +08:00
|
|
|
backgroundColor: token.bgColorHover,
|
2022-05-11 19:35:00 +08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
// block styles
|
|
|
|
'&&-block': {
|
|
|
|
display: 'flex',
|
|
|
|
},
|
|
|
|
|
2022-05-26 09:14:09 +08:00
|
|
|
[`&&-block ${componentCls}-item`]: {
|
2022-05-11 19:35:00 +08:00
|
|
|
flex: 1,
|
|
|
|
minWidth: 0,
|
|
|
|
},
|
|
|
|
|
|
|
|
// item styles
|
|
|
|
[`${componentCls}-item`]: {
|
|
|
|
position: 'relative',
|
|
|
|
textAlign: 'center',
|
|
|
|
cursor: 'pointer',
|
|
|
|
transition: `color ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
|
|
|
|
|
|
|
'&-selected': {
|
|
|
|
...getSegmentedItemSelectedStyle(token),
|
2022-06-17 18:47:47 +08:00
|
|
|
color: token.labelColorHover,
|
2022-05-11 19:35:00 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
'&:hover, &:focus': {
|
2022-06-17 18:47:47 +08:00
|
|
|
color: token.labelColorHover,
|
2022-05-11 19:35:00 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
'&-label': {
|
|
|
|
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 + *': {
|
|
|
|
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`]: {
|
|
|
|
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`]: {
|
|
|
|
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 ==============================
|
2022-06-17 18:47:47 +08:00
|
|
|
export default genComponentStyleHook(
|
|
|
|
'Segmented',
|
|
|
|
token => {
|
|
|
|
const { lineWidthBold, controlLineWidth } = token;
|
|
|
|
|
|
|
|
const segmentedToken = mergeToken<SegmentedToken>(token, {
|
|
|
|
segmentedPaddingHorizontal: token.controlPaddingHorizontal - controlLineWidth,
|
|
|
|
segmentedPaddingHorizontalSM: token.controlPaddingHorizontalSM - controlLineWidth,
|
|
|
|
segmentedContainerPadding: lineWidthBold,
|
|
|
|
});
|
|
|
|
return [genSegmentedStyle(segmentedToken)];
|
|
|
|
},
|
|
|
|
{
|
|
|
|
bgColor: new TinyColor('#000').setAlpha(0.04).toRgbString(),
|
|
|
|
bgColorHover: new TinyColor('#000').setAlpha(0.06).toRgbString(),
|
|
|
|
bgColorSelected: '#fff',
|
|
|
|
labelColor: new TinyColor('#000').setAlpha(0.65).toRgbString(),
|
|
|
|
labelColorHover: '#262626',
|
|
|
|
},
|
|
|
|
);
|