this repo has no description
1<script lang="ts" context="module">
2 import type { Artwork as JetArtworkType } from '@jet-app/app-store/api/models';
3 import type { NamedProfile } from '~/config/components/artwork';
4
5 export type AppIconProfile = Extract<
6 NamedProfile,
7 | 'app-icon'
8 | 'app-icon-large'
9 | 'app-icon-medium'
10 | 'app-icon-small'
11 | 'app-icon-xlarge'
12 | 'app-icon-river'
13 | 'brick-app-icon'
14 >;
15
16 export function doesAppIconNeedBorder(icon: JetArtworkType): boolean {
17 const doesIconHaveTransparentBackground =
18 icon.backgroundColor &&
19 isNamedColor(icon.backgroundColor) &&
20 icon.backgroundColor.name === 'clear';
21 const isIconPrerendered =
22 icon.style === 'roundedRectPrerendered' ||
23 icon.style === 'roundPrerendered';
24 const isIconUnadorned = icon.style === 'unadorned';
25
26 return (
27 !doesIconHaveTransparentBackground &&
28 !isIconPrerendered &&
29 !isIconUnadorned
30 );
31 }
32</script>
33
34<script lang="ts">
35 import Artwork from '~/components/Artwork.svelte';
36 import { ArtworkConfig } from '@amp/web-app-components/config/components/artwork';
37 import { isNamedColor } from '~/utils/color';
38
39 export let icon: JetArtworkType;
40 export let profile: AppIconProfile = 'app-icon';
41 export let fixedWidth: boolean = true;
42 export let disableAutoCenter: boolean = false;
43 export let withBorder: boolean = false;
44
45 const profiles = ArtworkConfig.get().PROFILES;
46
47 $: computedProfile = (
48 icon.style === 'pill'
49 ? `${profile}-pill`
50 : icon.style === 'tvRect'
51 ? `${profile}-tv-rect`
52 : profile
53 ) as NamedProfile;
54 $: widthFromProfile = profiles?.get(computedProfile)?.[0] ?? 0;
55 $: hasTransparentBackground =
56 !!icon.backgroundColor &&
57 isNamedColor(icon.backgroundColor) &&
58 icon.backgroundColor.name === 'clear';
59 $: needsBorder = withBorder || doesAppIconNeedBorder(icon);
60
61 // These prerendered "Solarium" icons need to use higher than normal quality due to how their
62 // rendering pipeline downscales/transforms sources.
63 $: quality =
64 icon.style &&
65 ['roundedRectPrerendered', 'roundPrerendered'].includes(icon.style)
66 ? 75
67 : undefined;
68</script>
69
70<div
71 class="app-icon"
72 class:pill={icon.style === 'pill'}
73 class:round={icon.style === 'round'}
74 class:rounded-rect={icon.style === 'roundedRect'}
75 class:tv-rect={icon.style === 'tvRect'}
76 class:rounded-rect-prerendered={icon.style === 'roundedRectPrerendered'}
77 class:round-prerendered={icon.style === 'roundPrerendered'}
78 class:with-border={needsBorder}
79 style={fixedWidth ? `--profileWidth: ${widthFromProfile}px` : ''}
80>
81 <Artwork
82 {disableAutoCenter}
83 {hasTransparentBackground}
84 {quality}
85 artwork={icon}
86 profile={computedProfile}
87 noShelfChevronAnchor={true}
88 />
89</div>
90
91<style>
92 .app-icon {
93 aspect-ratio: 1 / 1;
94 min-width: var(--profileWidth, auto);
95 }
96
97 .app-icon.pill {
98 aspect-ratio: 4 / 3;
99
100 /*
101 Creates elliptical corners with horizontal radii at 50% of the width and vertical radii
102 at 65% of the height, for a rounded, squished, pill-like effect
103 */
104 border-radius: 50% 50% 50% 50% / 65% 65% 65% 65%;
105 }
106
107 .app-icon.round {
108 border-radius: 50%;
109 }
110
111 .app-icon.rounded-rect {
112 border-radius: 23%;
113 }
114
115 .app-icon.tv-rect {
116 aspect-ratio: 16/9;
117 border-radius: 9% / 16%;
118 }
119
120 .app-icon.rounded-rect-prerendered {
121 border-radius: 25%;
122 }
123
124 .app-icon.round-prerendered {
125 border-radius: 50%;
126 }
127
128 .app-icon.with-border {
129 box-shadow: 0 0 0 1px var(--systemQuaternary);
130 }
131</style>