Skip to content

Commit

Permalink
Merge pull request #103 from nextcloud-gmbh/bugfix/96/accessibility
Browse files Browse the repository at this point in the history
Keyboard accessibility for emoji picker and profile tabs
  • Loading branch information
juliushaertl committed Dec 3, 2018
2 parents a08cd46 + 1782e51 commit c45cfe6
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 8 deletions.
27 changes: 21 additions & 6 deletions src/components/Composer.vue
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -286,7 +300,8 @@ export default {
},
directives: {
tooltip: VTooltip,
ClickOutside: ClickOutside
ClickOutside: ClickOutside,
FocusOnCreate: FocusOnCreate
},
mixins: [CurrentUserMixin],
props: {
Expand Down
6 changes: 5 additions & 1 deletion src/components/ProfileInfo.vue
Expand Up @@ -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>
Expand Down
5 changes: 4 additions & 1 deletion src/components/TimelineEntry.vue
Expand Up @@ -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>
Expand All @@ -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 />')
Expand Down
31 changes: 31 additions & 0 deletions 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()
})
}
}

0 comments on commit c45cfe6

Please sign in to comment.