fix: mobile toc issue with custom banners#3382
Conversation
🦋 Changeset detectedLatest commit: 5c487f5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for astro-starlight ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Lunaria Status Overview🌕 This pull request will trigger status changes. Learn moreBy default, every PR changing files present in the Lunaria configuration's You can change this by adding one of the keywords present in the Tracked Files
Warnings reference
|
delucis
left a comment
There was a problem hiding this comment.
Thanks for having a go at this @trueberryless!
this issue could also be resolved in some other ways of course and I'm not sure if introducing a second
IntersectionObserveris a good practice just for this edge case. Feel free to suggest cleaner solutions!
I think you might be right here — we can probably aim to fix the underlying issue if we can.
I tried adding https://github.com/pomber/intersection-observer-debugger to the page which is a handy way to visualize what is happening when working with IntersectionObserver and took a screenshot. This shows the problem quite clearly: the area we track using the rootMargin (highlighted at the top in purple) and the page title (highlighted below in green) don’t intersect:
If we look at a page without the banner, we can see these areas intersect (yellow highlight), triggering the initial ToC state:
The correct fix is probably to see if we can make the getRootMargin() method correctly detect an appropriate position by taking the banner into account:
starlight/packages/starlight/components/TableOfContents/starlight-toc.ts
Lines 100 to 110 in 266eed4
|
Ah, although re-reading your second considered solution is related to that same idea. Hmm. I’ll have to think about that. |
Yeah exactly, if we include the height of the banner in the As I think that this problem would be much harder to solve with potentially more edge cases, I gave up on the idea quite early, but maybe there is potential 🤔 Also just to mention it if (maybe I forgot to say): It's impossible to change the
Notice the read-only. |
Yeah that’s correct, that’s why we destroy and recreate the observer on window resizes currently. |
delucis
left a comment
There was a problem hiding this comment.
Thanks again for the PR @trueberryless and for helping us find even more problems 😄
Left a suggestion for the direction to take this.
|
I will remove the red banner (TODO) in the "Getting started" guide once this PR is approved. |
This comment was marked as resolved.
This comment was marked as resolved.
|
Isn't this related to |
That was it, thanks for the heads up! |
|
Now that #3656 is merged, should we also add some test cases to prevent this bug from happening again? |
That would be great! Can you see how to do it or do you need any pointers? |
I small pointer in the right direction would actually be very useful to me. Mainly:
|
I would. But you may want to add a new page to the basics fixture that includes the custom banner.
I think that function should work, yeah! Just pass it the |
Suggested-by: Chris Swithinbank <swithinbank@gmail.com> Inspired-by: HiDeoo <494699+HiDeoo@users.noreply.github.com>
Co-authored-by: HiDeoo <494699+HiDeoo@users.noreply.github.com>
35e120b to
24e107f
Compare
|
Sorry for the force push, but I found some completely unrelated commits in this PR (I don't know how I managed to get them in here), which messed up the labels, so I cleaned up the history a little bit (even if everything get's squashed nonetheless). Now at least the commits look clean here 🥳 |
delucis
left a comment
There was a problem hiding this comment.
Thanks for the tests @trueberryless! Left a couple of comments/questions.
Co-authored-by: Chris Swithinbank <357379+delucis@users.noreply.github.com>
delucis
left a comment
There was a problem hiding this comment.
I ended up pushing an entirely different strategy for this fix!
So here’s my thinking: while reviewing the change and thinking about that code repetition, I asked myself why this is an issue to start with? Why do we hit the issue at all. And the answer is “because the banner is too tall, so it pushes the observed elements out of the way”.
Until now we were thinking “OK, we can make a special case, just on page load, where we force the current item to be the page title”.
But in my last round of fixes we already introduced a similar case: we force the page title when walking up the tree and finding the .sl-markdown-content container.
So I thought, “Why does a similar thing not work here?” And long story short, it does! I added the banner (actually any direct child of <main> just in case someone adds e.g. a banner that doesn’t use the sl-banner class name) to the items to observe for intersections and also added them to the page title escape hatch. Seems to work well!
delucis
left a comment
There was a problem hiding this comment.
I believe this is ready, so approving, but will wait for your comment @trueberryless before merging in case you spot something I missed given the code change is quite different now.
trueberryless
left a comment
There was a problem hiding this comment.
Awesome! 🥳
I can't approve my own PR, but I would love to with this clean solution.
Overall everything seems reasonable to me, just left a small question.
| // Short circuit if we reach the top-level content container. | ||
| if (el.classList.contains('sl-markdown-content')) { | ||
| // Short circuit if we reach the top-level content container or one of the other containers in main. | ||
| if (el.matches('.sl-markdown-content, main > *')) { |
There was a problem hiding this comment.
I don't fully understand why the addition of main > * is necessary just for the banner? Couldn't we restrict more to avoid unexpected matches or is this intentional?
There was a problem hiding this comment.
This is what I was trying to explain in this part of my comment:
any direct child of
<main>just in case someone adds e.g. a banner that doesn’t use thesl-bannerclass name
In other words, we could check for .sl-banner specifically, but we support overriding the banner component and people could use a different component without that class name, OR add some other additional above the page title. And we want to cover both those cases, so that’s why I preferred a more generic selector.
In practice this cannot match most elements in <main> because we exclude most of them in the selector that determines what to watch.
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [@astrojs/starlight](https://starlight.astro.build) ([source](https://github.com/withastro/starlight/tree/HEAD/packages/starlight)) | [`0.37.3` → `0.37.4`](https://renovatebot.com/diffs/npm/@astrojs%2fstarlight/0.37.3/0.37.4) |  |  | --- ### Release Notes <details> <summary>withastro/starlight (@​astrojs/starlight)</summary> ### [`v0.37.4`](https://github.com/withastro/starlight/blob/HEAD/packages/starlight/CHANGELOG.md#0374) [Compare Source](https://github.com/withastro/starlight/compare/@astrojs/starlight@0.37.3...@astrojs/starlight@0.37.4) ##### Patch Changes - [#​3534](withastro/starlight#3534) [`703fab0`](withastro/starlight@703fab0) Thanks [@​HiDeoo](https://github.com/HiDeoo)! - Fixes support for running builds when `npx` is unavailable. Previously, Starlight would spawn a process to run the Pagefind search indexing binary using `npx`. On platforms where `npx` isn’t available, this could cause issues. Starlight now runs Pagefind using its Node.js API to avoid a separate process. As a side effect, you may notice that logging during builds is now less verbose. - [#​3656](withastro/starlight#3656) [`a0e6368`](withastro/starlight@a0e6368) Thanks [@​delucis](https://github.com/delucis)! - Fixes several edge cases in highlighting the current page heading in Starlight’s table of contents - [#​3663](withastro/starlight#3663) [`00cbf00`](withastro/starlight@00cbf00) Thanks [@​lines-of-codes](https://github.com/lines-of-codes)! - Adds Thai language support - [#​3658](withastro/starlight#3658) [`ac79329`](withastro/starlight@ac79329) Thanks [@​delucis](https://github.com/delucis)! - Avoids adding redundant `aria-current="false"` attributes to sidebar entries - [#​3382](withastro/starlight#3382) [`db295c2`](withastro/starlight@db295c2) Thanks [@​trueberryless](https://github.com/trueberryless)! - Fixes an issue where the mobile table of contents is unable to find the first heading when a page has a tall banner. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi45Mi40IiwidXBkYXRlZEluVmVyIjoiNDIuOTIuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> Co-authored-by: Renovate Bot <renovate@zarantonello.dev> Co-committed-by: Renovate Bot <renovate@zarantonello.dev>
* main: [ci] release (withastro#3659) fix: mobile toc issue with custom banners (withastro#3382) chore(deps): update actions/checkout action to v6.0.2 (withastro#3670) Fix table of contents intersection observer (withastro#3656) chore(deps): update peter-evans/create-pull-request action to v8.1.0 (withastro#3669) Pagefind CLI → Pagefind API (withastro#3534) chore(deps): update changesets/action action to v1.6.0 (withastro#3668) i18n(de): Fix orthographic errors in `getting-started.mdx` and `index.mdx` (withastro#3664) i18n(fr): update `resources/plugins.mdx` (withastro#3665) [ci] format i18n(th): Add Thai translations to Starlight UI (withastro#3663) i18n(de): update resources/plugins.mdx (withastro#3662) i18n(ko): update community plugins (withastro#3661)


Description
This PR fixes an issue with the Table of Contents being unable to find any heading when the page has a banner with custom styling. This issue is currently tracked in #3047.
The issue is fixed by setting the current heading to the page title, when not found otherwise.
Related stuff and todo