diff --git a/components/_util/__tests__/wave.test.js b/components/_util/__tests__/wave.test.js index 7e733b9e3b..27fc2c216c 100644 --- a/components/_util/__tests__/wave.test.js +++ b/components/_util/__tests__/wave.test.js @@ -49,7 +49,10 @@ describe('Wave component', () => { it('wave color is grey', async () => { const wrapper = mount( - , @@ -197,4 +200,36 @@ describe('Wave component', () => { it('should not throw when no children', () => { expect(() => mount()).not.toThrow(); }); + + it('wave color should inferred if border is transparent and background is not', async () => { + const wrapper = mount( + + + , + ); + wrapper.find('button').getDOMNode().click(); + await sleep(200); + const styles = wrapper.find('button').getDOMNode().getRootNode().getElementsByTagName('style'); + expect(styles.length).toBe(1); + expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: red;'); + wrapper.unmount(); + }); + + it('wave color should inferred if borderTopColor is transparent and borderColor is not', async () => { + const wrapper = mount( + + + , + ); + wrapper.find('button').getDOMNode().click(); + await sleep(200); + const styles = wrapper.find('button').getDOMNode().getRootNode().getElementsByTagName('style'); + expect(styles.length).toBe(1); + expect(styles[0].innerHTML).toContain('--antd-wave-shadow-color: red;'); + wrapper.unmount(); + }); }); diff --git a/components/_util/wave/index.tsx b/components/_util/wave/index.tsx index 9a19afa651..e72127fc0e 100644 --- a/components/_util/wave/index.tsx +++ b/components/_util/wave/index.tsx @@ -27,6 +27,31 @@ function isNotGrey(color: string) { return true; } +function isValidWaveColor(color: string) { + return ( + color && + color !== '#ffffff' && + color !== 'rgb(255, 255, 255)' && + isNotGrey(color) && + !/rgba\((?:\d*, ){3}0\)/.test(color) && // any transparent rgba color + color !== 'transparent' + ); +} + +function getTargetWaveColor(node: HTMLElement) { + const computedStyle = getComputedStyle(node); + const borderTopColor = computedStyle.getPropertyValue('border-top-color'); + const borderColor = computedStyle.getPropertyValue('border-color'); + const backgroundColor = computedStyle.getPropertyValue('background-color'); + if (isValidWaveColor(borderTopColor)) { + return borderTopColor; + } + if (isValidWaveColor(borderColor)) { + return borderColor; + } + return backgroundColor; +} + export interface WaveProps { insertExtraNode?: boolean; disabled?: boolean; @@ -90,14 +115,7 @@ class InternalWave extends React.Component { const attributeName = this.getAttributeName(); node.setAttribute(attributeName, 'true'); // Not white or transparent or grey - if ( - waveColor && - waveColor !== '#ffffff' && - waveColor !== 'rgb(255, 255, 255)' && - isNotGrey(waveColor) && - !/rgba\((?:\d*, ){3}0\)/.test(waveColor) && // any transparent rgba color - waveColor !== 'transparent' - ) { + if (isValidWaveColor(waveColor)) { extraNode.style.borderColor = waveColor; const nodeRoot = node.getRootNode?.() || node.ownerDocument; @@ -167,10 +185,7 @@ class InternalWave extends React.Component { } this.resetEffect(node); // Get wave color from target - const waveColor = - getComputedStyle(node).getPropertyValue('border-top-color') || // Firefox Compatible - getComputedStyle(node).getPropertyValue('border-color') || - getComputedStyle(node).getPropertyValue('background-color'); + const waveColor = getTargetWaveColor(node); this.clickWaveTimeoutId = window.setTimeout(() => this.onClick(node, waveColor), 0); raf.cancel(this.animationStartId); diff --git a/components/_util/wave/style.ts b/components/_util/wave/style.ts index 352a7dfe9a..7381e1677c 100644 --- a/components/_util/wave/style.ts +++ b/components/_util/wave/style.ts @@ -15,7 +15,7 @@ interface WaveToken extends AliasToken { const genWaveStyle: GenerateStyle = token => { const waveEffect = new Keyframes('waveEffect', { '100%': { - boxShadow: `0 0 0 6px ${token.colorPrimary}`, + boxShadow: `0 0 0 6px var(--antd-wave-shadow-color)`, }, }); @@ -29,6 +29,8 @@ const genWaveStyle: GenerateStyle = token => { { [`${token.clickAnimatingWithoutExtraNodeTrue}, ${token.clickAnimatingTrue}`]: { + '--antd-wave-shadow-color': token.colorPrimary, + '--scroll-bar': 0, position: 'relative', }, [`${token.clickAnimatingWithoutExtraNodeTrueAfter}, @@ -40,16 +42,20 @@ const genWaveStyle: GenerateStyle = token => { bottom: 0, display: 'block', borderRadius: 'inherit', - boxShadow: `0 0 0 0 ${token.colorPrimary}`, + boxShadow: `0 0 0 0 var(--antd-wave-shadow-color)`, opacity: 0.2, - animation: `${fadeEffect.getName(token.hashId)} 2s ${ - token.motionEaseOutCirc - }, ${waveEffect.getName(token.hashId)} 0.4s ${token.motionEaseOutCirc}`, + animation: { + _skip_check_: true, + value: `${fadeEffect.getName(token.hashId)} 2s ${ + token.motionEaseOutCirc + }, ${waveEffect.getName(token.hashId)} 0.4s ${token.motionEaseOutCirc}`, + }, animationFillMode: 'forwards', content: '""', pointerEvents: 'none', }, }, + {}, waveEffect, fadeEffect, ];