From 274c1f7fa37105d873dcbebf9790ebdcaf6e4e8b Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Mon, 25 Apr 2022 14:45:26 +0800 Subject: [PATCH] refactor: collpase cssinjs (#35066) --- components/_util/theme/interface.ts | 1 + components/collapse/Collapse.tsx | 7 +- components/collapse/demo/custom.md | 2 +- components/collapse/style/index.less | 270 +++++++++++++-------------- components/collapse/style/index.tsx | 252 ++++++++++++++++++++++++- 5 files changed, 392 insertions(+), 140 deletions(-) diff --git a/components/_util/theme/interface.ts b/components/_util/theme/interface.ts index bd4e5d40e2..18dd247409 100644 --- a/components/_util/theme/interface.ts +++ b/components/_util/theme/interface.ts @@ -54,6 +54,7 @@ export interface OverrideToken { Carousel?: CarouselComponentToken; Cascader?: CascaderComponentToken; Checkbox?: {}; + Collapse?: {}; DatePicker?: DatePickerComponentToken; Descriptions?: {}; Divider?: DividerComponentToken; diff --git a/components/collapse/Collapse.tsx b/components/collapse/Collapse.tsx index 7a96140566..932e43cae3 100644 --- a/components/collapse/Collapse.tsx +++ b/components/collapse/Collapse.tsx @@ -10,6 +10,7 @@ import CollapsePanel, { CollapsibleType } from './CollapsePanel'; import { ConfigContext } from '../config-provider'; import collapseMotion from '../_util/motion'; import { cloneElement } from '../_util/reactNode'; +import useStyle from './style'; export type ExpandIconPosition = 'left' | 'right' | undefined; @@ -52,6 +53,7 @@ const Collapse: CollapseInterface = props => { const { getPrefixCls, direction } = React.useContext(ConfigContext); const { prefixCls: customizePrefixCls, className = '', bordered = true, ghost } = props; const prefixCls = getPrefixCls('collapse', customizePrefixCls); + const [wrapSSR, hashId] = useStyle(prefixCls); const getIconPosition = () => { const { expandIconPosition } = props; @@ -90,6 +92,7 @@ const Collapse: CollapseInterface = props => { [`${prefixCls}-ghost`]: !!ghost, }, className, + hashId, ); const openMotion: CSSMotionProps = { ...collapseMotion, @@ -114,7 +117,7 @@ const Collapse: CollapseInterface = props => { }); }; - return ( + return wrapSSR( { className={collapseClassName} > {getItems()} - + , ); }; diff --git a/components/collapse/demo/custom.md b/components/collapse/demo/custom.md index 83d0622352..547b3c6389 100644 --- a/components/collapse/demo/custom.md +++ b/components/collapse/demo/custom.md @@ -51,7 +51,7 @@ export default () => ( margin-bottom: 24px; overflow: hidden; background: #f7f7f7; - border: 0px; + border: 0px !important; border-radius: 2px; } ``` diff --git a/components/collapse/style/index.less b/components/collapse/style/index.less index b92378d523..a45659247b 100644 --- a/components/collapse/style/index.less +++ b/components/collapse/style/index.less @@ -1,162 +1,162 @@ -@import '../../style/themes/index'; -@import '../../style/mixins/index'; +// @import '../../style/themes/index'; +// @import '../../style/mixins/index'; -@collapse-prefix-cls: ~'@{ant-prefix}-collapse'; +// @collapse-prefix-cls: ~'@{ant-prefix}-collapse'; -.@{collapse-prefix-cls} { - .reset-component(); +// .@{collapse-prefix-cls} { +// .reset-component(); - background-color: @collapse-header-bg; - border: @border-width-base @border-style-base @border-color-base; - border-bottom: 0; - border-radius: @collapse-panel-border-radius; +// background-color: @collapse-header-bg; +// border: @border-width-base @border-style-base @border-color-base; +// border-bottom: 0; +// border-radius: @collapse-panel-border-radius; - & > &-item { - border-bottom: @border-width-base @border-style-base @border-color-base; +// & > &-item { +// border-bottom: @border-width-base @border-style-base @border-color-base; - &:last-child { - &, - & > .@{collapse-prefix-cls}-header { - border-radius: 0 0 @collapse-panel-border-radius @collapse-panel-border-radius; - } - } +// &:last-child { +// &, +// & > .@{collapse-prefix-cls}-header { +// border-radius: 0 0 @collapse-panel-border-radius @collapse-panel-border-radius; +// } +// } - > .@{collapse-prefix-cls}-header { - position: relative; // Compatible with old version of antd, should remove in next version - display: flex; - flex-wrap: nowrap; - align-items: flex-start; - padding: @collapse-header-padding; - color: @heading-color; - line-height: @line-height-base; - cursor: pointer; - transition: all 0.3s, visibility 0s; +// > .@{collapse-prefix-cls}-header { +// position: relative; // Compatible with old version of antd, should remove in next version +// display: flex; +// flex-wrap: nowrap; +// align-items: flex-start; +// padding: @collapse-header-padding; +// color: @heading-color; +// line-height: @line-height-base; +// cursor: pointer; +// transition: all 0.3s, visibility 0s; - .@{collapse-prefix-cls}-arrow { - display: inline-block; - margin-right: @margin-sm; - font-size: @font-size-sm; - vertical-align: -1px; +// .@{collapse-prefix-cls}-arrow { +// display: inline-block; +// margin-right: @margin-sm; +// font-size: @font-size-sm; +// vertical-align: -1px; - & svg { - transition: transform 0.24s; - } - } +// & svg { +// transition: transform 0.24s; +// } +// } - .@{collapse-prefix-cls}-extra { - margin-left: auto; - } +// .@{collapse-prefix-cls}-extra { +// margin-left: auto; +// } - &:focus { - outline: none; - } - } +// &:focus { +// outline: none; +// } +// } - .@{collapse-prefix-cls}-header-collapsible-only { - cursor: default; - .@{collapse-prefix-cls}-header-text { - cursor: pointer; - } - } +// .@{collapse-prefix-cls}-header-collapsible-only { +// cursor: default; +// .@{collapse-prefix-cls}-header-text { +// cursor: pointer; +// } +// } - &.@{collapse-prefix-cls}-no-arrow { - > .@{collapse-prefix-cls}-header { - padding-left: @padding-sm; - } - } - } +// &.@{collapse-prefix-cls}-no-arrow { +// > .@{collapse-prefix-cls}-header { +// padding-left: @padding-sm; +// } +// } +// } - // Expand Icon right - &-icon-position-right { - & > .@{collapse-prefix-cls}-item { - > .@{collapse-prefix-cls}-header { - position: relative; - padding: @collapse-header-padding; - padding-right: @collapse-header-padding-extra; +// // Expand Icon right +// &-icon-position-right { +// & > .@{collapse-prefix-cls}-item { +// > .@{collapse-prefix-cls}-header { +// position: relative; +// padding: @collapse-header-padding; +// padding-right: @collapse-header-padding-extra; - .@{collapse-prefix-cls}-arrow { - position: absolute; - top: 50%; - right: @padding-md; - left: auto; - margin: 0; - transform: translateY(-50%); - } - } - } - } +// .@{collapse-prefix-cls}-arrow { +// position: absolute; +// top: 50%; +// right: @padding-md; +// left: auto; +// margin: 0; +// transform: translateY(-50%); +// } +// } +// } +// } - &-content { - color: @text-color; - background-color: @collapse-content-bg; - border-top: @border-width-base @border-style-base @border-color-base; +// &-content { +// color: @text-color; +// background-color: @collapse-content-bg; +// border-top: @border-width-base @border-style-base @border-color-base; - & > &-box { - padding: @collapse-content-padding; - } +// & > &-box { +// padding: @collapse-content-padding; +// } - &-hidden { - display: none; - } - } +// &-hidden { +// display: none; +// } +// } - &-item:last-child { - > .@{collapse-prefix-cls}-content { - border-radius: 0 0 @collapse-panel-border-radius @collapse-panel-border-radius; - } - } +// &-item:last-child { +// > .@{collapse-prefix-cls}-content { +// border-radius: 0 0 @collapse-panel-border-radius @collapse-panel-border-radius; +// } +// } - &-borderless { - background-color: @collapse-header-bg; - border: 0; - } +// &-borderless { +// background-color: @collapse-header-bg; +// border: 0; +// } - &-borderless > &-item { - border-bottom: 1px solid @border-color-base; - } +// &-borderless > &-item { +// border-bottom: 1px solid @border-color-base; +// } - &-borderless > &-item:last-child, - &-borderless > &-item:last-child &-header { - border-radius: 0; - } +// &-borderless > &-item:last-child, +// &-borderless > &-item:last-child &-header { +// border-radius: 0; +// } - // hide the last border-bottom in borderless mode - &-borderless > &-item:last-child { - border-bottom: 0; - } +// // hide the last border-bottom in borderless mode +// &-borderless > &-item:last-child { +// border-bottom: 0; +// } - &-borderless > &-item > &-content { - background-color: transparent; - border-top: 0; - } +// &-borderless > &-item > &-content { +// background-color: transparent; +// border-top: 0; +// } - &-borderless > &-item > &-content > &-content-box { - padding-top: 4px; - } +// &-borderless > &-item > &-content > &-content-box { +// padding-top: 4px; +// } - &-ghost { - background-color: transparent; - border: 0; - > .@{collapse-prefix-cls}-item { - border-bottom: 0; - > .@{collapse-prefix-cls}-content { - background-color: transparent; - border-top: 0; - > .@{collapse-prefix-cls}-content-box { - padding-top: 12px; - padding-bottom: 12px; - } - } - } - } +// &-ghost { +// background-color: transparent; +// border: 0; +// > .@{collapse-prefix-cls}-item { +// border-bottom: 0; +// > .@{collapse-prefix-cls}-content { +// background-color: transparent; +// border-top: 0; +// > .@{collapse-prefix-cls}-content-box { +// padding-top: 12px; +// padding-bottom: 12px; +// } +// } +// } +// } - & &-item-disabled > &-header { - &, - & > .arrow { - color: @disabled-color; - cursor: not-allowed; - } - } -} +// & &-item-disabled > &-header { +// &, +// & > .arrow { +// color: @disabled-color; +// cursor: not-allowed; +// } +// } +// } -@import './rtl'; +// @import './rtl'; diff --git a/components/collapse/style/index.tsx b/components/collapse/style/index.tsx index 3a3ab0de59..e73ba6033c 100644 --- a/components/collapse/style/index.tsx +++ b/components/collapse/style/index.tsx @@ -1,2 +1,250 @@ -import '../../style/index.less'; -import './index.less'; +// import '../../style/index.less'; +// import './index.less'; + +// deps-lint-skip-all +import { CSSInterpolation } from '@ant-design/cssinjs'; +import { + GenerateStyle, + resetComponent, + genComponentStyleHook, + mergeToken, + FullToken, +} from '../../_util/theme'; + +type CollapseToken = FullToken<'Collapse'> & { + collapseContentBg: string; + collapseContentPadding: number; + collapseHeaderBg: string; + collapseHeaderPadding: string; + collapseHeaderPaddingExtra: number; + collapsePanelBorderRadius: number; +}; + +export const genBaseStyle: GenerateStyle = token => { + const { + componentCls, + collapseContentBg, + collapseContentPadding, + collapseHeaderBg, + collapseHeaderPadding, + collapseHeaderPaddingExtra, + collapsePanelBorderRadius, + + controlLineWidth, + controlLineType, + colorBorder, + colorText, + colorTextHeading, + colorTextDisabled, + lineHeight, + marginSM, + padding, + paddingSM, + fontSizeSM, + } = 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 0.3s, visibility 0s`, + + [`${componentCls}-arrow`]: { + display: 'inline-block', + marginInlineEnd: marginSM, + fontSize: fontSizeSM, + // FIXME + verticalAlign: '-1px', + + [`${componentCls}-rtl &`]: { + + }, + + [`& svg`]: { + // FIXME + transition: 'transform 0.24s', + }, + }, + + [`${componentCls}-extra`]: { + marginInlineStart: 'auto', + }, + + [`&:focus`]: { + outline: 'none', + }, + }, + + [`${componentCls}-header-collapsible-only`]: { + cursor: 'default', + + [`${componentCls}-header-text`]: { + cursor: 'pointer', + }, + }, + + [`&${componentCls}-no-arrow`]: { + [`> ${componentCls}-header`]: { + paddingInlineStart: paddingSM, + }, + }, + }, + + [`&-icon-position-right`]: { + [`& > ${componentCls}-item `]: { + [`> ${componentCls}-header`]: { + position: 'relative', + padding: collapseHeaderPadding, + paddingInlineEnd: collapseHeaderPaddingExtra, + + [`${componentCls}-arrow`]: { + position: 'absolute', + top: '50%', + insetInlineEnd: padding, + insetInlineStart: 'auto', + margin: 0, + transform: 'translateY(-50%)', + }, + }, + }, + }, + + [`${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`]: { + backgroundColor: 'transparent', + border: 0, + [`> ${componentCls}-item`]: { + borderBottom: 0, + [`> ${componentCls}-content`]: { + backgroundColor: 'transparent', + border: 0, + [`> ${componentCls}-content-box`]: { + // FIXME + paddingTop: 12, + paddingBottom: 12, + }, + }, + }, + }, + }, + }; +} + +const genBorderlessStyle: GenerateStyle = token => { + const { + componentCls, + collapseHeaderBg, + + 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`]: { + // FIXME + paddingTop: 4, + }, + }, + }; +} + +export const genCollapseStyle: GenerateStyle = (token: CollapseToken): CSSInterpolation => [ + genBaseStyle(token), + genBorderlessStyle(token), +]; + +export default genComponentStyleHook('Collapse', token => { + const collapseToken = mergeToken(token, { + collapseContentBg: token.colorBgComponent, + collapseContentPadding: token.padding, + collapseHeaderBg: token.colorBgComponentSecondary, + collapseHeaderPadding: `${token.paddingSM}px ${token.padding}px`, + // FIXME + collapseHeaderPaddingExtra: 40, + collapsePanelBorderRadius: token.radiusBase, + }); + + return [genCollapseStyle(collapseToken)]; +});