A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/bootstrap-vue/bootstrap-vue/commit/b7adc6dc726f75c0578b3de5208f112bef58b4ad below:

new directive for reacting to hover changes (#4771) · bootstrap-vue/bootstrap-vue@b7adc6d · GitHub

File tree Expand file treeCollapse file tree 11 files changed

+243

-160

lines changed

Filter options

Expand file treeCollapse file tree 11 files changed

+243

-160

lines changed Original file line number Diff line number Diff line change

@@ -0,0 +1,89 @@

1 +

# Hover

2 + 3 +

> `v-b-hover` is a lightweight directive that allows you to react when an element either becomes

4 +

> hovered or unhovered.

5 + 6 +

The `v-b-hover` directive can be used as an alternative to using custom CSS to handle hover states.

7 + 8 +

The `v-b-hover` directive was added in version `2.5.0`.

9 + 10 +

## Overview

11 + 12 +

- `v-b-hover` will call your callback method with a boolean value indicating if the element is

13 +

hovered or not.

14 +

- The directive can be placed on almost any element or component.

15 +

- Internally, BootstrapVue uses this directive in several components.

16 + 17 +

## Directive syntax and usage

18 + 19 +

```html

20 +

<div v-b-hover="callback">content</div>

21 +

```

22 + 23 +

Where callback is required:

24 + 25 +

- A function reference that will be called whenever hover state changes. The callback is passed a

26 +

single boolean argument. `true` indicates that the element (or component) is hovered by the users

27 +

pointing device, or `false` if the element is not hovered.

28 + 29 +

The directive has no modifiers.

30 + 31 +

### Usage example

32 + 33 +

```html

34 +

<template>

35 +

<div v-b-hover="hoverHandler"> ... </div>

36 +

</template>

37 + 38 +

<script>

39 +

export default {

40 +

methods: {

41 +

hoverHandler(isHovered) {

42 +

if (isHovered) {

43 +

// Do something

44 +

} else {

45 +

// Do something else

46 +

}

47 +

}

48 +

}

49 +

}

50 +

</script>

51 +

```

52 + 53 +

## Live example

54 + 55 +

In the following, we are swapping icons and tet color depending on the hover state of the element:

56 + 57 +

```html

58 +

<template>

59 +

<div>

60 +

<div v-b-hover="handleHover" class="border rounded py-3 px-4">

61 +

<b-icon v-if="isHovered" icon="battery-full" scale="2"></b-icon>

62 +

<b-icon v-else icon="battery" scale="2"></b-icon>

63 +

<span class="ml-2" :class="isHovered ? 'text-danger' : ''">Hover this area</span>

64 +

</div>

65 +

</div>

66 +

</template>

67 + 68 +

<script>

69 +

export default {

70 +

data() {

71 +

return {

72 +

isHovered: false

73 +

}

74 +

},

75 +

methods: {

76 +

handleHover(hovered) {

77 +

this.isHovered = hovered

78 +

}

79 +

}

80 +

}

81 +

</script>

82 + 83 +

<!-- b-v-hover-example.vue -->

84 +

```

85 + 86 +

## Accessibility concerns

87 + 88 +

Hover state should not be used to convey special meaning, as screen reader users and keyboard only

89 +

users typically ac not typically trigger hover state on elements.

Original file line number Diff line number Diff line change

@@ -0,0 +1,53 @@

1 +

// v-b-hover directive

2 +

import { isBrowser } from '../../utils/env'

3 +

import { EVENT_OPTIONS_NO_CAPTURE, eventOnOff } from '../../utils/events'

4 +

import { isFunction } from '../../utils/inspect'

5 + 6 +

// --- Constants ---

7 + 8 +

const PROP = '__BV_hover_handler__'

9 +

const MOUSEENTER = 'mouseenter'

10 +

const MOUSELEAVE = 'mouseleave'

11 + 12 +

// --- Utility methods ---

13 + 14 +

const createListener = handler => {

15 +

const listener = evt => {

16 +

handler(evt.type === MOUSEENTER, evt)

17 +

}

18 +

listener.fn = handler

19 +

return listener

20 +

}

21 + 22 +

const updateListeners = (on, el, listener) => {

23 +

eventOnOff(on, el, MOUSEENTER, listener, EVENT_OPTIONS_NO_CAPTURE)

24 +

eventOnOff(on, el, MOUSELEAVE, listener, EVENT_OPTIONS_NO_CAPTURE)

25 +

}

26 + 27 +

// --- Directive bind/unbind/update handler ---

28 + 29 +

const directive = (el, { value: handler = null }) => {

30 +

if (isBrowser) {

31 +

const listener = el[PROP]

32 +

const hasListener = isFunction(listener)

33 +

const handlerChanged = !(hasListener && listener.fn === handler)

34 +

if (hasListener && handlerChanged) {

35 +

updateListeners(false, el, listener)

36 +

delete el[PROP]

37 +

}

38 +

if (isFunction(handler) && handlerChanged) {

39 +

el[PROP] = createListener(handler)

40 +

updateListeners(true, el, el[PROP])

41 +

}

42 +

}

43 +

}

44 + 45 +

// VBHover directive

46 + 47 +

export const VBHover = {

48 +

bind: directive,

49 +

componentUpdated: directive,

50 +

unbind(el) {

51 +

directive(el, { value: null })

52 +

}

53 +

}

Original file line number Diff line number Diff line change

@@ -0,0 +1,61 @@

1 +

import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils'

2 +

import { waitNT } from '../../../tests/utils'

3 +

import { VBHover } from './hover'

4 + 5 +

describe('v-b-hover directive', () => {

6 +

it('works', async () => {

7 +

const localVue = new CreateLocalVue()

8 +

let hovered1 = false

9 +

let hovered2 = false

10 +

const App = localVue.extend({

11 +

data() {

12 +

return {

13 +

text: 'FOO',

14 +

changeHandler: false

15 +

}

16 +

},

17 +

directives: {

18 +

BHover: VBHover

19 +

},

20 +

methods: {

21 +

handleHover1(isHovered) {

22 +

hovered1 = isHovered

23 +

},

24 +

handleHover2(isHovered) {

25 +

hovered2 = isHovered

26 +

}

27 +

},

28 +

template: `<div v-b-hover="changeHandler ? handleHover2 : handleHover1"><span>{{ text }}</span></div>`

29 +

})

30 +

const wrapper = mount(App)

31 + 32 +

expect(wrapper.isVueInstance()).toBe(true)

33 +

expect(hovered1).toBe(false)

34 + 35 +

wrapper.trigger('mouseenter')

36 +

await waitNT(wrapper.vm)

37 + 38 +

expect(hovered1).toBe(true)

39 + 40 +

wrapper.trigger('mouseleave')

41 +

await waitNT(wrapper.vm)

42 + 43 +

expect(hovered1).toBe(false)

44 + 45 +

wrapper.setData({ text: 'BAR' })

46 + 47 +

wrapper.trigger('mouseenter')

48 +

await waitNT(wrapper.vm)

49 + 50 +

expect(hovered1).toBe(true)

51 + 52 +

wrapper.setData({ changeHandler: true })

53 + 54 +

wrapper.trigger('mouseenter')

55 +

await waitNT(wrapper.vm)

56 + 57 +

expect(hovered2).toBe(true)

58 + 59 +

wrapper.destroy()

60 +

})

61 +

})

Original file line number Diff line number Diff line change

@@ -0,0 +1,11 @@

1 +

//

2 +

// VBHover

3 +

//

4 +

import Vue, { DirectiveOptions } from 'vue'

5 +

import { BvPlugin } from '../../'

6 + 7 +

// Plugin

8 +

export declare const VBHoverPlugin: BvPlugin

9 + 10 +

// directive: v-b-hover

11 +

export declare const VBHover: DirectiveOptions

Original file line number Diff line number Diff line change

@@ -0,0 +1,8 @@

1 +

import { VBHover } from './hover'

2 +

import { pluginFactory } from '../../utils/plugins'

3 + 4 +

const VBHoverPlugin = /*#__PURE__*/ pluginFactory({

5 +

directives: { VBHover }

6 +

})

7 + 8 +

export { VBHoverPlugin, VBHover }

Original file line number Diff line number Diff line change

@@ -0,0 +1,14 @@

1 +

{

2 +

"name": "@bootstrap-vue/v-b-hover",

3 +

"version": "1.0.0",

4 +

"meta": {

5 +

"title": "Hover",

6 +

"description": "A lightweight directive that allows you to react when an element either becomes hovered or unhovered",

7 +

"directive": "VBHover",

8 +

"new": true,

9 +

"version": "2.5.0",

10 +

"expression": [

11 +

"Function"

12 +

]

13 +

}

14 +

}

Original file line number Diff line number Diff line change

@@ -4,6 +4,7 @@ import { BvPlugin } from '../'

4 4

export declare const directivesPlugin: BvPlugin

5 5 6 6

// Named exports of all directives

7 +

export * from './hover'

7 8

export * from './modal'

8 9

export * from './popover'

9 10

export * from './scrollspy'

Original file line number Diff line number Diff line change

@@ -1,5 +1,6 @@

1 1

import { pluginFactory } from '../utils/plugins'

2 2 3 +

import { VBHoverPlugin } from './hover'

3 4

import { VBModalPlugin } from './modal'

4 5

import { VBPopoverPlugin } from './popover'

5 6

import { VBScrollspyPlugin } from './scrollspy'

@@ -10,6 +11,7 @@ import { VBVisiblePlugin } from './visible'

10 11

// Main plugin for installing all directive plugins

11 12

export const directivesPlugin = /*#__PURE__*/ pluginFactory({

12 13

plugins: {

14 +

VBHoverPlugin,

13 15

VBModalPlugin,

14 16

VBPopoverPlugin,

15 17

VBScrollspyPlugin,

Original file line number Diff line number Diff line change

@@ -285,6 +285,10 @@ export { BTooltip } from './components/tooltip/tooltip'

285 285

// can be reverted back to `export * from './scrollspy'` when Webpack v5 is released

286 286

// https://github.com/webpack/webpack/pull/9203 (available in Webpack v5.0.0-alpha.15)

287 287 288 +

// export * from './directives/hover'

289 +

export { VBHoverPlugin } from './directives/hover'

290 +

export { VBHover } from './directives/hover/hover'

291 + 288 292

// export * from './directives/modal'

289 293

export { VBModalPlugin } from './directives/modal'

290 294

export { VBModal } from './directives/modal/modal'

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4