ui: Modifier based tooltips (#9288)

This commit is contained in:
John Cowen 2020-11-30 16:52:13 +00:00 committed by GitHub
parent 0f2c396334
commit a59a2f8604
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 355 additions and 380 deletions

View File

@ -20,8 +20,9 @@
<header>
<h2>
{{chain.ServiceName}} Router
<span>
<em role="tooltip">Use routers to intercept traffic using L7 criteria such as path prefixes or http headers.</em>
<span
{{tooltip 'Use routers to intercept traffic using L7 criteria such as path prefixes or http headers.'}}
>
</span>
</h2>
</header>
@ -38,8 +39,9 @@
<header>
<h2>
Splitters
<span>
<em role="tooltip">Splitters are configured to split incoming requests across different services or subsets of a single service.</em>
<span
{{tooltip 'Splitters are configured to split incoming requests across different services or subsets of a single service.'}}
>
</span>
</h2>
</header>
@ -56,8 +58,8 @@
<header>
<h2>
Resolvers
<span>
<em role="tooltip">Resolvers are used to define which instances of a service should satisfy discovery requests.</em>
<span {{tooltip "Resolvers are used to define which instances of a service should satisfy discovery requests."}}>
</span>
</h2>
</header>
@ -70,10 +72,15 @@
{{/each}}
</div>
</div>
<svg width="100%" height="100%" viewBox={{concat '0 0 ' width ' ' height}} preserveAspectRatio="none">
<svg class="edges"
width="100%"
height="100%"
viewBox={{concat '0 0 ' width ' ' height}}
preserveAspectRatio="none"
>
{{#each routes as |item|}}
{{#let (dom-position (concat '#' item.ID)) as |src|}}
{{#let (dom-position (concat '#' item.NextNode)) as |destRect|}}
{{#let (dom-position (concat '#' item.ID) '.edges') as |src|}}
{{#let (dom-position (concat '#' item.NextNode) '.edges') as |destRect|}}
{{#let (tween-to (hash
x=destRect.x
y=(add destRect.y (div destRect.height 2))
@ -93,17 +100,17 @@
{{/let}}
{{/each}}
{{#each splitters as |splitter|}}
{{#let (dom-position (concat '#' splitter.ID)) as |src|}}
{{#let (dom-position (concat '#' splitter.ID) '.edges') as |src|}}
{{#each splitter.Splits as |item index|}}
{{#let (dom-position (concat '#' item.NextNode)) as |destRect|}}
{{#let (dom-position (concat '#' item.NextNode) '.edges') as |destRect|}}
{{#let (tween-to (hash
x=destRect.x
y=(add destRect.y (div destRect.height 2))
) (concat splitter.ID '-' index)) as |dest|}}
<path
{{tooltip (concat (round (or item.Weight 0) decimals=2) '%') options=(hash followCursor=true)}}
id={{concat 'splitter:' splitter.Name '>' item.NextNode}}
class="split"
data-percentage={{or item.Weight 0}}
d={{
svg-curve (hash
x=dest.x
@ -121,14 +128,14 @@
<svg class="resolver-inlets" viewBox={{concat '0 0 10 ' height}}>
{{#each routes as |item|}}
{{#if (starts-with 'resolver:' item.NextNode) }}
{{#let (dom-position (concat '#' item.NextNode)) as |dest|}}
{{#let (dom-position (concat '#' item.NextNode) '.edges') as |dest|}}
<circle r="2.5" cx="5" cy={{add dest.y (div dest.height 2)}} />
{{/let}}
{{/if}}
{{/each}}
{{#each splitters as |item|}}
{{#each item.Splits as |item|}}
{{#let (dom-position (concat '#' item.NextNode)) as |dest|}}
{{#let (dom-position (concat '#' item.NextNode) '.edges') as |dest|}}
<circle r="2.5" cx="5" cy={{add dest.y (div dest.height 2)}} />
{{/let}}
{{/each}}
@ -137,12 +144,9 @@
<svg class="splitter-inlets" viewBox={{concat '0 0 10 ' height}}>
{{#each routes as |item|}}
{{#if (starts-with 'splitter:' item.NextNode) }}
{{#let (dom-position (concat '#' item.NextNode)) as |dest|}}
{{#let (dom-position (concat '#' item.NextNode) '.edges') as |dest|}}
<circle r="2.5" cx="5" cy={{add dest.y (div dest.height 2)}} />
{{/let}}
{{/if}}
{{/each}}
</svg>
<div class={{concat 'tooltip' (if activeTooltip ' active' '')}} style={{{ concat 'top:' y 'px;left:' x 'px;'}}}>
<span role="tooltip">{{round tooltip decimals=2}}%</span>
</div>

View File

@ -11,21 +11,22 @@ export default Component.extend({
dataStructs: service('data-structs'),
classNames: ['discovery-chain'],
classNameBindings: ['active'],
isDisplayed: false,
selectedId: '',
x: 0,
y: 0,
tooltip: '',
activeTooltip: false,
init: function() {
this._super(...arguments);
this._listeners = this.dom.listeners();
},
didReceiveAttrs: function() {
this._super(...arguments);
if (this.element) {
this.addPathListeners();
}
didInsertElement: function() {
this._listeners.add(this.dom.document(), {
click: e => {
// all route/splitter/resolver components currently
// have classes that end in '-card'
if (!this.dom.closest('[class$="-card"]', e.target)) {
set(this, 'active', false);
set(this, 'selectedId', '');
}
},
});
},
willDestroyElement: function() {
this._super(...arguments);
@ -122,53 +123,7 @@ export default Component.extend({
height: computed('chain.{Nodes,Targets}', function() {
return this.element.offsetHeight;
}),
// TODO(octane): ember has trouble adding mouse events to svg elements whilst giving
// the developer access to the mouse event therefore we just use JS to add our events
// revisit this post Octane
addPathListeners: function() {
schedule('afterRender', () => {
this._listeners.remove();
// as this is now afterRender, theoretically
// it could happen after the component is destroyed?
// watch for that incase
if (this.element && !this.isDestroyed) {
this._listeners.add(this.dom.document(), {
click: e => {
// all route/splitter/resolver components currently
// have classes that end in '-card'
if (!this.dom.closest('[class$="-card"]', e.target)) {
set(this, 'active', false);
set(this, 'selectedId', '');
}
},
});
[...this.dom.elements('path.split', this.element)].forEach(item => {
this._listeners.add(item, {
mouseover: e => this.actions.showSplit.apply(this, [e]),
mouseout: e => this.actions.hideSplit.apply(this, [e]),
});
});
}
});
// TODO: currently don't think there is a way to listen
// for an element being removed inside a component, possibly
// using IntersectionObserver. It's a tiny detail, but we just always
// remove the tooltip on component update as its so tiny, ideal
// the tooltip would stay if there was no change to the <path>
// set(this, 'activeTooltip', false);
},
actions: {
showSplit: function(e) {
this.setProperties({
x: e.clientX,
y: e.clientY - 3,
tooltip: e.target.dataset.percentage,
activeTooltip: true,
});
},
hideSplit: function(e = null) {
set(this, 'activeTooltip', false);
},
click: function(e) {
const id = e.currentTarget.getAttribute('id');
if (id === this.selectedId) {

View File

@ -25,17 +25,6 @@
%discovery-chain [id*=':']:not(path):hover {
@extend %chain-node-active;
}
%discovery-chain .tooltip {
position: fixed;
z-index: 5;
}
%discovery-chain .tooltip.active > [role='tooltip'],
%discovery-chain .tooltip.active > [role='tooltip']::after {
@extend %blink-in-fade-out-active;
}
%resolver-card dt {
@extend %with-pseudo-tooltip, %tooltip-right;
}
%discovery-chain {
position: relative;
@ -49,6 +38,9 @@
padding: 10px 1% 10px 1%;
width: 32%;
}
%chain-group > header {
height: 18px;
}
%chain-group > header span {
position: relative;
z-index: 1;
@ -102,7 +94,8 @@
}
%route-card section header {
display: block;
width: 33px;
width: 19px;
margin-right: 14px
}
/**/
/* resolver */

View File

@ -7,7 +7,9 @@
<h3>{{@item.Name}}</h3>
{{#if item.Failover}}
<dl class="failover">
<dt data-tooltip={{concat @item.Failover.Type ' failover'}}>
<dt
{{tooltip (concat @item.Failover.Type ' failover')}}
>
{{concat @item.Failover.Type ' failover'}}
</dt>
<dd>
@ -30,14 +32,22 @@
<a name="">
{{#if child.Redirect}}
<dl class="redirect">
<dt data-tooltip="Redirect">Redirect</dt>
<dt
{{tooltip "Redirect"}}
>
Redirect
</dt>
<dd>
{{child.Name}}
</dd>
</dl>
{{#if child.Failover}}
<dl class="failover">
<dt data-tooltip={{concat child.Failover.Type ' failover'}}>{{concat child.Failover.Type ' failover'}}</dt>
<dt
{{tooltip (concat child.Failover.Type ' failover')}}
>
{{concat child.Failover.Type ' failover'}}
</dt>
<dd>
<ol>
{{#each child.Failover.Targets as |target|}}
@ -52,7 +62,11 @@
{{else if child.Failover}}
{{child.Name}}
<dl class="failover">
<dt data-tooltip={{concat child.Failover.Type ' failover'}}>{{concat child.Failover.Type ' failover'}}</dt>
<dt
{{tooltip (concat child.Failover.Type ' failover')}}
>
{{concat child.Failover.Type ' failover'}}
</dt>
<dd>
<ol>
{{#each child.Failover.Targets as |target|}}

View File

@ -22,7 +22,7 @@
</header>
{{#if (gt @item.Definition.Match.HTTP.Header.length 0) }}
<section class="match-headers">
<header data-tooltip="Header">
<header {{tooltip 'Header'}}>
<h4>Headers</h4>
</header>
<dl>
@ -39,7 +39,7 @@
{{/if}}
{{#if (gt @item.Definition.Match.HTTP.QueryParam.length 0) }}
<section class="match-queryparams">
<header data-tooltip="Query Params">
<header {{tooltip 'Query Params'}}>
<h4>Query Params</h4>
</header>
<dl>

View File

@ -3,10 +3,6 @@
/* the styling there almost 100% uses our CSS vars */
/* defined in our CSS files, but be sure to */
/* take a look in the discovery-chain.hbs */
%discovery-chain .tooltip,
%chain-group > header span {
@extend %with-tooltip;
}
%route-card > header ul li {
@extend %pill-500, %frame-gray-900;
}
@ -63,14 +59,6 @@
height: 1.2em;
opacity: 0.6;
}
/* TODO: this is tooltip related, we also do this elsewhere */
/* so would be good to look and see if we can centralize this */
%chain-group > header span em {
text-transform: none;
width: 250px;
font-style: normal;
white-space: normal !important;
}
%chain-node {
@extend %discovery-chain-tween;
transition-property: opacity background-color border-color;

View File

@ -1,16 +1,29 @@
<StateChart @src={{chart}} as |State Guard Action dispatch state|>
<Ref @target={{this}} @name="dispatch" @value={{dispatch}} />
<State @matches="success">
<Tooltip @targetId={{guid}} @isShown={{true}} @position={{position}} @duration={{3000}} @oncomplete={{action dispatch 'RESET'}}>
<span role="alert">Copied {{name}}!</span>
</Tooltip>
</State>
<State @matches="error">
<Tooltip role="alert" @targetId={{guid}} @isShown={{true}} @position={{position}} @duration={{3000}} @oncomplete={{action dispatch 'RESET'}}>
<span role="alert">There was an problem!</span>
</Tooltip>
</State>
<div class="copy-button" id={{guid}}>
<button title={{concat "Copy " name " to the clipboard"}} ...attributes type="button" class="copy-btn" data-clipboard-text={{value}}>{{~yield~}}</button>
<div
{{did-insert this.connect}}
{{will-destroy this.disconnect}}
class="copy-button"
id={{this.guid}}
...attributes
>
<button
title={{concat "Copy " @name " to the clipboard"}}
type="button"
class="copy-btn"
data-clipboard-text={{@value}}
...attributes
{{tooltip
(if (state-matches state 'success') (concat 'Copied ' @name '!!') 'There was a problem!')
options=(hash
trigger='manual'
showOnCreate=(not (state-matches state 'idle'))
delay=(array 0 3000)
onHidden=(action dispatch 'RESET')
)
}}
>
{{~yield~}}
</button>
</div>
</StateChart>

View File

@ -1,26 +1,29 @@
import Component from '@ember/component';
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import chart from './chart.xstate';
export default Component.extend({
clipboard: service('clipboard/os'),
dom: service('dom'),
tagName: '',
init: function() {
this._super(...arguments);
export default class CopyButton extends Component {
@service('clipboard/os') clipboard;
@service('dom') dom;
constructor() {
super(...arguments);
this.chart = chart;
this.guid = this.dom.guid(this);
this._listeners = this.dom.listeners();
},
willDestroyElement: function() {
this._super(...arguments);
this._listeners.remove();
},
didInsertElement: function() {
this._super(...arguments);
}
@action
connect() {
this._listeners.add(this.clipboard.execute(`#${this.guid} button`), {
success: () => this.dispatch('SUCCESS'),
error: () => this.dispatch('ERROR'),
});
},
});
}
@action
disconnect() {
this._listeners.remove();
}
}

View File

@ -24,7 +24,10 @@
<dd>
{{item.Type}}
{{#if (and exposed (contains item.Type (array 'http' 'grpc')))}}
<em data-test-exposed="true" data-tooltip="Expose.checks is set to true, so all registered HTTP and gRPC check paths are exposed through Envoy for the Consul agent.">Exposed</em>
<em
data-test-exposed="true"
{{tooltip "Expose.checks is set to true, so all registered HTTP and gRPC check paths are exposed through Envoy for the Consul agent."}}
>Exposed</em>
{{/if}}
</dd>
</dl>

View File

@ -1,11 +1,11 @@
<EmberTooltip
@targetId={{targetId}}
@onHide={{oncomplete}}
@isShown={{isShown}}
@duration={{duration}}
@event={{if isShown 'none' (or event 'hover')}}
@popperContainer=".app-view"
@side={{or position 'top'}}
<div
class="tooltip"
...attributes
{{tooltip
options=(hash
triggerTarget="parentNode"
)
}}
>
{{yield}}
</EmberTooltip>
</div>

View File

@ -1,5 +0,0 @@
import Component from '@ember/component';
export default Component.extend({
tagName: '',
});

View File

@ -0,0 +1,119 @@
[data-tippy-root] {
@extend %tooltip-layer;
}
.tippy-box[data-theme~=tooltip] {
& {
@extend %tooltip-bubble;
}
&[data-placement^=bottom] > .tippy-arrow {
@extend %tooltip-tail-bottom;
}
&[data-placement^=top] > .tippy-arrow {
@extend %tooltip-tail-top;
}
&[data-placement^=left] > .tippy-arrow {
@extend %tooltip-tail-left;
}
&[data-placement^=right] > .tippy-arrow {
@extend %tooltip-tail-right;
}
.tippy-arrow {
@extend %tooltip-tail;
}
.tippy-content {
@extend %tooltip-content;
}
}
%tooltip-layer {
max-width: calc(100vw - 10px);
}
%tooltip-bubble {
& {
position: relative;
outline: 0;
background-color: $gray-700;
color: $white;
border-radius: $decor-radius-100;
box-shadow: $decor-elevation-400;
transition-property: transform, visibility, opacity;
}
&[data-animation=fade][data-state=hidden] {
opacity: 0;
}
&[data-inertia][data-state=visible] {
transition-timing-function: cubic-bezier(.54, 1.5, .38, 1.11);
}
}
%tooltip-tail {
--size: 5px;
& {
color: $gray-700;
width: calc(var(--size) * 2);
height: calc(var(--size) * 2);
}
&::before {
content: "";
position: absolute;
border-color: $transparent;
border-style: solid;
}
}
%tooltip-tail-top {
& {
bottom: 0;
}
&::before {
bottom: calc(0px - var(--size));
left: 0;
border-width: var(--size) var(--size) 0;
border-top-color: initial;
transform-origin: center top;
}
}
%tooltip-tail-bottom {
& {
top: 0
}
&::before {
top: calc(0px - var(--size));
left: 0;
border-width: 0 var(--size) var(--size);
border-bottom-color: initial;
transform-origin: center bottom;
}
}
%tooltip-tail-left {
& {
right: 0;
}
&::before {
right: calc(0px - var(--size));
border-width: var(--size) 0 var(--size) var(--size);
border-left-color: initial;
transform-origin: center left;
}
}
%tooltip-tail-right {
& {
left: 0
}
&::before {
left: calc(0px - var(--size));
border-width: var(--size) var(--size) var(--size) 0;
border-right-color: initial;
transform-origin: center right;
}
}
%tooltip-content {
@extend %p3;
padding: 12px;
max-width: 192px;
position: relative;
z-index: 1;
}

View File

@ -9,14 +9,18 @@
<div class="stats">
{{#if hasLoaded }}
{{#each stats as |stat|}}
<dl>
<dl {{tooltip
stat.desc
options=(hash
allowHTML=true
)
}}>
<dt>
{{stat.value}}
</dt>
<dd>
{{stat.label}}
</dd>
<Tooltip>{{{stat.desc}}}</Tooltip>
</dl>
{{else}}
<span>No Metrics Available</span>

View File

@ -1,28 +1,14 @@
import Helper from '@ember/component/helper';
import { inject as service } from '@ember/service';
export default Helper.extend({
dom: service('dom'),
compute: function([selector, id], hash) {
const $el = this.dom.element(selector);
const $refs = [$el.offsetParent, $el];
// TODO: helper probably needs to accept a `reference=` option
// with a selector to use as reference/root
if (selector.startsWith('#resolver:')) {
$refs.unshift($refs[0].offsetParent);
}
return $refs.reduce(
function(prev, item) {
prev.x += item.offsetLeft;
prev.y += item.offsetTop;
return prev;
},
{
x: 0,
y: 0,
height: $el.offsetHeight,
width: $el.offsetWidth,
}
);
compute: function([target, from], hash) {
const $target = this.dom.element(target);
const $from = this.dom.element(from);
const fromRect = $from.getBoundingClientRect();
const rect = $target.getBoundingClientRect();
rect.x = rect.x - fromRect.x;
rect.y = rect.y - fromRect.y;
return rect;
},
});

View File

@ -0,0 +1,65 @@
import { modifier } from 'ember-modifier';
import tippy, { followCursor } from 'tippy.js';
/**
* Tooltip modifier using Tippy.js
* https://atomiks.github.io/tippyjs
*
* {{tooltip 'Text' options=(hash )}}
*/
export default modifier(($element, [content], hash = {}) => {
const options = hash.options || {};
let $anchor = $element;
// make it easy to specify the modified element as the actual tooltip
if (typeof options.triggerTarget === 'string') {
const $el = $anchor;
switch (options.triggerTarget) {
case 'parentNode':
$anchor = $anchor.parentNode;
break;
default:
$anchor = $anchor.querySelectorAll(options.triggerTarget);
}
content = $anchor.cloneNode(true);
$el.remove();
hash.options.triggerTarget = undefined;
}
// {{tooltip}} will just use the HTML content
if (typeof content === 'undefined') {
content = $anchor.innerHTML;
$anchor.innerHTML = '';
}
let interval;
if (options.trigger === 'manual') {
// if we are manually triggering, a out delay means only show for the
// amount of time specified by the delay
const delay = options.delay || [];
if (typeof delay[1] !== 'undefined') {
hash.options.onShown = tooltip => {
clearInterval(interval);
interval = setTimeout(() => {
tooltip.hide();
}, delay[1]);
};
}
}
let $trigger = $anchor;
const tooltip = tippy($anchor, {
theme: 'tooltip',
triggerTarget: $trigger,
content: $anchor => content,
// showOnCreate: true,
// hideOnClick: false,
plugins: [typeof options.followCursor !== 'undefined' ? followCursor : undefined].filter(item =>
Boolean(item)
),
...hash.options,
});
return () => {
clearInterval(interval);
tooltip.destroy();
};
});

View File

@ -14,4 +14,3 @@
@import './table/index';
@import './tabs/index';
@import './toggle-button/index';
@import './tooltip/index';

View File

@ -1,32 +0,0 @@
@import './skin';
@import './layout';
%with-pseudo-tooltip,
%with-tooltip {
@extend %tooltip;
}
%with-pseudo-tooltip::before,
%with-tooltip [role='tooltip'] {
@extend %tooltip-bubble;
}
%with-pseudo-tooltip::after,
%with-tooltip [role='tooltip']::after {
@extend %tooltip-tail;
}
%with-pseudo-tooltip::after,
%with-pseudo-tooltip::before,
%with-tooltip [role='tooltip']::after,
%with-tooltip [role='tooltip'] {
@extend %blink-in-fade-out;
}
%with-pseudo-tooltip:hover::after,
%with-pseudo-tooltip:hover::before,
%with-pseudo-tooltip:focus::after,
%with-pseudo-tooltip:focus::before,
%with-tooltip:hover [role='tooltip']::after,
%with-tooltip:hover [role='tooltip'],
%with-tooltip:focus [role='tooltip']::after,
%with-tooltip:focus [role='tooltip'] {
@extend %blink-in-fade-out-active;
}

View File

@ -1,59 +0,0 @@
%tooltip {
position: relative;
display: inline-flex;
justify-content: center;
align-items: center;
vertical-align: text-top;
}
%tooltip-bubble,
%tooltip-tail {
position: absolute;
z-index: 1;
}
%tooltip-bubble {
padding: 12px;
white-space: nowrap;
content: attr(data-tooltip);
text-indent: 0;
min-width: 192px;
}
%tooltip-bubble {
/* TODO: structure says left aligned, check this is correct */
text-align: center;
}
%tooltip-tail {
content: '';
transform: scale(1, 0.5);
width: 0;
height: 0;
}
/* TODO: positioning */
%tooltip-bubble {
bottom: calc(100% + 5px);
}
%tooltip-tail {
left: 50%;
margin-left: -9px;
bottom: -13px;
}
/* TODO: Try and use the same vertical positioning all tooltips */
/* this is only for pseudo tooltips be want to avoid */
/* specifying pseudo in this file */
%tooltip::after {
bottom: calc(100% - 8px);
}
%tooltip-bottom::before {
bottom: auto;
top: calc(100% + 8px);
}
%tooltip-bottom::after {
bottom: -12px;
}
// Ember Tooltips
.ember-tooltip {
padding: 12px;
max-width: 192px;
z-index: 4;
}

View File

@ -1,38 +0,0 @@
%tooltip-bubble {
color: $white;
background-color: $gray-700;
}
%tooltip-tail {
background-color: $transparent;
border-color: $transparent;
border-top-color: $gray-700;
border-bottom-color: $gray-700;
}
/* borders here are used to draw a triangle in CSS */
/* they are not actual borders */
%tooltip-tail {
border-style: solid;
border-bottom-width: 0;
border-top-width: 18px;
border-left-width: 9px;
border-right-width: 9px;
}
%tooltip-bottom::after {
border-top-width: 0;
border-bottom-width: 18px;
}
%tooltip-bubble {
border-radius: $decor-radius-100;
box-shadow: $decor-elevation-400;
}
// Ember Tooltips
.ember-tooltip {
background-color: $gray-700;
border-radius: $decor-radius-100;
}
.ember-tooltip[x-placement^='top'] .ember-tooltip-arrow {
border-top-color: $gray-700;
}

View File

@ -17,7 +17,6 @@
@import './components/tabs';
@import './components/pill';
@import './components/table';
@import './components/tooltip';
@import './components/tag-list';
@import './components/healthcheck-output';
@import './components/freetext-filter';
@ -46,11 +45,12 @@
@import './components/loader';
@import './components/main-header-horizontal';
@import './components/main-nav-horizontal';
@import './components/app-view';
@import './components/footer';
/**/
@import './components/app-view';
@import 'consul-ui/components/tooltip';
@import 'consul-ui/components/notice';
@import 'consul-ui/components/modal-dialog';

View File

@ -3,10 +3,6 @@
.app-view {
@extend %app-view;
}
%app-view-actions label + div {
/* We need this extra to allow tooltips to show */
overflow: visible !important;
}
%app-view header form {
@extend %filter-bar;

View File

@ -15,8 +15,8 @@
.consul-lock-session-list ul > li:not(:first-child) {
@extend %with-one-action-row;
}
/*TODO: This hides the icons-less dt's in the below lists as */
/* they don't have tooltips */
// TODO: This hides the icons-less dt's in the below lists as they don't have
// tooltips the todo would be to wrap these texts in spans
.consul-nspace-list > ul > li:not(:first-child) dt,
.consul-token-list > ul > li:not(:first-child) dt,
.consul-policy-list > ul li:not(:first-child) dl:not(.datacenter) dt,
@ -57,13 +57,11 @@
padding: 0 !important;
margin: 0 !important;
}
/* buttons need to be displayed in order for the tooltip */
/* to track them */
%composite-row-header .copy-button button {
opacity: 0;
display: none;
}
%composite-row-header:hover .copy-button button {
opacity: 1;
display: block;
}
%composite-row .copy-button button:hover {
background-color: transparent !important;

View File

@ -2,13 +2,3 @@
.healthcheck-output {
@extend %healthcheck-output;
}
%healthcheck-output dd em[data-tooltip] {
@extend %with-pseudo-tooltip;
}
%healthcheck-output dd em::before {
width: 250px;
/* TODO: All tooltips previously used */
/* nowrap, they shouldn't */
white-space: normal !important;
}
/**/

View File

@ -1,25 +0,0 @@
/* override structure min-width for the moment */
/* TODO: Clarify whether these should actually use */
/* the min-width from structure */
/* TODO: See if we can move all these to base */
%tooltip-bubble {
min-width: 0;
}
%tooltip-below::after {
top: calc(100% - 8px);
bottom: auto;
border-top: none;
border-bottom: 18px solid $gray-500;
}
%tooltip-below::before {
top: calc(100% + 4px);
bottom: auto;
/*TODO: This should probably go into base*/
line-height: 1em;
}
%tooltip-left::before {
right: 0;
}
%tooltip-right::before {
left: -7px;
}

View File

@ -32,7 +32,6 @@ fieldset > header,
%healthcheck-output dt,
%table th,
%table td strong,
%tooltip-bubble,
%sliding-toggle label span {
@extend %h6;
}
@ -133,8 +132,3 @@ pre code,
font-size: 16px !important;
}
}
//Ember Tooltip
.ember-tooltip {
font-size: $typo-size-800;
}

View File

@ -113,6 +113,7 @@
"ember-load-initializers": "^2.1.1",
"ember-math-helpers": "^2.4.0",
"ember-maybe-import-regenerator": "^0.1.6",
"ember-modifier": "^2.1.1",
"ember-named-blocks-polyfill": "^0.2.3",
"ember-on-helper": "^0.1.0",
"ember-page-title": "^5.2.3",
@ -150,6 +151,7 @@
"sass": "^1.28.0",
"tape": "^5.0.1",
"text-encoding": "^0.7.0",
"tippy.js": "^6.2.7",
"torii": "^0.10.1"
},
"resolutions": {

View File

@ -1,25 +0,0 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | tooltip', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(hbs`<Tooltip />`);
assert.equal(this.element.textContent.trim(), '');
// Template block usage:
await render(hbs`
<Tooltip>
</Tooltip>
`);
assert.equal(this.element.textContent.trim(), '');
});
});

View File

@ -1683,6 +1683,11 @@
dependencies:
mkdirp "^1.0.4"
"@popperjs/core@^2.4.4":
version "2.5.4"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.5.4.tgz#de25b5da9f727985a3757fd59b5d028aba75841a"
integrity sha512-ZpKr+WTb8zsajqgDkvCEWgp6d5eJT6Q63Ng2neTbzBO76Lbe91vX/iVIW9dikq+Fs3yEo+ls4cxeXABD2LtcbQ==
"@reach/router@^1.3.3":
version "1.3.4"
resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.3.4.tgz#d2574b19370a70c80480ed91f3da840136d10f8c"
@ -7995,6 +8000,15 @@ ember-data@~3.20.4:
ember-cli-typescript "^3.1.3"
ember-inflector "^3.0.1"
ember-destroyable-polyfill@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ember-destroyable-polyfill/-/ember-destroyable-polyfill-2.0.2.tgz#2cc7532bd3c00e351b4da9b7fc683f4daff79671"
integrity sha512-9t+ya+9c+FkNM5IAyJIv6ETG8jfZQaUnFCO5SeLlV0wkSw7TOexyb61jh5GVee0KmknfRhrRGGAyT4Y0TwkZ+w==
dependencies:
ember-cli-babel "^7.22.1"
ember-cli-version-checker "^5.1.1"
ember-compatibility-helpers "^1.2.1"
ember-element-helper@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.2.0.tgz#eacdf4d8507d6708812623206e24ad37bad487e7"
@ -8108,7 +8122,7 @@ ember-maybe-in-element@^2.0.1:
ember-cli-version-checker "^5.1.1"
ember-in-element-polyfill "^1.0.0"
ember-modifier-manager-polyfill@^1.1.0:
ember-modifier-manager-polyfill@^1.1.0, ember-modifier-manager-polyfill@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/ember-modifier-manager-polyfill/-/ember-modifier-manager-polyfill-1.2.0.tgz#cf4444e11a42ac84f5c8badd85e635df57565dda"
integrity sha512-bnaKF1LLKMkBNeDoetvIJ4vhwRPKIIumWr6dbVuW6W6p4QV8ZiO+GdF8J7mxDNlog9CeL9Z/7wam4YS86G8BYA==
@ -8117,6 +8131,18 @@ ember-modifier-manager-polyfill@^1.1.0:
ember-cli-version-checker "^2.1.2"
ember-compatibility-helpers "^1.2.0"
ember-modifier@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ember-modifier/-/ember-modifier-2.1.1.tgz#aa3a12e2d6cf1622f774f3f1eab4880982a43fa9"
integrity sha512-g9mcpFWgw5lgNU40YNf0USNWqoGTJ+EqjDQKjm7556gaRNDeGnLylFKqx9O3opwLHEt6ZODnRDy9U0S5YEMREg==
dependencies:
ember-cli-babel "^7.22.1"
ember-cli-normalize-entity-name "^1.0.0"
ember-cli-string-utils "^1.1.0"
ember-cli-typescript "^3.1.3"
ember-destroyable-polyfill "^2.0.2"
ember-modifier-manager-polyfill "^1.2.0"
ember-named-blocks-polyfill@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/ember-named-blocks-polyfill/-/ember-named-blocks-polyfill-0.2.3.tgz#05fb3b40cff98a0d30e8c3b1e3d2155951007d84"
@ -16135,6 +16161,13 @@ tinycolor2@^1.4.1:
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==
tippy.js@^6.2.7:
version "6.2.7"
resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.2.7.tgz#62fb34eda23f7d78151ddca922b62818c1ab9869"
integrity sha512-k+kWF9AJz5xLQHBi3K/XlmJiyu+p9gsCyc5qZhxxGaJWIW8SMjw1R+C7saUnP33IM8gUhDA2xX//ejRSwqR0tA==
dependencies:
"@popperjs/core" "^2.4.4"
tmp@0.0.28:
version "0.0.28"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120"