feat: modal support cssVar (#45798)

* feat: modal support cssVar

* feat: optimize code

* feat: optimize code

* feat: optimize code
This commit is contained in:
kiner-tang(文辉) 2023-11-13 15:31:49 +08:00 committed by GitHub
parent 6c044c7f2d
commit ad9763299c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 31 deletions

View File

@ -16,6 +16,8 @@ import type { ModalProps, MousePosition } from './interface';
import { Footer, renderCloseIcon } from './shared';
import useStyle from './style';
import { useZIndex } from '../_util/hooks/useZIndex';
import useCSSVar from './style/cssVar';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
let mousePosition: MousePosition;
@ -93,7 +95,9 @@ const Modal: React.FC<ModalProps> = (props) => {
const prefixCls = getPrefixCls('modal', customizePrefixCls);
const rootPrefixCls = getPrefixCls();
// Style
const [wrapSSR, hashId] = useStyle(prefixCls);
const [, hashId] = useStyle(prefixCls);
const rootCls = useCSSVarCls(prefixCls);
const wrapCSSVar = useCSSVar(rootCls);
const wrapClassNameExtended = classNames(wrapClassName, {
[`${prefixCls}-centered`]: !!centered,
@ -119,7 +123,7 @@ const Modal: React.FC<ModalProps> = (props) => {
const [zIndex, contextZIndex] = useZIndex('Modal', restProps.zIndex);
// =========================== Render ===========================
return wrapSSR(
return wrapCSSVar(
<NoCompactStyle>
<NoFormStyle status override>
<zIndexContext.Provider value={contextZIndex}>
@ -129,7 +133,7 @@ const Modal: React.FC<ModalProps> = (props) => {
zIndex={zIndex}
getContainer={getContainer === undefined ? getContextPopupContainer : getContainer}
prefixCls={prefixCls}
rootClassName={classNames(hashId, rootClassName)}
rootClassName={classNames(hashId, rootClassName, rootCls)}
footer={dialogFooter}
visible={open ?? visible}
mousePosition={restProps.mousePosition ?? mousePosition}

View File

@ -11,6 +11,8 @@ import { ConfirmContent } from './ConfirmDialog';
import type { ModalFuncProps } from './interface';
import { Footer, renderCloseIcon } from './shared';
import useStyle from './style';
import useCSSVar from './style/cssVar';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
export interface PurePanelProps
extends Omit<PanelProps, 'prefixCls' | 'footer'>,
@ -35,6 +37,8 @@ const PurePanel: React.FC<PurePanelProps> = (props) => {
const rootPrefixCls = getPrefixCls();
const prefixCls = customizePrefixCls || getPrefixCls('modal');
const rootCls = useCSSVarCls(rootPrefixCls);
const wrapCSSVar = useCSSVar(rootCls);
const [, hashId] = useStyle(prefixCls);
@ -66,7 +70,7 @@ const PurePanel: React.FC<PurePanelProps> = (props) => {
};
}
return (
return wrapCSSVar(
<Panel
prefixCls={prefixCls}
className={classNames(
@ -75,12 +79,13 @@ const PurePanel: React.FC<PurePanelProps> = (props) => {
type && confirmPrefixCls,
type && `${confirmPrefixCls}-${type}`,
className,
rootCls,
)}
{...restProps}
closeIcon={renderCloseIcon(prefixCls, closeIcon)}
closable={closable}
{...additionalProps}
/>
/>,
);
};

View File

@ -1,4 +1,5 @@
// Style as confirm component
import { unit } from '@ant-design/cssinjs';
import { prepareComponentToken, prepareToken, type ModalToken } from '.';
import { clearFix } from '../../style';
import { genSubStyleComponent, type GenerateStyle } from '../../theme/internal';
@ -13,12 +14,11 @@ const genModalConfirmStyle: GenerateStyle<ModalToken> = (token) => {
modalConfirmIconSize,
fontSize,
lineHeight,
modalTitleHeight,
fontHeight,
} = token;
const confirmComponentCls = `${componentCls}-confirm`;
const titleHeight = Math.round(titleFontSize * titleLineHeight);
const contentHeight = Math.round(fontSize * lineHeight);
return {
[confirmComponentCls]: {
'&-rtl': {
@ -41,10 +41,16 @@ const genModalConfirmStyle: GenerateStyle<ModalToken> = (token) => {
flex: 'none',
fontSize: modalConfirmIconSize,
marginInlineEnd: token.marginSM,
marginTop: (contentHeight - modalConfirmIconSize) / 2,
marginTop: token
.calc(token.calc(fontHeight).sub(modalConfirmIconSize).equal())
.div(2)
.equal(),
},
[`&-has-title > ${token.iconCls}`]: {
marginTop: (titleHeight - modalConfirmIconSize) / 2,
marginTop: token
.calc(token.calc(modalTitleHeight).sub(modalConfirmIconSize).equal())
.div(2)
.equal(),
},
},
@ -53,7 +59,9 @@ const genModalConfirmStyle: GenerateStyle<ModalToken> = (token) => {
flexDirection: 'column',
flex: 'auto',
rowGap: token.marginXS,
maxWidth: `calc(100% - ${token.modalConfirmIconSize + token.marginSM}px)`,
maxWidth: `calc(100% - ${unit(
token.calc(token.modalConfirmIconSize).add(token.marginSM).equal(),
)})`,
},
[`${confirmComponentCls}-title`]: {

View File

@ -0,0 +1,8 @@
import { genCSSVarRegister } from '../../theme/internal';
import { prepareComponentToken } from '.';
export default genCSSVarRegister('Modal', prepareComponentToken, {
unitless: {
titleLineHeight: true,
},
});

View File

@ -6,6 +6,7 @@ import type { GlobalToken } from '../../theme';
import type { AliasToken, FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
import type { GenStyleFn, TokenWithCommonCls } from '../../theme/util/genComponentStyleHook';
import { unit } from '@ant-design/cssinjs';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
@ -44,7 +45,7 @@ export interface ComponentToken {
export interface ModalToken extends FullToken<'Modal'> {
// Custom token here
modalHeaderHeight: number;
modalHeaderHeight: number | string;
modalBodyPadding: number;
modalHeaderPadding: string;
modalHeaderBorderWidth: number;
@ -57,8 +58,9 @@ export interface ModalToken extends FullToken<'Modal'> {
modalFooterBorderWidth: number;
modalIconHoverColor: string;
modalCloseIconColor: string;
modalCloseBtnSize: number;
modalConfirmIconSize: number;
modalCloseBtnSize: number | string;
modalConfirmIconSize: number | string;
modalTitleHeight: number | string;
}
function box(position: React.CSSProperties['position']): React.CSSProperties {
@ -153,7 +155,7 @@ const genModalStyle: GenerateStyle<ModalToken> = (token) => {
[`@media (max-width: ${token.screenSMMax})`]: {
[componentCls]: {
maxWidth: 'calc(100vw - 16px)',
margin: `${token.marginXS} auto`,
margin: `${unit(token.marginXS)} auto`,
},
[`${componentCls}-centered`]: {
[componentCls]: {
@ -172,7 +174,7 @@ const genModalStyle: GenerateStyle<ModalToken> = (token) => {
position: 'relative',
top: 100,
width: 'auto',
maxWidth: `calc(100vw - ${token.margin * 2}px)`,
maxWidth: `calc(100vw - ${unit(token.calc(token.margin).mul(2).equal())})`,
margin: '0 auto',
paddingBottom: token.paddingLG,
@ -193,14 +195,18 @@ const genModalStyle: GenerateStyle<ModalToken> = (token) => {
borderRadius: token.borderRadiusLG,
boxShadow: token.boxShadow,
pointerEvents: 'auto',
padding: `${token.paddingMD}px ${token.paddingContentHorizontalLG}px`,
padding: `${unit(token.paddingMD)} ${unit(token.paddingContentHorizontalLG)}`,
},
[`${componentCls}-close`]: {
position: 'absolute',
top: (token.modalHeaderHeight - token.modalCloseBtnSize) / 2,
insetInlineEnd: (token.modalHeaderHeight - token.modalCloseBtnSize) / 2,
zIndex: token.zIndexPopupBase + 10,
top: token.calc(token.modalHeaderHeight).sub(token.modalCloseBtnSize).div(2).equal(),
insetInlineEnd: token
.calc(token.modalHeaderHeight)
.sub(token.modalCloseBtnSize)
.div(2)
.equal(),
zIndex: token.calc(token.zIndexPopupBase).add(10).equal(),
padding: 0,
color: token.modalCloseIconColor,
fontWeight: token.fontWeightStrong,
@ -219,7 +225,7 @@ const genModalStyle: GenerateStyle<ModalToken> = (token) => {
display: 'flex',
fontSize: token.fontSizeLG,
fontStyle: 'normal',
lineHeight: `${token.modalCloseBtnSize}px`,
lineHeight: `${unit(token.modalCloseBtnSize)}`,
justifyContent: 'center',
textTransform: 'none',
textRendering: 'auto',
@ -241,7 +247,7 @@ const genModalStyle: GenerateStyle<ModalToken> = (token) => {
[`${componentCls}-header`]: {
color: token.colorText,
background: token.headerBg,
borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`,
borderRadius: `${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)} 0 0`,
marginBottom: token.marginXS,
},
@ -304,7 +310,9 @@ const genWireframeStyle: GenerateStyle<ModalToken> = (token) => {
[`${componentCls}-header`]: {
padding: token.modalHeaderPadding,
borderBottom: `${token.modalHeaderBorderWidth}px ${token.modalHeaderBorderStyle} ${token.modalHeaderBorderColorSplit}`,
borderBottom: `${unit(token.modalHeaderBorderWidth)} ${token.modalHeaderBorderStyle} ${
token.modalHeaderBorderColorSplit
}`,
marginBottom: 0,
},
@ -313,16 +321,22 @@ const genWireframeStyle: GenerateStyle<ModalToken> = (token) => {
},
[`${componentCls}-footer`]: {
padding: `${token.modalFooterPaddingVertical}px ${token.modalFooterPaddingHorizontal}px`,
borderTop: `${token.modalFooterBorderWidth}px ${token.modalFooterBorderStyle} ${token.modalFooterBorderColorSplit}`,
borderRadius: `0 0 ${token.borderRadiusLG}px ${token.borderRadiusLG}px`,
padding: `${unit(token.modalFooterPaddingVertical)} ${unit(
token.modalFooterPaddingHorizontal,
)}`,
borderTop: `${unit(token.modalFooterBorderWidth)} ${token.modalFooterBorderStyle} ${
token.modalFooterBorderColorSplit
}`,
borderRadius: `0 0 ${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)}`,
marginTop: 0,
},
},
[confirmComponentCls]: {
[`${antCls}-modal-body`]: {
padding: `${token.padding * 2}px ${token.padding * 2}px ${token.paddingLG}px`,
padding: `${unit(token.calc(token.padding).mul(2).equal())} ${unit(
token.calc(token.padding).mul(2).equal(),
)} ${unit(token.paddingLG)}`,
},
[`${confirmComponentCls}-body > ${token.iconCls}`]: {
marginInlineEnd: token.margin,
@ -357,11 +371,14 @@ export const prepareToken: (token: Parameters<GenStyleFn<'Modal'>>[0]) => ModalT
const modalToken = mergeToken<ModalToken>(token, {
modalBodyPadding: token.paddingLG,
modalHeaderPadding: `${headerPaddingVertical}px ${token.paddingLG}px`,
modalHeaderPadding: `${unit(headerPaddingVertical)} ${unit(token.paddingLG)}`,
modalHeaderBorderWidth: token.lineWidth,
modalHeaderBorderStyle: token.lineType,
modalHeaderBorderColorSplit: token.colorSplit,
modalHeaderHeight: headerLineHeight * headerFontSize + headerPaddingVertical * 2,
modalHeaderHeight: token
.calc(token.calc(headerLineHeight).mul(headerFontSize).equal())
.add(token.calc(headerPaddingVertical).mul(2).equal())
.equal(),
modalFooterBorderColorSplit: token.colorSplit,
modalFooterBorderStyle: token.lineType,
modalFooterPaddingVertical: token.paddingXS,
@ -369,8 +386,9 @@ export const prepareToken: (token: Parameters<GenStyleFn<'Modal'>>[0]) => ModalT
modalFooterBorderWidth: token.lineWidth,
modalIconHoverColor: token.colorIconHover,
modalCloseIconColor: token.colorIcon,
modalCloseBtnSize: token.fontSize * token.lineHeight,
modalConfirmIconSize: token.fontSize * token.lineHeight,
modalCloseBtnSize: token.fontHeight,
modalConfirmIconSize: token.fontHeight,
modalTitleHeight: token.calc(token.titleFontSize).mul(token.titleLineHeight).equal(),
});
return modalToken;