301 lines
9.7 KiB
JavaScript
301 lines
9.7 KiB
JavaScript
|
"use client";
|
||
|
|
||
|
import { genFocusStyle, resetComponent } from '../../style';
|
||
|
import { initFadeMotion, initZoomMotion } from '../../style/motion';
|
||
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||
|
function box(position) {
|
||
|
return {
|
||
|
position,
|
||
|
inset: 0
|
||
|
};
|
||
|
}
|
||
|
export const genModalMaskStyle = token => {
|
||
|
const {
|
||
|
componentCls,
|
||
|
antCls
|
||
|
} = token;
|
||
|
return [{
|
||
|
[`${componentCls}-root`]: {
|
||
|
[`${componentCls}${antCls}-zoom-enter, ${componentCls}${antCls}-zoom-appear`]: {
|
||
|
// reset scale avoid mousePosition bug
|
||
|
transform: 'none',
|
||
|
opacity: 0,
|
||
|
animationDuration: token.motionDurationSlow,
|
||
|
// https://github.com/ant-design/ant-design/issues/11777
|
||
|
userSelect: 'none'
|
||
|
},
|
||
|
// https://github.com/ant-design/ant-design/issues/37329
|
||
|
// https://github.com/ant-design/ant-design/issues/40272
|
||
|
[`${componentCls}${antCls}-zoom-leave ${componentCls}-content`]: {
|
||
|
pointerEvents: 'none'
|
||
|
},
|
||
|
[`${componentCls}-mask`]: Object.assign(Object.assign({}, box('fixed')), {
|
||
|
zIndex: token.zIndexPopupBase,
|
||
|
height: '100%',
|
||
|
backgroundColor: token.colorBgMask,
|
||
|
pointerEvents: 'none',
|
||
|
[`${componentCls}-hidden`]: {
|
||
|
display: 'none'
|
||
|
}
|
||
|
}),
|
||
|
[`${componentCls}-wrap`]: Object.assign(Object.assign({}, box('fixed')), {
|
||
|
zIndex: token.zIndexPopupBase,
|
||
|
overflow: 'auto',
|
||
|
outline: 0,
|
||
|
WebkitOverflowScrolling: 'touch',
|
||
|
// Note: Firefox not support `:has` yet
|
||
|
[`&:has(${componentCls}${antCls}-zoom-enter), &:has(${componentCls}${antCls}-zoom-appear)`]: {
|
||
|
pointerEvents: 'none'
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}, {
|
||
|
[`${componentCls}-root`]: initFadeMotion(token)
|
||
|
}];
|
||
|
};
|
||
|
const genModalStyle = token => {
|
||
|
const {
|
||
|
componentCls
|
||
|
} = token;
|
||
|
return [
|
||
|
// ======================== Root =========================
|
||
|
{
|
||
|
[`${componentCls}-root`]: {
|
||
|
[`${componentCls}-wrap-rtl`]: {
|
||
|
direction: 'rtl'
|
||
|
},
|
||
|
[`${componentCls}-centered`]: {
|
||
|
textAlign: 'center',
|
||
|
'&::before': {
|
||
|
display: 'inline-block',
|
||
|
width: 0,
|
||
|
height: '100%',
|
||
|
verticalAlign: 'middle',
|
||
|
content: '""'
|
||
|
},
|
||
|
[componentCls]: {
|
||
|
top: 0,
|
||
|
display: 'inline-block',
|
||
|
paddingBottom: 0,
|
||
|
textAlign: 'start',
|
||
|
verticalAlign: 'middle'
|
||
|
}
|
||
|
},
|
||
|
[`@media (max-width: ${token.screenSMMax})`]: {
|
||
|
[componentCls]: {
|
||
|
maxWidth: 'calc(100vw - 16px)',
|
||
|
margin: `${token.marginXS} auto`
|
||
|
},
|
||
|
[`${componentCls}-centered`]: {
|
||
|
[componentCls]: {
|
||
|
flex: 1
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
// ======================== Modal ========================
|
||
|
{
|
||
|
[componentCls]: Object.assign(Object.assign({}, resetComponent(token)), {
|
||
|
pointerEvents: 'none',
|
||
|
position: 'relative',
|
||
|
top: 100,
|
||
|
width: 'auto',
|
||
|
maxWidth: `calc(100vw - ${token.margin * 2}px)`,
|
||
|
margin: '0 auto',
|
||
|
paddingBottom: token.paddingLG,
|
||
|
[`${componentCls}-title`]: {
|
||
|
margin: 0,
|
||
|
color: token.titleColor,
|
||
|
fontWeight: token.fontWeightStrong,
|
||
|
fontSize: token.titleFontSize,
|
||
|
lineHeight: token.titleLineHeight,
|
||
|
wordWrap: 'break-word'
|
||
|
},
|
||
|
[`${componentCls}-content`]: {
|
||
|
position: 'relative',
|
||
|
backgroundColor: token.contentBg,
|
||
|
backgroundClip: 'padding-box',
|
||
|
border: 0,
|
||
|
borderRadius: token.borderRadiusLG,
|
||
|
boxShadow: token.boxShadow,
|
||
|
pointerEvents: 'auto',
|
||
|
padding: `${token.paddingMD}px ${token.paddingContentHorizontalLG}px`
|
||
|
},
|
||
|
[`${componentCls}-close`]: Object.assign({
|
||
|
position: 'absolute',
|
||
|
top: (token.modalHeaderHeight - token.modalCloseBtnSize) / 2,
|
||
|
insetInlineEnd: (token.modalHeaderHeight - token.modalCloseBtnSize) / 2,
|
||
|
zIndex: token.zIndexPopupBase + 10,
|
||
|
padding: 0,
|
||
|
color: token.modalCloseIconColor,
|
||
|
fontWeight: token.fontWeightStrong,
|
||
|
lineHeight: 1,
|
||
|
textDecoration: 'none',
|
||
|
background: 'transparent',
|
||
|
borderRadius: token.borderRadiusSM,
|
||
|
width: token.modalCloseBtnSize,
|
||
|
height: token.modalCloseBtnSize,
|
||
|
border: 0,
|
||
|
outline: 0,
|
||
|
cursor: 'pointer',
|
||
|
transition: `color ${token.motionDurationMid}, background-color ${token.motionDurationMid}`,
|
||
|
'&-x': {
|
||
|
display: 'flex',
|
||
|
fontSize: token.fontSizeLG,
|
||
|
fontStyle: 'normal',
|
||
|
lineHeight: `${token.modalCloseBtnSize}px`,
|
||
|
justifyContent: 'center',
|
||
|
textTransform: 'none',
|
||
|
textRendering: 'auto'
|
||
|
},
|
||
|
'&:hover': {
|
||
|
color: token.modalIconHoverColor,
|
||
|
backgroundColor: token.wireframe ? 'transparent' : token.colorFillContent,
|
||
|
textDecoration: 'none'
|
||
|
},
|
||
|
'&:active': {
|
||
|
backgroundColor: token.wireframe ? 'transparent' : token.colorFillContentHover
|
||
|
}
|
||
|
}, genFocusStyle(token)),
|
||
|
[`${componentCls}-header`]: {
|
||
|
color: token.colorText,
|
||
|
background: token.headerBg,
|
||
|
borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`,
|
||
|
marginBottom: token.marginXS
|
||
|
},
|
||
|
[`${componentCls}-body`]: {
|
||
|
fontSize: token.fontSize,
|
||
|
lineHeight: token.lineHeight,
|
||
|
wordWrap: 'break-word'
|
||
|
},
|
||
|
[`${componentCls}-footer`]: {
|
||
|
textAlign: 'end',
|
||
|
background: token.footerBg,
|
||
|
marginTop: token.marginSM,
|
||
|
[`${token.antCls}-btn + ${token.antCls}-btn:not(${token.antCls}-dropdown-trigger)`]: {
|
||
|
marginBottom: 0,
|
||
|
marginInlineStart: token.marginXS
|
||
|
}
|
||
|
},
|
||
|
[`${componentCls}-open`]: {
|
||
|
overflow: 'hidden'
|
||
|
}
|
||
|
})
|
||
|
},
|
||
|
// ======================== Pure =========================
|
||
|
{
|
||
|
[`${componentCls}-pure-panel`]: {
|
||
|
top: 'auto',
|
||
|
padding: 0,
|
||
|
display: 'flex',
|
||
|
flexDirection: 'column',
|
||
|
[`${componentCls}-content,
|
||
|
${componentCls}-body,
|
||
|
${componentCls}-confirm-body-wrapper`]: {
|
||
|
display: 'flex',
|
||
|
flexDirection: 'column',
|
||
|
flex: 'auto'
|
||
|
},
|
||
|
[`${componentCls}-confirm-body`]: {
|
||
|
marginBottom: 'auto'
|
||
|
}
|
||
|
}
|
||
|
}];
|
||
|
};
|
||
|
const genWireframeStyle = token => {
|
||
|
const {
|
||
|
componentCls,
|
||
|
antCls
|
||
|
} = token;
|
||
|
const confirmComponentCls = `${componentCls}-confirm`;
|
||
|
return {
|
||
|
[componentCls]: {
|
||
|
[`${componentCls}-content`]: {
|
||
|
padding: 0
|
||
|
},
|
||
|
[`${componentCls}-header`]: {
|
||
|
padding: token.modalHeaderPadding,
|
||
|
borderBottom: `${token.modalHeaderBorderWidth}px ${token.modalHeaderBorderStyle} ${token.modalHeaderBorderColorSplit}`,
|
||
|
marginBottom: 0
|
||
|
},
|
||
|
[`${componentCls}-body`]: {
|
||
|
padding: token.modalBodyPadding
|
||
|
},
|
||
|
[`${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`,
|
||
|
marginTop: 0
|
||
|
}
|
||
|
},
|
||
|
[confirmComponentCls]: {
|
||
|
[`${antCls}-modal-body`]: {
|
||
|
padding: `${token.padding * 2}px ${token.padding * 2}px ${token.paddingLG}px`
|
||
|
},
|
||
|
[`${confirmComponentCls}-body`]: {
|
||
|
[`> ${token.iconCls}`]: {
|
||
|
marginInlineEnd: token.margin,
|
||
|
// `content` after `icon` should set marginLeft
|
||
|
[`+ ${confirmComponentCls}-title + ${confirmComponentCls}-content`]: {
|
||
|
marginInlineStart: token.modalConfirmIconSize + token.margin
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
[`${confirmComponentCls}-btns`]: {
|
||
|
marginTop: token.marginLG
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
const genRTLStyle = token => {
|
||
|
const {
|
||
|
componentCls
|
||
|
} = token;
|
||
|
return {
|
||
|
[`${componentCls}-root`]: {
|
||
|
[`${componentCls}-wrap-rtl`]: {
|
||
|
direction: 'rtl',
|
||
|
[`${componentCls}-confirm-body`]: {
|
||
|
direction: 'rtl'
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
// ============================== Export ==============================
|
||
|
export const prepareToken = token => {
|
||
|
const headerPaddingVertical = token.padding;
|
||
|
const headerFontSize = token.fontSizeHeading5;
|
||
|
const headerLineHeight = token.lineHeightHeading5;
|
||
|
const modalToken = mergeToken(token, {
|
||
|
modalBodyPadding: token.paddingLG,
|
||
|
modalHeaderPadding: `${headerPaddingVertical}px ${token.paddingLG}px`,
|
||
|
modalHeaderBorderWidth: token.lineWidth,
|
||
|
modalHeaderBorderStyle: token.lineType,
|
||
|
modalHeaderBorderColorSplit: token.colorSplit,
|
||
|
modalHeaderHeight: headerLineHeight * headerFontSize + headerPaddingVertical * 2,
|
||
|
modalFooterBorderColorSplit: token.colorSplit,
|
||
|
modalFooterBorderStyle: token.lineType,
|
||
|
modalFooterPaddingVertical: token.paddingXS,
|
||
|
modalFooterPaddingHorizontal: token.padding,
|
||
|
modalFooterBorderWidth: token.lineWidth,
|
||
|
modalIconHoverColor: token.colorIconHover,
|
||
|
modalCloseIconColor: token.colorIcon,
|
||
|
modalCloseBtnSize: token.fontSize * token.lineHeight,
|
||
|
modalConfirmIconSize: token.fontSize * token.lineHeight
|
||
|
});
|
||
|
return modalToken;
|
||
|
};
|
||
|
export const prepareComponentToken = token => ({
|
||
|
footerBg: 'transparent',
|
||
|
headerBg: token.colorBgElevated,
|
||
|
titleLineHeight: token.lineHeightHeading5,
|
||
|
titleFontSize: token.fontSizeHeading5,
|
||
|
contentBg: token.colorBgElevated,
|
||
|
titleColor: token.colorTextHeading
|
||
|
});
|
||
|
export default genComponentStyleHook('Modal', token => {
|
||
|
const modalToken = prepareToken(token);
|
||
|
return [genModalStyle(modalToken), genRTLStyle(modalToken), genModalMaskStyle(modalToken), token.wireframe && genWireframeStyle(modalToken), initZoomMotion(modalToken, 'zoom')];
|
||
|
}, prepareComponentToken);
|