|
25 | 25 |
|
26 | 26 | const [throttledHighlightHeader] = throttle(highlightHeader, 100); |
27 | 27 | const debouncedHighlightHeader = debounce(highlightHeader, 100); |
| 28 | +
|
| 29 | + const getHeaderLevel = (header: HTMLElement) => { |
| 30 | + const tagName = header.tagName; |
| 31 | + return Number(tagName.split('')[1]); |
| 32 | + }; |
| 33 | +
|
| 34 | + const headerIsVisibleAmongSiblings = (header: HTMLElement) => { |
| 35 | + const level = getHeaderLevel(header); |
| 36 | + const sameLevelHeaders = trackedHeaders.filter((h) => getHeaderLevel(h.element) === level); |
| 37 | + const index = sameLevelHeaders.findIndex((h) => h.element === header); |
| 38 | +
|
| 39 | + let selectedSameLevelHeaderIndex = 0; |
| 40 | + for (let i = sameLevelHeaders.length - 1; i >= 0; i--) { |
| 41 | + const rect = sameLevelHeaders[i].element.getBoundingClientRect(); |
| 42 | + if (rect.top < Padding) { |
| 43 | + selectedSameLevelHeaderIndex = i; |
| 44 | + break; |
| 45 | + } |
| 46 | + } |
| 47 | +
|
| 48 | + return selectedSameLevelHeaderIndex === index; |
| 49 | + }; |
28 | 50 | </script> |
29 | 51 |
|
30 | 52 | <svelte:window |
|
36 | 58 |
|
37 | 59 | <div class="h-full space-y-3 {className}"> |
38 | 60 | {#each trackedHeaders as header, i} |
39 | | - {@const margin = Number(header.element.tagName.split('')[1]) - 1} |
| 61 | + {@const headerLevel = getHeaderLevel(header.element)} |
| 62 | + {@const margin = headerLevel - 1} |
| 63 | + {@const parentHeader = trackedHeaders |
| 64 | + .filter((_, j) => j < i) |
| 65 | + .findLast((h) => { |
| 66 | + const parentHeaderLevel = getHeaderLevel(h.element); |
| 67 | + return parentHeaderLevel === headerLevel - 1; |
| 68 | + })} |
40 | 69 | {#key selectedHeaderIndex} |
41 | | - {#if header.element.children[0] instanceof HTMLAnchorElement && header.element.children[0].href} |
42 | | - <a |
43 | | - style="margin-left: {margin * 0.75}rem;" |
44 | | - class="block text-sm {selectedHeaderIndex === i |
45 | | - ? 'font-medium text-sky-300' |
46 | | - : 'text-neutral-400'}" |
47 | | - href={header.element.children[0].href}>{header.element.innerText}</a |
48 | | - > |
| 70 | + {#if headerLevel <= 2 || (parentHeader && headerIsVisibleAmongSiblings(parentHeader.element))} |
| 71 | + {#if header.element.children[0] instanceof HTMLAnchorElement && header.element.children[0].href} |
| 72 | + <a |
| 73 | + style="margin-left: {margin * 0.75}rem;" |
| 74 | + class="block text-sm transition {selectedHeaderIndex === i |
| 75 | + ? 'font-medium text-sky-300' |
| 76 | + : 'text-neutral-400'}" |
| 77 | + href={header.element.children[0].href} |
| 78 | + >{header.element.innerText} |
| 79 | + </a> |
| 80 | + {/if} |
49 | 81 | {/if} |
50 | 82 | {/key} |
51 | 83 | {/each} |
|
0 commit comments