Skip to content

Commit be47d33

Browse files
committed
feat(action): add action attribute to control display of tooltip
1 parent c3d39c6 commit be47d33

File tree

5 files changed

+79
-19
lines changed

5 files changed

+79
-19
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Checkout out my <u use:tooltip={{ content: 'Hello World!' }}>tooltip</u>
4242
### Props
4343
| Prop | Description | Value |
4444
| :----------- | :------------------------------------------------------------------ | :---------------------------------------------- |
45+
| action | The action that triggers the tooltip (hover | click) | `string` (default: `hover`) |
4546
| animation | The animation to apply to the tooltip | `string` (default: ``) |
4647
| arrow | If `false`, the tooltip arrow will not be shown. | `boolean` (default: `true`) |
4748
| autoPosition | Adjust tooltip position if viewport clipping occurs | `string` (default: `false`) |

docs/src/App.svelte

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212

1313
<hr />
1414

15-
<h2>Examples using action</h2>
15+
<h2>Examples using action</h2>
1616

1717
<div class="example">
18-
<p>This tooltip should appear on the <u title="hello world!" use:tooltip>top</u> and use the content in the <code>title</code> attribute.</p>
18+
<p>This tooltip should appear on the <u title="hello world!" action="click" use:tooltip>top</u> when clicked. The content for the tooltip is provided by the <code>title</code> attribute.</p>
1919

20-
<Prism code={'<u title="hello world!" use:tooltip>top</u>'} />
20+
<Prism code={'<u title="hello world!" action="click" use:tooltip>top</u>'} />
2121
</div>
2222

2323
<div class="example">
@@ -27,9 +27,9 @@
2727
</div>
2828

2929
<div class="example">
30-
<p>This tooltip should appear to the <b use:tooltip={{ content: 'Whoa! I appear to the right.', position: 'right', theme: 'tooltip-theme' }}>right</b>.</p>
30+
<p>This tooltip should appear to the <b use:tooltip={{ content: 'Whoa! I appear to the right.', action: 'click', position: 'right', theme: 'tooltip-theme' }}>right</b> when clicked.</p>
3131

32-
<Prism code={"<b use:tooltip={{ content: 'Whoa! I appear to the right.', position: 'right', theme: 'tooltip-theme' }}>right</b>"} />
32+
<Prism code={"<b use:tooltip={{ content: 'Whoa! I appear to the right.', position: 'right', action: 'click', theme: 'tooltip-theme' }}>right</b>"} />
3333

3434
<p>This is also demonstrates the use of the <code>theme</code> property:</p>
3535

@@ -83,7 +83,7 @@
8383
</div>
8484

8585
<div class="example">
86-
This tooltip should appear on the <Tooltip content="<b>Tooltip Top</b><p>This is an example of using HTML and content wrapping.</p>" position="top" animation="slide" arrow={false}><i>top</i>.</Tooltip>
86+
This tooltip should appear on the <Tooltip content="<b>Tooltip Top</b><p>This is an example of using HTML and content wrapping.</p>" action="click" position="top" animation="slide" arrow={false}><i>top</i></Tooltip> when clicked.
8787
</div>
8888

8989
<div class="example">
@@ -92,6 +92,7 @@
9292
<Tooltip
9393
content="Whoa! I appear to the right."
9494
position="right"
95+
action="click"
9596
theme="tooltip-theme">
9697
<b>right</b>.
9798
</Tooltip>
@@ -100,6 +101,7 @@
100101
<Tooltip
101102
content="Whoa! I appear to the right."
102103
position="right"
104+
action="click"
103105
theme="tooltip-theme">
104106
<b>right</b>
105107
</Tooltip>

src/action-tooltip.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { formatVariableKey, getMinWidth, isInViewport } from './helpers';
44
import { inverse } from './constants';
55
6+
export let action = 'hover';
67
export let content = '';
78
export let align = 'left';
89
export let position = 'top';
@@ -24,7 +25,7 @@
2425
2526
if (ref !== null) {
2627
if (isComponent && !component) {
27-
component = new content.component({ target: ref, props: content.props });
28+
component = new content.component({ target: ref, props: { action, ...content.props } });
2829
}
2930
3031
minWidth = getMinWidth(ref, maxWidth);

src/action.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const tooltip = (element, props) => {
44

55
let component = null;
66
let title = element.getAttribute('title');
7+
let action = props?.action || element.getAttribute('action') || 'hover';
78

89
if (title) {
910
element.removeAttribute('title');
@@ -14,6 +15,14 @@ export const tooltip = (element, props) => {
1415
}
1516
}
1617

18+
const onClick = () => {
19+
if (component) {
20+
onMouseLeave();
21+
} else {
22+
onMouseEnter();
23+
}
24+
};
25+
1726
const onMouseEnter = () => {
1827
if (!component) {
1928
component = new Tooltip({
@@ -30,14 +39,34 @@ export const tooltip = (element, props) => {
3039
}
3140
};
3241

33-
element.addEventListener('mouseenter', onMouseEnter);
34-
element.addEventListener('mouseleave', onMouseLeave);
42+
const addListeners = () => {
43+
if (element !== null) {
44+
removeListeners();
45+
46+
if (action === 'click') {
47+
element.addEventListener('click', onClick);
48+
} else {
49+
element.addEventListener('mouseenter', onMouseEnter);
50+
element.addEventListener('mouseleave', onMouseLeave);
51+
}
52+
}
53+
}
54+
55+
const removeListeners = () => {
56+
if (element !== null) {
57+
element.removeEventListener('click', onClick);
58+
element.removeEventListener('mouseenter', onMouseEnter);
59+
element.removeEventListener('mouseleave', onMouseLeave);
60+
}
61+
};
62+
63+
addListeners();
64+
3565
element.style.position = 'relative';
3666

3767
return {
3868
destroy() {
39-
element.removeEventListener('mouseenter', onMouseEnter);
40-
element.removeEventListener('mouseleave', onMouseLeave);
69+
removeListeners();
4170

4271
if (title) {
4372
element.setAttribute('title', title);

src/tooltip.svelte

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
import { formatVariableKey, getMinWidth, isInViewport } from './helpers';
66
import { inverse } from './constants';
77
8+
export let action = 'hover';
89
export let content = '';
910
export let align = 'left';
1011
export let position = 'top';
1112
export let maxWidth = 200;
1213
/**
1314
* @type {{ [x: string]: any; } | null}
1415
*/
15-
export let style = null;
16+
export let style = null;
1617
export let theme = '';
1718
export let animation = '';
1819
export let arrow = true;
@@ -42,6 +43,14 @@
4243
*/
4344
let timer = null;
4445
46+
const onClick = () => {
47+
if (show) {
48+
onMouseLeave();
49+
} else {
50+
onMouseEnter();
51+
}
52+
};
53+
4554
const onMouseEnter = () => {
4655
const delay = animation ? 200 : 0;
4756
@@ -68,11 +77,31 @@
6877
}
6978
};
7079
71-
onMount(() => {
80+
const addListeners = () => {
7281
if (containerRef !== null) {
73-
containerRef.addEventListener('mouseenter', onMouseEnter);
74-
containerRef.addEventListener('mouseleave', onMouseLeave);
82+
removeListeners();
83+
84+
if (action === 'click') {
85+
containerRef.addEventListener('click', onClick);
86+
}
87+
88+
if (action === 'hover') {
89+
containerRef.addEventListener('mouseenter', onMouseEnter);
90+
containerRef.addEventListener('mouseleave', onMouseLeave);
91+
}
7592
}
93+
}
94+
95+
const removeListeners = () => {
96+
if (containerRef !== null) {
97+
containerRef.removeEventListener('click', onClick);
98+
containerRef.removeEventListener('mouseenter', onMouseEnter);
99+
containerRef.removeEventListener('mouseleave', onMouseLeave);
100+
}
101+
};
102+
103+
onMount(() => {
104+
addListeners();
76105
77106
if (tooltipRef !== null) {
78107
if (isComponent && !component) {
@@ -103,13 +132,11 @@
103132
component = null;
104133
}
105134
106-
if (containerRef !== null) {
107-
containerRef.removeEventListener('mouseenter', onMouseEnter);
108-
containerRef.removeEventListener('mouseleave', onMouseLeave);
109-
}
135+
removeListeners();
110136
});
111137
112138
$: isComponent = typeof content === 'object';
139+
$: action, addListeners();
113140
</script>
114141

115142
{#if content}

0 commit comments

Comments
 (0)