Skip to content

Commit 5fa7e22

Browse files
authored
feat(v-b-visible): make v-b-visible directive available for public use (#4318)
1 parent 29f797c commit 5fa7e22

File tree

11 files changed

+207
-18
lines changed

11 files changed

+207
-18
lines changed

docs/components/section-toc.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
active-class=""
1616
>
1717
<strong class="text-primary">{{ page.title }}</strong> &mdash;
18+
<b-badge v-if="page.new" variant="success">NEW</b-badge>
1819
<span class="text-muted">{{ page.description }}</span>
20+
<b-badge v-if="page.version" variant="secondary">v{{ page.version }}</b-badge>
1921
</b-list-group-item>
2022
</b-list-group>
2123
</Section>

src/components/form-textarea/form-textarea.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Vue from '../../utils/vue'
2-
import { VBVisible } from '../../directives/visible'
2+
import { VBVisible } from '../../directives/visible/visible'
33
import idMixin from '../../mixins/id'
44
import formMixin from '../../mixins/form'
55
import formSizeMixin from '../../mixins/form-size'

src/components/image/img-lazy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Vue from '../../utils/vue'
22
import { getComponentConfig } from '../../utils/config'
33
import { hasIntersectionObserverSupport } from '../../utils/env'
4-
import { VBVisible } from '../../directives/visible'
4+
import { VBVisible } from '../../directives/visible/visible'
55
import { BImg } from './img'
66

77
const NAME = 'BImgLazy'

src/directives/index.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import { BvPlugin } from '../'
44
export declare const directivesPlugin: BvPlugin
55

66
// Named exports of all directives
7-
export * from './toggle'
87
export * from './modal'
8+
export * from './popover'
99
export * from './scrollspy'
10+
export * from './toggle'
1011
export * from './tooltip'
11-
export * from './popover'
12+
export * from './visible'

src/directives/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { VBPopoverPlugin } from './popover'
55
import { VBScrollspyPlugin } from './scrollspy'
66
import { VBTogglePlugin } from './toggle'
77
import { VBTooltipPlugin } from './tooltip'
8+
import { VBVisiblePlugin } from './visible'
89

910
// Main plugin for installing all directive plugins
1011
export const directivesPlugin = /*#__PURE__*/ pluginFactory({
@@ -13,6 +14,7 @@ export const directivesPlugin = /*#__PURE__*/ pluginFactory({
1314
VBPopoverPlugin,
1415
VBScrollspyPlugin,
1516
VBTogglePlugin,
16-
VBTooltipPlugin
17+
VBTooltipPlugin,
18+
VBVisiblePlugin
1719
}
1820
})

src/directives/visible/README.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Visible
2+
3+
> The `v-b-visible` directive allows you to react when an element becomes visible in the viewport.
4+
5+
The `v-b-visible` directive was added in version `2.1.0`.
6+
7+
## Overview
8+
9+
- `v-b-visible` will call your callback method with a boolean value indicating if the element is
10+
visible (intersecting) with the viewport.
11+
- The directive can be placed on almost any element or component.
12+
- Changes in visibility cqn also be detected (such as `display: none`), as long as the element is
13+
within (or partially within) the viewport, or within the optional offset.
14+
- Several BootstrapVue components use `v-b-visible`, such as `<b-img-lazy>`.
15+
- The `v-b-visible` directive requires browser support of
16+
[`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).
17+
For older browsers that do not support `IntersectionObserver`, you will need to use a
18+
[polyfill](/docs/#js).
19+
20+
## Directive syntax and usage
21+
22+
```html
23+
<div v-b-visible.[mod].[...]="callback">content</div>
24+
```
25+
26+
Where `callback` is required:
27+
28+
- A function reference that will be called whenever visibility changes. The callback is passed a
29+
single boolean argument. `true` indicates that the element is intersecting (partially or entirely
30+
visible) in the viewport, or `false` if the element is not visible/intersecting with the viewport.
31+
The callback will be called each time the element's visibility changes (except when hte `once`
32+
modifier is used. See below for details)
33+
34+
Where `[mod]` can be (all optional):
35+
36+
- A positive number representing the offset (margin) in pixels _away_ from the edge of the viewport
37+
to determine when the element is considered in (or just about to be in) the viewport. The value
38+
adds a margin around the view port. The default value is `0`.
39+
- The keyword `once`. When this modifier is present, the callback will be called once (with the
40+
argument of `true` indicating the element is intersecting/visible) when the element is
41+
intersecting with the viewport. Note the callback may be called prior to this with an argument of
42+
`false` signifying the element is not intersecting/visible.
43+
44+
### Usage examples
45+
46+
Basic:
47+
48+
```html
49+
<template>
50+
<div v-b-visible="visibleHandler"> ... </div>
51+
</template>
52+
<script>
53+
export default {
54+
methods: {
55+
visibleHandler(isVisible) {
56+
if (isVisible) {
57+
// Do something
58+
} else {
59+
// Do something else
60+
}
61+
}
62+
}
63+
}
64+
</script>
65+
```
66+
67+
With viewport offset modifier of 350px (if the element is outside of the physical viewport by at
68+
least 350px, then it will be considered "visible"):
69+
70+
```html
71+
<template>
72+
<div v-b-visible.350="visibleHandler"> ... </div>
73+
</template>
74+
<script>
75+
export default {
76+
methods: {
77+
visibleHandler(isVisible) {
78+
if (isVisible) {
79+
// Do something
80+
} else {
81+
// Do something else
82+
}
83+
}
84+
}
85+
}
86+
</script>
87+
```
88+
89+
With `once` modifier:
90+
91+
```html
92+
<template>
93+
<div v-b-visible.350="visibleHandler"> ... </div>
94+
</template>
95+
<script>
96+
export default {
97+
methods: {
98+
visibleHandler(isVisible) {
99+
if (isVisible) {
100+
// This will only ever happen once, when the
101+
// element has become visible for the first time
102+
} else {
103+
// This may happen zero or more times before
104+
// the element becomes visible, but will never
105+
// happen after the element has become visible
106+
}
107+
}
108+
}
109+
}
110+
</script>
111+
```
112+
113+
With `once` and offset modifiers:
114+
115+
```html
116+
<template>
117+
<div v-b-visible.350.once="visibleHandler"> ... </div>
118+
</template>
119+
<script>
120+
export default {
121+
methods: {
122+
visibleHandler(isVisible) {
123+
if (isVisible) {
124+
// This will only ever happen once, when the
125+
// element has become visible for the first time
126+
} else {
127+
// This may happen zero or more times before
128+
// the element becomes visible, but will never
129+
// happen after the element has become visible
130+
}
131+
}
132+
}
133+
}
134+
</script>
135+
```

src/directives/visible/index.d.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//
2+
// VBVisible
3+
//
4+
import Vue, { DirectiveOptions } from 'vue'
5+
import { BvPlugin } from '../../'
6+
7+
// Plugin
8+
export declare const VBVisiblePlugin: BvPlugin
9+
10+
// Directive: v-b-visible
11+
export declare const VBVisible: DirectiveOptions

src/directives/visible/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { VBVisible } from './visible'
2+
import { pluginFactory } from '../../utils/plugins'
3+
4+
const VBVisiblePlugin = /*#__PURE__*/ pluginFactory({
5+
directives: { VBVisible }
6+
})
7+
8+
export { VBVisiblePlugin, VBVisible }

src/directives/visible/package.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "@bootstrap-vue/v-b-visible",
3+
"version": "0.0.0",
4+
"meta": {
5+
"title": "Visible",
6+
"description": "The `v-b-visible` directive allows you to react when an element becomes visible in the viewport.",
7+
"directive": "VBVisible",
8+
"new": true,
9+
"version": "2.1.0",
10+
"expression": [
11+
"Function"
12+
],
13+
"modifiers": [
14+
{
15+
"name": "once",
16+
"description": "Only calls the callback once when the element becomes visible in the viewport"
17+
},
18+
{
19+
"name": "{###}",
20+
"pattern": "[0-9]+",
21+
"description": "An offset value in pixels (where `{###}` is the number of pixels) relative to the viewport, defaults to 0. Negative values allowed"
22+
}
23+
]
24+
}
25+
}

src/directives/visible.js renamed to src/directives/visible/visible.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
// )
3232
// }
3333

34-
import looseEqual from '../utils/loose-equal'
35-
import { requestAF } from '../utils/dom'
36-
import { isFunction } from '../utils/inspect'
37-
import { keys } from '../utils/object'
34+
import looseEqual from '../../utils/loose-equal'
35+
import { requestAF } from '../../utils/dom'
36+
import { isFunction } from '../../utils/inspect'
37+
import { keys } from '../../utils/object'
3838

3939
const OBSERVER_PROP_NAME = '__bv__visibility_observer'
4040

0 commit comments

Comments
 (0)