diff options
Diffstat (limited to 'src/components/emoji-input')
| -rw-r--r-- | src/components/emoji-input/emoji-input.js | 30 | ||||
| -rw-r--r-- | src/components/emoji-input/emoji-input.vue | 54 |
2 files changed, 80 insertions, 4 deletions
diff --git a/src/components/emoji-input/emoji-input.js b/src/components/emoji-input/emoji-input.js index 62c58446..1c49c710 100644 --- a/src/components/emoji-input/emoji-input.js +++ b/src/components/emoji-input/emoji-input.js @@ -53,6 +53,11 @@ const EmojiInput = { */ required: true, type: String + }, + emojiPicker: { + required: false, + type: Boolean, + default: false } }, data () { @@ -61,7 +66,8 @@ const EmojiInput = { highlighted: 0, caret: 0, focused: false, - blurTimeout: null + blurTimeout: null, + showPicker: false, } }, components: { @@ -83,12 +89,15 @@ const EmojiInput = { highlighted: index === this.highlighted })) }, - showPopup () { + showSuggestions () { return this.focused && this.suggestions && this.suggestions.length > 0 }, textAtCaret () { return (this.wordAtCaret || {}).word || '' }, + pickerIconBottom () { + return this.input && this.input.tag === 'textarea' + }, wordAtCaret () { if (this.value && this.caret) { const word = Completion.wordAtPosition(this.value, this.caret - 1) || {} @@ -124,11 +133,22 @@ const EmojiInput = { } }, methods: { + togglePicker () { + this.showPicker = !this.showPicker + }, replace (replacement) { const newValue = Completion.replaceWord(this.value, this.wordAtCaret, replacement) this.$emit('input', newValue) this.caret = 0 }, + insert (insertion) { + const newValue = [ + this.value.substring(0, this.caret), + insertion, + this.value.substring(this.caret) + ].join('') + this.$emit('input', newValue) + }, replaceText (e, suggestion) { const len = this.suggestions.length || 0 if (this.textAtCaret.length === 1) { return } @@ -195,6 +215,7 @@ const EmojiInput = { this.blurTimeout = null } + this.showPicker = false this.focused = true this.setCaret(e) this.resize() @@ -231,6 +252,7 @@ const EmojiInput = { } }, onInput (e) { + this.showPicker = false this.setCaret(e) this.$emit('input', e.target.value) }, @@ -239,6 +261,9 @@ const EmojiInput = { this.resize() this.$emit('input', e.target.value) }, + onClickOutside () { + this.showPicker = false + }, setCaret ({ target: { selectionStart } }) { this.caret = selectionStart }, @@ -247,6 +272,7 @@ const EmojiInput = { if (!panel) return const { offsetHeight, offsetTop } = this.input.elm this.$refs.panel.style.top = (offsetTop + offsetHeight) + 'px' + this.$refs.picker.$el.style.top = (offsetTop + offsetHeight) + 'px' } } } diff --git a/src/components/emoji-input/emoji-input.vue b/src/components/emoji-input/emoji-input.vue index 48739ec8..605882e8 100644 --- a/src/components/emoji-input/emoji-input.vue +++ b/src/components/emoji-input/emoji-input.vue @@ -1,10 +1,29 @@ <template> - <div class="emoji-input"> +<div + class="emoji-input" + v-click-outside="onClickOutside" + > <slot /> + <template v-if="emojiPicker"> + <div + @click.prevent="togglePicker" + class="emoji-picker-icon" + :class="pickerIconBottom ? 'picker-icon-bottom': 'picker-icon-right'" + > + <i class="icon-smile"></i> + </div> + <EmojiPicker + v-if="emojiPicker" + :class="{ hide: !showPicker }" + ref="picker" + class="emoji-picker-panel" + @emoji="insert" + /> + </template> <div ref="panel" class="autocomplete-panel" - :class="{ hide: !showPopup }" + :class="{ hide: !showSuggestions }" > <div class="autocomplete-panel-body"> <div @@ -39,6 +58,37 @@ .emoji-input { display: flex; flex-direction: column; + position: relative; + + .emoji-picker-icon { + position: absolute; + margin: 0 .25em; + font-size: 16px; + cursor: pointer; + + &:hover i { + color: $fallback--text; + color: var(--text, $fallback--text); + } + + &.picker-icon-bottom { + bottom: 0; + left: 0; + } + &.picker-icon-right { + top: 0; + right: 0; + } + } + .emoji-picker-panel { + position: absolute; + z-index: 9; + margin-top: 2px; + + &.hide { + display: none + } + } .autocomplete { &-panel { |
