From 691bd2b965617ceec56da686b6a1983ce50e9a83 Mon Sep 17 00:00:00 2001 From: aibayanyu Date: Sat, 18 Mar 2023 18:17:20 +0800 Subject: [PATCH] feat: add wave --- components/_util/wave/index.tsx | 12 ++++++++ components/_util/wave/style.ts | 34 +++++++++++++++++++++++ components/_util/wave/util.ts | 35 ++++++++++++++++++++++++ components/button/button.tsx | 15 ++++++---- components/theme/interface/components.ts | 4 +-- 5 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 components/_util/wave/index.tsx create mode 100644 components/_util/wave/style.ts create mode 100644 components/_util/wave/util.ts diff --git a/components/_util/wave/index.tsx b/components/_util/wave/index.tsx new file mode 100644 index 0000000..6af4c35 --- /dev/null +++ b/components/_util/wave/index.tsx @@ -0,0 +1,12 @@ +import { defineComponent } from 'vue' + +const Wave = defineComponent({ + name: 'Wave', + setup(_, { slots }) { + return () => { + return slots.default?.() + } + } +}) + +export default Wave diff --git a/components/_util/wave/style.ts b/components/_util/wave/style.ts new file mode 100644 index 0000000..f72b0d6 --- /dev/null +++ b/components/_util/wave/style.ts @@ -0,0 +1,34 @@ +import { genComponentStyleHook } from '../../theme/internal' +import type { FullToken, GenerateStyle } from '../../theme/internal' + +export interface ComponentToken {} + +export interface WaveToken extends FullToken<'Wave'> {} + +const genWaveStyle: GenerateStyle = token => { + const { componentCls, colorPrimary } = token + return { + [componentCls]: { + position: 'absolute', + background: 'transparent', + pointerEvents: 'none', + boxSizing: 'border-box', + color: `var(--wave-color, ${colorPrimary})`, + + boxShadow: `0 0 0 0 currentcolor`, + opacity: 0.2, + + // =================== Motion =================== + '&.wave-motion-appear': { + transition: [`box-shadow 0.4s ${token.motionEaseOutCirc}`, `opacity 2s ${token.motionEaseOutCirc}`].join(','), + + '&-active': { + boxShadow: `0 0 0 6px currentcolor`, + opacity: 0 + } + } + } + } +} + +export default genComponentStyleHook('Wave', token => [genWaveStyle(token)]) diff --git a/components/_util/wave/util.ts b/components/_util/wave/util.ts new file mode 100644 index 0000000..ff5c1e7 --- /dev/null +++ b/components/_util/wave/util.ts @@ -0,0 +1,35 @@ +export function isNotGrey(color: string) { + // eslint-disable-next-line no-useless-escape + const match = (color || '').match(/rgba?\((\d*), (\d*), (\d*)(, [\d.]*)?\)/) + if (match && match[1] && match[2] && match[3]) { + return !(match[1] === match[2] && match[2] === match[3]) + } + return true +} + +export function isValidWaveColor(color: string) { + return ( + color && + color !== '#fff' && + color !== '#ffffff' && + color !== 'rgb(255, 255, 255)' && + color !== 'rgba(255, 255, 255, 1)' && + isNotGrey(color) && + !/rgba\((?:\d*, ){3}0\)/.test(color) && // any transparent rgba color + color !== 'transparent' + ) +} + +export function getTargetWaveColor(node: HTMLElement) { + const { borderTopColor, borderColor, backgroundColor } = getComputedStyle(node) + if (isValidWaveColor(borderTopColor)) { + return borderTopColor + } + if (isValidWaveColor(borderColor)) { + return borderColor + } + if (isValidWaveColor(backgroundColor)) { + return backgroundColor + } + return null +} diff --git a/components/button/button.tsx b/components/button/button.tsx index 626328e..e540b6d 100644 --- a/components/button/button.tsx +++ b/components/button/button.tsx @@ -1,5 +1,6 @@ import { computed, defineComponent } from 'vue' import { useProviderConfigState } from '../config-provider/context' +import Wave from '../_util/wave' import useStyle from './style' const Button = defineComponent({ @@ -29,12 +30,14 @@ const Button = defineComponent({ return () => { return wrapSSR( - + + + ) } } diff --git a/components/theme/interface/components.ts b/components/theme/interface/components.ts index 02ea390..a2ccfe9 100644 --- a/components/theme/interface/components.ts +++ b/components/theme/interface/components.ts @@ -48,7 +48,7 @@ import type { ComponentToken as ButtonComponentToken } from '../../button/style' // import type { ComponentToken as TourComponentToken } from '../../tour/style' // import type { ComponentToken as QRCodeComponentToken } from '../../qrcode/style' // import type { ComponentToken as AppComponentToken } from '../../app/style' -// import type { ComponentToken as WaveToken } from '../../_util/wave/style' +import type { ComponentToken as WaveToken } from '../../_util/wave/style' export interface ComponentTokenMap { Affix?: {} @@ -115,5 +115,5 @@ export interface ComponentTokenMap { // App?: AppComponentToken // // /** @private Internal TS definition. Do not use. */ - // Wave?: WaveToken + Wave?: WaveToken }