diff --git a/docs/components/section-toc.vue b/docs/components/section-toc.vue index e66cc17f58b..4ce199323e8 100644 --- a/docs/components/section-toc.vue +++ b/docs/components/section-toc.vue @@ -15,7 +15,9 @@ active-class="" > {{ page.title }} — + NEW {{ page.description }} + v{{ page.version }} diff --git a/src/components/form-textarea/form-textarea.js b/src/components/form-textarea/form-textarea.js index 7f7f9c06c11..1c874354cbf 100644 --- a/src/components/form-textarea/form-textarea.js +++ b/src/components/form-textarea/form-textarea.js @@ -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' diff --git a/src/components/image/img-lazy.js b/src/components/image/img-lazy.js index 66681da6fc5..08bdbc1520f 100644 --- a/src/components/image/img-lazy.js +++ b/src/components/image/img-lazy.js @@ -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' diff --git a/src/directives/index.d.ts b/src/directives/index.d.ts index 7ff01bd1c33..4c4235c6eeb 100644 --- a/src/directives/index.d.ts +++ b/src/directives/index.d.ts @@ -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' diff --git a/src/directives/index.js b/src/directives/index.js index 50cdbaad94f..359771b1851 100644 --- a/src/directives/index.js +++ b/src/directives/index.js @@ -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 } }) diff --git a/src/directives/visible/README.md b/src/directives/visible/README.md new file mode 100644 index 00000000000..70fb655462e --- /dev/null +++ b/src/directives/visible/README.md @@ -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 ``. +- 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 +
content
+``` + +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 + + +``` + +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 + + +``` + +With `once` modifier: + +```html + + +``` + +With `once` and offset modifiers: + +```html + + +``` diff --git a/src/directives/visible/index.d.ts b/src/directives/visible/index.d.ts new file mode 100644 index 00000000000..d2ea62bb3fd --- /dev/null +++ b/src/directives/visible/index.d.ts @@ -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 diff --git a/src/directives/visible/index.js b/src/directives/visible/index.js new file mode 100644 index 00000000000..7b97b5f9798 --- /dev/null +++ b/src/directives/visible/index.js @@ -0,0 +1,8 @@ +import { VBVisible } from './visible' +import { pluginFactory } from '../../utils/plugins' + +const VBVisiblePlugin = /*#__PURE__*/ pluginFactory({ + directives: { VBVisible } +}) + +export { VBVisiblePlugin, VBVisible } diff --git a/src/directives/visible/package.json b/src/directives/visible/package.json new file mode 100644 index 00000000000..593053ce8a7 --- /dev/null +++ b/src/directives/visible/package.json @@ -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" + } + ] + } +} diff --git a/src/directives/visible.js b/src/directives/visible/visible.js similarity index 96% rename from src/directives/visible.js rename to src/directives/visible/visible.js index 8ef04b63d76..124c62b6301 100644 --- a/src/directives/visible.js +++ b/src/directives/visible/visible.js @@ -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' diff --git a/src/index.js b/src/index.js index 55476dfdc14..c763a851ae2 100644 --- a/src/index.js +++ b/src/index.js @@ -47,8 +47,9 @@ 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' @@ -56,12 +57,12 @@ 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) and Plugins (VBPlugin) // -// 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