Skip to content
Permalink
Browse files

feat(v-b-visible): make `v-b-visible` directive available for public …

…use (#4318)
  • Loading branch information
tmorehouse committed Oct 30, 2019
1 parent 29f797c commit 5fa7e22cc3cca6295d226037f880074cfe841b2c
@@ -15,7 +15,9 @@
active-class=""
>
<strong class="text-primary">{{ page.title }}</strong> &mdash;
<b-badge v-if="page.new" variant="success">NEW</b-badge>
<span class="text-muted">{{ page.description }}</span>
<b-badge v-if="page.version" variant="secondary">v{{ page.version }}</b-badge>
</b-list-group-item>
</b-list-group>
</Section>
@@ -1,5 +1,5 @@
import Vue from '../../utils/vue'
import { VBVisible } from '../../directives/visible'
import { VBVisible } from '../../directives/visible/visible'
import idMixin from '../../mixins/id'
import formMixin from '../../mixins/form'
import formSizeMixin from '../../mixins/form-size'
@@ -1,7 +1,7 @@
import Vue from '../../utils/vue'
import { getComponentConfig } from '../../utils/config'
import { hasIntersectionObserverSupport } from '../../utils/env'
import { VBVisible } from '../../directives/visible'
import { VBVisible } from '../../directives/visible/visible'
import { BImg } from './img'

const NAME = 'BImgLazy'
@@ -4,8 +4,9 @@ import { BvPlugin } from '../'
export declare const directivesPlugin: BvPlugin

// Named exports of all directives
export * from './toggle'
export * from './modal'
export * from './popover'
export * from './scrollspy'
export * from './toggle'
export * from './tooltip'
export * from './popover'
export * from './visible'
@@ -5,6 +5,7 @@ import { VBPopoverPlugin } from './popover'
import { VBScrollspyPlugin } from './scrollspy'
import { VBTogglePlugin } from './toggle'
import { VBTooltipPlugin } from './tooltip'
import { VBVisiblePlugin } from './visible'

// Main plugin for installing all directive plugins
export const directivesPlugin = /*#__PURE__*/ pluginFactory({
@@ -13,6 +14,7 @@ export const directivesPlugin = /*#__PURE__*/ pluginFactory({
VBPopoverPlugin,
VBScrollspyPlugin,
VBTogglePlugin,
VBTooltipPlugin
VBTooltipPlugin,
VBVisiblePlugin
}
})
@@ -0,0 +1,135 @@
# Visible

> The `v-b-visible` directive allows you to react when an element becomes visible in the viewport.
The `v-b-visible` directive was added in version `2.1.0`.

## Overview

- `v-b-visible` will call your callback method with a boolean value indicating if the element is
visible (intersecting) with the viewport.
- The directive can be placed on almost any element or component.
- Changes in visibility cqn also be detected (such as `display: none`), as long as the element is
within (or partially within) the viewport, or within the optional offset.
- Several BootstrapVue components use `v-b-visible`, such as `<b-img-lazy>`.
- The `v-b-visible` directive requires browser support of
[`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).
For older browsers that do not support `IntersectionObserver`, you will need to use a
[polyfill](/docs/#js).

## Directive syntax and usage

```html
<div v-b-visible.[mod].[...]="callback">content</div>
```

Where `callback` is required:

- A function reference that will be called whenever visibility changes. The callback is passed a
single boolean argument. `true` indicates that the element is intersecting (partially or entirely
visible) in the viewport, or `false` if the element is not visible/intersecting with the viewport.
The callback will be called each time the element's visibility changes (except when hte `once`
modifier is used. See below for details)

Where `[mod]` can be (all optional):

- A positive number representing the offset (margin) in pixels _away_ from the edge of the viewport
to determine when the element is considered in (or just about to be in) the viewport. The value
adds a margin around the view port. The default value is `0`.
- The keyword `once`. When this modifier is present, the callback will be called once (with the
argument of `true` indicating the element is intersecting/visible) when the element is
intersecting with the viewport. Note the callback may be called prior to this with an argument of
`false` signifying the element is not intersecting/visible.

### Usage examples

Basic:

```html
<template>
<div v-b-visible="visibleHandler"> ... </div>
</template>
<script>
export default {
methods: {
visibleHandler(isVisible) {
if (isVisible) {
// Do something
} else {
// Do something else
}
}
}
}
</script>
```

With viewport offset modifier of 350px (if the element is outside of the physical viewport by at
least 350px, then it will be considered "visible"):

```html
<template>
<div v-b-visible.350="visibleHandler"> ... </div>
</template>
<script>
export default {
methods: {
visibleHandler(isVisible) {
if (isVisible) {
// Do something
} else {
// Do something else
}
}
}
}
</script>
```

With `once` modifier:

```html
<template>
<div v-b-visible.350="visibleHandler"> ... </div>
</template>
<script>
export default {
methods: {
visibleHandler(isVisible) {
if (isVisible) {
// This will only ever happen once, when the
// element has become visible for the first time
} else {
// This may happen zero or more times before
// the element becomes visible, but will never
// happen after the element has become visible
}
}
}
}
</script>
```

With `once` and offset modifiers:

```html
<template>
<div v-b-visible.350.once="visibleHandler"> ... </div>
</template>
<script>
export default {
methods: {
visibleHandler(isVisible) {
if (isVisible) {
// This will only ever happen once, when the
// element has become visible for the first time
} else {
// This may happen zero or more times before
// the element becomes visible, but will never
// happen after the element has become visible
}
}
}
}
</script>
```
@@ -0,0 +1,11 @@
//
// VBVisible
//
import Vue, { DirectiveOptions } from 'vue'
import { BvPlugin } from '../../'

// Plugin
export declare const VBVisiblePlugin: BvPlugin

// Directive: v-b-visible
export declare const VBVisible: DirectiveOptions
@@ -0,0 +1,8 @@
import { VBVisible } from './visible'
import { pluginFactory } from '../../utils/plugins'

const VBVisiblePlugin = /*#__PURE__*/ pluginFactory({
directives: { VBVisible }
})

export { VBVisiblePlugin, VBVisible }
@@ -0,0 +1,25 @@
{
"name": "@bootstrap-vue/v-b-visible",
"version": "0.0.0",
"meta": {
"title": "Visible",
"description": "The `v-b-visible` directive allows you to react when an element becomes visible in the viewport.",
"directive": "VBVisible",
"new": true,
"version": "2.1.0",
"expression": [
"Function"
],
"modifiers": [
{
"name": "once",
"description": "Only calls the callback once when the element becomes visible in the viewport"
},
{
"name": "{###}",
"pattern": "[0-9]+",
"description": "An offset value in pixels (where `{###}` is the number of pixels) relative to the viewport, defaults to 0. Negative values allowed"
}
]
}
}
@@ -31,10 +31,10 @@
// )
// }

import looseEqual from '../utils/loose-equal'
import { requestAF } from '../utils/dom'
import { isFunction } from '../utils/inspect'
import { keys } from '../utils/object'
import looseEqual from '../../utils/loose-equal'
import { requestAF } from '../../utils/dom'
import { isFunction } from '../../utils/inspect'
import { keys } from '../../utils/object'

const OBSERVER_PROP_NAME = '__bv__visibility_observer'

@@ -47,21 +47,22 @@ export {
//
// Export named injection plugins
//
// TODO: we should probably move injections into their
// own parent directory (i.e. /src/injections)
// TODO:
// We should probably move injections into their own
// parent directory (i.e. `/src/injections`)
export { BVModalPlugin } from './components/modal/helpers/bv-modal'
export { BVToastPlugin } from './components/toast/helpers/bv-toast'

//
// Export all individual components and component group plugins as named exports.
//

// Webpack 4 has optimization difficulties with re-eport of re-exports, so
// we import the components individulaly here for better tree shaking,
// Webpack 4 has optimization difficulties with re-export of re-exports,
// so we import the components individually here for better tree shaking
//
// Webpack v5 fixes the optimizations with re-export of re-exports so this
// can be reverted back to `export * from './table'` when Webpack v5 is released.
// https://github.com/webpack/webpack/pull/9203 (available in Webpack v5.0.0-alpha.15)
// can be reverted back to `export * from './table'` when Webpack v5 is released
// See: https://github.com/webpack/webpack/pull/9203 (available in Webpack v5.0.0-alpha.15)

// export * from './components/alert'
export { AlertPlugin } from './components/alert'
@@ -273,11 +274,11 @@ export { BTooltip } from './components/tooltip/tooltip'
// Named exports of all directives (VB<Name>) and Plugins (VB<name>Plugin)
//

// Webpack 4 has optimization difficulties with re-eport of re-exports, so
// we import the directives individulaly here for better tree shaking,
// Webpack 4 has optimization difficulties with re-export of re-exports,
// so we import the directives individually here for better tree shaking
//
// Webpack v5 fixes the optimizations with re-export of re-exports so this
// can be reverted back to `export * from './scrollspy'` when Webpack v5 is released.
// can be reverted back to `export * from './scrollspy'` when Webpack v5 is released
// https://github.com/webpack/webpack/pull/9203 (available in Webpack v5.0.0-alpha.15)

// export * from './directives/modal'
@@ -300,5 +301,9 @@ export { VBToggle } from './directives/toggle/toggle'
export { VBTooltipPlugin } from './directives/tooltip'
export { VBTooltip } from './directives/tooltip/tooltip'

// export * from './directives/tooltip'
export { VBVisiblePlugin } from './directives/visible'
export { VBVisible } from './directives/visible/visible'

// Default export is the BootstrapVue plugin
export default BootstrapVue

0 comments on commit 5fa7e22

Please sign in to comment.
You can’t perform that action at this time.