ArticlePage.svelte
1 <script lang="ts" context="module"> 2 import type { ArticlePage } from '@jet-app/app-store/api/models'; 3 4 import type { DefaultPageRequirements } from './DefaultPage.svelte'; 5 6 /** 7 * Just the `Page` props that we actually need to render this component 8 */ 9 export type ArticlePageRequirements = DefaultPageRequirements & { 10 card: ArticlePage['card']; 11 footerLockup: ArticlePage['footerLockup']; 12 }; 13 </script> 14 15 <script lang="ts"> 16 import TodayCard from '~/components/jet/today-card/TodayCard.svelte'; 17 import ShelfComponent from '~/components/jet/shelf/Shelf.svelte'; 18 import FooterLockupItem from '~/components/jet/item/FooterLockupItem.svelte'; 19 export let page: ArticlePageRequirements; 20 21 $: ({ card } = page); 22 </script> 23 24 <div class="article-page-container" data-testid="article-page-container"> 25 <div class="article-layout"> 26 {#if card} 27 <div class="card-container"> 28 <TodayCard {card} suppressClickAction /> 29 </div> 30 {/if} 31 32 <div class="story-container"> 33 {#each page.shelves as shelf} 34 {#if !shelf.isHidden} 35 <ShelfComponent {shelf} /> 36 {/if} 37 {/each} 38 39 {#if page.footerLockup} 40 <div class="footer-lockup-container"> 41 <FooterLockupItem item={page.footerLockup} /> 42 </div> 43 {/if} 44 </div> 45 </div> 46 </div> 47 48 <style lang="scss"> 49 @use 'ac-sasskit/modules/viewportcontent/core' as *; 50 @use 'amp/stylekit/core/viewports' as *; 51 52 .article-page-container { 53 flex-grow: 1; 54 width: 100%; 55 margin: 0 auto; 56 } 57 58 .article-layout { 59 --article-page-padding: 20px; 60 display: flex; 61 flex-direction: column; 62 align-items: center; 63 justify-content: center; 64 gap: var(--article-page-padding); 65 max-width: 1600px; 66 margin: 0 auto; 67 68 @media (--range-small-up) { 69 padding: 2em var(--bodyGutter); 70 } 71 72 @media (--range-small-only) { 73 --article-page-padding: 40px; 74 } 75 76 @media (--range-medium-up) { 77 align-items: flex-start; 78 flex-direction: row; 79 } 80 81 @media (--range-medium-only) { 82 --article-page-padding: 20px; 83 } 84 85 @media (--range-large-up) { 86 --article-page-padding: 40px; 87 } 88 } 89 90 .card-container { 91 flex-shrink: 0; 92 aspect-ratio: 3/4; 93 width: 100%; 94 95 @media (--range-xsmall-only) { 96 --border-radius: 0; 97 } 98 99 @media (--range-small-only) { 100 aspect-ratio: 16/9; 101 } 102 103 @media (--range-small-up) { 104 width: 100%; 105 } 106 107 @media (--range-medium-up) { 108 position: sticky; 109 top: 2em; 110 aspect-ratio: 3 / 4; 111 height: min(calc(100vh - 80px), calc(33vw * 4 / 3)); 112 min-height: 420px; 113 max-height: 700px; 114 width: auto; 115 } 116 } 117 118 .story-container { 119 width: 100%; 120 margin-top: 20px; 121 padding-bottom: var(--bodyGutter); 122 123 @media (--range-small-up) { 124 width: calc(100%); 125 margin-top: 0; 126 } 127 128 @media (--range-medium-up) { 129 min-width: calc(50% - calc(var(--article-page-padding))); 130 } 131 } 132 133 .story-container :global(.shelf:first-of-type) { 134 padding-top: 0; 135 padding-bottom: 13px; 136 } 137 138 .footer-lockup-container { 139 margin: var(--bodyGutter); 140 } 141 </style>