ant-design/components/collapse/style/index.tsx
2022-07-12 14:32:54 +08:00

272 lines
7.0 KiB
TypeScript

import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook, mergeToken } from '../../theme';
import { resetComponent, resetIcon } from '../../style';
type CollapseToken = FullToken<'Collapse'> & {
collapseContentBg: string;
collapseContentPadding: number;
collapseHeaderBg: string;
collapseHeaderPadding: string;
collapsePanelBorderRadius: number;
};
export const genBaseStyle: GenerateStyle<CollapseToken> = token => {
const {
componentCls,
collapseContentBg,
collapseContentPadding,
collapseHeaderBg,
collapseHeaderPadding,
collapsePanelBorderRadius,
controlLineWidth,
controlLineType,
colorBorder,
colorText,
colorTextHeading,
colorTextDisabled,
fontSize,
lineHeight,
marginSM,
paddingSM,
motionDurationSlow,
fontSizeIcon,
} = token;
const borderBase = `${controlLineWidth}px ${controlLineType} ${colorBorder}`;
return {
[componentCls]: {
...resetComponent(token),
backgroundColor: collapseHeaderBg,
border: borderBase,
borderBottom: 0,
borderRadius: `${collapsePanelBorderRadius}px`,
[`&-rtl`]: {
direction: 'rtl',
},
[`& > ${componentCls}-item`]: {
borderBottom: borderBase,
[`&:last-child`]: {
[`
&,
& > ${componentCls}-header`]: {
borderRadius: `0 0 ${collapsePanelBorderRadius}px ${collapsePanelBorderRadius}px`,
},
},
[`> ${componentCls}-header`]: {
position: 'relative', // Compatible with old version of antd, should remove in next version
display: 'flex',
flexWrap: 'nowrap',
alignItems: 'flex-start',
padding: collapseHeaderPadding,
color: colorTextHeading,
lineHeight,
cursor: 'pointer',
transition: `all ${motionDurationSlow}, visibility 0s`,
'&:focus': {
outline: 'none',
},
// >>>>> Arrow
[`${componentCls}-expand-icon`]: {
height: fontSize * lineHeight,
display: 'flex',
alignItems: 'center',
paddingInlineEnd: marginSM,
},
[`${componentCls}-arrow`]: {
...resetIcon(),
fontSize: fontSizeIcon,
svg: {
transition: `transform ${motionDurationSlow}`,
},
},
// >>>>> Text
[`${componentCls}-header-text`]: {
marginInlineEnd: 'auto',
},
},
[`${componentCls}-header-collapsible-only`]: {
cursor: 'default',
[`${componentCls}-header-text`]: {
cursor: 'pointer',
},
},
[`&${componentCls}-no-arrow`]: {
[`> ${componentCls}-header`]: {
paddingInlineStart: paddingSM,
},
},
},
[`${componentCls}-content`]: {
color: colorText,
backgroundColor: collapseContentBg,
borderTop: borderBase,
[`& > ${componentCls}-content-box`]: {
padding: collapseContentPadding,
},
[`&-hidden`]: {
display: 'none',
},
},
[`${componentCls}-item:last-child`]: {
[`> ${componentCls}-content`]: {
borderRadius: `0 0 ${collapsePanelBorderRadius}px ${collapsePanelBorderRadius}px`,
},
},
[`& ${componentCls}-item-disabled > ${componentCls}-header`]: {
[`
&,
& > .arrow
`]: {
color: colorTextDisabled,
cursor: 'not-allowed',
},
},
// ============================== Ghost ==============================
[`&-ghost`]: {
backgroundColor: 'transparent',
border: 0,
[`> ${componentCls}-item`]: {
borderBottom: 0,
[`> ${componentCls}-content`]: {
backgroundColor: 'transparent',
border: 0,
[`> ${componentCls}-content-box`]: {
paddingBlock: paddingSM,
},
},
},
},
// ========================== Icon Position ==========================
[`&${componentCls}-icon-position-end`]: {
[`& > ${componentCls}-item`]: {
[`> ${componentCls}-header`]: {
[`${componentCls}-expand-icon`]: {
order: 1,
paddingInlineEnd: 0,
paddingInlineStart: marginSM,
},
},
},
},
},
};
};
const genArrowStyle: GenerateStyle<CollapseToken> = token => {
const { componentCls } = token;
const fixedSelector = `> ${componentCls}-item > ${componentCls}-header ${componentCls}-arrow svg`;
return {
[`${componentCls}-icon-position-end, ${componentCls}-rtl`]: {
[fixedSelector]: {
transform: `rotate(180deg)`,
},
},
[`${componentCls}-rtl${componentCls}-icon-position-end`]: {
[fixedSelector]: {
transform: `rotate(0deg)`,
},
},
};
};
const genBorderlessStyle: GenerateStyle<CollapseToken> = token => {
const {
componentCls,
collapseHeaderBg,
paddingXXS,
colorBorder,
} = token;
return {
[`${componentCls}-borderless`]: {
backgroundColor: collapseHeaderBg,
border: 0,
[`> ${componentCls}-item`]: {
borderBottom: `1px solid ${colorBorder}`,
},
[`
> ${componentCls}-item:last-child,
> ${componentCls}-item:last-child ${componentCls}-header
`]: {
borderRadius: 0,
},
[`> ${componentCls}-item:last-child`]: {
borderBottom: 0,
},
[`> ${componentCls}-item > ${componentCls}-content`]: {
backgroundColor: 'transparent',
borderTop: 0,
},
[`> ${componentCls}-item > ${componentCls}-content > ${componentCls}-content-box`]: {
paddingTop: paddingXXS,
},
},
};
};
const genMotion: GenerateStyle<CollapseToken> = token => ({
[token.componentCls]: {
// For common/openAnimation
[`${token.antCls}-motion-collapse-legacy`]: {
overflow: 'hidden',
'&-active': {
transition: `height ${token.motionDurationMid} ${token.motionEaseInOut},
opacity ${token.motionDurationMid} ${token.motionEaseInOut} !important`,
},
},
[`${token.antCls}-motion-collapse`]: {
overflow: 'hidden',
transition: `height ${token.motionDurationMid} ${token.motionEaseInOut},
opacity ${token.motionDurationMid} ${token.motionEaseInOut} !important`,
},
},
});
export default genComponentStyleHook('Collapse', token => {
const collapseToken = mergeToken<CollapseToken>(token, {
collapseContentBg: token.colorBgContainer,
collapseContentPadding: token.padding,
collapseHeaderBg: token.colorBgContainerSecondary,
collapseHeaderPadding: `${token.paddingSM}px ${token.padding}px`,
collapsePanelBorderRadius: token.radiusBase,
});
return [
genBaseStyle(collapseToken),
genBorderlessStyle(collapseToken),
genArrowStyle(collapseToken),
genMotion(collapseToken),
];
});