mirror of
				https://github.com/antd-tiny-vue/antd-tiny-vue.git
				synced 2025-10-31 08:41: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 | ||||
|   ) | ||||
| } | ||||
| @@ -17,7 +17,7 @@ | ||||
|     "@ant-design/colors": "^7.0.0", | ||||
|     "@antd-tiny-vue/cssinjs": "^0.0.4", | ||||
|     "@ctrl/tinycolor": "^3.6.0", | ||||
|     "@v-c/utils": "^0.0.5", | ||||
|     "@v-c/utils": "^0.0.12", | ||||
|     "@vueuse/core": "^9.13.0", | ||||
|     "vue": "^3.2.0" | ||||
|   }, | ||||
|   | ||||
							
								
								
									
										8
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @@ -10,7 +10,7 @@ specifiers: | ||||
|   '@mistjs/tsconfig': ^1.0.0 | ||||
|   '@mistjs/tsconfig-vue': ^0.0.3 | ||||
|   '@types/node': ^18.13.0 | ||||
|   '@v-c/utils': ^0.0.5 | ||||
|   '@v-c/utils': ^0.0.12 | ||||
|   '@vitejs/plugin-vue-jsx': ^3.0.0 | ||||
|   '@vueuse/core': ^9.13.0 | ||||
|   eslint: ^8.34.0 | ||||
| @@ -28,7 +28,7 @@ dependencies: | ||||
|   '@ant-design/colors': 7.0.0 | ||||
|   '@antd-tiny-vue/cssinjs': 0.0.4_vue@3.2.47 | ||||
|   '@ctrl/tinycolor': 3.6.0 | ||||
|   '@v-c/utils': 0.0.5 | ||||
|   '@v-c/utils': 0.0.12 | ||||
|   '@vueuse/core': 9.13.0_vue@3.2.47 | ||||
|   vue: 3.2.47 | ||||
|  | ||||
| @@ -1280,8 +1280,8 @@ packages: | ||||
|       eslint-visitor-keys: 3.3.0 | ||||
|     dev: true | ||||
|  | ||||
|   /@v-c/utils/0.0.5: | ||||
|     resolution: {integrity: sha512-HiK9iupJ3YIl4AO8VxvQMVh5G7pkTYo7wMhWdsWr6XOPw86p5MgWdQRLhQNX1WbDjA9BsbpjuO7I5PyEhGYoFw==} | ||||
|   /@v-c/utils/0.0.12: | ||||
|     resolution: {integrity: sha512-onwjLSQpH6SG78WJnKiw8XgJfCgYtq59zFW19yiT22ik7ncaLkjojjCU0cAZDA6j6zY6li5U0VuZk91KbOrw2A==} | ||||
|     dependencies: | ||||
|       lodash.clonedeep: 4.5.0 | ||||
|       vue: 3.2.47 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user