diff --git a/components/_util/wave/index.tsx b/components/_util/wave/index.tsx new file mode 100644 index 0000000..e3f2c20 --- /dev/null +++ b/components/_util/wave/index.tsx @@ -0,0 +1,11 @@ +import { defineComponent } from 'vue' + +const Wave = defineComponent({ + name: 'Wave', + inheritAttrs: false, + setup() { + return () => {} + } +}) + +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/config-provider/context.ts b/components/config-provider/context.ts index bbfe898..7d79327 100644 --- a/components/config-provider/context.ts +++ b/components/config-provider/context.ts @@ -1,5 +1,4 @@ -import { createInjectionState } from '@vueuse/core' -import { computed } from 'vue' +import { computed, inject, provide } from 'vue' export const defaultIconPrefixCls = 'anticon' @@ -8,21 +7,27 @@ const defaultGetPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => return suffixCls ? `ant-${suffixCls}` : 'ant' } -const [useProviderConfigProvide, useProviderConfigInject] = createInjectionState(() => { + +export const ConfigProviderContext = Symbol('ConfigProviderContext') + +export const defaultConfigProviderState = () => { const getPrefixCls = defaultGetPrefixCls const iconPrefixCls = computed(() => defaultIconPrefixCls) return { getPrefixCls, iconPrefixCls } -}) +} + +const useProviderConfigProvide = () => { + const defaultState = defaultConfigProviderState() + provide(ConfigProviderContext, defaultState) + return { + ...defaultState + } +} export { useProviderConfigProvide } export const useProviderConfigState = () => { - return ( - useProviderConfigInject() ?? { - getPrefixCls: defaultGetPrefixCls, - iconPrefixCls: computed(() => defaultIconPrefixCls) - } - ) + return inject(ConfigProviderContext, defaultConfigProviderState()) } diff --git a/components/theme/interface/components.ts b/components/theme/interface/components.ts index b776fb8..9d488d5 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 } diff --git a/components/theme/internal.ts b/components/theme/internal.ts index c819b2e..de16cd6 100644 --- a/components/theme/internal.ts +++ b/components/theme/internal.ts @@ -1,8 +1,7 @@ import type { CSSInterpolation, Theme } from '@antd-tiny-vue/cssinjs' import { createTheme, useCacheToken, useStyleRegister } from '@antd-tiny-vue/cssinjs' -import { createInjectionState } from '@vueuse/core' import type { ComputedRef, VNodeChild } from 'vue' -import { computed } from 'vue' +import { computed, inject, provide } from 'vue' import version from '../version' import type { AliasToken, GlobalToken, MapToken, OverrideToken, PresetColorKey, PresetColorType, SeedToken } from './interface' import { PresetColors } from './interface' @@ -50,12 +49,14 @@ export interface DesignTokenConfig { hashed?: string | boolean } -const [useDesignTokenProvider, useDesignTokenInject] = createInjectionState((token: DesignTokenConfig) => { - return token -}) +export const DesignTokenContext = Symbol('DesignTokenContext') + +const useDesignTokenProvider = (token: DesignTokenConfig) => { + provide(DesignTokenContext, token) +} export { useDesignTokenProvider } -export const useDesignTokenState = () => useDesignTokenInject() ?? defaultConfig +export const useDesignTokenState = () => inject(DesignTokenContext, defaultConfig) // ================================== Hook ================================== export function useToken(): [ComputedRef>, ComputedRef, ComputedRef] {