starlight-cannoli-plugins 2.10.2 → 2.10.4

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.
@@ -3,6 +3,57 @@ import { fileURLToPath } from "url";
3
3
  var css = String.raw;
4
4
  var js = String.raw;
5
5
  var CONDITIONAL_CSS = {
6
+ offerTabbedContent: {
7
+ enabled: css`
8
+ /* Suppress the default crossfade for the named panel transition. */
9
+ ::view-transition-old(tabbed-panel),
10
+ ::view-transition-new(tabbed-panel) {
11
+ animation: none;
12
+ mix-blend-mode: normal;
13
+ }
14
+
15
+ /* Slide animation — only when the user has no motion preference. */
16
+ @media (prefers-reduced-motion: no-preference) {
17
+ :root[data-tab-direction="next"]::view-transition-old(tabbed-panel) {
18
+ animation: tabbed-slide-out-to-left 250ms ease both;
19
+ }
20
+ :root[data-tab-direction="next"]::view-transition-new(tabbed-panel) {
21
+ animation: tabbed-slide-in-from-right 250ms ease both;
22
+ }
23
+ :root[data-tab-direction="prev"]::view-transition-old(tabbed-panel) {
24
+ animation: tabbed-slide-out-to-right 250ms ease both;
25
+ }
26
+ :root[data-tab-direction="prev"]::view-transition-new(tabbed-panel) {
27
+ animation: tabbed-slide-in-from-left 250ms ease both;
28
+ }
29
+ }
30
+
31
+ @keyframes tabbed-slide-out-to-left {
32
+ to {
33
+ transform: translateX(-30%);
34
+ opacity: 0;
35
+ }
36
+ }
37
+ @keyframes tabbed-slide-in-from-right {
38
+ from {
39
+ transform: translateX(30%);
40
+ opacity: 0;
41
+ }
42
+ }
43
+ @keyframes tabbed-slide-out-to-right {
44
+ to {
45
+ transform: translateX(30%);
46
+ opacity: 0;
47
+ }
48
+ }
49
+ @keyframes tabbed-slide-in-from-left {
50
+ from {
51
+ transform: translateX(-30%);
52
+ opacity: 0;
53
+ }
54
+ }
55
+ `
56
+ },
6
57
  limitDetailsElementHeight: {
7
58
  enabled: css`
8
59
  .main-pane details[open] {
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  } from "./chunk-NCXV367P.js";
25
25
  import {
26
26
  starlightDomPatches
27
- } from "./chunk-RHYQUYJ3.js";
27
+ } from "./chunk-PPNIMJPX.js";
28
28
  import "./chunk-4VNS5WPM.js";
29
29
 
30
30
  // src/plugins/starlight-index-sourced-sidebar/index.ts
@@ -146,16 +146,40 @@ function tabbedH2Content() {
146
146
  contentContainer.appendChild(tabbedWrapper);
147
147
  contentContainer.appendChild(paginationBar);
148
148
  let activeTabIndex = 0;
149
- function activateTab(targetIndex, updateHash = true) {
150
- activeTabIndex = targetIndex;
151
- tabButtons.forEach((tabButton, buttonIndex) => {
152
- tabButton.dataset.active = String(buttonIndex === targetIndex);
153
- });
154
- tabPanels.forEach((tabPanel, panelIndex) => {
155
- tabPanel.hidden = panelIndex !== targetIndex;
149
+ function isTabNavVisible() {
150
+ const rect = tabNav.getBoundingClientRect();
151
+ return rect.top < window.innerHeight && rect.bottom > 0;
152
+ }
153
+ function activateTab(targetIndex, updateHash = true, scrollToNav = false) {
154
+ const applySwitch = () => {
155
+ tabPanels[activeTabIndex].style.viewTransitionName = "";
156
+ activeTabIndex = targetIndex;
157
+ tabButtons.forEach((tabButton, buttonIndex) => {
158
+ tabButton.dataset.active = String(buttonIndex === targetIndex);
159
+ });
160
+ tabPanels.forEach((tabPanel, panelIndex) => {
161
+ tabPanel.hidden = panelIndex !== targetIndex;
162
+ });
163
+ tabPanels[targetIndex].style.viewTransitionName = "tabbed-panel";
164
+ prevTabButton.disabled = targetIndex === 0;
165
+ nextTabButton.disabled = targetIndex === allSections.length - 1;
166
+ };
167
+ if (targetIndex !== activeTabIndex && "startViewTransition" in document) {
168
+ document.documentElement.dataset.tabDirection = targetIndex > activeTabIndex ? "next" : "prev";
169
+ tabPanels[activeTabIndex].style.viewTransitionName = "tabbed-panel";
170
+ document.startViewTransition(applySwitch);
171
+ } else {
172
+ applySwitch();
173
+ }
174
+ const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior;
175
+ tabButtons[targetIndex].scrollIntoView({
176
+ behavior: scrollBehavior,
177
+ block: "nearest",
178
+ inline: "nearest"
156
179
  });
157
- prevTabButton.disabled = targetIndex === 0;
158
- nextTabButton.disabled = targetIndex === allSections.length - 1;
180
+ if (scrollToNav) {
181
+ tabNav.scrollIntoView({ behavior: scrollBehavior, block: "nearest" });
182
+ }
159
183
  if (updateHash) {
160
184
  const targetHeadingId = allSections[targetIndex].headingId;
161
185
  if (targetHeadingId) {
@@ -169,12 +193,19 @@ function tabbedH2Content() {
169
193
  }
170
194
  }
171
195
  }
196
+ function findPanelIndexForHash(urlHash) {
197
+ const targetHeadingId = urlHash.startsWith("#") ? urlHash.slice(1) : urlHash;
198
+ return tabPanels.findIndex(
199
+ (tabPanel) => tabPanel.querySelector(`#${CSS.escape(targetHeadingId)}`)
200
+ );
201
+ }
172
202
  function setEnabled(enabled) {
173
203
  tabbedWrapper.dataset.enabled = String(enabled);
174
204
  tabNav.hidden = !enabled;
175
205
  paginationBar.hidden = !enabled;
176
206
  if (enabled) {
177
- activateTab(activeTabIndex, false);
207
+ const hashPanelIndex = window.location.hash ? findPanelIndexForHash(window.location.hash) : -1;
208
+ activateTab(hashPanelIndex >= 0 ? hashPanelIndex : activeTabIndex, false);
178
209
  } else {
179
210
  tabPanels.forEach((tabPanel) => {
180
211
  tabPanel.hidden = false;
@@ -183,19 +214,22 @@ function tabbedH2Content() {
183
214
  }
184
215
  function navigateToHash(urlHash) {
185
216
  if (!urlHash || tabbedWrapper.dataset.enabled !== "true") return;
186
- const targetHeadingId = urlHash.startsWith("#") ? urlHash.slice(1) : urlHash;
187
- tabPanels.forEach((tabPanel, panelIndex) => {
188
- if (tabPanel.querySelector(`#${CSS.escape(targetHeadingId)}`) && panelIndex !== activeTabIndex)
189
- activateTab(panelIndex, false);
190
- });
217
+ const targetPanelIndex = findPanelIndexForHash(urlHash);
218
+ if (targetPanelIndex >= 0 && targetPanelIndex !== activeTabIndex)
219
+ activateTab(targetPanelIndex, false);
191
220
  }
192
221
  function wireInteractions(viewToggleCheckbox2) {
193
222
  prevTabButton.addEventListener("click", () => {
194
- if (activeTabIndex > 0) activateTab(activeTabIndex - 1);
223
+ if (activeTabIndex > 0) {
224
+ const scrollToNav = !isTabNavVisible();
225
+ activateTab(activeTabIndex - 1, true, scrollToNav);
226
+ }
195
227
  });
196
228
  nextTabButton.addEventListener("click", () => {
197
- if (activeTabIndex < allSections.length - 1)
198
- activateTab(activeTabIndex + 1);
229
+ if (activeTabIndex < allSections.length - 1) {
230
+ const scrollToNav = !isTabNavVisible();
231
+ activateTab(activeTabIndex + 1, true, scrollToNav);
232
+ }
199
233
  });
200
234
  tabButtons.forEach((tabButton, buttonIndex) => {
201
235
  tabButton.addEventListener("click", () => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  starlightDomPatches
3
- } from "../chunk-RHYQUYJ3.js";
3
+ } from "../chunk-PPNIMJPX.js";
4
4
  import "../chunk-4VNS5WPM.js";
5
5
  export {
6
6
  starlightDomPatches
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "starlight-cannoli-plugins",
3
3
  "type": "module",
4
- "version": "2.10.2",
4
+ "version": "2.10.4",
5
5
  "description": "Starlight plugins for automatic sidebar generation and link validation",
6
6
  "license": "ISC",
7
7
  "main": "./dist/index.js",