this repo has no description
1<script lang="ts">
2 import { getI18n } from '~/stores/i18n';
3 import { isSome } from '@jet/environment/types/optional';
4 import type { TopChartsPage } from '@jet-app/app-store/api/models';
5
6 import DefaultPage from '~/components/pages/DefaultPage.svelte';
7 import Shelf from '~/components/Shelf/Wrapper.svelte';
8 import Artwork, { getNaturalProfile } from '~/components/Artwork.svelte';
9 import Menu from '~/components/Menu.svelte';
10 import LinkWrapper from '~/components/LinkWrapper.svelte';
11 import SFSymbol from '~/components/SFSymbol.svelte';
12
13 export let page: TopChartsPage;
14
15 const i18n = getI18n();
16
17 $: ({ categories, categoriesButtonTitle, segments, initialSegmentIndex } =
18 page);
19 $: segment = segments[initialSegmentIndex];
20</script>
21
22<DefaultPage page={{ shelves: segment.shelves, title: page.title }}>
23 <Shelf slot="before-shelves" centered>
24 <header>
25 <div class="dropdown-container">
26 {#if categoriesButtonTitle}
27 <Menu options={categories}>
28 <svelte:fragment slot="trigger">
29 <span class="menu-trigger-contents">
30 {categoriesButtonTitle}
31
32 <SFSymbol name="chevron.down" />
33 </span>
34 </svelte:fragment>
35
36 <svelte:fragment slot="option" let:option>
37 {@const { artwork, chartSelectAction, name } =
38 option}
39
40 <LinkWrapper action={chartSelectAction}>
41 <div
42 class="category-menu-item"
43 class:active={name ===
44 categoriesButtonTitle}
45 >
46 {#if isSome(artwork)}
47 <div class="artwork-container">
48 <Artwork
49 {artwork}
50 profile={getNaturalProfile(
51 artwork,
52 [24],
53 )}
54 />
55 </div>
56 {/if}
57
58 <span>{name}</span>
59 </div>
60 </LinkWrapper>
61 </svelte:fragment>
62 </Menu>
63 {/if}
64 </div>
65
66 <div class="segment-selector" aria-label={categoriesButtonTitle}>
67 {#each segments as segment, index}
68 {@const { segmentSelectAction } = segment}
69 {@const isSelected = initialSegmentIndex === index}
70 {@const filterLabel = $i18n.t(
71 isSelected
72 ? 'ASE.Web.AppStore.SelectedFilterApps.AX.Label'
73 : 'ASE.Web.AppStore.FilterApps.AX.Label',
74 { filterName: segment.shortName },
75 )}
76
77 <LinkWrapper
78 action={segmentSelectAction}
79 label={filterLabel}
80 >
81 <span class="segment" class:selected={isSelected}>
82 {segment.shortName}
83 </span>
84 </LinkWrapper>
85 {/each}
86 </div>
87 </header>
88 </Shelf>
89</DefaultPage>
90
91<style>
92 header {
93 --pill-button-border-radius: 1000px; /* Arbitrary large value for "pill-style" rounded sides */
94 --menu-item-padding: 0;
95 --menu-item-margin: 0 0 8px 0;
96 --menu-popover-padding: 12px 16px;
97 --menu-common-padding: 0;
98 --menu-trigger-border-radius: var(--pill-button-border-radius);
99 --menu-trigger-background-color: var(--systemPrimary-onDark);
100 --menu-trigger-padding: 6px 16px;
101 --menu-trigger-font: var(--body-semibold-tall);
102 --menu-popover-background-color: white;
103 --menu-popover-box-shadow: 10px 10px 10px 0
104 var(--systemQuaternary-onLight);
105 --menu-popover-border-radius: 14px;
106 --menu-popover-border: 1px solid var(--systemQuaternary);
107 --menu-popover-z-index: calc(var(--z-web-chrome) + 1);
108 display: grid;
109 grid-template-columns: 1fr 1fr;
110 gap: 20px;
111
112 @media (--range-small-up) {
113 display: grid;
114 align-items: center;
115 justify-items: start;
116 grid-template-columns: 1fr max-content 1fr;
117 }
118
119 @media (prefers-color-scheme: dark) {
120 --menu-trigger-background-color: var(--systemQuaternary);
121 --menu-popover-background-color: var(--systemQuaternary-vibrant);
122 }
123 }
124
125 .segment-selector {
126 display: flex;
127 justify-self: end;
128 gap: 4px;
129 padding: 2px;
130 background: var(--systemQuaternary);
131 border-radius: var(--pill-button-border-radius);
132
133 @media (--range-small-up) {
134 align-items: center;
135 justify-self: center;
136 grid-column: 2;
137 }
138 }
139
140 .segment-selector :global(a) {
141 display: contents;
142 }
143
144 .segment {
145 border-radius: var(--pill-button-border-radius);
146 font: var(--body-semibold-tall);
147 padding: 6px 16px;
148 }
149
150 .segment.selected {
151 background-color: var(--systemPrimary-onDark);
152 color: var(--systemPrimary);
153
154 @media (prefers-color-scheme: dark) {
155 background-color: var(--systemQuaternary);
156 }
157 }
158
159 .dropdown-container {
160 justify-self: start;
161
162 @media (--range-small-up) {
163 grid-column: 1;
164 }
165 }
166
167 .menu-trigger-contents {
168 display: flex;
169 align-items: center;
170 gap: 4px;
171 }
172
173 .menu-trigger-contents :global(svg) {
174 height: 0.7em;
175 }
176
177 .menu-trigger-contents :global(path:not([fill='none'])) {
178 fill: currentColor;
179 }
180
181 .category-menu-item {
182 display: flex;
183 align-items: center;
184 padding: 8px;
185 border-radius: 10px;
186 height: 40px;
187 transition: background 150ms ease-in;
188 }
189
190 .category-menu-item.active {
191 background: var(--systemQuinary);
192 }
193
194 .category-menu-item:not(.active):hover {
195 background: rgba(0, 0, 0, 0.035);
196 }
197
198 .artwork-container {
199 width: 24px;
200 margin-inline-end: 8px;
201 flex-shrink: 0;
202 }
203
204 .category-menu-item span {
205 text-overflow: ellipsis;
206 overflow: hidden;
207 }
208
209 .dropdown-container :global(.menu-popover) {
210 max-width: 600px;
211 width: 100%;
212 column-count: 2;
213
214 @media (--range-medium-up) {
215 column-count: 3;
216 }
217 }
218</style>