LinkWrapper.svelte
1 <!-- 2 @component 3 Wraps a link around the provided slot contents if a valid `FlowAction` or `ExternalUrlAction` is given. 4 If no valid action is provided, the contents are rendered as-is with no decoration. 5 6 💡 For accessibility, this component should ideally wrap the entire visual block (e.g., `div`, `article`) so that 7 screen readers and keyboard users interpret the entire element as a single link. 8 9 @example 10 ``` 11 <LinkWrapper action={item.clickAction}> 12 <article> 13 <Artwork artwork={item.artwork} /> 14 {item.title} 15 </article> 16 </LinkWrapper> 17 ``` 18 --> 19 <script lang="ts"> 20 import { type Action, isFlowAction } from '@jet-app/app-store/api/models'; 21 import { type Opt, isSome } from '@jet/environment/types/optional'; 22 23 import FlowActionComponent from '~/components/jet/action/FlowAction.svelte'; 24 import { isExternalUrlAction } from '~/jet/models'; 25 import ExternalUrlAction from './jet/action/ExternalUrlAction.svelte'; 26 import ShelfBasedPageScrollAction, { 27 isShelfBasedPageScrollAction, 28 } from './jet/action/ShelfBasedPageScrollAction.svelte'; 29 30 export let action: Opt<Action> = null; 31 export let label: Opt<string> = null; 32 export let withoutLabel: Opt<boolean> = false; 33 export let includeExternalLinkArrowIcon: boolean = true; 34 </script> 35 36 {#if isSome(action) && isFlowAction(action) && isSome(action.pageUrl)} 37 <FlowActionComponent 38 destination={action} 39 aria-label={withoutLabel ? null : label || action.title} 40 > 41 <slot /> 42 </FlowActionComponent> 43 {:else if isSome(action) && isExternalUrlAction(action)} 44 <ExternalUrlAction 45 destination={action} 46 aria-label={withoutLabel ? null : label || action.title} 47 includeArrowIcon={includeExternalLinkArrowIcon} 48 > 49 <slot /> 50 </ExternalUrlAction> 51 {:else if isSome(action) && isShelfBasedPageScrollAction(action)} 52 <ShelfBasedPageScrollAction 53 destination={action} 54 aria-label={withoutLabel ? null : label || action.title} 55 > 56 <slot /> 57 </ShelfBasedPageScrollAction> 58 {:else} 59 <slot /> 60 {/if}