tolltop 3.0.0 → 3.0.1
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 +4 -4
- package/package.json +6 -2
- package/tolltop.js +38 -7
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# tolltop
|
|
2
2
|
|
|
3
3
|
Tiny, dependency-free tooltips with smart edge-aware positioning. One attribute to add a
|
|
4
|
-
tooltip, one call to configure them all, no build step, and it works in
|
|
5
|
-
|
|
4
|
+
tooltip, one call to configure them all, no build step, and it works in all modern
|
|
5
|
+
browsers.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -42,7 +42,7 @@ tolltop({
|
|
|
42
42
|
padding: '6px 9px',
|
|
43
43
|
maxWidth: 240, // px
|
|
44
44
|
placement: 'auto', // 'auto' | 'top' | 'bottom'
|
|
45
|
-
gap:
|
|
45
|
+
gap: 10, // px between the trigger and the tooltip
|
|
46
46
|
edge: 24, // px min gap from each viewport side
|
|
47
47
|
});
|
|
48
48
|
```
|
|
@@ -56,7 +56,7 @@ tolltop({
|
|
|
56
56
|
| `padding` | `'8px 12px'` | `6px 9px` |
|
|
57
57
|
| `maxWidth` | `320` | `240` |
|
|
58
58
|
| `placement` | `'top'` | `'auto'` |
|
|
59
|
-
| `gap` | `
|
|
59
|
+
| `gap` | `12` | `10` |
|
|
60
60
|
| `edge` | `16` | `24` |
|
|
61
61
|
|
|
62
62
|
Calling `tolltop()` with no arguments returns the current config. The only per-element
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tolltop",
|
|
3
|
-
"version": "3.0.
|
|
4
|
-
"description": "Tiny dependency-free tooltips with smart edge-aware positioning. One attribute, no build, works in
|
|
3
|
+
"version": "3.0.1",
|
|
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
|
+
"scripts": {
|
|
8
|
+
"build": "node build.js",
|
|
9
|
+
"prepublishOnly": "node build.js"
|
|
10
|
+
},
|
|
7
11
|
"files": [
|
|
8
12
|
"tolltop.js",
|
|
9
13
|
"tolltop.css"
|
package/tolltop.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* tolltop v3.0.1
|
|
3
|
+
* Tiny edge-aware tooltips with smart positioning. One attribute, one config call.
|
|
4
|
+
* MIT License · https://github.com/panphora/tolltop
|
|
5
|
+
*/
|
|
1
6
|
(() => {
|
|
2
7
|
'use strict';
|
|
3
8
|
if (window.__tolltop) return;
|
|
@@ -7,8 +12,8 @@
|
|
|
7
12
|
const TIP_ID = 'tolltop-tip';
|
|
8
13
|
|
|
9
14
|
// Baseline styles, injected only if tolltop.css isn't already on the page.
|
|
10
|
-
//
|
|
11
|
-
const CSS = `.tolltop{--tt-bg:#18181b;--tt-color:#e4e4e7;--tt-radius:6px;--tt-font-size:12px;--tt-padding:6px 9px;--tt-arrow:6px;--tt-arrow-x:50%;position:fixed;top:0;left:0;z-index:2147483647;box-sizing:border-box;margin:0;width:max-content;max-width:240px;padding:var(--tt-padding);border-radius:var(--tt-radius);background:var(--tt-bg);color:var(--tt-color);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:var(--tt-font-size);font-weight:500;line-height:1.4;text-align:center;white-space:normal;overflow-wrap:break-word;pointer-events:none;box-shadow:0 2px 12px rgba(0,0,0
|
|
15
|
+
// Generated from tolltop.css by build.js; do not edit by hand. Run `npm run build`.
|
|
16
|
+
const CSS = `.tolltop{--tt-bg:#18181b;--tt-color:#e4e4e7;--tt-radius:6px;--tt-font-size:12px;--tt-padding:6px 9px;--tt-arrow:6px;--tt-arrow-x:50%;position:fixed;top:0;left:0;z-index:2147483647;box-sizing:border-box;margin:0;width:max-content;max-width:240px;padding:var(--tt-padding);border-radius:var(--tt-radius);background:var(--tt-bg);color:var(--tt-color);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:var(--tt-font-size);font-weight:500;line-height:1.4;text-align:center;white-space:normal;overflow-wrap:break-word;pointer-events:none;box-shadow:0 2px 12px rgba(0,0,0,0.3);opacity:0;visibility:hidden;}.tolltop[data-show]{opacity:1;visibility:visible;}.tolltop::after{content:"";position:absolute;left:var(--tt-arrow-x);transform:translateX(-50%);width:0;height:0;border:var(--tt-arrow) solid transparent;}.tolltop[data-placement="top"]::after{top:100%;border-bottom-width:0;border-top-color:var(--tt-bg);}.tolltop[data-placement="bottom"]::after{bottom:100%;border-top-width:0;border-bottom-color:var(--tt-bg);}`;
|
|
12
17
|
|
|
13
18
|
const cfg = {
|
|
14
19
|
bg: null,
|
|
@@ -18,7 +23,7 @@
|
|
|
18
23
|
padding: null,
|
|
19
24
|
maxWidth: 240,
|
|
20
25
|
placement: 'auto',
|
|
21
|
-
gap:
|
|
26
|
+
gap: 10,
|
|
22
27
|
edge: 24,
|
|
23
28
|
};
|
|
24
29
|
|
|
@@ -68,7 +73,7 @@
|
|
|
68
73
|
// clientWidth/Height exclude the scrollbar; innerWidth would not.
|
|
69
74
|
const vw = document.documentElement.clientWidth;
|
|
70
75
|
const vh = document.documentElement.clientHeight;
|
|
71
|
-
const gap = Math.max(0, numOr(cfg.gap,
|
|
76
|
+
const gap = Math.max(0, numOr(cfg.gap, 10));
|
|
72
77
|
const edge = Math.max(0, numOr(cfg.edge, 24));
|
|
73
78
|
|
|
74
79
|
const maxW = Math.min(numOr(cfg.maxWidth, 240), vw - edge * 2);
|
|
@@ -133,10 +138,36 @@
|
|
|
133
138
|
if (tip) tip.removeAttribute('data-show');
|
|
134
139
|
}
|
|
135
140
|
|
|
141
|
+
// True when a scrollable/overflow ancestor fully clips the element out of its box.
|
|
142
|
+
function clippedOut(el) {
|
|
143
|
+
const pos = getComputedStyle(el).position;
|
|
144
|
+
if (pos === 'fixed') return false; // viewport-positioned, not clipped by scroll ancestors
|
|
145
|
+
const r = el.getBoundingClientRect();
|
|
146
|
+
// An absolute element isn't clipped by overflow ancestors below its containing block.
|
|
147
|
+
const cb = pos === 'absolute' ? el.offsetParent : null;
|
|
148
|
+
let node = el.parentElement;
|
|
149
|
+
let clips = !cb;
|
|
150
|
+
while (node && node !== document.documentElement) {
|
|
151
|
+
if (!clips && node === cb) clips = true;
|
|
152
|
+
// Skip non-rendered/zero-box ancestors (e.g. display:contents) that don't actually clip.
|
|
153
|
+
if (clips && (node.clientWidth || node.clientHeight)) {
|
|
154
|
+
const o = getComputedStyle(node);
|
|
155
|
+
if (/auto|scroll|hidden|clip/.test(o.overflow + o.overflowX + o.overflowY)) {
|
|
156
|
+
const c = node.getBoundingClientRect();
|
|
157
|
+
const left = c.left + node.clientLeft; // padding box: where overflow actually clips
|
|
158
|
+
const top = c.top + node.clientTop;
|
|
159
|
+
if (r.bottom <= top || r.top >= top + node.clientHeight || r.right <= left || r.left >= left + node.clientWidth) return true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
node = node.parentElement;
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
|
|
136
167
|
function reposition() {
|
|
137
168
|
if (!active) return;
|
|
138
|
-
//
|
|
139
|
-
//
|
|
169
|
+
// A fixed tip isn't clipped by an ancestor's overflow, so hide it ourselves when the
|
|
170
|
+
// trigger is removed, scrolled out of the viewport, or clipped out of a scroll container.
|
|
140
171
|
if (!active.isConnected) {
|
|
141
172
|
hide();
|
|
142
173
|
return;
|
|
@@ -144,7 +175,7 @@
|
|
|
144
175
|
const r = active.getBoundingClientRect();
|
|
145
176
|
const vw = document.documentElement.clientWidth;
|
|
146
177
|
const vh = document.documentElement.clientHeight;
|
|
147
|
-
if (r.bottom < 0 || r.top > vh || r.right < 0 || r.left > vw) {
|
|
178
|
+
if (r.bottom < 0 || r.top > vh || r.right < 0 || r.left > vw || clippedOut(active)) {
|
|
148
179
|
hide();
|
|
149
180
|
return;
|
|
150
181
|
}
|