@nu-appdev/northwestern-starlight-theme 1.3.0 → 1.3.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/CHANGELOG.md +11 -1
- package/package.json +1 -1
- package/src/components/Tooltip.astro +54 -9
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.3.1] - 2026-03-27
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Tooltips on mobile rendered outside the viewport near screen edges. Horizontal position now clamps with 8px padding; arrow shifts to track the trigger.
|
|
15
|
+
- Tooltips stayed visible while scrolling on touch devices. Dismisses when the trigger moves 50px from its open position or leaves the viewport.
|
|
16
|
+
- Tapping a tooltip after scroll-dismiss had no effect. Trigger now blurs on scroll-dismiss so the next tap re-focuses.
|
|
17
|
+
- Tooltips near the top of the page overlapped Starlight's fixed header and "On this page" dropdown. Flips to bottom when space above is insufficient (100px header safe zone).
|
|
18
|
+
|
|
10
19
|
## [1.3.0] - 2026-03-26
|
|
11
20
|
|
|
12
21
|
### Added
|
|
@@ -121,7 +130,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
121
130
|
- OpenAPI plugin compatibility with method badge preservation
|
|
122
131
|
- Reduced motion support for transitions
|
|
123
132
|
|
|
124
|
-
[Unreleased]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.3.
|
|
133
|
+
[Unreleased]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.3.1...HEAD
|
|
134
|
+
[1.3.1]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.3.0...v1.3.1
|
|
125
135
|
[1.3.0]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.2.0...v1.3.0
|
|
126
136
|
[1.2.0]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.1.1...v1.2.0
|
|
127
137
|
[1.1.1]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.1.0...v1.1.1
|
package/package.json
CHANGED
|
@@ -66,15 +66,25 @@ if (resolvedColor) {
|
|
|
66
66
|
if (!trigger || !content) return;
|
|
67
67
|
|
|
68
68
|
let isVisible = false;
|
|
69
|
+
let openY = 0;
|
|
69
70
|
const hasPopover = "showPopover" in content;
|
|
71
|
+
const preferredSide = wrapper.classList.contains("nu-tooltip--bottom") ? "bottom" : "top";
|
|
70
72
|
|
|
71
73
|
function onScroll() {
|
|
72
|
-
if (isVisible)
|
|
74
|
+
if (!isVisible) return;
|
|
75
|
+
const rect = trigger!.getBoundingClientRect();
|
|
76
|
+
if (rect.bottom < 0 || rect.top > window.innerHeight || Math.abs(rect.top - openY) > 50) {
|
|
77
|
+
trigger!.blur();
|
|
78
|
+
hide();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
position();
|
|
73
82
|
}
|
|
74
83
|
|
|
75
84
|
function show() {
|
|
76
85
|
if (isVisible) return;
|
|
77
86
|
isVisible = true;
|
|
87
|
+
openY = trigger!.getBoundingClientRect().top;
|
|
78
88
|
if (hasPopover) {
|
|
79
89
|
content!.showPopover();
|
|
80
90
|
} else {
|
|
@@ -102,17 +112,52 @@ if (resolvedColor) {
|
|
|
102
112
|
|
|
103
113
|
function position() {
|
|
104
114
|
const rect = trigger!.getBoundingClientRect();
|
|
105
|
-
const
|
|
115
|
+
const preferred = preferredSide;
|
|
106
116
|
const gap = 8;
|
|
117
|
+
const pad = 8;
|
|
118
|
+
const vw = document.documentElement.clientWidth;
|
|
119
|
+
|
|
120
|
+
// Measure tooltip height to decide if we need to flip
|
|
121
|
+
content!.style.transform = "";
|
|
122
|
+
content!.style.left = "0";
|
|
123
|
+
content!.style.top = "0";
|
|
124
|
+
const tipHeight = content!.offsetHeight;
|
|
125
|
+
const tipWidth = content!.offsetWidth;
|
|
126
|
+
|
|
127
|
+
// Reserve space for fixed header + mobile TOC (~100px)
|
|
128
|
+
const headerZone = 100;
|
|
129
|
+
|
|
130
|
+
// Auto-flip: if preferred side would overflow, use the other
|
|
131
|
+
const spaceAbove = rect.top - headerZone - gap;
|
|
132
|
+
const spaceBelow = window.innerHeight - rect.bottom - gap;
|
|
133
|
+
let side = preferred;
|
|
134
|
+
if (preferred === "top" && spaceAbove < tipHeight + pad && spaceBelow > spaceAbove) {
|
|
135
|
+
side = "bottom";
|
|
136
|
+
} else if (preferred === "bottom" && spaceBelow < tipHeight + pad && spaceAbove > spaceBelow) {
|
|
137
|
+
side = "top";
|
|
138
|
+
}
|
|
107
139
|
|
|
108
|
-
|
|
140
|
+
// Update wrapper class so CSS arrow borders match
|
|
141
|
+
wrapper.classList.toggle("nu-tooltip--top", side === "top");
|
|
142
|
+
wrapper.classList.toggle("nu-tooltip--bottom", side === "bottom");
|
|
109
143
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
144
|
+
content!.style.top = side === "top"
|
|
145
|
+
? `${rect.top - gap}px`
|
|
146
|
+
: `${rect.bottom + gap}px`;
|
|
147
|
+
|
|
148
|
+
let left = rect.left + rect.width / 2 - tipWidth / 2;
|
|
149
|
+
left = Math.max(pad, Math.min(left, vw - tipWidth - pad));
|
|
150
|
+
|
|
151
|
+
content!.style.left = `${left}px`;
|
|
152
|
+
content!.style.transform = side === "top" ? "translateY(-100%)" : "";
|
|
153
|
+
|
|
154
|
+
// Shift arrow to stay centered on trigger and flip its direction
|
|
155
|
+
const arrow = content!.querySelector<HTMLElement>(".nu-tooltip__arrow");
|
|
156
|
+
if (arrow) {
|
|
157
|
+
const tipCenter = left + tipWidth / 2;
|
|
158
|
+
const triggerCenter = rect.left + rect.width / 2;
|
|
159
|
+
const offset = triggerCenter - tipCenter;
|
|
160
|
+
arrow.style.left = `calc(50% + ${offset}px)`;
|
|
116
161
|
}
|
|
117
162
|
}
|
|
118
163
|
|