mirror of
				https://github.com/antd-tiny-vue/antd-tiny-vue.git
				synced 2025-10-31 16:51:45 +08:00 
			
		
		
		
	feat: add wave
This commit is contained in:
		| @@ -1,10 +1,58 @@ | ||||
| import { defineComponent } from 'vue' | ||||
| import type { VNode } from 'vue' | ||||
| import { cloneVNode, computed, defineComponent, shallowRef } from 'vue' | ||||
| import { booleanType, classNames, filterEmpty, isVisible } from '@v-c/utils' | ||||
| import { useEventListener } from '@vueuse/core' | ||||
| import { useProviderConfigState } from '../../config-provider/context' | ||||
| import useStyle from './style' | ||||
| import useWave from './use-wave' | ||||
|  | ||||
| const Wave = defineComponent({ | ||||
|   name: 'Wave', | ||||
|   setup(_, { slots }) { | ||||
|   props: { | ||||
|     disabled: booleanType() | ||||
|   }, | ||||
|   setup(props, { slots }) { | ||||
|     const { getPrefixCls } = useProviderConfigState() | ||||
|     const containerRef = shallowRef() | ||||
|  | ||||
|     // ============================== Style =============================== | ||||
|     const prefixCls = computed(() => getPrefixCls('wave')) | ||||
|     const [, hashId] = useStyle(prefixCls) | ||||
|     const showWave = useWave( | ||||
|       containerRef, | ||||
|       computed(() => classNames(prefixCls, hashId)) | ||||
|     ) | ||||
|  | ||||
|     const onClick = (e: MouseEvent) => { | ||||
|       const node = containerRef.value | ||||
|       const { disabled } = props | ||||
|       if (!node || node.nodeType !== 1 || disabled) { | ||||
|         return | ||||
|       } | ||||
|       // Fix radio button click twice | ||||
|       if ( | ||||
|         (e.target as HTMLElement).tagName === 'INPUT' || | ||||
|         !isVisible(e.target as HTMLElement) || | ||||
|         // No need wave | ||||
|         !node.getAttribute || | ||||
|         node.getAttribute('disabled') || | ||||
|         (node as HTMLInputElement).disabled || | ||||
|         node.className.includes('disabled') || | ||||
|         node.className.includes('-leave') | ||||
|       ) { | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       showWave() | ||||
|     } | ||||
|  | ||||
|     useEventListener(containerRef, 'click', onClick, true) | ||||
|  | ||||
|     return () => { | ||||
|       return slots.default?.() | ||||
|       const children = slots.default?.() | ||||
|       const child = filterEmpty(children)[0] | ||||
|       if (!child) return null | ||||
|       return cloneVNode(child as VNode, { ref: containerRef }) | ||||
|     } | ||||
|   } | ||||
| }) | ||||
|   | ||||
							
								
								
									
										11
									
								
								components/_util/wave/use-wave.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								components/_util/wave/use-wave.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| import type { ComputedRef, Ref } from 'vue' | ||||
| import showWaveEffect from './wave-effect' | ||||
|  | ||||
| export default function useWave(nodeRef: Ref<HTMLElement>, className: ComputedRef<string>): VoidFunction { | ||||
|   function showWave() { | ||||
|     // const node = nodeRef.va! | ||||
|     showWaveEffect(nodeRef, className) | ||||
|   } | ||||
|  | ||||
|   return showWave | ||||
| } | ||||
							
								
								
									
										32
									
								
								components/_util/wave/wave-effect.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								components/_util/wave/wave-effect.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| import type { ComputedRef, Ref } from 'vue' | ||||
| import { unrefElement } from '@vueuse/core' | ||||
| import { defineComponent, render } from 'vue' | ||||
| import { objectType } from '@v-c/utils' | ||||
|  | ||||
| export const WaveEffect = defineComponent({ | ||||
|   name: 'WaveEffect', | ||||
|   props: { | ||||
|     target: objectType<HTMLElement>() | ||||
|   }, | ||||
|   setup() { | ||||
|     return () => null | ||||
|   } | ||||
| }) | ||||
|  | ||||
| export default function showWaveEffect(nodeRef: Ref<HTMLElement>, className: ComputedRef<string>) { | ||||
|   const node = unrefElement(nodeRef) | ||||
|   // Create holder | ||||
|   const holder = document.createElement('div') | ||||
|   holder.style.position = 'absolute' | ||||
|   holder.style.left = `0px` | ||||
|   holder.style.top = `0px` | ||||
|   node?.insertBefore(holder, node?.firstChild) | ||||
|  | ||||
|   render( | ||||
|     <WaveEffect | ||||
|       target={node} | ||||
|       class={className.value} | ||||
|     />, | ||||
|     holder | ||||
|   ) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user