mirror of
https://github.com/ReVanced/revanced-website.git
synced 2026-01-19 09:13:56 +00:00
feat: add banner component
This commit is contained in:
87
src/lib/components/molecules/Banner.svelte
Normal file
87
src/lib/components/molecules/Banner.svelte
Normal file
@@ -0,0 +1,87 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { slide } from 'svelte/transition';
|
||||
import { cubicInOut } from 'svelte/easing';
|
||||
import storable from '@madkarma/svelte-storable';
|
||||
import type { WithChildren } from '$types';
|
||||
import Info from 'virtual:icons/material-symbols/info-outline';
|
||||
import Warning from 'virtual:icons/material-symbols/warning-outline';
|
||||
import Error from 'virtual:icons/material-symbols/error-outline';
|
||||
import Close from 'virtual:icons/material-symbols/close';
|
||||
|
||||
const readBannerIds = storable<string[]>('read_banner_ids', []);
|
||||
|
||||
type Props = {
|
||||
type: 'info' | 'warning' | 'error';
|
||||
id: string;
|
||||
permanent?: boolean;
|
||||
closed?: boolean;
|
||||
} & WithChildren;
|
||||
let {
|
||||
type,
|
||||
children,
|
||||
id,
|
||||
permanent = false,
|
||||
closed = $bindable($readBannerIds.includes(id))
|
||||
}: Props = $props();
|
||||
|
||||
const Icon = type === 'info' ? Info : type === 'warning' ? Warning : Error;
|
||||
|
||||
let visible = $state(false);
|
||||
|
||||
onMount(() => {
|
||||
if (closed) return;
|
||||
visible = true;
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if visible}
|
||||
<div class="banner {type}" {id} transition:slide={{ duration: 200, easing: cubicInOut }}>
|
||||
<Icon />
|
||||
|
||||
<div class="content">
|
||||
{@render children()}
|
||||
</div>
|
||||
|
||||
{#if !permanent}
|
||||
<button
|
||||
class="close"
|
||||
type="button"
|
||||
onclick={() => {
|
||||
closed = true;
|
||||
visible = false;
|
||||
$readBannerIds = [...$readBannerIds, id];
|
||||
}}
|
||||
>
|
||||
<Close />
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
padding: 1rem 2rem;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9999;
|
||||
|
||||
&.info {
|
||||
}
|
||||
|
||||
&.warning {
|
||||
}
|
||||
|
||||
&.error {
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user