@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 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.0...HEAD
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nu-appdev/northwestern-starlight-theme",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "A Northwestern-branded theme for Astro Starlight",
5
5
  "license": "MIT",
6
6
  "author": "Danny Foster <danny@northwestern.edu>",
@@ -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) position();
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 side = wrapper.classList.contains("nu-tooltip--bottom") ? "bottom" : "top";
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
- content!.style.left = `${rect.left + rect.width / 2}px`;
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
- if (side === "top") {
111
- content!.style.top = `${rect.top - gap}px`;
112
- content!.style.transform = "translate(-50%, -100%)";
113
- } else {
114
- content!.style.top = `${rect.bottom + gap}px`;
115
- content!.style.transform = "translate(-50%, 0)";
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