semaphore/src/routes/_components/dialog/components/EmojiDialog.html

137 lines
4.3 KiB
HTML

<ModalDialog
{id}
{label}
{title}
shrinkWidthToFit={true}
background="var(--main-bg)"
>
<div class="emoji-container">
<emoji-picker
ref:picker
locale={emojiPickerLocale}
data-source={emojiPickerDataSource}
class={darkMode ? 'dark' : 'light'}
on:emoji-click="onEmojiSelected(event)"
on:keydown="onPickerKeydown(event)"
></emoji-picker>
</div>
</ModalDialog>
<style>
emoji-picker {
--indicator-color: var(--main-theme-color);
--outline-color: var(--focus-outline);
--input-border-radius: var(--input-border-radius-size);
}
@media (max-width: 479px) {
.emoji-container, emoji-picker {
width: 100%;
}
}
@media (max-width: 320px) {
emoji-picker {
--emoji-padding: 0.25rem;
--input-padding: 0.125rem;
}
emoji-picker {
--num-columns: 6;
}
}
@media (max-width: 240px) {
emoji-picker {
--num-columns: 6;
--emoji-size: 1.125rem;
--emoji-padding: 0.125rem;
height: 240px;
}
}
@media (max-height: 450px) {
emoji-picker {
height: calc(100vh - 75px); /* leave room for the dialog bar */
}
}
</style>
<script>
import ModalDialog from './ModalDialog.html'
import { store } from '../../../_store/store.js'
import { insertEmoji } from '../../../_actions/emoji.js'
import { show } from '../helpers/showDialog.js'
import { close } from '../helpers/closeDialog.js'
import { oncreate as onCreateDialog } from '../helpers/onCreateDialog.js'
import { isDarkTheme } from '../../../_utils/isDarkTheme.js'
import 'emoji-picker-element/picker'
import { registerShadowRoot, unregisterShadowRoot } from '../../../_thirdparty/a11y-dialog/a11y-dialog.js'
import { doubleRAF } from '../../../_utils/doubleRAF.js'
import { convertCustomEmojiToEmojiPickerFormat } from '../../../_utils/convertCustomEmojiToEmojiPickerFormat.js'
import { supportsFocusVisible } from '../../../_utils/supportsFocusVisible.js'
import { importFocusVisible } from '../../../_utils/polyfills/asyncPolyfills.js'
import { emojiPickerI18n, emojiPickerDataSource, emojiPickerLocale } from '../../../_static/emojiPickerIntl.js'
export default {
async oncreate () {
onCreateDialog.call(this)
const { customEmoji } = this.get()
const { enableGrayscale, isUserTouching } = this.store.get()
const { picker } = this.refs
picker.customEmoji = customEmoji
if (emojiPickerI18n) {
picker.i18n = emojiPickerI18n
}
// break into shadow DOM to fix grayscale in Wellness grayscale mode
if (enableGrayscale) {
const style = document.createElement('style')
style.textContent = '.emoji { filter: grayscale(100%); }'
picker.shadowRoot.appendChild(style)
}
registerShadowRoot(picker.shadowRoot)
this.on('destroy', () => unregisterShadowRoot(picker.shadowRoot))
if (!isUserTouching) { // auto focus the input on desktop
doubleRAF(() => { // triple rAF because a11y tries to focus as well
requestAnimationFrame(() => {
picker.shadowRoot.querySelector('input').focus()
})
})
}
if (!supportsFocusVisible()) {
await importFocusVisible()
/* global applyFocusVisiblePolyfill */
applyFocusVisiblePolyfill(picker.shadowRoot)
}
},
components: {
ModalDialog
},
store: () => store,
data: () => ({
emojiPickerLocale,
emojiPickerDataSource
}),
computed: {
darkMode: ({ $currentTheme }) => isDarkTheme($currentTheme),
customEmoji: ({ $currentCustomEmoji, $autoplayGifs }) => (
convertCustomEmojiToEmojiPickerFormat($currentCustomEmoji, $autoplayGifs)
)
},
methods: {
show,
close,
onEmojiSelected (event) {
const { realm } = this.get()
insertEmoji(realm, event.detail)
this.close()
},
onPickerKeydown (event) {
// workaround for shortcuts -- see acceptShortcutEvent() in shortcuts.js
if (event.key === 'Backspace' &&
event.target.shadowRoot.activeElement &&
event.target.shadowRoot.activeElement.tagName === 'INPUT') {
event.stopPropagation() // prevent our hotkeys from activating when pressing backspace in the input
}
}
}
}
</script>