Powered by NeGD | MeitY Government of India® UX4G
Popovers
Documentation and examples for adding UX4G popovers, like those found in iOS, to any element on your site.
Overview #
Things to know when using the popover plugin:
- The third-party library Popper is used by Poppers for positioning. It is a must to use one UX4G .bundle.min.js that contains Popper or include popper.min.js before UX4G.js.
- The popover plugin is a dependency for popovers.
- Popovers must be initialized by you because they are opt-in for performance reasons.
- A popover will never appear if the title and content values are zero.
- To prevent rendering issues in more complicated components (like our input groups, button groups, etc.), use container: 'body'.
- Popovers cannot be triggered by elements that are concealed.
- For popovers on a wrapper element, disabled or disabled elements must be triggered.
- Popovers that are triggered from anchors that wrap across multiple lines will be centered between the width of the anchors. To prevent this behavior, use
.text-nowrap
on the<a>
s. - Before their related elements are deleted from the DOM, popovers must first be hidden.
- An element contained within a shadow DOM can cause popovers.
prefers-reduced-motion
media query. Keep reading to see how popovers work with some examples.
Examples #
Enable popovers #
Popovers must first be initialized, as was already indicated, in order to be used. One method for initializing all popovers on a page is to choose them based on the data-bs-toggle attribute, like in the following example:
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]')
const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new UX4G.Popover(popoverTriggerEl))
Live demo #
The snippet of JavaScript shown above is used to render the following live popover. Body content is set via data-bs-content, while titles are set via data-bs-title.
title
or
data-bs-title
in your HTML. When title
is used, Popper will replace it automatically with
data-bs-title
when the element is rendered.
<button type="button" class="btn btn-lg btn-danger" data-bs-toggle="popover" data-bs-title="Popover title" data-bs-content="And here's some amazing content. It's very engaging. Right?">Click to toggle popover</button>
RESULT
Four directions #
There are four choices: top, right, bottom, and left. When using UX4G in RTL, directions are mirrored. To change the direction, adjust data-bs-placement
.
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="Top popover">
Popover on top
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="Right popover">
Popover on right
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-content="Bottom popover">
Popover on bottom
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="left" data-bs-content="Left popover">
Popover on left
</button>
RESULT
Custom container #
When a parent element's styles conflict with a popover, specify a custom container so that the popover's HTML will appear inside of that element instead. This is typical of input groups, responsive tables, and the like.
const popover = new ux4g.Popover('.example-popover', {
container: 'body'
})
Custom popovers #
Added in v1.0.0
Using CSS variables, there is an option to change how popovers look. To scope the customized design, simply set a custom class with data-bs-custom-class="custom-popover"
and utilize it to override some of the regional CSS variables.
.custom-popover {
--bs-popover-max-width: 200px;
--bs-popover-border-color: var(--bs-primary);
--bs-popover-header-bg: var(--bs-primary);
--bs-popover-header-color: var(--bs-white);
--bs-popover-body-padding-x: 1rem;
--bs-popover-body-padding-y: .5rem;
}
<button type="button" class="btn btn-secondary"data-bs-toggle="popover" data-bs-placement="right"data-bs-custom-class="custom-popover"data-bs-title="Custom popover"data-bs-content="This popover is themed via CSS variables.">Custom popover</button>
RESULT
Dismiss on next click #
When a user clicks on an element other than the toggle element after opening a popover, utilize the focus trigger to dismiss the popover.
Specific markup required for dismiss-on-next-click
For proper cross-browser and cross-platform behavior, you
must use the <a>
tag, not
the <button>
tag, and you also must
include a tabindex
attribute.
<a tabindex="0" class="btn btn-lg btn-danger" role="button" data-bs-toggle="popover" data-bs-trigger="focus" data-bs-title="Dismissible popover" data-bs-content="And here's some amazing content. It's very engaging. Right?">Dismissible popover</a>
RESULT
const popover = new ux4g.Popover('.popover-dismiss', {
trigger: 'focus'
})
Disabled elements #
Users cannot hover over or click non-interactive elements with the disabled property to launch popovers (or tooltips) since they are not interactive. Developers should use a wrapper <div>
or <span>
that is ideally made keyboard-focusable
using tabindex="0"
to initiate the popover as a workaround.
Developers may also select data-bs-trigger="hover focus"
for disabled popover triggers so that your users see the popover right away because they might not expect to click on a disabled element.
<span class="d-inline-block" tabindex="0" data-bs-toggle="popover" data-bs-trigger="hover focus" data-bs-content="Disabled popover"><button class="btn btn-primary" type="button" disabled>Disabled button</button></span>
RESULT
CSS #
Variables #
Added in v1.0.0
Popovers now leverage local CSS variables on .popover
for improved real-time customisation as part of UX4G's growing CSS variables strategy. Sass is used to set the values for the CSS variables, therefore Sass customization is still available
--#{$prefix}popover-zindex: #{$zindex-popover};
--#{$prefix}popover-max-width: #{$popover-max-width};
@include rfs($popover-font-size, --#{$prefix}popover-font-size);
--#{$prefix}popover-bg: #{$popover-bg};
--#{$prefix}popover-border-width: #{$popover-border-width};
--#{$prefix}popover-border-color: #{$popover-border-color};
--#{$prefix}popover-border-radius: #{$popover-border-radius};
--#{$prefix}popover-inner-border-radius: #{$popover-inner-border-radius};
--#{$prefix}popover-box-shadow: #{$popover-box-shadow};
--#{$prefix}popover-header-padding-x: #{$popover-header-padding-x};
--#{$prefix}popover-header-padding-y: #{$popover-header-padding-y};
@include rfs($popover-header-font-size, --#{$prefix}popover-header-font-size);
--#{$prefix}popover-header-color: #{$popover-header-color};
--#{$prefix}popover-header-bg: #{$popover-header-bg};
--#{$prefix}popover-body-padding-x: #{$popover-body-padding-x};
--#{$prefix}popover-body-padding-y: #{$popover-body-padding-y};
--#{$prefix}popover-body-color: #{$popover-body-color};
--#{$prefix}popover-arrow-width: #{$popover-arrow-width};
--#{$prefix}popover-arrow-height: #{$popover-arrow-height};
--#{$prefix}popover-arrow-border: var(--#{$prefix}popover-border-color);
Sass variables #
$popover-font-size: $font-size-sm;
$popover-bg: $white;
$popover-max-width: 276px;
$popover-border-width: $border-width;
$popover-border-color: var(--#{$prefix}border-color-translucent);
$popover-border-radius: $border-radius-lg;
$popover-inner-border-radius: subtract($popover-border-radius, $popover-border-width);
$popover-box-shadow: $box-shadow;
$popover-header-font-size: $font-size-base;
$popover-header-bg: shade-color($popover-bg, 6%);
$popover-header-color: $headings-color;
$popover-header-padding-y: .5rem;
$popover-header-padding-x: $spacer;
$popover-body-color: $body-color;
$popover-body-padding-y: $spacer;
$popover-body-padding-x: $spacer;
$popover-arrow-width: 1rem;
$popover-arrow-height: .5rem;
Making popovers work for keyboard and assistive technology users
Only add popovers to HTML elements that are typically keyboard-focusable and interactive (like links or form controls) if want keyboard users to be able to use them. Although arbitrary HTML elements (such as <span>s) can be made focusable by adding the tabindex="0" attribute, this will add tab stops on non-interactive elements for keyboard users, which could be obtrusive and confusing, and the majority of assistive technologies currently do not announce the popover's content in this situation. Additionally, avoid relying only on hover to activate popovers because doing so will prevent keyboard users from doing so.
Despite the fact that the html option allows to insert rich, structured HTML inside popovers, it is firmly advised against doing so. Popovers now function by having an aria-describedby
property that links their content to the trigger element once it has been displayed. As a result, users of assistive technologies will hear the whole content of the popover as a single, continuous stream.
Be careful that while interactive controls (such form elements or links) can be added to the popover by adding them to the allowList of permitted attributes and tags, the popover presently does not govern keyboard focus order. There is no guarantee that clicking forward or pressing TAB will take a keyboard user into the popover itself since when a keyboard user starts a popover, focus stays on the triggering element and the popover typically does not follow the trigger in the document's structure immediately. In other words, adding interactive controls to a popover by themselves is likely to make them inaccessible to keyboard users and those who use assistive technology, or at the very least, create an unnatural attention order. Consider employing a modal dialog in these circumstances.
Options #
Data-bs-animation
can have an option name appended to it, for example, data-bs-animation="{value}"
since options can be provided through data attributes or JavaScript. When sending the choices via data attributes, be sure to modify the case type of the option name from "camelCase"
to "kebab-case."
Use data-bs-custom-class="beautifier"
as opposed to data-bs-customClass="beautifier,"
for instance.
Since UX4G v1.0.0, all components have support for the experimental reserved data attribute data-bs-config
, which can store a JSON string for basic component setting. When an element has the data-bs-config='{"delay":0, "title":123}'
and data-bs-title="456" attributes, the final title value will be 456 and the individual data attributes will take precedence over the values specified on the data-bs-config
. Additionally, JSON variables like data-bs-delay='{"show":0,"hide":150}'
can be stored in existing data attributes.
sanitize
,
sanitizeFn
, and allowList
options
cannot be supplied using data attributes.
Data attributes for individual popovers ​
Options for individual popovers can alternatively be specified through the use of data attributes, as explained above.
Using function with popperConfig
#
const popover = new ux4g.Popover(element, {
popperConfig(defaultBsPopperConfig) {
// const newPopperConfig = {...}
// use defaultBsPopperConfig if needed...
// return newPopperConfig
}
})
Methods #
Asynchronous methods and transitions
All API methods are asynchronous and start a transition. They return to the caller as soon as the transition is started but before it ends. In addition, a method call on a transitioning component will be ignored.
Method | Description |
---|---|
disable |
Removes the ability for an element’s popover to be shown. The popover will only be able to be shown if it is re-enabled. |
dispose |
Hides and destroys an element’s popover (Removes stored data on the DOM element). Popovers that use delegation (which are created using the selector option) cannot be individually destroyed on descendant trigger elements. |
enable |
Gives an element’s popover the ability to be shown. Popovers are enabled by default. |
getInstance |
Static method which allows you to get the popover instance associated with a DOM element. |
getOrCreateInstance |
Static method which allows you to get the popover instance associated with a DOM element, or create a new one in case it wasn’t initialized. |
hide |
Hides an element’s popover. Returns to the caller before the popover has actually been hidden (i.e. before the hidden.bs.popover event occurs). This is considered a “manual” triggering of the popover. |
setContent |
Gives a way to change the popover’s content after its initialization. |
show |
Reveals an element’s popover. Returns to the caller before the popover has actually been shown (i.e. before the shown.bs.popover event occurs). This is considered a “manual” triggering of the popover. Popovers whose title and content are both zero-length are never displayed. |
toggle |
Toggles an element’s popover. Returns to the caller before the popover has actually been shown or hidden (i.e. before the shown.bs.popover or hidden.bs.popover event occurs). This is considered a “manual” triggering of the popover. |
toggleEnabled |
Toggles the ability for an element’s popover to be shown or hidden. |
update |
Updates the position of an element’s popover. |
// getOrCreateInstance example
const popover = ux4g.Popover.getOrCreateInstance('#example') // Returns a UX4G popover instance
// setContent example
myPopover.setContent({
'.popover-header': 'another title',
'.popover-body': 'another content'
})
setContent
method accepts an object
argument, where each property-key is a valid string
selector within the popover template, and each related
property-value can be string
| element
| function
| null
Events #
const myPopoverTrigger = document.getElementById('myPopover')
myPopoverTrigger.addEventListener('hidden.bs.popover', () => {
// do something...
})