Skip to content

Latest commit

 

History

History
executable file
·
254 lines (224 loc) · 10.2 KB

README.md

File metadata and controls

executable file
·
254 lines (224 loc) · 10.2 KB

Popover

The Popover feature, which provides a tooltip-like behavior, can be easily applied to any interactive element via the <b-popover> component or v-b-popover directive.

Overview

Things to know when using popover component:

  • Popovers rely on the 3rd party library Popper.js for positioning. The library is bundled with Bootstrap-Vue dist files!
  • Popovers with zero-length title and content are never displayed.
  • Triggering popovers on hidden elements will not work.
  • Popovers for disabled elements must be triggered on a wrapper element.
  • When triggered from hyperlinks that span multiple lines, popovers will be centered. Use white-space: nowrap; on your <a>s, <b-link>s and <router-link>s to avoid this behavior.
  • Popovers must be hidden before their corresponding markup elements have been removed from the DOM.

The <b-popover> component inserts a hidden (display: none;) <div> container element at the point in the DOM where the <b-popover> component is placed. This may affect layout and/or styling of components such as <b-button-group>, <b-button-toolbar>, and <b-input-group>. To avoid these posible layout issues, place the <b-popover> component outside of theese types of components.

The target element must exist in the document before <b-popover> is mounted. If the target element is not found during mount, the popover will never open. Always place your <b-popover> component lower in the DOM than your target element.

Note: When using slots for content and/or title, <b-popover> transfers the rendered DOM from those slots into the popover's markup when shown, and returns them back to the <b-popover> component when hidden. This may cause some issues in rare circumstances, so please test your implmentation accordingly! The title and content props do not have this behavior. For simple popovers, we recommend using the v-b-popover directive and enable the html modifer if needed.

<b-popover> Component basic usage

<template>
  <b-container fluid>

    <h5 class="my-3">Placement</h5>
    <b-row>
      <b-col md="3" class="py-4 text-center"
           v-for="placement in ['top', 'left', 'right', 'bottom']" :key="placement">
        <b-btn :id="'exPopover1-'+placement" variant="primary">
          {{ placement }}
        </b-btn>
        <b-popover :target-id="'exPopover1-'+placement"
                   :placement="placement"
                   title="Popover!"
                   triggers="hover focus"
                   :content="placement">
        </b-popover>
      </b-col>
    </b-row>

    <h5 class="my-3">Content via properties or slots</h5>
    <b-row>
      <b-col md="6" class="py-4 text-center">
        <b-btn id="exPopover2" variant="primary">Using properties</b-btn>
        <b-popover target-id="exPopover2" 
            title="Prop Examples"
            triggers="hover focus"
            content="Embedding content using properties is easy">
        </b-popover>
      </b-col>
      <b-col md="6" class="py-4 text-center">
        <b-btn id="exPopover3" variant="primary">Using slots</b-btn>
        <b-popover target-id="exPopover3">
           <template slot="title">Content via Slots</template>
           Embedding content <span class="text-danger">using slots</span>
           affords you <em>greater <strong>control.</strong></em> and
           basic HTML support.
        </b-popover>
      </b-col>
    </b-row>

  </b-container>  
</template>

<!-- popover-1.vue -->

Component options via props

Prop Default Description Supported values
target-id null ID of element that you want to trigger the popover. Required Any valid, in-document unique element ID
title null Title of popover (text only, no HTML). if HTML is required, place it in the title named slot Plain text
content null Content of popover (text only, no HTML). if HTML is required, place it in the default slot Plain text
placement top Positioning of the popover, relative to the trigger element. top, bottom, left, right, auto
triggers hover focus Space separated list of which event(s) will trigger open/close of popover hover, focus, click. Note blur is a special use case to close popover on next click.
no-fade false Disable fade animation when set to true true or false
delay 0 Number of milliseconds to delay showing and hidding of popover 0 and up, integers only.
offset 0 Number of pixels to shift the center of the popover. Also affects the position of the popover arrow. Any negative or positive integer

v-b-popover Directive usage

Just need quick popovers without too much markup? Use the v-b-popover directive:

<template>
    <b-container fluid>

      <h4 class="mt-sm-4 ms-sm-4 text-muted">Placement</h4>
      <b-row>
        <b-col md="3" class="py-3 text-center">
          <b-btn v-b-popover.hover.top="'I am Top'"
                 title="Popover!"
                 variant="primary">Top</b-btn>
        </b-col>
        <b-col md="3" class="py-3 text-center">
          <b-btn v-b-popover.hover.left="'I am Left'"
                 title="Popover!"
                 variant="primary">Left</b-btn>
        </b-col>
        <b-col md="3" class="py-3 text-center">
          <b-btn v-b-popover.hover.right="'I am Right'"
                 title="Popover!"
                 variant="primary">Right</b-btn>
        </b-col>
        <b-col md="3" class="py-3 text-center">
          <b-btn v-b-popover.hover.bottom="'I am Bottom'"
                 title="Popover!"
                 variant="primary">Bottom</b-btn>
        </b-col>
      </b-row>

    </b-container>
</template>

<!-- popover-directive-1.vue -->

Refer to the v-b-popover directive documentation for detailed information on the directive usage.

Advanced <b-popover> usage with reactive content

You can even make your <b-popover> content interactive. Just remember not to use the focus, hover or blur triggers (use only click), otherwsie your popover will close automatically as soon as someone trys to interact with the content.

If you absolutely must use a trigger other than click (or want to disable closing of the popover when the trigger element is clicked a second time), then you can either:

  • Listen for the hide event on the <b-popover> element, and call the preventDefault() method (when apropriate) on the BvEvent passed to your hide handler, or
  • Disable your trigger element (if possible) as soon as the popover opens (via the show event), and re-enable it when apropriate.

For practical purposes, interactive content popovers should be minimal. The maximum width of the popover is hard coded by Bootstrap V4 CSS to 276px. Tall popovers on small screens can be harder to deal with on mobile devices (such as smart-phones).

<template>
  <div>
    <div class="my-3">
      <!-- our triggering (target) element -->
      <b-btn id="exPopoverReactive1"
             :disabled="disabled"
             variant="primary">
        Reactive Content Using Slots
      </b-btn>
    </div>

    <!-- output from teh popover interaction -->
    <b-card title="Returned values:" v-if="input1Return && input2Return">
      <p class="card-text" style="max-width:20rem;">
        Name: <strong>{{ input1Return }}</strong><br>
        Color: <strong>{{ input2Return }}</strong>
      </p>
    </b-card>

    <!-- Our popover title and content render container -->
    <!-- We use placement 'auto' so popover fits in the best spot on viewport -->
    <b-popover target-id="exPopoverReactive1"
               trigger="click",
               placement="auto"
               ref="popover"
               @show="onShow"
               @hidden="onHidden">
      <template slot="title">
        <b-btn @click="onClose" class="close" aria-label="Close">
          <span class="d-inline-block" aria-hidden="true">&times;</span>
        </b-btn>
        Interactive Content
      </template>
      <b-form-group label="Name" class="mb-1" description="Enter your name">
        <b-form-input size="sm" v-model="input1"></b-form-input>
      </b-form-group>
      <b-form-group label="Color" class="mb-1" description="Pick a color">
        <b-form-select size="sm" v-model="input2" :options="options"></b-form-select>
      </b-form-group>
      <b-alert show>
        <h6>Current Values:</h6>
        Name: <strong>{{ input1 }}</strong><br>
        Color: <strong>{{ input2 }}</strong>
      </b-alert>
      <b-btn @click="onCancel" size="sm" variant="danger">Cancel</b-btn>
      <b-btn @click="onOk" size="sm" variant="primary">Ok</b-btn>
    </b-popover>
  </div>
</template>

<script>
  export default {
    data: {
      input1: '',
      input2: '',
      options: [{text:'- Choose 1 -', value:''},'Red','Green','Blue'],
      input1Return: '',
      input2Return: '',
      disabled: false
    },
    methods: {
      onClose() {
        // Emitting 'close' on the popover will trigger it to hide for us
        this.$refs.popover.$emit('close');
      },
      onCancel() {
        // Emitting 'close' on the popover will trigger it to hide for us
        this.$refs.popover.$emit('close');
      },
      onOk() {
        if (!this.input1 || !this.input2) {
          alert('Please enter something');
        } else {
          alert('Thats great!');
          // Emitting 'close' on the popover will trigger it to hide for us
          this.$refs.popover.$emit('close');
          // "Return" our popover "form" results
          this.input1Return = this.input1;
          this.input2Return = this.input2;
        }
      },
      onShow() {
        // This is called just before the popover is shown
        // Reset our popover "form" variables
        this.input1 = '';
        this.input2 = '';
        this.input1Return = '';
        this.input2Return = '';
        // Disable our trigger button to prevent popover closing on second click
        this.disabled = true;
      },
      onHidden() {
        // Called just after the popover has finished hiding
        // We re-enable our button
        this.disabled = false;
      }
    }
  };
</script>

<!-- popover-advanced-1.vue -->