summaryrefslogtreecommitdiff
path: root/src/components/jet/item/Annotation/ModernAnnotationItemRenderer.svelte
blob: 20611d316c5439923b489106f0c6a2aaef8cb9cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<script lang="ts">
    import type { AnnotationItem_V3 } from '@jet-app/app-store/api/models';
    import { sanitizeHtml } from '@amp/web-app-components/src/utils/sanitize-html';
    import SystemImage, {
        isSystemImageArtwork,
    } from '~/components/SystemImage.svelte';
    import LinkWrapper from '~/components/LinkWrapper.svelte';

    export let items: AnnotationItem_V3[];
    export let summary: string | undefined;

    const formatStyledText = (text: string): string => {
        return (
            text
                // Replace \n with <br>
                .replace(/\n/g, '<br>')
                // Replace **text** with <strong>text</strong>
                .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
        );
    };
</script>

<ul>
    {#each items as annotationItem}
        <li>
            {#if annotationItem.$kind === 'textEncapsulation'}
                <div class="text-encapsulation">
                    {annotationItem.text}
                </div>
            {:else if annotationItem.$kind === 'linkableText'}
                <div class="styled-text">
                    {@html sanitizeHtml(
                        formatStyledText(
                            annotationItem.linkableText.styledText.rawText,
                        ),
                    )}
                </div>
            {:else if annotationItem.$kind === 'artwork'}
                {#if isSystemImageArtwork(annotationItem.artwork)}
                    <div class="artwork-wrapper" aria-label={summary}>
                        <SystemImage artwork={annotationItem.artwork} />
                    </div>
                {/if}
            {:else if annotationItem.$kind === 'textPair'}
                <div class="text-pair">
                    <span>{annotationItem.leadingText}</span>
                    <span>
                        {annotationItem.trailingText}
                    </span>
                </div>
            {:else if annotationItem.$kind === 'button'}
                <div class="button-wrapper">
                    <LinkWrapper action={annotationItem.action}>
                        {annotationItem.action.title}
                    </LinkWrapper>
                </div>
            {:else if annotationItem.$kind === 'spacer'}
                <div class="spacer" />
            {/if}
        </li>
    {/each}
</ul>

<style>
    li {
        font: var(--body-tall);
    }

    .styled-text :global(strong) {
        color: var(--systemPrimary);
        font: var(--body-emphasized);
    }

    .text-encapsulation {
        width: fit-content;
        color: var(--keyColor);
        border: 1px solid;
        border-radius: 3px;
        padding-inline: 3px;
        border-color: var(--keyColor);
        margin-block: 3px;
    }

    .artwork-wrapper :global(svg) {
        height: 18px;
        width: 18px;
        margin-top: 4px;
    }

    .spacer {
        height: 16px;
    }

    .button-wrapper :global(a) {
        color: var(--keyColor);
        text-decoration: none;
    }

    .button-wrapper :global(a:hover) {
        text-decoration: underline;
    }

    .button-wrapper :global(a) :global(.external-link-arrow) {
        width: 7px;
        height: 7px;
        fill: var(--keyColor);
        margin-top: 3px;
    }

    .text-pair {
        display: flex;
        justify-content: space-between;
    }
</style>