diff options
| author | rxliuli <rxliuli@gmail.com> | 2025-11-04 05:03:50 +0800 |
|---|---|---|
| committer | rxliuli <rxliuli@gmail.com> | 2025-11-04 05:03:50 +0800 |
| commit | bce557cc2dc767628bed6aac87301a1be7c5431b (patch) | |
| tree | b51a051228d01fe3306cd7626d4a96768aadb944 /src/context/accessibility-layout.ts | |
init commit
Diffstat (limited to 'src/context/accessibility-layout.ts')
| -rw-r--r-- | src/context/accessibility-layout.ts | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/context/accessibility-layout.ts b/src/context/accessibility-layout.ts new file mode 100644 index 0000000..110100f --- /dev/null +++ b/src/context/accessibility-layout.ts @@ -0,0 +1,93 @@ +import { getContext, setContext } from 'svelte'; + +import type { Shelf } from '@jet-app/app-store/api/models'; +import { isAccessibilityHeaderShelf } from '~/components/jet/shelf/AccessibilityHeaderShelf.svelte'; +import { isAccessibilityFeaturesShelf } from '~/components/jet/shelf/AccessibilityFeaturesShelf.svelte'; +import { isAccessibilityDeveloperLinkShelf } from '~/components/jet/shelf/AccessibilityDeveloperLinkShelf.svelte'; + +/** + * Describes the layout configuration for accessibility shelves + */ +interface AccessibilityLayoutConfiguration { + withBottomPadding: boolean; +} + +const ACCESSIBILITY_LAYOUT_FALLBACK: AccessibilityLayoutConfiguration = + Object.freeze({ + withBottomPadding: false, + }); + +type AccessibilityLayoutStore = WeakMap< + Shelf, + AccessibilityLayoutConfiguration +>; +type AccessibilityLayoutStoreContext = AccessibilityLayoutStore | undefined; + +const ACCESSIBILITY_LAYOUT_CONTEXT_ID = 'accessibility-layout-context'; + +/** + * Check if a shelf is accessibility-related + */ +function isAccessibilityRelated(shelf: Shelf): boolean { + return ( + shelf.contentType === 'accessibilityParagraph' || + shelf.contentType === 'accessibilityFeatures' + ); +} + +/** + * Check if a shelf is one of the target accessibility shelves + */ +function isTargetAccessibilityShelf(shelf: Shelf): boolean { + return ( + isAccessibilityHeaderShelf(shelf) || + isAccessibilityFeaturesShelf(shelf) || + isAccessibilityDeveloperLinkShelf(shelf) + ); +} + +/** + * Store the {@linkcode AccessibilityLayoutConfiguration} for each accessibility shelf + * in "context", so it can be retrieved at the shelf-component level + * + * This determines bottom padding based on whether the next shelf is accessibility-related + */ +export function setAccessibilityLayoutContext(page: { shelves: Shelf[] }) { + const store: AccessibilityLayoutStore = new WeakMap(); + + for (let i = 0; i < page.shelves.length; i++) { + const shelf = page.shelves[i]; + + // Only process target accessibility shelves + if (!isTargetAccessibilityShelf(shelf)) { + continue; + } + + // Check if the next shelf is accessibility-related + const nextShelf = page.shelves[i + 1]; + const hasAccessibilityNext = + nextShelf && isAccessibilityRelated(nextShelf); + + store.set(shelf, { + withBottomPadding: !hasAccessibilityNext, + }); + } + + setContext<AccessibilityLayoutStoreContext>( + ACCESSIBILITY_LAYOUT_CONTEXT_ID, + store, + ); +} + +/** + * Retrieve the {@linkcode AccessibilityLayoutConfiguration} for a given accessibility shelf + */ +export function getAccessibilityLayoutConfiguration( + shelf: Shelf, +): AccessibilityLayoutConfiguration { + const accessibilityLayout = getContext<AccessibilityLayoutStoreContext>( + ACCESSIBILITY_LAYOUT_CONTEXT_ID, + ); + + return accessibilityLayout?.get(shelf) ?? ACCESSIBILITY_LAYOUT_FALLBACK; +} |
