refactor(breadcrumb): replace scrollBreadcrumbsStore singleton with lazy accessor
Convert the eager scrollBreadcrumbsStore singleton to getScrollBreadcrumbsStore() (+ __resetScrollBreadcrumbsStore for tests) and add a public destroy() that disconnects the IntersectionObserver and scroll listener. Update the feature barrel and consumers (BreadcrumbHeader, BreadcrumbHeaderSeeded, NavigationWrapper).
This commit is contained in:
@@ -26,8 +26,8 @@
|
||||
*/
|
||||
|
||||
export {
|
||||
getScrollBreadcrumbsStore,
|
||||
type NavigationAction,
|
||||
scrollBreadcrumbsStore,
|
||||
} from './model';
|
||||
export {
|
||||
BreadcrumbHeader,
|
||||
|
||||
@@ -167,6 +167,13 @@ class ScrollBreadcrumbsStore {
|
||||
this.#detachScrollListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tears down the observer and scroll listener. Call on store disposal.
|
||||
*/
|
||||
destroy(): void {
|
||||
this.#disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* All tracked items sorted by index
|
||||
*/
|
||||
@@ -272,7 +279,17 @@ export function createScrollBreadcrumbsStore(): ScrollBreadcrumbsStore {
|
||||
return new ScrollBreadcrumbsStore();
|
||||
}
|
||||
|
||||
let _scrollBreadcrumbsStore: ScrollBreadcrumbsStore | undefined;
|
||||
|
||||
/**
|
||||
* Singleton scroll breadcrumbs store instance
|
||||
* App-wide scroll breadcrumbs store, created on first access.
|
||||
*/
|
||||
export const scrollBreadcrumbsStore = createScrollBreadcrumbsStore();
|
||||
export function getScrollBreadcrumbsStore(): ScrollBreadcrumbsStore {
|
||||
return (_scrollBreadcrumbsStore ??= createScrollBreadcrumbsStore());
|
||||
}
|
||||
|
||||
// test-only reset, so specs don't share observer/scroll state
|
||||
export function __resetScrollBreadcrumbsStore() {
|
||||
_scrollBreadcrumbsStore?.destroy();
|
||||
_scrollBreadcrumbsStore = undefined;
|
||||
}
|
||||
|
||||
@@ -14,9 +14,10 @@ import { cubicOut } from 'svelte/easing';
|
||||
import { slide } from 'svelte/transition';
|
||||
import {
|
||||
type BreadcrumbItem,
|
||||
scrollBreadcrumbsStore,
|
||||
getScrollBreadcrumbsStore,
|
||||
} from '../../model';
|
||||
|
||||
const scrollBreadcrumbsStore = getScrollBreadcrumbsStore();
|
||||
const breadcrumbs = $derived(scrollBreadcrumbsStore.scrolledPastItems);
|
||||
const responsive = getContext<ResponsiveManager>('responsive');
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { scrollBreadcrumbsStore } from '../../model';
|
||||
import { getScrollBreadcrumbsStore } from '../../model';
|
||||
import BreadcrumbHeader from './BreadcrumbHeader.svelte';
|
||||
|
||||
const scrollBreadcrumbsStore = getScrollBreadcrumbsStore();
|
||||
|
||||
const sections = [
|
||||
{ index: 100, title: 'Introduction' },
|
||||
{ index: 101, title: 'Typography' },
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
import { type Snippet } from 'svelte';
|
||||
import {
|
||||
type NavigationAction,
|
||||
scrollBreadcrumbsStore,
|
||||
getScrollBreadcrumbsStore,
|
||||
} from '../../model';
|
||||
|
||||
const scrollBreadcrumbsStore = getScrollBreadcrumbsStore();
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* Navigation index
|
||||
|
||||
Reference in New Issue
Block a user