@nextcloud/vue
Version:
Nextcloud vue components
307 lines (306 loc) • 12.4 kB
JavaScript
require('../assets/NcEmojiPicker-rk5qcSl7.css');
"use strict";
const emojiMartVueFast = require("emoji-mart-vue-fast");
const _l10n = require("./_l10n-CjO_W5Dt.cjs");
const emoji = require("./emoji-VgSjNTd5.cjs");
const GenColors = require("./GenColors-Di5GSft7.cjs");
const data = require("emoji-mart-vue-fast/data/all.json");
const _pluginVue2_normalizer = require("./_plugin-vue2_normalizer-V0q-tHlQ.cjs");
const Components_NcButton = require("../Components/NcButton.cjs");
const NcColorPicker = require("./NcColorPicker-CTQlyVCL.cjs");
const NcPopover = require("./NcPopover-BKlH1mbx.cjs");
const NcTextField = require("./NcTextField-Pbox9mQE.cjs");
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
const data__default = /* @__PURE__ */ _interopDefault(data);
_l10n.register(_l10n.t5, _l10n.t14, _l10n.t34, _l10n.t39);
const _sfc_main$1 = {
name: "CircleIcon",
emits: ["click"],
props: {
title: {
type: String
},
fillColor: {
type: String,
default: "currentColor"
},
size: {
type: Number,
default: 24
}
}
};
var _sfc_render$1 = function render() {
var _vm = this, _c = _vm._self._c;
return _c("span", _vm._b({ staticClass: "material-design-icon circle-icon", attrs: { "aria-hidden": _vm.title ? null : "true", "aria-label": _vm.title, "role": "img" }, on: { "click": function($event) {
return _vm.$emit("click", $event);
} } }, "span", _vm.$attrs, false), [_c("svg", { staticClass: "material-design-icon__svg", attrs: { "fill": _vm.fillColor, "width": _vm.size, "height": _vm.size, "viewBox": "0 0 24 24" } }, [_c("path", { attrs: { "d": "M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" } }, [_vm.title ? _c("title", [_vm._v(_vm._s(_vm.title))]) : _vm._e()])])]);
};
var _sfc_staticRenderFns$1 = [];
var __component__$1 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main$1,
_sfc_render$1,
_sfc_staticRenderFns$1,
false,
null,
null
);
const IconCircle = __component__$1.exports;
let emojiIndex;
const i18n = {
search: _l10n.t("Search emoji"),
notfound: _l10n.t("No emoji found"),
categories: {
search: _l10n.t("Search results"),
recent: _l10n.t("Frequently used"),
smileys: _l10n.t("Smileys & Emotion"),
people: _l10n.t("People & Body"),
nature: _l10n.t("Animals & Nature"),
foods: _l10n.t("Food & Drink"),
activity: _l10n.t("Activities"),
places: _l10n.t("Travel & Places"),
objects: _l10n.t("Objects"),
symbols: _l10n.t("Symbols"),
flags: _l10n.t("Flags"),
custom: _l10n.t("Custom")
}
};
const skinTonePalette = [
new GenColors.Color(255, 222, 52, _l10n.t("Neutral skin color")),
new GenColors.Color(228, 205, 166, _l10n.t("Light skin tone")),
new GenColors.Color(250, 221, 192, _l10n.t("Medium light skin tone")),
new GenColors.Color(174, 129, 87, _l10n.t("Medium skin tone")),
new GenColors.Color(158, 113, 88, _l10n.t("Medium dark skin tone")),
new GenColors.Color(96, 79, 69, _l10n.t("Dark skin tone"))
];
const _sfc_main = {
name: "NcEmojiPicker",
components: {
Emoji: emojiMartVueFast.Emoji,
IconCircle,
NcButton: Components_NcButton,
NcColorPicker: NcColorPicker.NcColorPicker,
NcPopover: NcPopover.NcPopover,
NcTextField: NcTextField.NcTextField,
Picker: emojiMartVueFast.Picker
},
props: {
/**
* The emoji-set
*/
activeSet: {
type: String,
default: "native"
},
/**
* Show preview section when hovering emoji
*/
showPreview: {
type: Boolean,
default: false
},
/**
* Allow unselecting the selected emoji
*/
allowUnselect: {
type: Boolean,
default: false
},
/**
* Selected emoji to allow unselecting
*/
selectedEmoji: {
type: String,
default: ""
},
/**
* The fallback emoji in the preview section
*/
previewFallbackEmoji: {
type: String,
default: "grinning"
},
/**
* The fallback text in the preview section
*/
previewFallbackName: {
type: String,
default: _l10n.t("Pick an emoji")
},
/**
* Whether to close the emoji picker after picking one
*/
closeOnSelect: {
type: Boolean,
default: true
},
/**
* Selector for the popover container
*/
container: {
type: [String, Object, Element, Boolean],
default: "body"
}
},
emits: [
"select",
"select-data",
"unselect"
],
setup() {
if (!emojiIndex) {
emojiIndex = new emojiMartVueFast.EmojiIndex(data__default.default);
}
return {
// Non-reactive constants
emojiIndex,
skinTonePalette,
i18n
};
},
data() {
const currentSkinTone = emoji.getCurrentSkinTone();
return {
/**
* The current active color from the skin tone palette
*/
currentColor: skinTonePalette[currentSkinTone - 1],
/**
* The current active skin tone
* @type {1|2|3|4|5|6}
*/
currentSkinTone,
search: "",
open: false
};
},
computed: {
native() {
return this.activeSet === "native";
}
},
methods: {
t: _l10n.t,
clearSearch() {
this.search = "";
this.$refs.search.focus();
},
/**
* Update the current skin tone by the result of the color picker
* @param {string} color Color set
*/
onChangeSkinTone(color) {
const index = this.skinTonePalette.findIndex((tone) => tone.color.toLowerCase() === color.toLowerCase());
if (index > -1) {
this.currentSkinTone = index + 1;
this.currentColor = this.skinTonePalette[index];
emoji.setCurrentSkinTone(this.currentSkinTone);
}
},
select(emojiObject) {
this.$emit("select", emojiObject.native);
this.$emit("select-data", emojiObject);
if (this.closeOnSelect) {
this.open = false;
}
},
unselect() {
this.$emit("unselect");
},
afterShow() {
this.$refs.search.focus();
},
afterHide() {
this.$refs.popover.$el.querySelector('button, [role="button"]')?.focus();
},
/**
* Manually handle Tab navigation skipping emoji buttons.
* Navigation over emojis is handled by Arrow keys.
* @param {KeyboardEvent} event - Keyboard event
*/
handleTabNavigationSkippingEmojis(event) {
const current = event.target;
const focusable = Array.from(this.$refs.picker.$el.querySelectorAll("button:not(.emoji-mart-emoji), input"));
if (!event.shiftKey) {
const nextNode = focusable.find((node) => current.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_FOLLOWING) || focusable[0];
nextNode.focus();
} else {
const prevNode = focusable.findLast((node) => current.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_PRECEDING) || focusable.at(-1);
prevNode.focus();
}
},
/**
* Handle arrow navigation via <Picker>'s handlers with scroll bug fix
* @param {'onArrowLeft' | 'onArrowRight' | 'onArrowDown' | 'onArrowUp'} originalHandlerName - Picker's arrow keydown handler name
* @param {KeyboardEvent} event - Keyboard event
*/
async callPickerArrowHandlerWithScrollFix(originalHandlerName, event) {
this.$refs.picker[originalHandlerName](event);
await this.$nextTick();
const selectedEmoji = this.$refs.picker.$el.querySelector(".emoji-mart-emoji-selected");
selectedEmoji?.scrollIntoView({
block: "center",
inline: "center"
});
}
}
};
var _sfc_render = function render2() {
var _vm = this, _c = _vm._self._c;
return _c("NcPopover", _vm._g(_vm._b({ ref: "popover", attrs: {
"shown": _vm.open,
"container": _vm.container,
"popup-role": "dialog",
"focus-trap": false
/* Handled manually to remove emoji buttons from TAB sequence */
}, on: { "update:shown": function($event) {
_vm.open = $event;
}, "after-show": _vm.afterShow, "after-hide": _vm.afterHide }, scopedSlots: _vm._u([{ key: "trigger", fn: function(slotProps) {
return [_vm._t("default", null, null, slotProps)];
} }], null, true) }, "NcPopover", _vm.$attrs, false), _vm.$listeners), [_c("Picker", _vm._b({ ref: "picker", staticClass: "nc-emoji-picker", attrs: { "color": "var(--color-primary-element)", "data": _vm.emojiIndex, "emoji": _vm.previewFallbackEmoji, "i18n": _vm.i18n, "native": _vm.native, "emoji-size": 20, "per-line": 8, "picker-styles": { width: "320px" }, "show-preview": _vm.showPreview, "skin": _vm.currentSkinTone, "show-skin-tones": false, "title": _vm.previewFallbackName, "role": "dialog", "aria-modal": "true", "aria-label": _vm.t("Emoji picker") }, on: { "select": _vm.select }, nativeOn: { "keydown": function($event) {
if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "tab", 9, $event.key, "Tab")) return null;
$event.preventDefault();
return _vm.handleTabNavigationSkippingEmojis.apply(null, arguments);
} }, scopedSlots: _vm._u([{ key: "searchTemplate", fn: function({ onSearch }) {
return [_c("div", { staticClass: "search__wrapper" }, [_c("NcTextField", { ref: "search", staticClass: "search", attrs: { "value": _vm.search, "label": _vm.t("Search"), "label-visible": true, "placeholder": _vm.i18n.search, "trailing-button-icon": "close", "trailing-button-label": _vm.t("Clear search"), "show-trailing-button": _vm.search !== "" }, on: { "update:value": [function($event) {
_vm.search = $event;
}, function($event) {
return onSearch(_vm.search);
}], "keydown": [function($event) {
if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "left", 37, $event.key, ["Left", "ArrowLeft"])) return null;
if ("button" in $event && $event.button !== 0) return null;
return _vm.callPickerArrowHandlerWithScrollFix("onArrowLeft", $event);
}, function($event) {
if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "right", 39, $event.key, ["Right", "ArrowRight"])) return null;
if ("button" in $event && $event.button !== 2) return null;
return _vm.callPickerArrowHandlerWithScrollFix("onArrowRight", $event);
}, function($event) {
if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "down", 40, $event.key, ["Down", "ArrowDown"])) return null;
return _vm.callPickerArrowHandlerWithScrollFix("onArrowDown", $event);
}, function($event) {
if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "up", 38, $event.key, ["Up", "ArrowUp"])) return null;
return _vm.callPickerArrowHandlerWithScrollFix("onArrowUp", $event);
}, function($event) {
if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "enter", 13, $event.key, "Enter")) return null;
return _vm.$refs.picker.onEnter.apply(null, arguments);
}], "trailing-button-click": function($event) {
_vm.clearSearch();
onSearch("");
} } }), _c("NcColorPicker", { attrs: { "palette-only": "", "container": _vm.container, "palette": _vm.skinTonePalette, "value": _vm.currentColor.color }, on: { "update:value": _vm.onChangeSkinTone } }, [_c("NcButton", { attrs: { "aria-label": _vm.t("Skin tone"), "type": "tertiary-no-background" }, scopedSlots: _vm._u([{ key: "icon", fn: function() {
return [_c("IconCircle", { style: { color: _vm.currentColor.color }, attrs: { "title": _vm.currentColor.name, "size": 20 } })];
}, proxy: true }], null, true) })], 1)], 1)];
} }, _vm.allowUnselect && _vm.selectedEmoji ? { key: "customCategory", fn: function() {
return [_c("div", { staticClass: "emoji-mart-category-label" }, [_c("h3", { staticClass: "emoji-mart-category-label" }, [_vm._v(" " + _vm._s(_vm.t("Selected")) + " ")])]), _c("Emoji", { staticClass: "emoji-selected", attrs: { "data": _vm.emojiIndex, "emoji": _vm.selectedEmoji, "native": true, "size": 32 }, on: { "click": _vm.unselect } }), _c("Emoji", { staticClass: "emoji-delete", attrs: { "data": _vm.emojiIndex, "emoji": ":x:", "native": true, "size": 10 }, on: { "click": _vm.unselect } })];
}, proxy: true } : null], null, true) }, "Picker", _vm.$attrs, false))], 1);
};
var _sfc_staticRenderFns = [];
var __component__ = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main,
_sfc_render,
_sfc_staticRenderFns,
false,
null,
"6e39597a"
);
const NcEmojiPicker = __component__.exports;
exports.NcEmojiPicker = NcEmojiPicker;