summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2018-12-03 16:14:37 +0100
committerGitHub <noreply@github.com>2018-12-03 16:14:37 +0100
commitc45cfe6b497cc92db806fd6f8b51f3560eac3b08 (patch)
tree7d7a8b5c3880e2c959124ab2e6e0461cc50fb810 /src
parenta08cd4612333aa8b04e82a7248a7114beef2f9ca (diff)
parent1782e51169f5d1d390a7916a9a102bc015cb5cdd (diff)
Merge pull request #103 from nextcloud-gmbh/bugfix/96/accessibility
Keyboard accessibility for emoji picker and profile tabs
Diffstat (limited to 'src')
-rw-r--r--src/components/Composer.vue27
-rw-r--r--src/components/ProfileInfo.vue6
-rw-r--r--src/components/TimelineEntry.vue5
-rw-r--r--src/directives/focusOnCreate.js31
4 files changed, 61 insertions, 8 deletions
diff --git a/src/components/Composer.vue b/src/components/Composer.vue
index f179516d..d2b9513e 100644
--- a/src/components/Composer.vue
+++ b/src/components/Composer.vue
@@ -36,19 +36,22 @@
placeholder="Share a thought…" @keyup.enter="keyup" />
</vue-tribute>
<emoji-picker :search="search" class="emoji-picker-wrapper" @emoji="insert">
- <div v-tooltip="'Insert emoji'" slot="emoji-invoker" slot-scope="{ events }"
- class="emoji-invoker" v-on="events" />
+ <a v-tooltip="'Insert emoji'" slot="emoji-invoker" slot-scope="{ events }"
+ class="emoji-invoker" tabindex="0" v-on="events"
+ @keyup.enter="events.click" @keyup.space="events.click" />
<div slot="emoji-picker" slot-scope="{ emojis, insert, display }" class="emoji-picker popovermenu">
<div>
<div>
- <input v-model="search" type="text">
+ <input v-focus-on-create v-model="search" type="text">
</div>
<div>
<div v-for="(emojiGroup, category) in emojis" :key="category">
<h5>{{ category }}</h5>
<div>
<span v-for="(emoji, emojiName) in emojiGroup" :key="emojiName" :title="emojiName"
- class="emoji" @click="insert(emoji)" v-html="$twemoji.parse(emoji)" />
+ tabindex="0"
+ class="emoji" @click="insert(emoji)" @keyup.enter="insert(emoji)"
+ @keyup.space="insert(emoji)" v-html="$twemoji.parse(emoji)" />
</div>
</div>
</div>
@@ -142,6 +145,11 @@
background-size: 16px 16px;
height: 38px;
cursor: pointer;
+ display: block;
+ }
+ .emoji-invoker:focus,
+ .emoji-invoker:hover {
+ opacity: 1;
}
.emoji-picker-wrapper {
position: absolute;
@@ -163,8 +171,13 @@
.emoji-picker input {
width: 100%;
}
+ .emoji-picker span.emoji {
+ padding: 3px;
+ }
+ .emoji-picker span.emoji:focus {
+ background-color: var(--color-background-dark);
+ }
.emoji-picker .emoji img {
- margin: 3px;
width: 16px;
}
.popovermenu {
@@ -274,6 +287,7 @@ import EmojiPicker from 'vue-emoji-picker'
import VueTribute from 'vue-tribute'
import { VTooltip } from 'v-tooltip'
import CurrentUserMixin from './../mixins/currentUserMixin'
+import FocusOnCreate from '../directives/focusOnCreate'
import axios from 'nextcloud-axios'
export default {
@@ -286,7 +300,8 @@ export default {
},
directives: {
tooltip: VTooltip,
- ClickOutside: ClickOutside
+ ClickOutside: ClickOutside,
+ FocusOnCreate: FocusOnCreate
},
mixins: [CurrentUserMixin],
props: {
diff --git a/src/components/ProfileInfo.vue b/src/components/ProfileInfo.vue
index 0ca1aeb1..946b0e71 100644
--- a/src/components/ProfileInfo.vue
+++ b/src/components/ProfileInfo.vue
@@ -75,13 +75,17 @@
flex-grow: 1;
}
.user-profile--sections li a {
+ padding: 10px;
padding-left: 24px;
+ display: inline-block;
background-position: 0 center;
height: 40px;
opacity: .6;
}
- .user-profile--sections li a.active {
+ .user-profile--sections li a.router-link-exact-active,
+ .user-profile--sections li a:focus{
opacity: 1;
+ border-bottom: 1px solid var(--color-main-text);
}
</style>
<script>
diff --git a/src/components/TimelineEntry.vue b/src/components/TimelineEntry.vue
index 4d49befe..8b95c2bb 100644
--- a/src/components/TimelineEntry.vue
+++ b/src/components/TimelineEntry.vue
@@ -19,7 +19,7 @@
</div>
<div class="post-message" v-html="formatedMessage" />
</div>
- <div :data-timestamp="item.published" class="post-timestamp live-relative-timestamp">{{ relativeTimestamp }}</div>
+ <div :data-timestamp="timestamp" class="post-timestamp live-relative-timestamp">{{ relativeTimestamp }}</div>
</div>
</div>
</template>
@@ -45,6 +45,9 @@ export default {
relativeTimestamp() {
return OC.Util.relativeModifiedDate(this.item.published)
},
+ timestamp() {
+ return Date.parse(this.item.published)
+ },
formatedMessage() {
let message = this.item.content
message = message.replace(/(?:\r\n|\r|\n)/g, '<br />')
diff --git a/src/directives/focusOnCreate.js b/src/directives/focusOnCreate.js
new file mode 100644
index 00000000..d2a73db0
--- /dev/null
+++ b/src/directives/focusOnCreate.js
@@ -0,0 +1,31 @@
+/*
+ * @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Härtl <jus@bitgrid.net>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+import Vue from 'vue'
+
+export default {
+ bind: function(el) {
+ Vue.nextTick(() => {
+ el.focus()
+ })
+ }
+}