aboutsummaryrefslogtreecommitdiff
path: root/src/components/emoji_picker
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/emoji_picker')
-rw-r--r--src/components/emoji_picker/emoji_picker.js40
-rw-r--r--src/components/emoji_picker/emoji_picker.scss8
-rw-r--r--src/components/emoji_picker/emoji_picker.vue211
3 files changed, 136 insertions, 123 deletions
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index fafc2af1..dd5e5217 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -1,5 +1,6 @@
import { defineAsyncComponent } from 'vue'
import Checkbox from '../checkbox/checkbox.vue'
+import Popover from 'src/components/popover/popover.vue'
import StillImage from '../still-image/still-image.vue'
import { ensureFinalFallback } from '../../i18n/languages.js'
import lozad from 'lozad'
@@ -87,10 +88,6 @@ const EmojiPicker = {
required: false,
type: Boolean,
default: false
- },
- showing: {
- required: true,
- type: Boolean
}
},
data () {
@@ -111,15 +108,32 @@ const EmojiPicker = {
components: {
StickerPicker: defineAsyncComponent(() => import('../sticker_picker/sticker_picker.vue')),
Checkbox,
- StillImage
+ StillImage,
+ Popover
},
methods: {
+ showPicker () {
+ this.$refs.popover.showPopover()
+ this.onShowing()
+ },
+ hidePicker () {
+ this.$refs.popover.hidePopover()
+ },
+ setAnchorEl (el) {
+ this.$refs.popover.setAnchorEl(el)
+ },
setGroupRef (name) {
return el => { this.groupRefs[name] = el }
},
setEmojiRef (name) {
return el => { this.emojiRefs[name] = el }
},
+ onPopoverShown () {
+ this.$emit('show')
+ },
+ onPopoverClosed () {
+ this.$emit('close')
+ },
onStickerUploaded (e) {
this.$emit('sticker-uploaded', e)
},
@@ -128,6 +142,9 @@ const EmojiPicker = {
},
onEmoji (emoji) {
const value = emoji.imageUrl ? `:${emoji.displayText}:` : emoji.replacement
+ if (!this.keepOpen) {
+ this.$refs.popover.hidePopover()
+ }
this.$emit('emoji', { insertion: value, keepOpen: this.keepOpen })
},
onScroll (e) {
@@ -223,6 +240,9 @@ const EmojiPicker = {
},
onShowing () {
const oldContentLoaded = this.contentLoaded
+ this.$nextTick(() => {
+ this.$refs.search.focus()
+ })
this.contentLoaded = true
this.waitForDomAndInitializeLazyLoad()
this.filteredEmojiGroups = this.getFilteredEmojiGroups()
@@ -251,16 +271,6 @@ const EmojiPicker = {
allCustomGroups () {
this.waitForDomAndInitializeLazyLoad()
this.filteredEmojiGroups = this.getFilteredEmojiGroups()
- },
- showing (val) {
- if (val) {
- this.onShowing()
- }
- }
- },
- mounted () {
- if (this.showing) {
- this.onShowing()
}
},
destroyed () {
diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss
index 016c46d7..53363ec1 100644
--- a/src/components/emoji_picker/emoji_picker.scss
+++ b/src/components/emoji_picker/emoji_picker.scss
@@ -6,14 +6,10 @@ $emoji-picker-header-picture-height: 32px;
$emoji-picker-emoji-size: 32px;
.emoji-picker {
+ width: 25em;
+ max-width: 100vw;
display: flex;
flex-direction: column;
- position: absolute;
- right: 0;
- left: 0;
- margin: 0 !important;
- // TODO: actually use popover in emoji picker
- z-index: var(--ZI_popovers);
background-color: $fallback--bg;
background-color: var(--popover, $fallback--bg);
color: $fallback--link;
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 57bb0037..a2c99c16 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -1,129 +1,136 @@
<template>
- <div
- class="emoji-picker panel panel-default panel-body"
+ <Popover
+ trigger="click"
+ popover-class="emoji-picker popover-default"
+ ref="popover"
+ @show="onPopoverShown"
+ @close="onPopoverClosed"
>
- <div class="heading">
- <span
- ref="header"
- class="emoji-tabs"
- >
+ <template #content>
+ <div class="heading">
<span
- v-for="group in filteredEmojiGroups"
- :ref="setGroupRef('group-header-' + group.id)"
- :key="group.id"
- class="emoji-tabs-item"
- :class="{
- active: activeGroupView === group.id
- }"
- :title="group.text"
- @click.prevent="highlight(group.id)"
+ ref="header"
+ class="emoji-tabs"
>
<span
- v-if="group.image"
- class="emoji-picker-header-image"
+ v-for="group in filteredEmojiGroups"
+ :ref="setGroupRef('group-header-' + group.id)"
+ :key="group.id"
+ class="emoji-tabs-item"
+ :class="{
+ active: activeGroupView === group.id
+ }"
+ :title="group.text"
+ @click.prevent="highlight(group.id)"
>
- <still-image
- :alt="group.text"
- :src="group.image"
+ <span
+ v-if="group.image"
+ class="emoji-picker-header-image"
+ >
+ <still-image
+ :alt="group.text"
+ :src="group.image"
+ />
+ </span>
+ <FAIcon
+ v-else
+ :icon="group.icon"
+ fixed-width
/>
</span>
- <FAIcon
- v-else
- :icon="group.icon"
- fixed-width
- />
</span>
- </span>
- <span
- v-if="stickerPickerEnabled"
- class="additional-tabs"
- >
<span
- class="stickers-tab-icon additional-tabs-item"
- :class="{active: showingStickers}"
- :title="$t('emoji.stickers')"
- @click.prevent="toggleStickers"
+ v-if="stickerPickerEnabled"
+ class="additional-tabs"
>
- <FAIcon
- icon="sticky-note"
- fixed-width
- />
+ <span
+ class="stickers-tab-icon additional-tabs-item"
+ :class="{active: showingStickers}"
+ :title="$t('emoji.stickers')"
+ @click.prevent="toggleStickers"
+ >
+ <FAIcon
+ icon="sticky-note"
+ fixed-width
+ />
+ </span>
</span>
- </span>
- </div>
- <div
- v-if="contentLoaded"
- class="content"
- >
+ </div>
<div
- class="emoji-content"
- :class="{hidden: showingStickers}"
+ v-if="contentLoaded"
+ class="content"
>
- <div class="emoji-search">
- <input
- v-model="keyword"
- type="text"
- class="form-control"
- :placeholder="$t('emoji.search_emoji')"
- @input="$event.target.composing = false"
- >
- </div>
<div
- ref="emoji-groups"
- class="emoji-groups"
- :class="groupsScrolledClass"
- @scroll="onScroll"
+ class="emoji-content"
+ :class="{hidden: showingStickers}"
>
+ <div class="emoji-search">
+ <input
+ v-model="keyword"
+ type="text"
+ class="form-control"
+ :placeholder="$t('emoji.search_emoji')"
+ @input="$event.target.composing = false"
+ ref="search"
+ >
+ </div>
<div
- v-for="group in filteredEmojiGroups"
- :key="group.id"
- class="emoji-group"
+ ref="emoji-groups"
+ class="emoji-groups"
+ :class="groupsScrolledClass"
+ @scroll="onScroll"
>
- <h6
- :ref="setGroupRef('group-' + group.id)"
- class="emoji-group-title"
- >
- {{ group.text }}
- </h6>
- <span
- v-for="emoji in group.emojis"
- :key="group.id + emoji.displayText"
- :title="maybeLocalizedEmojiName(emoji)"
- class="emoji-item"
- @click.stop.prevent="onEmoji(emoji)"
+ <div
+ v-for="group in filteredEmojiGroups"
+ :key="group.id"
+ class="emoji-group"
>
+ <h6
+ :ref="setGroupRef('group-' + group.id)"
+ class="emoji-group-title"
+ >
+ {{ group.text }}
+ </h6>
<span
- v-if="!emoji.imageUrl"
- class="emoji-picker-emoji -unicode"
- >{{ emoji.replacement }}</span>
- <still-image
- v-else
- :ref="setEmojiRef(group.id + emoji.displayText)"
- class="emoji-picker-emoji -custom"
- :data-src="emoji.imageUrl"
- :data-emoji-name="group.id + emoji.displayText"
- />
- </span>
- <span :ref="setGroupRef('group-end-' + group.id)" />
+ v-for="emoji in group.emojis"
+ :key="group.id + emoji.displayText"
+ :title="maybeLocalizedEmojiName(emoji)"
+ class="emoji-item"
+ @click.stop.prevent="onEmoji(emoji)"
+ >
+ <span
+ v-if="!emoji.imageUrl"
+ class="emoji-picker-emoji -unicode"
+ >{{ emoji.replacement }}</span>
+ <still-image
+ v-else
+ :ref="setEmojiRef(group.id + emoji.displayText)"
+ class="emoji-picker-emoji -custom"
+ :data-src="emoji.imageUrl"
+ :data-emoji-name="group.id + emoji.displayText"
+ />
+ </span>
+ <span :ref="setGroupRef('group-end-' + group.id)" />
+ </div>
+ </div>
+ <div class="keep-open">
+ <Checkbox v-model="keepOpen">
+ {{ $t('emoji.keep_open') }}
+ </Checkbox>
</div>
</div>
- <div class="keep-open">
- <Checkbox v-model="keepOpen">
- {{ $t('emoji.keep_open') }}
- </Checkbox>
+ <div
+ v-if="showingStickers"
+ class="stickers-content"
+ >
+ <sticker-picker
+ @uploaded="onStickerUploaded"
+ @upload-failed="onStickerUploadFailed"
+ />
</div>
</div>
- <div
- v-if="showingStickers"
- class="stickers-content"
- >
- <sticker-picker
- @uploaded="onStickerUploaded"
- @upload-failed="onStickerUploadFailed"
- />
- </div>
- </div>
- </div>
+ </template>
+ </Popover>
</template>
<script src="./emoji_picker.js"></script>