summaryrefslogtreecommitdiffstatshomepage
path: root/frontend/src/lib/pills
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/lib/pills')
-rw-r--r--frontend/src/lib/pills/AssociationPill.svelte30
-rw-r--r--frontend/src/lib/pills/ComicPills.svelte37
-rw-r--r--frontend/src/lib/pills/Pill.svelte40
-rw-r--r--frontend/src/lib/pills/TagPill.svelte40
4 files changed, 147 insertions, 0 deletions
diff --git a/frontend/src/lib/pills/AssociationPill.svelte b/frontend/src/lib/pills/AssociationPill.svelte
new file mode 100644
index 0000000..85dbe39
--- /dev/null
+++ b/frontend/src/lib/pills/AssociationPill.svelte
@@ -0,0 +1,30 @@
+<script lang="ts">
+ import Pill from './Pill.svelte';
+
+ type Association = 'artist' | 'circle' | 'world' | 'character';
+
+ export let name: string;
+ export let type: Association;
+</script>
+
+<Pill {name}>
+ <span class={`${type} icon-xs`} slot="icon" />
+</Pill>
+
+<style lang="postcss">
+ .artist {
+ @apply icon-[material-symbols--person] -mx-px;
+ }
+
+ .character {
+ @apply icon-[material-symbols--face];
+ }
+
+ .circle {
+ @apply icon-[material-symbols--group] mx-px;
+ }
+
+ .world {
+ @apply icon-[material-symbols--public];
+ }
+</style>
diff --git a/frontend/src/lib/pills/ComicPills.svelte b/frontend/src/lib/pills/ComicPills.svelte
new file mode 100644
index 0000000..671bbf2
--- /dev/null
+++ b/frontend/src/lib/pills/ComicPills.svelte
@@ -0,0 +1,37 @@
+<script lang="ts">
+ import type { ComicFragment } from '$gql/graphql';
+ import AssociationPill from '$lib/pills/AssociationPill.svelte';
+ import TagPill from '$lib/pills/TagPill.svelte';
+
+ export let comic: ComicFragment;
+</script>
+
+<div class="flex flex-col gap-1">
+ {#if comic.artists.length || comic.circles.length}
+ <div class="flex flex-wrap gap-1">
+ {#each comic.artists as { name } (name)}
+ <AssociationPill {name} type="artist" />
+ {/each}
+ {#each comic.circles as { name } (name)}
+ <AssociationPill {name} type="circle" />
+ {/each}
+ </div>
+ {/if}
+ {#if comic.characters.length || comic.worlds.length}
+ <div class="flex flex-wrap gap-1">
+ {#each comic.worlds as { name } (name)}
+ <AssociationPill {name} type="world" />
+ {/each}
+ {#each comic.characters as { name } (name)}
+ <AssociationPill {name} type="character" />
+ {/each}
+ </div>
+ {/if}
+ {#if comic.tags.length}
+ <div class="flex flex-wrap gap-1">
+ {#each comic.tags as { name, description } (name)}
+ <TagPill {name} {description} />
+ {/each}
+ </div>
+ {/if}
+</div>
diff --git a/frontend/src/lib/pills/Pill.svelte b/frontend/src/lib/pills/Pill.svelte
new file mode 100644
index 0000000..7aa9670
--- /dev/null
+++ b/frontend/src/lib/pills/Pill.svelte
@@ -0,0 +1,40 @@
+<script lang="ts" context="module">
+ export type PillColour = 'pink' | 'blue' | 'violet' | 'amber' | 'zinc' | 'sky';
+</script>
+
+<script lang="ts">
+ export let name: string;
+ export let tooltip: string | null | undefined = undefined;
+ export let colour: PillColour = 'zinc';
+</script>
+
+<div class="flex items-center rounded border p-0.5 {colour}" title={tooltip}>
+ <slot name="icon" />
+ <span>{name}</span>
+</div>
+
+<style lang="postcss">
+ .pink {
+ @apply border-pink-800 bg-pink-800/20 text-pink-200;
+ }
+
+ .blue {
+ @apply border-blue-800 bg-blue-800/20 text-blue-200;
+ }
+
+ .violet {
+ @apply border-violet-800 bg-violet-800/20 text-violet-200;
+ }
+
+ .amber {
+ @apply border-amber-800 bg-amber-800/20 text-amber-200;
+ }
+
+ .sky {
+ @apply border-sky-800 bg-sky-800/20 text-sky-200;
+ }
+
+ .zinc {
+ @apply border-zinc-700 bg-zinc-700/20 text-zinc-300;
+ }
+</style>
diff --git a/frontend/src/lib/pills/TagPill.svelte b/frontend/src/lib/pills/TagPill.svelte
new file mode 100644
index 0000000..60221bd
--- /dev/null
+++ b/frontend/src/lib/pills/TagPill.svelte
@@ -0,0 +1,40 @@
+<script lang="ts">
+ import Female from '$lib/icons/Female.svelte';
+ import Location from '$lib/icons/Location.svelte';
+ import Male from '$lib/icons/Male.svelte';
+ import Transgender from '$lib/icons/Transgender.svelte';
+ import { SvelteComponent } from 'svelte';
+ import Pill, { type PillColour } from './Pill.svelte';
+
+ export let name: string;
+ export let description: string | undefined | null = undefined;
+
+ let [namespace, tag] = name.split(':');
+
+ const styles: Record<string, PillColour> = {
+ female: 'pink',
+ male: 'blue',
+ trans: 'violet',
+ mixed: 'amber',
+ location: 'sky',
+ rest: 'zinc'
+ };
+
+ const icons: Record<string, typeof SvelteComponent<Record<string, unknown>>> = {
+ female: Female,
+ male: Male,
+ trans: Transgender,
+ location: Location
+ };
+
+ const colour = styles[namespace] ?? styles.rest;
+ const icon = icons[namespace];
+
+ function formatTooltip() {
+ return [name, description].filter((v) => v).join('\n\n');
+ }
+</script>
+
+<Pill name={tag} tooltip={formatTooltip()} {colour}>
+ <svelte:component this={icon} slot="icon" />
+</Pill>