improve a11y
This commit is contained in:
parent
1f32b6a0ce
commit
18ad6ab1ab
|
@ -1,4 +1,4 @@
|
||||||
<div class="toast-modal {{shown ? 'shown' : ''}}">
|
<div class="toast-modal {{shown ? 'shown' : ''}}" role="alert" aria-hidden="{{shown}}">
|
||||||
<div class="toast-container">
|
<div class="toast-container">
|
||||||
{{text}}
|
{{text}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
|
{{#if label}}
|
||||||
|
<ul class="settings-list" aria-label="{{label}}">
|
||||||
|
<slot></slot>
|
||||||
|
</ul>
|
||||||
|
{{else}}
|
||||||
<ul class="settings-list">
|
<ul class="settings-list">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</ul>
|
</ul>
|
||||||
|
{{/if}}
|
||||||
<style>
|
<style>
|
||||||
ul.settings-list {
|
ul.settings-list {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
|
@ -5,9 +5,15 @@
|
||||||
<use xlink:href="{{icon}}" />
|
<use xlink:href="{{icon}}" />
|
||||||
</svg>
|
</svg>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{#if ariaLabel}}
|
||||||
|
<span aria-label="{{ariaLabel}}" class="{{offsetForIcon ? 'offset-for-icon' : ''}}">
|
||||||
|
{{label}}
|
||||||
|
</span>
|
||||||
|
{{else}}
|
||||||
<span class="{{offsetForIcon ? 'offset-for-icon' : ''}}">
|
<span class="{{offsetForIcon ? 'offset-for-icon' : ''}}">
|
||||||
{{label}}
|
{{label}}
|
||||||
</span>
|
</span>
|
||||||
|
{{/if}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
return page === name ? "selected" : ""
|
return page === name ? "selected" : ""
|
||||||
},
|
},
|
||||||
getAriaLabel(page, name, label) {
|
getAriaLabel(page, name, label) {
|
||||||
return page === name ? "Current page" : label
|
return page === name ? `${label} (current page)` : label
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,19 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<form class="add-new-instance" on:submit='onSubmit(event)' aria-labelledby="add-an-instance-h1">
|
<form class="add-new-instance" on:submit='onSubmit(event)' aria-labelledby="add-an-instance-h1">
|
||||||
|
|
||||||
<label for="instanceInput">Instance:</label>
|
<label for="instanceInput">Instance:</label>
|
||||||
<input class="new-instance-input" type="text" id="instanceInput" bind:value='$instanceNameInSearch' placeholder=''>
|
<input class="new-instance-input" type="text" id="instanceInput"
|
||||||
|
bind:value='$instanceNameInSearch' placeholder='' required
|
||||||
|
>
|
||||||
<button class="primary" type="submit" id="submitButton" disabled="{{!$instanceNameInSearch}}">Add instance</button>
|
<button class="primary" type="submit" id="submitButton" disabled="{{!$instanceNameInSearch}}">Add instance</button>
|
||||||
|
|
||||||
|
{{#if error}}
|
||||||
|
<div class="form-error" role="alert">
|
||||||
|
Error: {{error}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{{#if !$isUserLoggedIn}}
|
{{#if !$isUserLoggedIn}}
|
||||||
|
@ -26,6 +36,14 @@
|
||||||
</SettingsLayout>
|
</SettingsLayout>
|
||||||
</Layout>
|
</Layout>
|
||||||
<style>
|
<style>
|
||||||
|
.form-error {
|
||||||
|
border: 2px solid red;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 1.3em;
|
||||||
|
margin: 5px;
|
||||||
|
background-color: var(--main-bg);
|
||||||
|
}
|
||||||
input.new-instance-input {
|
input.new-instance-input {
|
||||||
min-width: 50%;
|
min-width: 50%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
@ -58,22 +76,20 @@
|
||||||
import { store } from '../../_utils/store'
|
import { store } from '../../_utils/store'
|
||||||
import { goto } from 'sapper/runtime.js'
|
import { goto } from 'sapper/runtime.js'
|
||||||
import { switchToTheme } from '../../_utils/themeEngine'
|
import { switchToTheme } from '../../_utils/themeEngine'
|
||||||
import { toast } from '../../_utils/toast'
|
|
||||||
import LoadingMask from '../../_components/LoadingMask'
|
import LoadingMask from '../../_components/LoadingMask'
|
||||||
|
|
||||||
const REDIRECT_URI = (typeof location !== 'undefined' ?
|
const REDIRECT_URI = (typeof location !== 'undefined' ?
|
||||||
location.origin : 'https://pinafore.social') + '/settings/instances/add'
|
location.origin : 'https://pinafore.social') + '/settings/instances/add'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
oncreate: function () {
|
async oncreate () {
|
||||||
if (process.browser) {
|
let params = new URLSearchParams(location.search)
|
||||||
(async () => {
|
if (params.has('code')) {
|
||||||
let params = new URLSearchParams(location.search)
|
this.onReceivedOauthCode(params.get('code'))
|
||||||
if (params.has('code')) {
|
|
||||||
this.onReceivedOauthCode(params.get('code'))
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
}
|
}
|
||||||
|
this.store.observe('instanceNameInSearch', () => {
|
||||||
|
this.set({error: false})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
|
@ -91,10 +107,11 @@
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
toast.say(`Error: ${err.message || err.name}. ` +
|
let error = `${err.message || err.name}. ` +
|
||||||
(navigator.onLine ?
|
(navigator.onLine ?
|
||||||
`Is this a valid Mastodon instance?` :
|
`Is this a valid Mastodon instance?` :
|
||||||
`Are you offline?`))
|
`Are you offline?`)
|
||||||
|
this.set({error: error})
|
||||||
} finally {
|
} finally {
|
||||||
this.set({loading: false})
|
this.set({loading: false})
|
||||||
}
|
}
|
||||||
|
@ -104,7 +121,7 @@
|
||||||
let loggedInInstances = this.store.get('loggedInInstances')
|
let loggedInInstances = this.store.get('loggedInInstances')
|
||||||
instanceName = instanceName.replace(/^https?:\/\//, '').replace('/$', '')
|
instanceName = instanceName.replace(/^https?:\/\//, '').replace('/$', '')
|
||||||
if (Object.keys(loggedInInstances).includes(instanceName)) {
|
if (Object.keys(loggedInInstances).includes(instanceName)) {
|
||||||
toast.say(`You've already logged in to ${instanceName}`)
|
this.set({error: `You've already logged in to ${instanceName}`})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let instanceData = await registerApplication(instanceName, REDIRECT_URI)
|
let instanceData = await registerApplication(instanceName, REDIRECT_URI)
|
||||||
|
@ -125,7 +142,7 @@
|
||||||
this.set({loading: true})
|
this.set({loading: true})
|
||||||
await this.registerNewInstance(code)
|
await this.registerNewInstance(code)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
toast.say(`Error: ${err.message || err.name}. Failed to connect to instance.`)
|
this.set({error: `${err.message || err.name}. Failed to connect to instance.`})
|
||||||
} finally {
|
} finally {
|
||||||
this.set({loading: false})
|
this.set({loading: false})
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,13 @@
|
||||||
|
|
||||||
{{#if $isUserLoggedIn}}
|
{{#if $isUserLoggedIn}}
|
||||||
<p>Instances you've logged in to:</p>
|
<p>Instances you've logged in to:</p>
|
||||||
<SettingsList>
|
<SettingsList label="Instances">
|
||||||
{{#each $loggedInInstancesAsList as instance}}
|
{{#each $loggedInInstancesAsList as instance}}
|
||||||
<SettingsListItem offsetForIcon="{{instance.name !== $currentInstance}}"
|
<SettingsListItem offsetForIcon="{{instance.name !== $currentInstance}}"
|
||||||
icon="{{instance.name === $currentInstance ? '#fa-star' : ''}}"
|
icon="{{instance.name === $currentInstance ? '#fa-star' : ''}}"
|
||||||
href="/settings/instances/{{instance.name}}"
|
href="/settings/instances/{{instance.name}}"
|
||||||
label="{{instance.name}}" />
|
label="{{instance.name}}"
|
||||||
|
ariaLabel="{{instance.name}} {{instance.name === $currentInstance ? '(current instance)' : ''}}" />
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</SettingsList>
|
</SettingsList>
|
||||||
<p><a href="/settings/instances/add">Add another instance</a></p>
|
<p><a href="/settings/instances/add">Add another instance</a></p>
|
||||||
|
|
Loading…
Reference in New Issue