huggi / src /lib /components /OpenWebSearchResults.svelte
nsarrazin's picture
nsarrazin HF staff
Refactor of websearch (#281)
6434339 unverified
raw
history blame
3.18 kB
<script lang="ts">
import type { WebSearchMessage } from "$lib/types/WebSearch";
import CarbonCaretRight from "~icons/carbon/caret-right";
import CarbonCheckmark from "~icons/carbon/checkmark-filled";
import CarbonError from "~icons/carbon/error-filled";
import EosIconsLoading from "~icons/eos-icons/loading";
export let loading = false;
export let classNames = "";
export let webSearchMessages: WebSearchMessage[] = [];
let detailsOpen: boolean;
let error: boolean;
$: error = webSearchMessages.some((message) => message.type === "error");
</script>
<details
class="flex w-fit rounded-xl border border-gray-200 bg-white shadow-sm dark:border-gray-800 dark:bg-gray-900 {classNames} max-w-full"
bind:open={detailsOpen}
>
<summary
class="align-center flex cursor-pointer select-none list-none py-1 pl-2.5 pr-2 align-text-top transition-all"
>
{#if error}
<CarbonError class="my-auto text-red-700 dark:text-red-500" />
{:else if loading}
<EosIconsLoading class="my-auto text-gray-500" />
{:else}
<CarbonCheckmark class="my-auto text-gray-500" />
{/if}
<span class="px-2 font-medium" class:text-red-700={error} class:dark:text-red-500={error}
>Web search
</span>
<div class="my-auto transition-all" class:rotate-90={detailsOpen}>
<CarbonCaretRight />
</div>
</summary>
<div class="content px-5 pb-5 pt-4">
{#if webSearchMessages.length === 0}
<div class="mx-auto w-fit">
<EosIconsLoading class="mb-3 h-4 w-4" />
</div>
{:else}
<ol>
{#each webSearchMessages as message}
{#if message.type === "update"}
<li class="group border-l pb-6 last:!border-transparent last:pb-0 dark:border-gray-800">
<div class="flex items-start">
<div
class="-ml-1.5 h-3 w-3 flex-none rounded-full bg-gray-200 dark:bg-gray-600 {loading
? 'group-last:animate-pulse group-last:bg-gray-300 group-last:dark:bg-gray-500'
: ''}"
/>
<h3 class="text-md -mt-1.5 pl-2.5 text-gray-800 dark:text-gray-100">
{message.message}
</h3>
</div>
{#if message.args}
<p class="mt-1.5 pl-4 text-gray-500 dark:text-gray-400">
{message.args}
</p>
{/if}
</li>
{:else if message.type === "error"}
<li class="group border-l pb-6 last:!border-transparent last:pb-0 dark:border-gray-800">
<div class="flex items-start">
<CarbonError
class="-ml-1.5 h-3 w-3 flex-none scale-110 text-red-700 dark:text-red-500"
/>
<h3 class="text-md -mt-1.5 pl-2.5 text-red-700 dark:text-red-500">
{message.message}
</h3>
</div>
{#if message.args}
<p class="mt-1.5 pl-4 text-gray-500 dark:text-gray-400">
{message.args}
</p>
{/if}
</li>
{/if}
{/each}
</ol>
{/if}
</div>
</details>
<style>
@keyframes grow {
0% {
font-size: 0;
opacity: 0;
}
30% {
font-size: 1em;
opacity: 0;
}
100% {
opacity: 1;
}
}
details[open] .content {
animation-name: grow;
animation-duration: 300ms;
animation-delay: 0ms;
}
details summary::-webkit-details-marker {
display: none;
}
</style>