A11y: various improvements

This commit is contained in:
Pieter Vander Vennet 2023-12-19 22:21:34 +01:00
parent 0d4f2c9c36
commit 5fa2ddd9c1
23 changed files with 327 additions and 98 deletions

View file

@ -0,0 +1,39 @@
<script lang="ts">
/**
* THe panel containing all filter- and layerselection options
*/
import OverlayToggle from "./OverlayToggle.svelte"
import Filterview from "./Filterview.svelte"
import ThemeViewState from "../../Models/ThemeViewState"
import Translations from "../i18n/Translations"
import Tr from "../Base/Tr.svelte"
import Filter from "../../assets/svg/Filter.svelte"
export let state: ThemeViewState
let layout = state.layout
</script>
<div class="m-2 flex flex-col">
<h2 class="flex items-center">
<Filter class="h-6 w-6 pr-2" />
<Tr t={Translations.t.general.menu.filter} />
</h2>
{#each layout.layers as layer}
<Filterview
zoomlevel={state.mapProperties.zoom}
filteredLayer={state.layerState.filteredLayers.get(layer.id)}
highlightedLayer={state.guistate.highlightedLayerInFilters}
/>
{/each}
{#each layout.tileLayerSources as tilesource}
<OverlayToggle
layerproperties={tilesource}
state={state.overlayLayerStates.get(tilesource.id)}
highlightedLayer={state.guistate.highlightedLayerInFilters}
zoomlevel={state.mapProperties.zoom}
/>
{/each}
</div>

View file

@ -1,8 +1,6 @@
<script lang="ts">
import { ImmutableStore, UIEventSource } from "../../Logic/UIEventSource"
import { UIEventSource } from "../../Logic/UIEventSource"
import type { Feature } from "geojson"
import ToSvelte from "../Base/ToSvelte.svelte"
import Svg from "../../Svg.js"
import Translations from "../i18n/Translations"
import Loading from "../Base/Loading.svelte"
import Hotkeys from "../Base/Hotkeys"
@ -23,7 +21,7 @@
onDestroy(
triggerSearch.addCallback((_) => {
performSearch()
})
}),
)
let isRunning: boolean = false
@ -31,15 +29,17 @@
let inputElement: HTMLInputElement
let feedback: string = undefined
function focusOnSearch() {
requestAnimationFrame(() => {
inputElement?.focus()
inputElement?.select()
})
}
Hotkeys.RegisterHotkey({ ctrl: "F" }, Translations.t.hotkeyDocumentation.selectSearch, () => {
feedback = undefined
requestAnimationFrame(() => {
inputElement?.focus()
inputElement?.select()
})
focusOnSearch()
})
const dispatch = createEventDispatcher<{ searchCompleted; searchIsValid: boolean }>()
@ -62,6 +62,7 @@
const result = await Geocoding.Search(searchContents, bounds.data)
if (result.length == 0) {
feedback = Translations.t.general.search.nothing.txt
focusOnSearch()
return
}
const poi = result[0]
@ -70,7 +71,7 @@
new BBox([
[lon0, lat0],
[lon1, lat1],
]).pad(0.01)
]).pad(0.01),
)
if (perLayer !== undefined) {
const id = poi.osm_type + "/" + poi.osm_id
@ -78,11 +79,11 @@
for (const layer of layers) {
const found = layer.features.data.find((f) => f.properties.id === id)
if (found === undefined) {
continue;
continue
}
selectedElement?.setData(found);
console.log("Found an element that probably matches:", selectedElement?.data);
break;
selectedElement?.setData(found)
console.log("Found an element that probably matches:", selectedElement?.data)
break
}
}
if (clearAfterView) {
@ -93,6 +94,7 @@
} catch (e) {
console.error(e)
feedback = Translations.t.general.search.error.txt
focusOnSearch()
} finally {
isRunning = false
}
@ -100,23 +102,25 @@
</script>
<div class="normal-background flex justify-between rounded-full pl-2">
<form class="w-full">
<form class="w-full flex flex-wrap">
{#if isRunning}
<Loading>{Translations.t.general.search.searching}</Loading>
{:else if feedback !== undefined}
<div class="alert" on:click={() => (feedback = undefined)}>
{feedback}
</div>
{:else}
<input
type="search"
class="w-full"
bind:this={inputElement}
on:keypress={(keypr) => (keypr.key === "Enter" ? performSearch() : undefined)}
on:keypress={(keypr) =>{ feedback = undefined; return (keypr.key === "Enter" ? performSearch() : undefined); }}
bind:value={searchContents}
use:placeholder={Translations.t.general.search.search}
/>
{#if feedback !== undefined}
<!-- The feedback is _always_ shown for screenreaders and to make sure that the searchfield can still be selected by tabbing-->
<div class="alert " role="alert" aria-live="assertive">
{feedback}
</div>
{/if}
{/if}
</form>
<SearchIcon class="h-6 w-6 self-end" aria-hidden="true" on:click={performSearch}/>
<SearchIcon aria-hidden="true" class="h-6 w-6 self-end" on:click={performSearch} />
</div>

View file

@ -0,0 +1,45 @@
<script lang="ts">/**
* Shows the current address when shaken
**/
import Motion from "../../Sensors/Motion"
import { Geocoding } from "../../Logic/Osm/Geocoding"
import type { MapProperties } from "../../Models/MapProperties"
export let mapProperties: MapProperties
let lastDisplayed: Date = undefined
let currentLocation: string = undefined
async function displayLocation() {
lastDisplayed = new Date()
let result = await Geocoding.reverse(
mapProperties.location.data,
mapProperties.zoom.data,
)
console.log("Got result", result)
let properties = result.features[0].properties
currentLocation = properties.display_name
window.setTimeout(() => {
currentLocation = undefined
}, 5000)
}
Motion.singleton.lastShakeEvent.addCallbackD(shaken => {
console.log("Got a shaken event")
if (shaken.getTime() - lastDisplayed.getTime() < 1000) {
console.log("To soon:",shaken.getTime() - lastDisplayed.getTime())
// return
}
displayLocation()
})
Motion.singleton.startListening()
mapProperties.location.stabilized(500).addCallbackAndRun(loc => {
displayLocation()
})
</script>
{#if currentLocation}
<div role="alert" aria-live="assertive" class="normal-background">
{currentLocation}
</div>
{/if}

View file

@ -30,10 +30,12 @@
)
</script>
<button class="cursor-pointer small flex" on:click={() => select()}>
<div class="cursor-pointer small flex" on:click={() => select()}>
<span class="flex">
{#if i !== undefined}
<span class="font-bold">{i + 1}.</span>
{/if}
<TagRenderingAnswer config={layer.title} {layer} selectedElement={feature} {state} {tags} />
<span class="flex">{$bearingAndDist.dist}m {$bearingAndDist.bearing}°</span>
</button>
<TagRenderingAnswer config={layer.title} {layer} selectedElement={feature} {state} {tags} />
{$bearingAndDist.dist}m {$bearingAndDist.bearing}°
</span>
</div>

View file

@ -19,7 +19,7 @@
})
lastAction.stabilized(750).addCallbackAndRunD(_ => lastAction.setData(undefined))
</script>
<div aria-live="assertive" class=" interactive p-1" role="alert">
<div aria-live="assertive" class="p-1" role="alert">
{#if $lastAction !== undefined}
<Tr t={Translations.t.general.visualFeedback[$lastAction.key]} />