/ src / components / jet / shelf / EditorialLinkShelf.svelte
EditorialLinkShelf.svelte
  1  <script lang="ts" context="module">
  2      import type { Shelf, EditorialLink } from '@jet-app/app-store/api/models';
  3  
  4      interface EditorialLinkShelf extends Shelf {
  5          contentType: 'smallStoryCard';
  6          items: [EditorialLink];
  7      }
  8  
  9      export function isEditorialLinkShelf(
 10          shelf: Shelf,
 11      ): shelf is EditorialLinkShelf {
 12          const { contentType, items } = shelf;
 13          return contentType === 'editorialLink' && Array.isArray(items);
 14      }
 15  </script>
 16  
 17  <script lang="ts">
 18      import ShelfWrapper from '~/components/Shelf/Wrapper.svelte';
 19      import ChevronRightIcon from '~/sf-symbols/chevron.right.svg';
 20      import LinkWrapper from '~/components/LinkWrapper.svelte';
 21  
 22      export let shelf: EditorialLinkShelf;
 23      $: item = shelf.items[0];
 24      $: ({ clickAction, descriptionText, summaryText } = item);
 25  </script>
 26  
 27  <ShelfWrapper {shelf} withBottomPadding={false}>
 28      <article>
 29          <LinkWrapper
 30              action={clickAction}
 31              includeExternalLinkArrowIcon={false}
 32              label={descriptionText}
 33          >
 34              <svelte:fragment>
 35                  <div>
 36                      <span class="title">{descriptionText}</span>
 37                      <span class="subtitle">{summaryText}</span>
 38                  </div>
 39  
 40                  <span class="icon-container" aria-hidden="true">
 41                      <ChevronRightIcon />
 42                  </span>
 43              </svelte:fragment>
 44          </LinkWrapper>
 45      </article>
 46  </ShelfWrapper>
 47  
 48  <style lang="scss">
 49      @use '@amp/web-shared-styles/sasskit-stylekit/ac-sasskit-config';
 50      @use 'ac-sasskit/core/helpers' as *;
 51      @use 'ac-sasskit/core/locale' as *;
 52  
 53      article {
 54          display: flex;
 55          align-items: center;
 56          flex-direction: row;
 57          justify-content: space-between;
 58          padding: 16px;
 59          margin: 0 var(--bodyGutter);
 60          border-radius: var(--global-border-radius-medium);
 61          background-color: var(--systemQuinary);
 62          transition: background-color 210ms ease-out;
 63      }
 64  
 65      article:hover {
 66          cursor: pointer;
 67          // a fallback for browsers that don't support relative colors (e.g. the `from` syntax)
 68          background-color: var(--systemQuinary);
 69          // stylelint-disable-next-line color-function-notation
 70          background-color: rgb(
 71              from var(--systemQuinary) r g b / calc(alpha + 0.02)
 72          );
 73      }
 74  
 75      article:hover .icon-container {
 76          transform: translateX(2px);
 77  
 78          @include rtl {
 79              transform: translateX(-2px) rotate(-180deg);
 80          }
 81      }
 82  
 83      div {
 84          display: flex;
 85          flex-direction: column;
 86          gap: 4px;
 87      }
 88  
 89      .title {
 90          font: var(--body-emphasized);
 91      }
 92  
 93      .subtitle {
 94          color: var(--systemSecondary);
 95      }
 96  
 97      .icon-container {
 98          position: relative;
 99          height: 10px;
100          aspect-ratio: 0.9;
101          transition: transform 210ms ease-out;
102  
103          @include rtl {
104              transform: rotate(-180deg);
105          }
106      }
107  
108      .icon-container :global(path:not([fill='none'])) {
109          fill: var(--systemPrimary);
110      }
111  
112      article :global(a) {
113          display: flex;
114          justify-content: space-between;
115          align-items: center;
116          width: 100%;
117  
118          &:hover {
119              text-decoration: none;
120          }
121      }
122  </style>