forked from MapComplete/MapComplete
Accessibility: add focus trapping, debug tab cycling, UI tweaks for mobile browser
This commit is contained in:
parent
307549b593
commit
8ae4d810d6
19 changed files with 123 additions and 77 deletions
|
|
@ -1,28 +1,35 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from "svelte";
|
||||
import { XCircleIcon } from "@rgossiaux/svelte-heroicons/solid"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
import { XCircleIcon } from "@rgossiaux/svelte-heroicons/solid";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { Utils } from "../../Utils";
|
||||
import { trapFocus } from 'trap-focus-svelte'
|
||||
/**
|
||||
* The slotted element will be shown on top, with a lower-opacity border
|
||||
*/
|
||||
const dispatch = createEventDispatcher<{ close }>()
|
||||
|
||||
export let extraClasses = "p-4 md:p-6"
|
||||
|
||||
let mainContent: HTMLElement
|
||||
const dispatch = createEventDispatcher<{ close }>();
|
||||
|
||||
export let extraClasses = "p-4 md:p-6";
|
||||
|
||||
let mainContent: HTMLElement;
|
||||
onMount(() => {
|
||||
console.log("Mounting floatover")
|
||||
mainContent?.focus()
|
||||
})
|
||||
requestAnimationFrame(() => {
|
||||
Utils.focusOnFocusableChild(mainContent);
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={twMerge("absolute top-0 right-0 h-screen w-screen", extraClasses)}
|
||||
style="background-color: #00000088; z-index: 20"
|
||||
on:click={() => {
|
||||
<!-- Draw the background over the total screen -->
|
||||
<div class="w-screen h-screen absolute top-0 left-0" style="background-color: #00000088; z-index: 20" on:click={() => {
|
||||
dispatch("close")
|
||||
}}
|
||||
}}>
|
||||
</div>
|
||||
<!-- draw a _second_ absolute div, placed using 'bottom' which will be above the navigation bar on mobile browsers -->
|
||||
<div
|
||||
class={twMerge("absolute bottom-0 right-0 h-full w-screen", extraClasses)}
|
||||
use:trapFocus
|
||||
style="z-index: 21"
|
||||
>
|
||||
<div bind:this={mainContent} class="content normal-background" on:click|stopPropagation={() => {}}>
|
||||
<div class="h-full rounded-xl">
|
||||
|
|
@ -30,21 +37,23 @@
|
|||
</div>
|
||||
<slot name="close-button">
|
||||
<!-- The close button is placed _after_ the default slot in order to always paint it on top -->
|
||||
<div
|
||||
class="absolute right-10 top-10 h-8 w-8 cursor-pointer"
|
||||
<button
|
||||
class="absolute right-10 top-10 h-8 w-8 cursor-pointer p-0 border-none bg-white"
|
||||
on:click={() => dispatch("close")}
|
||||
>
|
||||
<XCircleIcon />
|
||||
</div>
|
||||
</button>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
.content {
|
||||
height: 100%;
|
||||
border-radius: 0.5rem;
|
||||
overflow-x: hidden;
|
||||
box-shadow: 0 0 1rem #00000088;
|
||||
}
|
||||
.content {
|
||||
height: 100%;
|
||||
border-radius: 0.5rem;
|
||||
overflow-x: hidden;
|
||||
box-shadow: 0 0 1rem #00000088;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@
|
|||
|
||||
export let state: {
|
||||
osmConnection: OsmConnection
|
||||
featureSwitches?: { featureSwitchUserbadge?: UIEventSource<boolean> }
|
||||
featureSwitches?: { featureSwitchEnableLogin?: UIEventSource<boolean> }
|
||||
}
|
||||
/**
|
||||
* If set, 'loading' will act as if we are already logged in.
|
||||
*/
|
||||
export let ignoreLoading: boolean = false
|
||||
let loadingStatus = state?.osmConnection?.loadingStatus ?? new ImmutableStore("logged-in")
|
||||
let badge = state?.featureSwitches?.featureSwitchUserbadge ?? new ImmutableStore(true)
|
||||
let badge = state?.featureSwitches?.featureSwitchEnableLogin ?? new ImmutableStore(true)
|
||||
const t = Translations.t.general
|
||||
const offlineModes: Partial<Record<OsmServiceState, Translation>> = {
|
||||
offline: t.loginFailedOfflineMode,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { createEventDispatcher, onMount } from "svelte";
|
||||
import { XCircleIcon } from "@rgossiaux/svelte-heroicons/solid";
|
||||
import { Utils } from "../../Utils";
|
||||
import { trapFocus } from 'trap-focus-svelte'
|
||||
|
||||
/**
|
||||
* The slotted element will be shown on the right side
|
||||
|
|
@ -13,13 +14,13 @@
|
|||
onMount(() => {
|
||||
window.setTimeout(
|
||||
() => Utils.focusOnFocusableChild(mainContent), 250
|
||||
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div
|
||||
bind:this={mainContent}
|
||||
use:trapFocus
|
||||
class="absolute top-0 right-0 h-screen w-full overflow-y-auto drop-shadow-2xl md:w-6/12 lg:w-5/12 xl:w-4/12"
|
||||
style="max-width: 100vw; max-height: 100vh"
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue