All files / components/Accordion AccordionItem.svelte

100% Statements 58/58
55.55% Branches 5/9
100% Functions 1/1
100% Lines 58/58

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 591x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
<script lang="ts">
  import { afterNavigate } from "$app/navigation";
  import { page } from "$app/stores";
  import "./AccordionItem.scss";
  import { getAccordionContext } from "./context";
  import Link from "$lib/components/Link";
  import Icon from "$lib/components/Icon";
  import { url as linkIcon } from "$icons/link";
  import slugify from "$lib/util/slugify";
 
  export let id: string;
  export let title: string | null | undefined = "Title";
  export let onClickAnalyticsHandler: ((expanded: boolean) => void) | null = null;
 
  let ref: HTMLElement | null = null;
 
  $: ({ expandedItems, toggle } = getAccordionContext());
 
  let expanded: boolean;
  $: expanded = $expandedItems[id] ?? false;
 
  // TODO: Make `titleHref` come from Contentful instead of deriving it here
  const titleHref = title ? slugify(title) : null;
 
  // TODO fix storybook integration ($app/navigation store currently isn't mocked)
  afterNavigate(() => {
    if ($page.url.hash === `#${titleHref}` && $expandedItems) {
      $expandedItems[id] = true;
    }
  });
</script>
 
<h3 {...$$restProps} class="usa-accordion__heading" id={titleHref}>
  <button
    bind:this={ref}
    type="button"
    class="usa-accordion__button"
    aria-expanded={expanded}
    aria-controls={id}
    on:click={() => {
      toggle(id);
      if (expanded && ref && ref.getBoundingClientRect().top < 0) {
        ref.scrollIntoView();
      }
    }}
    on:click={() => onClickAnalyticsHandler?.(expanded)}
  >
    {title}
  </button>
</h3>
<div class="usa-accordion__content usa-prose" {id} hidden={!expanded}>
  <div class="accordion-deeplink--wrapper">
    <Link class="accordion-deeplink font-body-xs" href={`#${titleHref}`}
      >Link to item <Icon src={linkIcon} title="Link to item" /></Link
    >
  </div>
  <slot />
</div>