diff --git a/.eslintrc b/.eslintrc
index c5e7d6831a..36c82c3048 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -96,6 +96,7 @@
"hljs": true,
"Awesomplete": true,
"Sortable": true,
+ "gemoji": true,
"Showdown": true,
"Taggle": true,
"Gantt": true,
diff --git a/frappe/public/js/frappe/form/controls/icon.js b/frappe/public/js/frappe/form/controls/icon.js
index f3386ed813..a964153d2b 100644
--- a/frappe/public/js/frappe/form/controls/icon.js
+++ b/frappe/public/js/frappe/form/controls/icon.js
@@ -21,6 +21,7 @@ frappe.ui.form.ControlIcon = class ControlIcon extends frappe.ui.form.ControlDat
parent: picker_wrapper,
icon: this.get_icon(),
icons: frappe.symbols,
+ include_emoji: this.df.options == "Emojis",
});
this.$wrapper
diff --git a/frappe/public/js/frappe/icon_picker/icon_picker.js b/frappe/public/js/frappe/icon_picker/icon_picker.js
index 8d8cccd748..85c5582ca7 100644
--- a/frappe/public/js/frappe/icon_picker/icon_picker.js
+++ b/frappe/public/js/frappe/icon_picker/icon_picker.js
@@ -5,6 +5,7 @@ class Picker {
this.height = opts.height;
this.set_icon(opts.icon);
this.icons = opts.icons;
+ this.include_emoji = opts.include_emoji;
this.setup_picker();
}
@@ -19,7 +20,7 @@ class Picker {
${frappe.utils.icon("search", "sm")}
-
@@ -29,8 +30,75 @@ class Picker {
this.search_input = this.icon_picker_wrapper.find(".search-icons > input");
this.refresh();
this.setup_icons();
+ if (this.include_emoji) {
+ this.setup_emojis();
+ }
}
+ setup_emojis() {
+ console.log("Making emojis");
+ // setup tab
+ this.setup_tab();
+ // setup emoji container
+ this.setup_emoji_container();
+ // emojis
+ this.emoji_wrapper = this.icon_picker_wrapper.find(".emojis");
+ gemoji.forEach((emoji, i) => {
+ let $icon = $(
+ `${gemoji[i].emoji}
`
+ );
+ this.emoji_wrapper.append($icon);
+ const set_values = () => {
+ this.set_icon(gemoji[i].emoji);
+ this.update_icon_selected();
+ };
+ $icon.on("click", () => {
+ set_values();
+ });
+ // $icon.keydown((e) => {
+ // const key_code = e.keyCode;
+ // if ([13, 32].includes(key_code)) {
+ // e.preventDefault();
+ // set_values();
+ // }
+ // });
+ });
+ }
+ setup_emoji_container() {
+ this.icon_picker_wrapper.find(".icon-section")
+ .after(``);
+ }
+ setup_tab() {
+ this.icon_picker_wrapper.find(".search-icons").after(``);
+ let icon_types = ["icon", "emoji"];
+ const me = this;
+ this.icon_picker_wrapper.find(".nav-item").on("click", function (e) {
+ let container_name = $(this).text().trim().toLowerCase();
+
+ icon_types.forEach((type) => {
+ if (type === container_name) {
+ me.icon_picker_wrapper.find(`.${type}-section`).removeClass("hidden");
+ } else {
+ me.icon_picker_wrapper.find(`.${type}-section`).addClass("hidden");
+ }
+ });
+ });
+ }
setup_icons() {
this.icons.forEach((icon) => {
let $icon = $(
diff --git a/frappe/public/js/frappe/utils/utils.js b/frappe/public/js/frappe/utils/utils.js
index 2fc3fc64ac..bab0516b7b 100644
--- a/frappe/public/js/frappe/utils/utils.js
+++ b/frappe/public/js/frappe/utils/utils.js
@@ -1245,6 +1245,9 @@ Object.assign(frappe.utils, {
current_color = false,
stroke_color = null
) {
+ if (frappe.utils.is_emoji(icon_name)) {
+ return `${icon_name}`;
+ }
let size_class = "";
let is_espresso = icon_name.startsWith("es-");
@@ -1276,6 +1279,10 @@ Object.assign(frappe.utils, {
flag(country_code) {
return `
`;
},
+ is_emoji(emoji_name) {
+ let emojiList = gemoji.map((emoji) => emoji.emoji);
+ return emojiList.includes(emoji_name);
+ },
make_chart(wrapper, custom_options = {}) {
let chart_args = {
diff --git a/frappe/public/js/libs.bundle.js b/frappe/public/js/libs.bundle.js
index 77704bb173..0e1d5df2ef 100644
--- a/frappe/public/js/libs.bundle.js
+++ b/frappe/public/js/libs.bundle.js
@@ -5,9 +5,11 @@ import "../js/lib/leaflet_easy_button/easy-button.js";
import "../js/lib/leaflet_draw/leaflet.draw.js";
import "../js/lib/leaflet_control_locate/L.Control.Locate.js";
import Sortable from "sortablejs";
+import { gemoji } from "gemoji";
window.SetVueGlobals = (app) => {
app.config.globalProperties.__ = window.__;
app.config.globalProperties.frappe = window.frappe;
};
window.Sortable = Sortable;
+window.gemoji = gemoji;
diff --git a/frappe/public/scss/common/icon_picker.scss b/frappe/public/scss/common/icon_picker.scss
index 76270994e5..185eac366b 100644
--- a/frappe/public/scss/common/icon_picker.scss
+++ b/frappe/public/scss/common/icon_picker.scss
@@ -3,7 +3,8 @@
color: var(--text-muted);
--icon-picker-width: 240px;
width: var(--icon-picker-width);
- .icons {
+ .icons,
+ .emojis {
margin-top: 10px;
display: flex;
flex-wrap: wrap;
@@ -27,6 +28,13 @@
text-align: center;
align-items: center;
}
+ .emoji-wrapper {
+ font-size: 20px;
+ width: 30px;
+ height: 30px;
+ text-align: center;
+ align-items: center;
+ }
}
.search-icons {
diff --git a/package.json b/package.json
index a7fdc106f5..8e75cc962e 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,7 @@
"frappe-datatable": "1.19.0",
"frappe-gantt": "^0.6.0",
"frappe-quill-image-resize": "^3.0.9",
+ "gemoji": "^8.1.0",
"highlight.js": "^10.4.1",
"html5-qrcode": "^2.3.8",
"jquery": "3.7.0",
diff --git a/yarn.lock b/yarn.lock
index f52fc1a4ac..303baa1f56 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1489,6 +1489,11 @@ functions-have-names@^1.2.3:
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
+gemoji@^8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/gemoji/-/gemoji-8.1.0.tgz#3d47a26e569c51efa95198822a6f483d7a7ae600"
+ integrity sha512-HA4Gx59dw2+tn+UAa7XEV4ufUKI4fH1KgcbenVA9YKSj1QJTT0xh5Mwv5HMFNN3l2OtUe3ZIfuRwSyZS5pLIWw==
+
generic-names@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-1.0.3.tgz#2d786a121aee508876796939e8e3bff836c20917"