Skip to content

Commit

Permalink
fix(Ripple): prevent bubbled events from triggering more ripples
Browse files Browse the repository at this point in the history
fixes #7988
  • Loading branch information
KaelWD committed Mar 6, 2021
1 parent ce2d5f8 commit 364fb8e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
20 changes: 20 additions & 0 deletions packages/vuetify/src/directives/ripple/__tests__/ripple.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,24 @@ describe('ripple.ts', () => {
jest.runAllTimers()
expect(wrapper.find('.v-ripple__container').exists()).toBe(false)
})

it('should only ripple on one element', () => {
const wrapper = mount({
directives: { Ripple },
template: '<div v-ripple><div class="child" v-ripple></div></div>',
})

const child = wrapper.find('.child').element

const mousedownEvent = new MouseEvent('mousedown', { detail: 1, bubbles: true })
child.dispatchEvent(mousedownEvent)

expect(wrapper.findAll('.v-ripple__container')).toHaveLength(1)

const mouseupEvent = new MouseEvent('mouseup', { detail: 1, bubbles: true })
child.dispatchEvent(mouseupEvent)

jest.runAllTimers()
expect(wrapper.findAll('.v-ripple__container')).toHaveLength(0)
})
})
11 changes: 9 additions & 2 deletions packages/vuetify/src/directives/ripple/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { keyCodes } from '../../util/helpers'
// Types
import { VNode, VNodeDirective } from 'vue'

type VuetifyRippleEvent = MouseEvent | TouchEvent | KeyboardEvent
const rippleStop = Symbol('rippleStop')

type VuetifyRippleEvent = (MouseEvent | TouchEvent | KeyboardEvent) & { [rippleStop]?: boolean }

const DELAY_RIPPLE = 80

Expand Down Expand Up @@ -159,7 +161,12 @@ function isRippleEnabled (value: any): value is true {
function rippleShow (e: VuetifyRippleEvent) {
const value: RippleOptions = {}
const element = e.currentTarget as HTMLElement
if (!element || !element._ripple || element._ripple.touched) return

if (!element || !element._ripple || element._ripple.touched || e[rippleStop]) return

// Don't allow the event to trigger ripples on any other elements
e[rippleStop] = true

if (isTouchEvent(e)) {
element._ripple.touched = true
element._ripple.isTouch = true
Expand Down

0 comments on commit 364fb8e

Please sign in to comment.