kopia lustrzana https://github.com/nolanlawson/pinafore
153 wiersze
5.1 KiB
HTML
153 wiersze
5.1 KiB
HTML
<ModalDialog
|
|
{id}
|
|
{label}
|
|
{title}
|
|
shrinkWidthToFit={true}
|
|
background="var(--main-bg)"
|
|
className="emoji-dialog"
|
|
>
|
|
<div class="emoji-container" ref:container ></div>
|
|
</ModalDialog>
|
|
<style>
|
|
:global(emoji-picker) {
|
|
--indicator-color: var(--main-theme-color);
|
|
--outline-color: var(--focus-outline);
|
|
}
|
|
|
|
@media (max-width: 479px) {
|
|
:global(emoji-picker) {
|
|
--emoji-padding: 0.25rem;
|
|
--input-padding: 0.125rem;
|
|
}
|
|
|
|
.emoji-container, :global(emoji-picker) {
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 320px) {
|
|
:global(emoji-picker) {
|
|
--num-columns: 6;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 240px) {
|
|
:global(emoji-picker) {
|
|
--num-columns: 6;
|
|
--emoji-size: 1.125rem;
|
|
--emoji-padding: 0.125rem;
|
|
height: 240px;
|
|
}
|
|
}
|
|
</style>
|
|
<script>
|
|
/* global applyFocusVisiblePolyfill */
|
|
import ModalDialog from './ModalDialog.html'
|
|
import { store } from '../../../_store/store'
|
|
import { insertEmoji } from '../../../_actions/emoji'
|
|
import { show } from '../helpers/showDialog'
|
|
import { close } from '../helpers/closeDialog'
|
|
import { oncreate as onCreateDialog } from '../helpers/onCreateDialog'
|
|
import { isDarkTheme } from '../../../_utils/isDarkTheme'
|
|
import Picker from 'emoji-picker-element/picker'
|
|
import 'focus-visible'
|
|
import { registerShadowRoot, unregisterShadowRoot } from '../../../_thirdparty/a11y-dialog/a11y-dialog'
|
|
import { doubleRAF } from '../../../_utils/doubleRAF'
|
|
import { convertCustomEmojiToEmojiPickerFormat } from '../../../_utils/convertCustomEmojiToEmojiPickerFormat'
|
|
|
|
function applyShadowDomPolyfill (picker) {
|
|
// polyfill for :host, plus other fixes mostly targeted at KaiOS.
|
|
// We could use shadycss, but it doesn't really work for our use case (has to be injected
|
|
// into the web component's connectedCallback directly).
|
|
const style = picker.shadowRoot.querySelector('style')
|
|
style.remove()
|
|
if (!document.getElementById('emoji-picker-style')) {
|
|
let css = style.textContent
|
|
css = css.replace(/:host\(([.*?])\)/g, 'emoji-picker$1')
|
|
css = css.replace(/:host/g, 'emoji-picker')
|
|
css = css.replace(/\*/g, 'emoji-picker *')
|
|
css = css.replace(/\b(button|input|input\[type=search\])\s*\{/, 'emoji-picker $1{')
|
|
// fixes for KaiOS style bugs
|
|
css += `
|
|
emoji-picker .emoji-menu {
|
|
grid-template-columns: repeat(8, 1fr);
|
|
}
|
|
|
|
@media screen and (max-width: 320px) {
|
|
emoji-picker .emoji-menu {
|
|
grid-template-columns: repeat(6, 1fr);
|
|
}
|
|
.emoji-container {
|
|
width: calc(100% - 20px);
|
|
}
|
|
}
|
|
`
|
|
const newStyle = document.createElement('style')
|
|
newStyle.id = 'emoji-picker-style'
|
|
newStyle.textContent = css
|
|
document.head.appendChild(newStyle)
|
|
}
|
|
}
|
|
|
|
export default {
|
|
async oncreate () {
|
|
onCreateDialog.call(this)
|
|
const { customEmoji, darkMode } = this.get()
|
|
const { enableGrayscale, isUserTouching } = this.store.get()
|
|
const picker = new Picker({
|
|
dataSource: '/emoji-all-en.json',
|
|
customEmoji
|
|
})
|
|
picker.classList.add(darkMode ? 'dark' : 'light')
|
|
picker.addEventListener('emoji-click', this.onEmojiSelected.bind(this))
|
|
// workaround for shortcuts -- see acceptShortcutEvent() in shortcuts.js
|
|
picker.addEventListener('keydown', event => {
|
|
if (event.key === 'Backspace' &&
|
|
picker.shadowRoot.activeElement &&
|
|
picker.shadowRoot.activeElement.tagName === 'INPUT') {
|
|
event.stopPropagation() // prevent our hotkeys from activating when pressing backspace in the input
|
|
}
|
|
})
|
|
// break into shadow DOM to fix grayscale in Welness grayscale mode
|
|
if (enableGrayscale) {
|
|
const style = document.createElement('style')
|
|
style.textContent = '.emoji { filter: grayscale(100%); }'
|
|
picker.shadowRoot.appendChild(style)
|
|
}
|
|
applyFocusVisiblePolyfill(picker.shadowRoot)
|
|
registerShadowRoot(picker.shadowRoot)
|
|
if (process.env.LEGACY && !HTMLElement.prototype.attachShadow.toString().includes('[native code]')) {
|
|
applyShadowDomPolyfill(picker)
|
|
}
|
|
this.refs.container.appendChild(picker)
|
|
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()
|
|
})
|
|
})
|
|
}
|
|
},
|
|
components: {
|
|
ModalDialog
|
|
},
|
|
store: () => store,
|
|
computed: {
|
|
darkMode: ({ $currentTheme }) => isDarkTheme($currentTheme),
|
|
customEmoji: ({ $currentCustomEmoji, $autoplayGifs }) => (
|
|
convertCustomEmojiToEmojiPickerFormat($currentCustomEmoji, $autoplayGifs)
|
|
)
|
|
},
|
|
methods: {
|
|
show,
|
|
close,
|
|
onEmojiSelected (event) {
|
|
const { realm } = this.get()
|
|
insertEmoji(realm, event.detail.emoji)
|
|
this.close()
|
|
}
|
|
}
|
|
}
|
|
</script>
|