ant-design/components/collapse/style/index.ts

336 lines
8.5 KiB
TypeScript
Raw Normal View History

import type { CSSProperties } from 'react';
import { unit } from '@ant-design/cssinjs';
import { resetComponent, resetIcon } from '../../style';
import { genCollapseMotion } from '../../style/motion';
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
import { genStyleHooks, mergeToken } from '../../theme/internal';
2022-04-25 14:45:26 +08:00
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
// Component token here
2023-08-14 20:39:31 +08:00
/**
* @desc
* @descEN Padding of header
*/
headerPadding: CSSProperties['padding'];
2023-08-14 20:39:31 +08:00
/**
* @desc
* @descEN Background of header
*/
headerBg: string;
2023-08-14 20:39:31 +08:00
/**
* @desc
* @descEN Padding of content
*/
contentPadding: CSSProperties['padding'];
2023-08-14 20:39:31 +08:00
/**
* @desc
* @descEN Background of content
*/
contentBg: string;
}
2022-04-25 14:45:26 +08:00
type CollapseToken = FullToken<'Collapse'> & {
collapseHeaderPaddingSM: string;
collapseHeaderPaddingLG: string;
2022-04-25 14:45:26 +08:00
collapsePanelBorderRadius: number;
};
export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
2022-04-25 14:45:26 +08:00
const {
componentCls,
contentBg,
padding,
headerBg,
headerPadding,
collapseHeaderPaddingSM,
collapseHeaderPaddingLG,
2022-04-25 14:45:26 +08:00
collapsePanelBorderRadius,
lineWidth,
lineType,
2022-04-25 14:45:26 +08:00
colorBorder,
colorText,
colorTextHeading,
colorTextDisabled,
fontSizeLG,
2022-04-25 14:45:26 +08:00
lineHeight,
lineHeightLG,
2022-04-25 14:45:26 +08:00
marginSM,
paddingSM,
paddingLG,
paddingXS,
motionDurationSlow,
2022-07-12 14:32:54 +08:00
fontSizeIcon,
contentPadding,
fontHeight,
fontHeightLG,
2022-04-25 14:45:26 +08:00
} = token;
const borderBase = `${unit(lineWidth)} ${lineType} ${colorBorder}`;
2022-04-25 14:45:26 +08:00
return {
[componentCls]: {
...resetComponent(token),
backgroundColor: headerBg,
2022-04-25 14:45:26 +08:00
border: borderBase,
borderRadius: collapsePanelBorderRadius,
2022-04-25 14:45:26 +08:00
'&-rtl': {
2022-04-25 14:45:26 +08:00
direction: 'rtl',
},
[`& > ${componentCls}-item`]: {
borderBottom: borderBase,
'&:last-child': {
2022-04-25 14:45:26 +08:00
[`
&,
2022-05-06 14:02:45 +08:00
& > ${componentCls}-header`]: {
borderRadius: `0 0 ${unit(collapsePanelBorderRadius)} ${unit(
collapsePanelBorderRadius,
)}`,
2022-04-25 14:45:26 +08:00
},
},
[`> ${componentCls}-header`]: {
position: 'relative', // Compatible with old version of antd, should remove in next version
display: 'flex',
flexWrap: 'nowrap',
alignItems: 'flex-start',
padding: headerPadding,
2022-04-25 14:45:26 +08:00
color: colorTextHeading,
lineHeight,
cursor: 'pointer',
transition: `all ${motionDurationSlow}, visibility 0s`,
2022-04-25 14:45:26 +08:00
2022-07-29 15:56:11 +08:00
[`> ${componentCls}-header-text`]: {
flex: 'auto',
},
'&:focus': {
outline: 'none',
2022-04-25 14:45:26 +08:00
},
// >>>>> Arrow
[`${componentCls}-expand-icon`]: {
height: fontHeight,
display: 'flex',
alignItems: 'center',
paddingInlineEnd: marginSM,
2022-04-25 14:45:26 +08:00
},
[`${componentCls}-arrow`]: {
...resetIcon(),
2022-07-12 14:32:54 +08:00
fontSize: fontSizeIcon,
// when `transform: rotate()` is applied to icon's root element
transition: `transform ${motionDurationSlow}`,
// when `transform: rotate()` is applied to icon's child element
svg: {
transition: `transform ${motionDurationSlow}`,
},
},
// >>>>> Text
[`${componentCls}-header-text`]: {
marginInlineEnd: 'auto',
2022-04-25 14:45:26 +08:00
},
},
[`${componentCls}-icon-collapsible-only`]: {
cursor: 'unset',
[`${componentCls}-expand-icon`]: {
cursor: 'pointer',
},
},
2022-04-25 14:45:26 +08:00
},
[`${componentCls}-content`]: {
color: colorText,
backgroundColor: contentBg,
2022-04-25 14:45:26 +08:00
borderTop: borderBase,
[`& > ${componentCls}-content-box`]: {
padding: contentPadding,
2022-04-25 14:45:26 +08:00
},
'&-hidden': {
2022-04-25 14:45:26 +08:00
display: 'none',
},
},
'&-small': {
[`> ${componentCls}-item`]: {
[`> ${componentCls}-header`]: {
padding: collapseHeaderPaddingSM,
paddingInlineStart: paddingXS,
[`> ${componentCls}-expand-icon`]: {
// Arrow offset
marginInlineStart: token.calc(paddingSM).sub(paddingXS).equal(),
},
},
[`> ${componentCls}-content > ${componentCls}-content-box`]: {
padding: paddingSM,
},
},
},
'&-large': {
[`> ${componentCls}-item`]: {
fontSize: fontSizeLG,
lineHeight: lineHeightLG,
[`> ${componentCls}-header`]: {
padding: collapseHeaderPaddingLG,
paddingInlineStart: padding,
[`> ${componentCls}-expand-icon`]: {
height: fontHeightLG,
// Arrow offset
marginInlineStart: token.calc(paddingLG).sub(padding).equal(),
},
},
[`> ${componentCls}-content > ${componentCls}-content-box`]: {
padding: paddingLG,
},
},
},
2022-04-25 14:45:26 +08:00
[`${componentCls}-item:last-child`]: {
borderBottom: 0,
2022-04-25 14:45:26 +08:00
[`> ${componentCls}-content`]: {
borderRadius: `0 0 ${unit(collapsePanelBorderRadius)} ${unit(collapsePanelBorderRadius)}`,
2022-04-25 14:45:26 +08:00
},
},
[`& ${componentCls}-item-disabled > ${componentCls}-header`]: {
[`
&,
& > .arrow
`]: {
color: colorTextDisabled,
cursor: 'not-allowed',
},
},
// ========================== Icon Position ==========================
[`&${componentCls}-icon-position-end`]: {
[`& > ${componentCls}-item`]: {
[`> ${componentCls}-header`]: {
[`${componentCls}-expand-icon`]: {
order: 1,
paddingInlineEnd: 0,
paddingInlineStart: marginSM,
2022-04-25 14:45:26 +08:00
},
},
},
},
},
};
2022-05-06 14:02:45 +08:00
};
2022-04-25 14:45:26 +08:00
const genArrowStyle: GenerateStyle<CollapseToken> = (token) => {
const { componentCls } = token;
const fixedSelector = `> ${componentCls}-item > ${componentCls}-header ${componentCls}-arrow`;
return {
[`${componentCls}-rtl`]: {
[fixedSelector]: {
transform: `rotate(180deg)`,
},
},
};
};
const genBorderlessStyle: GenerateStyle<CollapseToken> = (token) => {
2022-04-25 14:45:26 +08:00
const {
componentCls,
headerBg,
paddingXXS,
2022-04-25 14:45:26 +08:00
colorBorder,
} = token;
return {
[`${componentCls}-borderless`]: {
backgroundColor: headerBg,
2022-04-25 14:45:26 +08:00
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,
2022-04-25 14:45:26 +08:00
},
},
};
2022-05-06 14:02:45 +08:00
};
2022-04-25 14:45:26 +08:00
const genGhostStyle: GenerateStyle<CollapseToken> = (token) => {
const { componentCls, paddingSM } = token;
return {
[`${componentCls}-ghost`]: {
backgroundColor: 'transparent',
border: 0,
[`> ${componentCls}-item`]: {
borderBottom: 0,
[`> ${componentCls}-content`]: {
backgroundColor: 'transparent',
border: 0,
[`> ${componentCls}-content-box`]: {
paddingBlock: paddingSM,
},
},
},
},
};
};
export const prepareComponentToken: GetDefaultToken<'Collapse'> = (token) => ({
headerPadding: `${token.paddingSM}px ${token.padding}px`,
headerBg: token.colorFillAlter,
contentPadding: `${token.padding}px 16px`, // Fixed Value
contentBg: token.colorBgContainer,
});
export default genStyleHooks(
'Collapse',
(token) => {
const collapseToken = mergeToken<CollapseToken>(token, {
collapseHeaderPaddingSM: `${unit(token.paddingXS)} ${unit(token.paddingSM)}`,
collapseHeaderPaddingLG: `${unit(token.padding)} ${unit(token.paddingLG)}`,
collapsePanelBorderRadius: token.borderRadiusLG,
});
return [
genBaseStyle(collapseToken),
genBorderlessStyle(collapseToken),
genGhostStyle(collapseToken),
genArrowStyle(collapseToken),
genCollapseMotion(collapseToken),
];
},
prepareComponentToken,
);