mirror of
https://github.com/ReVanced/revanced-website.git
synced 2026-01-27 12:51:03 +00:00
feat: add banner component
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify-json/material-symbols": "^1.2.45",
|
"@iconify-json/material-symbols": "^1.2.45",
|
||||||
|
"@madkarma/svelte-storable": "^1.0.4",
|
||||||
"unplugin-icons": "^22.5.0"
|
"unplugin-icons": "^22.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
pnpm-lock.yaml
generated
24
pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ importers:
|
|||||||
'@iconify-json/material-symbols':
|
'@iconify-json/material-symbols':
|
||||||
specifier: ^1.2.45
|
specifier: ^1.2.45
|
||||||
version: 1.2.45
|
version: 1.2.45
|
||||||
|
'@madkarma/svelte-storable':
|
||||||
|
specifier: ^1.0.4
|
||||||
|
version: 1.0.4(svelte@5.43.5)(typescript@5.9.3)
|
||||||
unplugin-icons:
|
unplugin-icons:
|
||||||
specifier: ^22.5.0
|
specifier: ^22.5.0
|
||||||
version: 22.5.0(svelte@5.43.5)
|
version: 22.5.0(svelte@5.43.5)
|
||||||
@@ -319,6 +322,16 @@ packages:
|
|||||||
'@jridgewell/trace-mapping@0.3.31':
|
'@jridgewell/trace-mapping@0.3.31':
|
||||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||||
|
|
||||||
|
'@madkarma/svelte-storable@1.0.4':
|
||||||
|
resolution: {integrity: sha512-E1vyfs89MzEjT4JJwUH23qKuwia50NP48zRXPLuOtEtIqXl46AW0ZbwpBFXGoSaHodhFOrbYROSLQ4iZCjbJag==}
|
||||||
|
peerDependencies:
|
||||||
|
svelte: ^5.0.0
|
||||||
|
|
||||||
|
'@madkarma/ts-utils@1.1.2':
|
||||||
|
resolution: {integrity: sha512-iQqKMtcd0QXSHzHm0L0VNHcUyAuYyd9W05F9fG/pvdB3YZOQzfN85v6pFUH5BdjbjhFGOIs/JwmXBEu290YRww==}
|
||||||
|
peerDependencies:
|
||||||
|
typescript: ^5.9.3
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -1452,6 +1465,17 @@ snapshots:
|
|||||||
'@jridgewell/resolve-uri': 3.1.2
|
'@jridgewell/resolve-uri': 3.1.2
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
|
||||||
|
'@madkarma/svelte-storable@1.0.4(svelte@5.43.5)(typescript@5.9.3)':
|
||||||
|
dependencies:
|
||||||
|
'@madkarma/ts-utils': 1.1.2(typescript@5.9.3)
|
||||||
|
svelte: 5.43.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- typescript
|
||||||
|
|
||||||
|
'@madkarma/ts-utils@1.1.2(typescript@5.9.3)':
|
||||||
|
dependencies:
|
||||||
|
typescript: 5.9.3
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nodelib/fs.stat': 2.0.5
|
'@nodelib/fs.stat': 2.0.5
|
||||||
|
|||||||
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