项目文件夹

文件
wehub-resource-sync adf0d17497
publish / version_or_publish (push) Has been cancelled
storybook-build / changes (push) Has been cancelled
storybook-build / :storybook-build (push) Has been cancelled
Sync Gradio Skills to Hugging Face / sync-skills (push) Has been cancelled
functional / changes (push) Has been cancelled
functional / build-frontend (push) Has been cancelled
functional / functional-test-SSR=false (push) Has been cancelled
functional / functional-reload (push) Has been cancelled
js / changes (push) Has been cancelled
js / js-test (push) Has been cancelled
docs-build / changes (push) Has been cancelled
docs-build / docs-build (push) Has been cancelled
docs-build / website-build (push) Has been cancelled
functional / functional-test-SSR=true (push) Has been cancelled
hygiene / hygiene-test (push) Has been cancelled
python / changes (push) Has been cancelled
python / build (push) Has been cancelled
python / test-ubuntu-latest-flaky (push) Has been cancelled
python / test-ubuntu-latest-not-flaky (push) Has been cancelled
python / test-windows-latest-flaky (push) Has been cancelled
python / test-windows-latest-not-flaky (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:17:32 +08:00

106 行
2.3 KiB
Svelte

<script lang="ts">
import type { ToastMessage, GroupedToastMessage } from "./types";
import ToastContent from "./ToastContent.svelte";
import { spring } from "svelte/motion";
interface Props {
messages?: ToastMessage[];
on_close: (id: number) => void;
}
let { messages = [], on_close }: Props = $props();
const top = spring(0, { stiffness: 0.4, damping: 0.5 });
let grouped_messages: GroupedToastMessage[] = $state([]);
$effect(() => {
scroll_to_top(messages);
});
$effect(() => {
grouped_messages = group_messages(messages);
});
function group_messages(msgs: ToastMessage[]): GroupedToastMessage[] {
const groups = new Map<string, GroupedToastMessage>();
msgs.forEach((msg) => {
const key = msg.type;
if (!groups.has(key)) {
groups.set(key, {
type: msg.type,
messages: [],
expanded: true
});
}
groups.get(key)!.messages.push(msg);
});
return Array.from(groups.values());
}
function scroll_to_top(_messages: ToastMessage[]): void {
if (_messages.length > 0) {
if ("parentIFrame" in window) {
window.parentIFrame?.getPageInfo((page_info) => {
if (page_info.scrollTop < page_info.offsetTop) {
top.set(0);
} else {
top.set(page_info.scrollTop - page_info.offsetTop);
}
});
}
}
}
function toggle_group(type: string): void {
grouped_messages = grouped_messages.map((group) => {
if (group.type === type) {
return { ...group, expanded: !group.expanded };
}
return group;
});
}
</script>
<div class="toast-wrap" style="--toast-top: {$top}px;">
{#each grouped_messages as group (group.type)}
<div class="toast-item">
<ToastContent
type={group.type}
messages={group.messages}
expanded={group.expanded}
ontoggle={() => toggle_group(group.type)}
onclose={(id) => on_close(id)}
/>
</div>
{/each}
</div>
<style>
.toast-wrap {
--toast-top: var(--size-4);
display: flex;
position: fixed;
top: calc(var(--toast-top) + var(--size-3));
flex-direction: column;
gap: var(--size-2);
z-index: var(--layer-top);
right: var(--size-3);
left: var(--size-3);
align-items: end;
max-width: none;
}
.toast-item {
width: 100%;
}
@media (min-width: 640px) {
.toast-wrap {
left: auto;
width: calc(var(--size-96) + var(--size-10));
}
}
</style>