web/SupportedServices: render popover only when needed

& also focus it for screen readers
This commit is contained in:
wukko
2024-12-14 12:51:00 +06:00
parent 89f197375c
commit 35d9917301

View File

@ -8,8 +8,11 @@
let services: string[] = []; let services: string[] = [];
let popover: HTMLDivElement;
$: expanded = false; $: expanded = false;
$: loaded = false; $: loaded = false;
$: renderPopover = false;
const loadInfo = async () => { const loadInfo = async () => {
await getServerInfo(); await getServerInfo();
@ -19,18 +22,28 @@
services = $cachedInfo.info.cobalt.services; services = $cachedInfo.info.cobalt.services;
} }
}; };
</script>
<div id="supported-services"> const showPopover = async () => {
<button const timeout = renderPopover ? 0 : 10;
id="services-button" renderPopover = true;
class:expanded
on:click={async () => { // 10ms delay to let the popover render for the first time
setTimeout(async () => {
expanded = !expanded; expanded = !expanded;
if (expanded && services.length === 0) { if (expanded && services.length === 0) {
await loadInfo(); await loadInfo();
} }
}} if (expanded) {
popover.focus();
}
}, timeout);
};
</script>
<div id="supported-services" class:expanded>
<button
id="services-button"
on:click={showPopover}
aria-label={$t(`save.services.title_${expanded ? "hide" : "show"}`)} aria-label={$t(`save.services.title_${expanded ? "hide" : "show"}`)}
> >
<div class="expand-icon"> <div class="expand-icon">
@ -39,26 +52,33 @@
<span class="title">{$t("save.services.title")}</span> <span class="title">{$t("save.services.title")}</span>
</button> </button>
<div id="services-popover" class:expanded> {#if renderPopover}
<div id="services-container"> <div id="services-popover">
{#if loaded} <div
{#each services as service} id="services-container"
<div class="service-item">{service}</div> bind:this={popover}
{/each} tabindex="-1"
{:else} data-focus-ring-hidden
{#each { length: 17 } as _} >
<Skeleton {#if loaded}
class="elevated" {#each services as service}
width={Math.random() * 44 + 50 + "px"} <div class="service-item">{service}</div>
height="24.5px" {/each}
/> {:else}
{/each} {#each { length: 17 } as _}
{/if} <Skeleton
class="elevated"
width={Math.random() * 44 + 50 + "px"}
height="24.5px"
/>
{/each}
{/if}
</div>
<div id="services-disclaimer" class="subtext">
{$t("save.services.disclaimer")}
</div>
</div> </div>
<div id="services-disclaimer" class="subtext"> {/if}
{$t("save.services.disclaimer")}
</div>
</div>
</div> </div>
<style> <style>
@ -94,7 +114,7 @@
opacity 0.25s cubic-bezier(0.53, 0.05, 0.23, 0.99); opacity 0.25s cubic-bezier(0.53, 0.05, 0.23, 0.99);
} }
#services-popover.expanded { .expanded #services-popover {
transform: scale(1); transform: scale(1);
opacity: 1; opacity: 1;
} }