-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
We have two cf.gov apps that use tooltips but limited documentation on best practices or how to use them in new projects. This PR adds one implementation to the DS. It requires a third party library called Tippy.js.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
title: Tooltips | ||
collection_name: pages | ||
layout: variation | ||
section: components | ||
status: Beta | ||
description: A tooltip is a short descriptive message that appears when a user | ||
hovers or focuses on an element. They display helpful but non-critical | ||
information and are useful in space-constrained user interfaces. | ||
variation_groups: | ||
- variations: | ||
- variation_is_deprecated: false | ||
variation_code_snippet: >+ | ||
The APR for the World Bank Platinum Credit Card is 9.7% <span | ||
data-tooltip="relevant-tooltip">{% include icons/help-round.svg | ||
%}</span> | ||
<template id="relevant-tooltip"> | ||
<div class="tippy-heading">This data is accurate as of June 2023</div> | ||
<div class="tippy-body">APRs change over time and are specific to the applicant. Check rates before applying.</div> | ||
</template> | ||
variation_group_name: Standard tooltip | ||
variation_group_description: "" | ||
guidelines: Tooltips should be activated by hovering or focusing over a help | ||
(question mark) icon that is next to text that requires additional clarity. | ||
They contain standard size body text and an optional `h3` heading. | ||
eyebrow: Components | ||
behavior: Pressing the `esc` key should dismiss all open tooltips. When a | ||
tooltip is at the edge of the user's viewport, it should automatically | ||
reorient itself away from the edge of the screen to prevent content clipping. | ||
accessibility: >- | ||
Tooltips are progressive enhancements for the `title` attribute, and will | ||
display as the `title` attribute if the component doesn’t initialize. | ||
When testing tooltips for accessibility, ensure they are compliant with [USWDS' guidelines](https://designsystem.digital.gov/components/tooltip/accessibility-tests/). | ||
related_items: "" | ||
--- |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* ========================================================================== | ||
Design System | ||
Tooltips | ||
========================================================================== */ | ||
|
||
export { Tooltip } from './tooltip.js'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* ========================================================================== | ||
Tooltip Organism | ||
========================================================================== */ | ||
|
||
import tippy from 'tippy.js'; | ||
|
||
import { instantiateAll } from '../../utilities'; | ||
|
||
import * as TooltipStyles from './tooltip.scss'; | ||
|
||
const BASE_ATTRIBUTE = 'data-tooltip'; | ||
|
||
/** | ||
* Tooltip | ||
* @class | ||
* @classdesc Initializes a new Tooltip. | ||
* @param {HTMLElement} element - The DOM element that should | ||
* activate the tooltip. | ||
* @returns {Tooltip} An instance. | ||
*/ | ||
function Tooltip(element) { | ||
// Internal vars. | ||
const tooltipContent = element.getAttribute('data-tooltip'); | ||
|
||
/** | ||
* Set up and create the multiselect. | ||
* @returns {Tooltip} An instance. | ||
*/ | ||
function init() { | ||
tippy(element, { | ||
theme: 'cfpb', | ||
maxWidth: 450, | ||
content: function (reference) { | ||
const template = reference.parentElement.querySelector( | ||
`#${tooltipContent}`, | ||
); | ||
const container = document.createElement('div'); | ||
const node = document.importNode(template.content, true); | ||
container.appendChild(node); | ||
return container; | ||
}, | ||
// See https://atomiks.github.io/tippyjs/v6/plugins/ | ||
plugins: [ | ||
{ | ||
name: 'hideOnEsc', | ||
defaultValue: true, | ||
fn({ hide }) { | ||
/** | ||
* Hide when the escape key is pressed. | ||
* @param {KeyboardEvent} event - Key down event. | ||
*/ | ||
function onKeyDown(event) { | ||
if (event.key === 'Escape') { | ||
hide(); | ||
} | ||
} | ||
return { | ||
onShow() { | ||
document.addEventListener('keydown', onKeyDown); | ||
}, | ||
onHide() { | ||
document.removeEventListener('keydown', onKeyDown); | ||
}, | ||
}; | ||
}, | ||
}, | ||
], | ||
}); | ||
} | ||
|
||
// Attach public events. | ||
this.init = init; | ||
|
||
return this; | ||
} | ||
|
||
Tooltip.BASE_ATTRIBUTE = BASE_ATTRIBUTE; | ||
Tooltip.init = (scope) => | ||
instantiateAll(`[${Tooltip.BASE_ATTRIBUTE}]`, Tooltip, scope); | ||
|
||
export { Tooltip, TooltipStyles }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
@use 'sass:math'; | ||
@use '@cfpb/cfpb-design-system/src/abstracts' as *; | ||
@import 'tippy.js/dist/tippy.css'; | ||
@import 'tippy.js/dist/border.css'; | ||
|
||
// Custom theme, see https://atomiks.github.io/tippyjs/v6/themes/ | ||
.tippy-box[data-theme='cfpb'] { | ||
background-color: var(--gray-5); | ||
border: 1px solid var(--gray-40); | ||
border-radius: 0; | ||
color: var(--black); | ||
padding: math.div(15px, $base-font-size-px) + rem; | ||
|
||
.tippy-arrow { | ||
color: var(--gray-5); | ||
} | ||
|
||
.tippy-heading { | ||
font-weight: 500; | ||
font-size: math.div(18px, $base-font-size-px) + rem; | ||
} | ||
|
||
.tippy-body { | ||
font-size: math.div(16px, $base-font-size-px) + rem; | ||
margin-top: math.div(15px, $base-font-size-px) + rem; | ||
} | ||
} |