diff --git a/components/_util/cssinjs/hooks/useStyleRegister.tsx b/components/_util/cssinjs/hooks/useStyleRegister.tsx index 8eb7f35cc..ce94ba7df 100644 --- a/components/_util/cssinjs/hooks/useStyleRegister.tsx +++ b/components/_util/cssinjs/hooks/useStyleRegister.tsx @@ -28,7 +28,7 @@ import type { VueNode } from '../../type'; const isClientSide = canUseDom(); const SKIP_CHECK = '_skip_check_'; - +const MULTI_VALUE = '_multi_value_'; export type CSSProperties = Omit, 'animationName'> & { animationName?: CSS.PropertiesFallback['animationName'] | Keyframes; }; @@ -39,6 +39,7 @@ export type CSSPropertiesWithMultiValues = { | Extract[] | { [SKIP_CHECK]: boolean; + [MULTI_VALUE]?: boolean; value: CSSProperties[K] | Extract[]; }; }; @@ -65,7 +66,7 @@ export function normalizeStyle(styleStr: string) { } function isCompoundCSSProperty(value: CSSObject[string]) { - return typeof value === 'object' && value && SKIP_CHECK in value; + return typeof value === 'object' && value && (SKIP_CHECK in value || MULTI_VALUE in value); } // 注入 hash 值 @@ -224,32 +225,45 @@ export const parseStyle = ( styleStr += `${mergedKey}${parsedStr}`; } else { + function appendStyle(cssKey: string, cssValue: any) { + if ( + process.env.NODE_ENV !== 'production' && + (typeof value !== 'object' || !(value as any)?.[SKIP_CHECK]) + ) { + [contentQuotesLinter, hashedAnimationLinter, ...linters].forEach(linter => + linter(cssKey, cssValue, { path, hashId, parentSelectors }), + ); + } + + // 如果是样式则直接插入 + const styleName = cssKey.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`); + + // Auto suffix with px + let formatValue = cssValue; + if (!unitless[cssKey] && typeof formatValue === 'number' && formatValue !== 0) { + formatValue = `${formatValue}px`; + } + + // handle animationName & Keyframe value + if (cssKey === 'animationName' && (cssValue as Keyframes)?._keyframe) { + parseKeyframes(cssValue as Keyframes); + formatValue = (cssValue as Keyframes).getName(hashId); + } + + styleStr += `${styleName}:${formatValue};`; + } const actualValue = (value as any)?.value ?? value; if ( - process.env.NODE_ENV !== 'production' && - (typeof value !== 'object' || !(value as any)?.[SKIP_CHECK]) + typeof value === 'object' && + (value as any)?.[MULTI_VALUE] && + Array.isArray(actualValue) ) { - [contentQuotesLinter, hashedAnimationLinter, ...linters].forEach(linter => - linter(key, actualValue, { path, hashId, parentSelectors }), - ); + actualValue.forEach(item => { + appendStyle(key, item); + }); + } else { + appendStyle(key, actualValue); } - - // 如果是样式则直接插入 - const styleName = key.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`); - - // Auto suffix with px - let formatValue = actualValue; - if (!unitless[key] && typeof formatValue === 'number' && formatValue !== 0) { - formatValue = `${formatValue}px`; - } - - // handle animationName & Keyframe value - if (key === 'animationName' && (value as Keyframes)?._keyframe) { - parseKeyframes(value as Keyframes); - formatValue = (value as Keyframes).getName(hashId); - } - - styleStr += `${styleName}:${formatValue};`; } }); } diff --git a/components/style/roundedArrow.ts b/components/style/roundedArrow.ts index da57debbc..304a8e3d0 100644 --- a/components/style/roundedArrow.ts +++ b/components/style/roundedArrow.ts @@ -10,31 +10,33 @@ export const roundedArrow = ( ): CSSObject => { const unitWidth = width / 2; - const ax = unitWidth - outerRadius * (Math.sqrt(2) - 1); + const ax = 0; const ay = unitWidth; - const bx = unitWidth + outerRadius * (1 - 1 / Math.sqrt(2)); + const bx = (outerRadius * 1) / Math.sqrt(2); const by = unitWidth - outerRadius * (1 - 1 / Math.sqrt(2)); - const cx = 2 * unitWidth - innerRadius * (1 / Math.sqrt(2)); - const cy = innerRadius * (1 / Math.sqrt(2)); - const dx = 4 * unitWidth - cx; + const cx = unitWidth - innerRadius * (1 / Math.sqrt(2)); + const cy = outerRadius * (Math.sqrt(2) - 1) + innerRadius * (1 / Math.sqrt(2)); + const dx = 2 * unitWidth - cx; const dy = cy; - const ex = 4 * unitWidth - bx; + const ex = 2 * unitWidth - bx; const ey = by; - const fx = 4 * unitWidth - ax; + const fx = 2 * unitWidth - ax; const fy = ay; + const shadowWidth = unitWidth * Math.sqrt(2) + outerRadius * (Math.sqrt(2) - 2); + const polygonOffset = outerRadius * (Math.sqrt(2) - 1); + return { - borderRadius: { _skip_check_: true, value: `0 0 ${innerRadius}px` }, pointerEvents: 'none', - width: width * 2, - height: width * 2, + width, + height: width, overflow: 'hidden', '&::after': { content: '""', position: 'absolute', - width: width / Math.sqrt(2), - height: width / Math.sqrt(2), + width: shadowWidth, + height: shadowWidth, bottom: 0, insetInline: 0, margin: 'auto', @@ -52,10 +54,18 @@ export const roundedArrow = ( position: 'absolute', bottom: 0, insetInlineStart: 0, - width: width * 2, + width, height: width / 2, background: bgColor, - clipPath: `path('M ${ax} ${ay} A ${outerRadius} ${outerRadius} 0 0 0 ${bx} ${by} L ${cx} ${cy} A ${innerRadius} ${innerRadius} 0 0 1 ${dx} ${dy} L ${ex} ${ey} A ${outerRadius} ${outerRadius} 0 0 0 ${fx} ${fy} Z')`, + clipPath: { + _multi_value_: true, + value: [ + `polygon(${polygonOffset}px 100%, 50% ${polygonOffset}px, ${ + 2 * unitWidth - polygonOffset + }px 100%, ${polygonOffset}px 100%)`, + `path('M ${ax} ${ay} A ${outerRadius} ${outerRadius} 0 0 0 ${bx} ${by} L ${cx} ${cy} A ${innerRadius} ${innerRadius} 0 0 1 ${dx} ${dy} L ${ex} ${ey} A ${outerRadius} ${outerRadius} 0 0 0 ${fx} ${fy} Z')`, + ], + } as any, content: '""', }, };