summaryrefslogtreecommitdiff
path: root/src/components/Artwork.svelte
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/Artwork.svelte')
-rw-r--r--src/components/Artwork.svelte118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/components/Artwork.svelte b/src/components/Artwork.svelte
new file mode 100644
index 0000000..04de1d4
--- /dev/null
+++ b/src/components/Artwork.svelte
@@ -0,0 +1,118 @@
+<script lang="ts" context="module">
+ import type { Artwork as JetArtworkType } from '@jet-app/app-store/api/models';
+ import type {
+ Artwork as ComponentArtworkType,
+ Profile as ArtworkProfile,
+ CropCode,
+ ImageSizes,
+ } from '@amp/web-app-components/src/components/Artwork/types';
+
+ import type { NamedProfile } from '~/config/components/artwork';
+
+ /**
+ * Creates a {@linkcode Profile} on-the-fly based on the properties of
+ * the {@linkcode artwork}
+ */
+ export function getNaturalProfile(
+ artwork: JetArtworkType,
+ imageSizes: ImageSizes = [artwork.width],
+ ): ArtworkProfile {
+ const aspectRatio = artwork.width / artwork.height;
+
+ return [imageSizes, aspectRatio, artwork.crop as CropCode];
+ }
+
+ export type Profile = NamedProfile | ArtworkProfile;
+</script>
+
+<script lang="ts">
+ import type { ImageSettings } from '@amp/web-app-components/src/components/Artwork/types';
+ import Artwork from '@amp/web-app-components/src/components/Artwork/Artwork.svelte';
+ import { colorAsString, isNamedColor } from '~/utils/color';
+
+ import {
+ ArtworkConfig,
+ type ArtworkProfileMap,
+ } from '@amp/web-app-components/config/components/artwork';
+
+ export let artwork: JetArtworkType;
+ export let profile: Profile;
+ export let alt: string = '';
+ export let topRoundedSecondary: boolean = false;
+ export let useContainerStyle: boolean = false;
+ export let forceFullWidth: boolean = true;
+ export let isDecorative: boolean = true;
+ export let lazyLoad: boolean = true;
+ export let disableAutoCenter: boolean = false;
+ export let noShelfChevronAnchor: boolean = false;
+ export let forceCropCode: boolean = false;
+ export let quality: number | undefined = undefined;
+ export let hasTransparentBackground: boolean =
+ !!artwork.backgroundColor &&
+ isNamedColor(artwork.backgroundColor) &&
+ artwork.backgroundColor.name === 'clear';
+ export let useCropCodeFromArtwork: boolean = true;
+ export let withoutBorder: boolean = false;
+
+ let imageSettings: ImageSettings;
+ $: imageSettings = {
+ forceCropCode,
+ hasTransparentBackground,
+ quality,
+ };
+
+ let PROFILES: ArtworkProfileMap<string> | undefined;
+ let computedProfileAttributes: Profile | undefined;
+
+ $: {
+ const config = ArtworkConfig?.get();
+ PROFILES = config?.PROFILES;
+
+ const defaultProfileAttributes: Profile | undefined =
+ typeof profile === 'string' ? PROFILES?.get(profile) : profile;
+
+ const cropCodeIndex = 2;
+
+ if (
+ useCropCodeFromArtwork &&
+ artwork?.crop &&
+ defaultProfileAttributes
+ ) {
+ computedProfileAttributes = [...defaultProfileAttributes];
+ computedProfileAttributes[cropCodeIndex] =
+ artwork?.crop as CropCode;
+ }
+ }
+
+ $: artworkForComponent = {
+ ...artwork,
+ backgroundColor: artwork.backgroundColor
+ ? colorAsString(artwork.backgroundColor)
+ : undefined,
+ } satisfies ComponentArtworkType;
+</script>
+
+<Artwork
+ artwork={artworkForComponent}
+ profile={computedProfileAttributes || profile}
+ {topRoundedSecondary}
+ {useContainerStyle}
+ {forceFullWidth}
+ {imageSettings}
+ {alt}
+ {isDecorative}
+ {lazyLoad}
+ {disableAutoCenter}
+ {noShelfChevronAnchor}
+ {withoutBorder}
+/>
+
+<style>
+ /* When a user enables the "Smart Invert" accessibility setting, images should not be inverted,
+ so we are re-inverting back to their normal state in this media query, which only currently works for Safari. */
+ @media (inverted-colors: inverted) {
+ :global(.artwork-component img) {
+ filter: invert(1);
+ }
+ }
+</style>