Add triggers and update examples

This commit is contained in:
Cory LaViska
2020-06-10 10:13:02 -04:00
parent cd74524866
commit 97b38d5547
3 changed files with 130 additions and 66 deletions

View File

@@ -19,89 +19,116 @@ A tooltip's target is its _first child element_, so you should only wrap one ele
### Placement
```html preview
<div class="tooltip-grid">
<sl-tooltip content="This is a tooltip" placement="top-start">
<div class="tooltip-target">top-start</div>
</sl-tooltip>
<div class="tooltip-placement-example">
<div class="tooltip-placement-example-row">
<sl-tooltip content="top-start" placement="top-start">
<sl-button></sl-button>
</sl-tooltip>
<sl-tooltip content="This is a tooltip" placement="top">
<div class="tooltip-target">top</div>
</sl-tooltip>
<sl-tooltip content="top" placement="top">
<sl-button></sl-button>
</sl-tooltip>
<sl-tooltip content="This is a tooltip" placement="top-end">
<div class="tooltip-target">top-end</div>
</sl-tooltip>
<sl-tooltip content="top-end" placement="top-end">
<sl-button></sl-button>
</sl-tooltip>
</div>
<sl-tooltip content="This is a tooltip" placement="bottom-start">
<div class="tooltip-target">bottom-start</div>
</sl-tooltip>
<div class="tooltip-placement-example-row">
<sl-tooltip content="left-start" placement="left-start">
<sl-button></sl-button>
</sl-tooltip>
<sl-tooltip content="This is a tooltip" placement="bottom">
<div class="tooltip-target">bottom</div>
</sl-tooltip>
<sl-tooltip content="right-start" placement="right-start" style="margin-left: 400px;">
<sl-button></sl-button>
</sl-tooltip>
</div>
<sl-tooltip content="This is a tooltip" placement="bottom-end">
<div class="tooltip-target">bottom-end</div>
</sl-tooltip>
<div class="tooltip-placement-example-row">
<sl-tooltip content="left" placement="left">
<sl-button></sl-button>
</sl-tooltip>
<sl-tooltip content="This is a tooltip" placement="left-start">
<div class="tooltip-target">left-start</div>
</sl-tooltip>
<sl-tooltip content="right" placement="right">
<sl-button></sl-button>
</sl-tooltip>
</div>
<sl-tooltip content="This is a tooltip" placement="left">
<div class="tooltip-target">left</div>
</sl-tooltip>
<div class="tooltip-placement-example-row">
<sl-tooltip content="left-end" placement="left-end">
<sl-button></sl-button>
</sl-tooltip>
<sl-tooltip content="This is a tooltip" placement="left-end">
<div class="tooltip-target">left-end</div>
</sl-tooltip>
<sl-tooltip content="right-end" placement="right-end">
<sl-button></sl-button>
</sl-tooltip>
</div>
<sl-tooltip content="This is a tooltip" placement="right-start">
<div class="tooltip-target">right-start</div>
</sl-tooltip>
<div class="tooltip-placement-example-row">
<sl-tooltip content="bottom-start" placement="bottom-start">
<sl-button></sl-button>
</sl-tooltip>
<sl-tooltip content="This is a tooltip" placement="right">
<div class="tooltip-target">right</div>
</sl-tooltip>
<sl-tooltip content="bottom" placement="bottom">
<sl-button></sl-button>
</sl-tooltip>
<sl-tooltip content="This is a tooltip" placement="right-end">
<div class="tooltip-target">right-end</div>
</sl-tooltip>
<sl-tooltip content="bottom-end" placement="bottom-end">
<sl-button></sl-button>
</sl-tooltip>
</div>
</div>
<style>
.tooltip-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
gap: 1rem 1rem;
.tooltip-placement-example {
width: 250px;
}
.tooltip-target {
display: flex;
min-height: 8em;
.tooltip-placement-example-row::after {
content: '';
display: table;
clear: both;
}
border: dashed 1px var(--sl-color-primary-80);
background-color: var(--sl-color-primary-95);
font-size: var(--sl-font-size-x-small);
align-items: center;
justify-content: center;
padding: 1rem;
.tooltip-placement-example sl-button {
float: left;
margin-right: .25rem;
margin-bottom: .25rem;
}
.tooltip-placement-example [placement="top-start"] sl-button,
.tooltip-placement-example [placement="bottom-start"] sl-button {
margin-left: calc(40px + .25rem);
}
.tooltip-placement-example [placement^="right"] sl-button {
margin-left: calc((40px * 3) + (.25rem * 3));
}
</style>
```
### Click Trigger
```html preview
<sl-tooltip content="I am shown and hidden programmatically" trigger="click">
<sl-button>Click to Toggle</sl-button>
</sl-tooltip>
```
### Manual Trigger
```html preview
<sl-tooltip content="I am shown and hidden programmatically" trigger="manual">
<sl-button>Click to Toggle</sl-button>
<sl-button style="margin-right: 4rem;">Toggle Manually</sl-button>
<sl-tooltip content="This is an avatar" trigger="manual">
<sl-avatar></sl-avatar>
</sl-tooltip>
<script>
const tooltip = document.querySelector('sl-tooltip[trigger="manual"]');
const button = tooltip.querySelector('sl-button');
const toggle = tooltip.previousElementSibling;
button.addEventListener('click', () => tooltip.open = !tooltip.open);
toggle.addEventListener('click', () => tooltip.open = !tooltip.open);
</script>
```

View File

@@ -42,7 +42,7 @@
// Arrow + bottom
.sl-tooltip[data-popper-placement^='bottom']::after {
bottom: 100%;
left: calc(50% - var(--sl-tooltip-arrow-size) / 2);
left: calc(50% - var(--sl-tooltip-arrow-size));
border-bottom: var(--sl-tooltip-arrow-size) solid var(--sl-tooltip-background-color);
border-left: var(--sl-tooltip-arrow-size) solid transparent;
border-right: var(--sl-tooltip-arrow-size) solid transparent;
@@ -60,7 +60,7 @@
// Arrow + top
.sl-tooltip[data-popper-placement^='top']::after {
top: 100%;
left: calc(50% - var(--sl-tooltip-arrow-size) / 2);
left: calc(50% - var(--sl-tooltip-arrow-size));
border-top: var(--sl-tooltip-arrow-size) solid var(--sl-tooltip-background-color);
border-left: var(--sl-tooltip-arrow-size) solid transparent;
border-right: var(--sl-tooltip-arrow-size) solid transparent;

View File

@@ -22,6 +22,9 @@ export class Tooltip {
tooltip: any;
constructor() {
this.handleBlur = this.handleBlur.bind(this);
this.handleClick = this.handleClick.bind(this);
this.handleFocus = this.handleFocus.bind(this);
this.handleMouseOver = this.handleMouseOver.bind(this);
this.handleMouseOut = this.handleMouseOut.bind(this);
this.handleSlotChange = this.handleSlotChange.bind(this);
@@ -56,14 +59,18 @@ export class Tooltip {
/** The distance in pixels from which to offset the tooltip away from its target. */
@Prop() distance = 10;
/** Indicates whether or not the tooltip is open. */
/** Indicates whether or not the tooltip is open. You can use this in lieu of the show/hide methods. */
@Prop({ mutable: true, reflect: true }) open = false;
/** The distance in pixels from which to offset the tooltip along its target. */
@Prop() skidding = 0;
/** When to activate the tooltip. When set to `manual`, the tooltip must be shown programmatically. */
@Prop() trigger: 'hover' | 'manual' = 'hover';
/**
* Controls how the tooltip is activated. Possible options include `click`, `hover`, `focus`, and `manual`. Multiple
* options can be passed by separating them with a space. When manual is used, the tooltip must be activated
* programmatically.
*/
@Prop() trigger: string = 'hover focus';
@Watch('open')
handleOpenChange() {
@@ -89,6 +96,9 @@ export class Tooltip {
this.popover = new Popover(this.target, this.tooltip);
this.syncOptions();
this.host.addEventListener('blur', this.handleBlur, true);
this.host.addEventListener('click', this.handleClick, true);
this.host.addEventListener('focus', this.handleFocus, true);
slot.addEventListener('slotchange', this.handleSlotChange);
// Show on init if open
@@ -104,6 +114,10 @@ export class Tooltip {
componentDidUnload() {
this.popover.destroy();
this.host.removeEventListener('blur', this.handleBlur, true);
this.host.removeEventListener('click', this.handleClick, true);
this.host.removeEventListener('focus', this.handleFocus, true);
this.host.shadowRoot.querySelector('slot').removeEventListener('slotchange', this.handleSlotChange);
}
@@ -142,15 +156,33 @@ export class Tooltip {
return target;
}
handleBlur() {
if (this.hasTrigger('focus')) {
this.hide();
}
}
handleClick() {
if (this.hasTrigger('click')) {
this.open ? this.hide() : this.show();
}
}
handleFocus() {
if (this.hasTrigger('focus')) {
this.show();
}
}
handleMouseOver() {
if (this.trigger === 'hover') {
this.open = true;
if (this.hasTrigger('hover')) {
this.show();
}
}
handleMouseOut() {
if (this.trigger === 'hover') {
this.open = false;
if (this.hasTrigger('hover')) {
this.hide();
}
}
@@ -164,6 +196,11 @@ export class Tooltip {
}
}
hasTrigger(triggerType: string) {
const triggers = this.trigger.split(' ');
return triggers.includes(triggerType);
}
syncOptions() {
this.popover.setOptions({
placement: this.placement,
@@ -172,13 +209,13 @@ export class Tooltip {
onAfterShow: () => this.slAfterShow.emit(),
hideStyles: {
opacity: '0',
transitionDelay: this.trigger === 'manual' ? '0' : 'var(--hide-delay)',
transitionDelay: this.hasTrigger('manual') ? '0' : 'var(--hide-delay)',
transitionProperty: 'opacity',
transitionDuration: 'var(--hide-duration)'
},
showStyles: {
opacity: '1',
transitionDelay: this.trigger === 'manual' ? '0' : 'var(--show-delay)',
transitionDelay: this.hasTrigger('manual') ? '0' : 'var(--show-delay)',
transitionProperty: 'opacity',
transitionDuration: 'var(--show-duration)'
}