tolltop 3.0.1 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +183 -42
- package/package.json +6 -2
- package/tolltop.js +2 -2
package/README.md
CHANGED
|
@@ -1,76 +1,217 @@
|
|
|
1
|
-
# tolltop
|
|
1
|
+
# tolltop ▸
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/tolltop)
|
|
2
4
|
|
|
3
5
|
Tiny, dependency-free tooltips with smart edge-aware positioning. One attribute to add a
|
|
4
|
-
tooltip, one call to configure them all
|
|
5
|
-
browsers.
|
|
6
|
+
tooltip, one call to configure them all. No build step, no framework, works in all modern
|
|
7
|
+
browsers. About 3 KB gzipped.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
**[Live demo →](https://tolltop.panphora.com)**
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
npm install tolltop
|
|
11
|
-
```
|
|
11
|
+
## Features
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
- One attribute: add `data-tooltip="..."` to any element.
|
|
14
|
+
- One config call: `tolltop({...})` themes and tunes every tooltip on the page at once.
|
|
15
|
+
- Smart positioning: shows above by default, flips below when there is no room, shifts
|
|
16
|
+
sideways to stay on screen, and wraps long text instead of overflowing.
|
|
17
|
+
- An arrow that always points at the trigger, even after the box shifts to avoid an edge.
|
|
18
|
+
- Shows on hover and on keyboard focus; hides on `Esc`, blur, or pointer-out.
|
|
19
|
+
- Works on dynamically added elements with zero re-init (events are delegated).
|
|
20
|
+
- Container-aware: hides itself when the trigger scrolls out of a scroll or overflow
|
|
21
|
+
container, or leaves the viewport.
|
|
22
|
+
- Accessible: `role="tooltip"` and `aria-describedby` are wired up automatically.
|
|
23
|
+
- One adaptive file: drop in a single `<script>` and it injects its own CSS, or link the
|
|
24
|
+
CSS yourself to theme it and the script skips its built-in copy.
|
|
25
|
+
- Safe to load more than once: a double-initialization guard makes re-including the script
|
|
26
|
+
a no-op.
|
|
27
|
+
- No dependencies, no build, ~3 KB gzipped.
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
Add one script tag, then mark any element. That is the whole setup.
|
|
14
32
|
|
|
15
33
|
```html
|
|
16
34
|
<script src="https://cdn.jsdelivr.net/npm/tolltop/tolltop.js"></script>
|
|
17
35
|
|
|
18
|
-
<!-- mark any element with the attribute -->
|
|
19
36
|
<button data-tooltip="Save your work">Save</button>
|
|
20
37
|
```
|
|
21
38
|
|
|
22
|
-
Tooltips
|
|
23
|
-
styles, so
|
|
24
|
-
|
|
39
|
+
Tooltips appear on hover and on keyboard focus, and hide on `Esc`. The script injects its
|
|
40
|
+
own styles, so nothing else is required.
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
### CDN, one file (simplest)
|
|
45
|
+
|
|
46
|
+
The script injects its own CSS:
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<script src="https://cdn.jsdelivr.net/npm/tolltop/tolltop.js"></script>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### CDN, with the CSS file (themeable)
|
|
53
|
+
|
|
54
|
+
Link the stylesheet before the script. The script detects it and skips its built-in copy,
|
|
55
|
+
so you can edit the CSS directly:
|
|
25
56
|
|
|
26
57
|
```html
|
|
27
58
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tolltop/tolltop.css">
|
|
28
59
|
<script src="https://cdn.jsdelivr.net/npm/tolltop/tolltop.js"></script>
|
|
29
60
|
```
|
|
30
61
|
|
|
62
|
+
Pin a version with `tolltop@3.0.1` in either URL. Also on unpkg:
|
|
63
|
+
`https://unpkg.com/tolltop/tolltop.js`.
|
|
64
|
+
|
|
65
|
+
### npm (bundlers)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm install tolltop
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
import 'tolltop';
|
|
73
|
+
// optional, only if you want to theme via CSS:
|
|
74
|
+
import 'tolltop/tolltop.css';
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Usage
|
|
78
|
+
|
|
79
|
+
Mark any element with `data-tooltip`. The attribute value is the text. This is the only
|
|
80
|
+
per-element attribute; everything else is global.
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<button data-tooltip="Save your work">Save</button>
|
|
84
|
+
<span data-tooltip="Works on inline elements too">hover me</span>
|
|
85
|
+
<a href="#" data-tooltip="And on links" tabindex="0">focus me</a>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- Shows on hover and on keyboard focus.
|
|
89
|
+
- Hides on pointer-out, blur, and the `Esc` key.
|
|
90
|
+
- New elements work immediately, with no init call, because events are delegated from the
|
|
91
|
+
document.
|
|
92
|
+
|
|
31
93
|
## Configuration
|
|
32
94
|
|
|
33
|
-
Style and behavior are global. Call `tolltop()` once with any subset of options
|
|
34
|
-
into the current config and applies immediately
|
|
95
|
+
Style and behavior are global. Call `tolltop()` once with any subset of options. It merges
|
|
96
|
+
into the current config and applies immediately, repositioning a tooltip that is already
|
|
97
|
+
open.
|
|
35
98
|
|
|
36
99
|
```js
|
|
37
100
|
tolltop({
|
|
38
|
-
bg: '#18181b',
|
|
39
|
-
color: '#e4e4e7',
|
|
40
|
-
radius: 6, // number = px, or any CSS length string
|
|
41
|
-
fontSize: 12, //
|
|
42
|
-
padding: '6px 9px',
|
|
43
|
-
maxWidth: 240, // px
|
|
101
|
+
bg: '#18181b', // any CSS color
|
|
102
|
+
color: '#e4e4e7', // any CSS color
|
|
103
|
+
radius: 6, // number = px, or any CSS length string ('10px', '0.5rem')
|
|
104
|
+
fontSize: 12, // number = px, or any CSS length string
|
|
105
|
+
padding: '6px 9px', // any CSS padding shorthand
|
|
106
|
+
maxWidth: 240, // px; capped to the viewport so long text wraps
|
|
44
107
|
placement: 'auto', // 'auto' | 'top' | 'bottom'
|
|
45
108
|
gap: 10, // px between the trigger and the tooltip
|
|
46
|
-
edge: 24, // px
|
|
109
|
+
edge: 24, // px minimum gap from each viewport side
|
|
47
110
|
});
|
|
48
111
|
```
|
|
49
112
|
|
|
50
|
-
| Option | Example
|
|
51
|
-
| ------------ |
|
|
52
|
-
| `bg` | `'#1e3a5f'`
|
|
53
|
-
| `color` | `'#fff'`
|
|
54
|
-
| `radius` | `10` or `'10px'`
|
|
55
|
-
| `fontSize` | `14` or `'.9rem'
|
|
56
|
-
| `padding` | `'8px 12px'`
|
|
57
|
-
| `maxWidth` | `320`
|
|
58
|
-
| `placement` | `'top'`
|
|
59
|
-
| `gap` | `12`
|
|
60
|
-
| `edge` | `16`
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
113
|
+
| Option | Type | Example | Default |
|
|
114
|
+
| ------------ | ------------------------- | ----------------- | --------- |
|
|
115
|
+
| `bg` | CSS color | `'#1e3a5f'` | `#18181b` |
|
|
116
|
+
| `color` | CSS color | `'#fff'` | `#e4e4e7` |
|
|
117
|
+
| `radius` | number (px) or CSS length | `10` or `'10px'` | `6` |
|
|
118
|
+
| `fontSize` | number (px) or CSS length | `14` or `'.9rem'` | `12` |
|
|
119
|
+
| `padding` | CSS padding shorthand | `'8px 12px'` | `6px 9px` |
|
|
120
|
+
| `maxWidth` | number (px) | `320` | `240` |
|
|
121
|
+
| `placement` | `'auto' \| 'top' \| 'bottom'` | `'top'` | `'auto'` |
|
|
122
|
+
| `gap` | number (px) | `12` | `10` |
|
|
123
|
+
| `edge` | number (px) | `16` | `24` |
|
|
124
|
+
|
|
125
|
+
Call `tolltop()` with no arguments to read back the current config (it returns a copy):
|
|
126
|
+
|
|
127
|
+
```js
|
|
128
|
+
const current = tolltop();
|
|
129
|
+
// { bg: null, color: null, radius: null, fontSize: null, padding: null,
|
|
130
|
+
// maxWidth: 240, placement: 'auto', gap: 10, edge: 24 }
|
|
131
|
+
// Style options read back as null until you set them; the visible defaults
|
|
132
|
+
// (#18181b, etc.) come from the CSS, not the config object.
|
|
133
|
+
|
|
134
|
+
tolltop({ placement: 'bottom' }); // change just one thing
|
|
135
|
+
```
|
|
64
136
|
|
|
65
137
|
## Positioning
|
|
66
138
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
|
|
139
|
+
The logic is deliberately simple and predictable:
|
|
140
|
+
|
|
141
|
+
- Shows **above** the trigger by default.
|
|
142
|
+
- **Flips below** when there is not room above. Setting `placement` forces a side, but it
|
|
143
|
+
still flips if the forced side will not fit.
|
|
144
|
+
- **Centers horizontally** on the trigger, then **shifts** left or right just enough to stay
|
|
145
|
+
on screen, keeping `edge` px of room on each side. The vertical scrollbar is excluded from
|
|
146
|
+
the math.
|
|
147
|
+
- **Wraps** long text: `maxWidth` is capped to the available width (`viewport - 2 × edge`)
|
|
148
|
+
so the box never runs off screen.
|
|
149
|
+
- The **arrow** stays centered on the trigger and points toward it, even after the box has
|
|
150
|
+
shifted.
|
|
151
|
+
- **Repositions** on scroll (capture phase, so nested scroll containers are tracked) and
|
|
152
|
+
resize.
|
|
153
|
+
- **Hides itself** when the trigger is removed from the DOM, scrolled out of the viewport, or
|
|
154
|
+
clipped out of a scroll or overflow container (it tracks the trigger through nested
|
|
155
|
+
scrollers).
|
|
156
|
+
|
|
157
|
+
## Theming with CSS
|
|
158
|
+
|
|
159
|
+
If you link `tolltop.css`, you can theme via CSS custom properties instead of, or alongside,
|
|
160
|
+
the JS config. The tooltip element has class `.tolltop`:
|
|
161
|
+
|
|
162
|
+
| Variable | Default |
|
|
163
|
+
| ---------------- | --------- |
|
|
164
|
+
| `--tt-bg` | `#18181b` |
|
|
165
|
+
| `--tt-color` | `#e4e4e7` |
|
|
166
|
+
| `--tt-radius` | `6px` |
|
|
167
|
+
| `--tt-font-size` | `12px` |
|
|
168
|
+
| `--tt-padding` | `6px 9px` |
|
|
169
|
+
| `--tt-arrow` | `6px` |
|
|
170
|
+
|
|
171
|
+
```css
|
|
172
|
+
.tolltop {
|
|
173
|
+
--tt-bg: #1e3a5f;
|
|
174
|
+
--tt-color: #fff;
|
|
175
|
+
--tt-radius: 10px;
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Values you set through `tolltop({...})` are applied as inline styles and win over the
|
|
180
|
+
stylesheet. Options you never pass stay on the CSS defaults. The script computes
|
|
181
|
+
`--tt-arrow-x` itself to keep the arrow on the trigger; do not set it.
|
|
182
|
+
|
|
183
|
+
## Accessibility
|
|
184
|
+
|
|
185
|
+
- The tooltip element has `role="tooltip"`.
|
|
186
|
+
- On show, the trigger gets `aria-describedby` pointing at the tooltip (merged with any
|
|
187
|
+
existing value), and it is restored on hide.
|
|
188
|
+
- Keyboard focus shows the tooltip, and `Esc` dismisses it.
|
|
189
|
+
|
|
190
|
+
## How the single file works
|
|
191
|
+
|
|
192
|
+
`tolltop.js` is self-contained. On first use it checks whether `.tolltop` is already styled:
|
|
193
|
+
|
|
194
|
+
- If `tolltop.css` is **not** on the page, it injects its built-in copy of the styles.
|
|
195
|
+
- If you **did** link `tolltop.css`, it detects that and skips injection, so your stylesheet
|
|
196
|
+
and your edits win.
|
|
197
|
+
|
|
198
|
+
That is why one `<script>` tag is enough, and why linking the CSS is purely optional and
|
|
199
|
+
only for theming.
|
|
200
|
+
|
|
201
|
+
Under the hood there is a single shared element appended to `<body>` with `position: fixed`,
|
|
202
|
+
a maximal `z-index`, and `pointer-events: none`, so it sits above everything and never blocks
|
|
203
|
+
clicks or hover on the page.
|
|
204
|
+
|
|
205
|
+
## Browser support
|
|
206
|
+
|
|
207
|
+
All modern browsers. No polyfills, no transpilation needed.
|
|
208
|
+
|
|
209
|
+
## Files
|
|
210
|
+
|
|
211
|
+
| File | Purpose |
|
|
212
|
+
| ------------- | ---------------------------------------------------- |
|
|
213
|
+
| `tolltop.js` | The whole library. Injects its CSS if none is linked.|
|
|
214
|
+
| `tolltop.css` | Optional. Link it only to theme via CSS. |
|
|
74
215
|
|
|
75
216
|
## License
|
|
76
217
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tolltop",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"description": "Tiny dependency-free tooltips with smart edge-aware positioning. One attribute, no build, works in all modern browsers.",
|
|
5
5
|
"main": "tolltop.js",
|
|
6
6
|
"style": "tolltop.css",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "node build.js",
|
|
9
|
-
"prepublishOnly": "node build.js"
|
|
9
|
+
"prepublishOnly": "node build.js",
|
|
10
|
+
"test": "playwright test"
|
|
10
11
|
},
|
|
11
12
|
"files": [
|
|
12
13
|
"tolltop.js",
|
|
@@ -25,5 +26,8 @@
|
|
|
25
26
|
"repository": {
|
|
26
27
|
"type": "git",
|
|
27
28
|
"url": "git+https://github.com/panphora/tolltop.git"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@playwright/test": "^1.60.0"
|
|
28
32
|
}
|
|
29
33
|
}
|
package/tolltop.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* tolltop v3.0.
|
|
2
|
+
* tolltop v3.0.2
|
|
3
3
|
* Tiny edge-aware tooltips with smart positioning. One attribute, one config call.
|
|
4
4
|
* MIT License · https://github.com/panphora/tolltop
|
|
5
5
|
*/
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
|
|
118
118
|
function show(el) {
|
|
119
119
|
const text = el.getAttribute('data-tooltip');
|
|
120
|
-
if (!text) return;
|
|
120
|
+
if (!text || !text.trim()) return;
|
|
121
121
|
ensureTip();
|
|
122
122
|
if (active !== el) {
|
|
123
123
|
if (active) restoreAria();
|