├── .browserslistrc ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── babel.config.js ├── dev ├── index.html ├── serve.ts └── serve.vue ├── package.json ├── rollup.config.js ├── shims-tsx.d.ts ├── shims-vue.d.ts ├── src ├── EmojiPicker.vue ├── emojis.ts ├── entry.esm.ts └── entry.ts ├── tsconfig.json └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | current node 2 | last 2 versions and > 2% 3 | ie > 10 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log 4 | yarn-error.log 5 | dist/* 6 | !dist/.gitkeep 7 | dist-module/ 8 | package-lock.json 9 | 10 | # Editor directories and files 11 | .idea 12 | *.suo 13 | *.ntvs* 14 | *.njsproj 15 | *.sln 16 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Project 2 | dev/ 3 | node_modules/ 4 | .browserslistrc 5 | babel.config.js 6 | rollup.config.js 7 | tsconfig.json 8 | yarn.lock 9 | 10 | # Other 11 | .DS_Store 12 | yarn-error.log 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-present, Yuxi (Evan) You 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Highly-customizable emoji picker for Vue 2 2 | Downloads 3 | Version 4 | License 5 | 6 | ## Table of contents 7 | - [Demo](#demo) 8 | - [Installation](#installation) 9 | - [With npm](#with-npm) 10 | - [With a CDN](#with-a-cdn) 11 | - [Import](#import) 12 | - [With an ES6 bundler (via npm)](#with-an-es6-bundler-via-npm) 13 | - [Use per component](#use-per-component) 14 | - [Use globally](#use-globally) 15 | - [Using a CDN](#using-a-cdn) 16 | - [Usage](#usage) 17 | - [Very simple usage, without any CSS defined](#very-simple-usage-without-any-css-defined) 18 | - [CSS-styled example](#css-styled-example) 19 | - [Available props](#available-props) 20 | - [License](#license) 21 | 22 | 23 | ## Demo 24 | The live demos are available here: 25 | - [Simple, html-only demo](https://codepen.io/DCzajkowski/pen/JLypqP), 26 | - [Complete, css-styled demo](https://codepen.io/DCzajkowski/pen/jzLzWp), 27 | - [TailwindCSS-styled demo](https://codepen.io/DCzajkowski/pen/Brxvzj). 28 | 29 | ## Installation 30 | ### With npm 31 | ```bash 32 | npm i vue-emoji-picker --save 33 | ``` 34 | 35 | ### With a CDN 36 | ```html 37 | 38 | ``` 39 | 40 | ## Import 41 | ### With an ES6 bundler (via npm) 42 | ```js 43 | import { EmojiPicker } from 'vue-emoji-picker' 44 | 45 | export default { 46 | // ... 47 | components: { 48 | EmojiPicker, 49 | }, 50 | // ... 51 | } 52 | ``` 53 | 54 | ### Using a CDN 55 | ```html 56 | 63 | ``` 64 | 65 | ## Usage 66 | vue-emoji-picker is a slot-based component, to provide maximum flexibility. 67 | Since every ounce of html is created by a consumer (ie. you), you can customize every piece of the component as you wish. 68 | 69 | ### Very simple usage, without any CSS defined 70 | You will need two things. A textarea (or an input), where emojis will be injected, and a component declaration. A simple example is provided below. 71 | ```html 72 | 73 | 74 | 75 |
76 | 77 |
78 |
79 |
80 |
81 | 82 |
83 |
84 |
85 |
{{ category }}
86 |
87 | {{ emoji }} 93 |
94 |
95 |
96 |
97 |
98 |
99 | ``` 100 | 101 | ```js 102 | { 103 | data() { 104 | return { 105 | input: '', 106 | search: '', 107 | } 108 | }, 109 | methods: { 110 | insert(emoji) { 111 | this.input += emoji 112 | }, 113 | }, 114 | } 115 | ``` 116 | 117 | As you may see, you have to declare some things yourself. Namely: 118 | - `input` - a model for your input/textarea, 119 | - `search` - a model for the search box inside the component (optional), 120 | - `insert(emoji)` - a method responsible to put emojis into your input/textarea. Provided `emoji` is a string representation of the emoji to be inserted. 121 | 122 | ### CSS-styled example 123 | To see what is possible with the component, you can simply have a look at a demo available [here](https://codepen.io/DCzajkowski/pen/jzLzWp). 124 | 125 | ## Available props 126 | - `search` _optional_ - If you are not using the search functionality, you can omit this one. It should be a model of the search passed from your `data`. 127 | - `emojiTable` _optional_ - You can overwrite the [default](https://github.com/DCzajkowski/vue-emoji-picker/blob/master/src/emojis.ts) emoji table by providing your own. 128 | 129 | ## Slots 130 | - `emoji-invoker` 131 | - `events` - delares the `v-on:click` toggle of the picker box, 132 | - `emoji-picker` 133 | - `emojis` - object of unicode emojis, 134 | - `insert()` - method to be invoked when an emoji is clicked, 135 | - `display` - object containting `x`, `y` and `visible` properties. 136 | 137 | ## License 138 | This work is an open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). 139 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | const devPresets = ['@vue/babel-preset-app'] 2 | const buildPresets = [ 3 | ['@babel/preset-env', {}], 4 | '@babel/preset-typescript', 5 | ] 6 | 7 | module.exports = { 8 | presets: (process.env.NODE_ENV === 'development' ? devPresets : buildPresets), 9 | } 10 | -------------------------------------------------------------------------------- /dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |
8 | 9 |
10 |
11 |
12 |
13 | 14 |
15 |
16 |
17 |
{{ category }}
18 |
19 | {{ emoji }} 25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /dev/serve.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from 'vue' 2 | import Dev from './serve.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: (h): VNode => h(Dev), 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /dev/serve.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-emoji-picker", 3 | "description": "Simple Vue.js emoji picker with unicode characters", 4 | "version": "1.0.3", 5 | "main": "dist/vue-emoji-picker.ssr.js", 6 | "browser": "dist/vue-emoji-picker.esm.js", 7 | "module": "dist/vue-emoji-picker.esm.js", 8 | "unpkg": "dist/vue-emoji-picker.min.js", 9 | "types": "dist/types/src/entry.esm.d.ts", 10 | "scripts": { 11 | "serve": "vue-cli-service serve dev/serve.ts", 12 | "prebuild": "rimraf ./dist", 13 | "build": "cross-env NODE_ENV=production rollup --config rollup.config.js", 14 | "build:ssr": "cross-env NODE_ENV=production rollup --config rollup.config.js --format cjs", 15 | "build:es": "cross-env NODE_ENV=production rollup --config rollup.config.js --format es", 16 | "build:unpkg": "cross-env NODE_ENV=production rollup --config rollup.config.js --format iife", 17 | "postbuild": "rimraf ./dist/types/dev ./dist/types/src/entry.d.ts" 18 | }, 19 | "files": [ 20 | "dist/*", 21 | "src/**/*.vue", 22 | "LICENSE", 23 | "README.md" 24 | ], 25 | "repository": { 26 | "url": "git+https://github.com/DCzajkowski/vue-emoji-picker.git", 27 | "type": "git" 28 | }, 29 | "keywords": [], 30 | "author": "Dariusz Czajkowski ", 31 | "license": "MIT", 32 | "bugs": { 33 | "url": "https://github.com/DCzajkowski/vue-emoji-picker/issues" 34 | }, 35 | "homepage": "https://github.com/DCzajkowski/vue-emoji-picker#readme", 36 | "peerDependencies": { 37 | "vue": "^2.6.14" 38 | }, 39 | "devDependencies": { 40 | "@babel/core": "^7.14.6", 41 | "@babel/preset-env": "^7.14.7", 42 | "@babel/preset-typescript": "^7.14.5", 43 | "@rollup/plugin-alias": "^3.1.2", 44 | "@rollup/plugin-babel": "^5.3.0", 45 | "@rollup/plugin-commonjs": "^14.0.0", 46 | "@rollup/plugin-node-resolve": "^9.0.0", 47 | "@rollup/plugin-replace": "^2.4.2", 48 | "@vue/cli-plugin-babel": "^4.5.13", 49 | "@vue/cli-plugin-typescript": "^4.5.13", 50 | "@vue/cli-service": "^4.5.13", 51 | "@zerollup/ts-transform-paths": "^1.7.18", 52 | "cross-env": "^7.0.3", 53 | "minimist": "^1.2.5", 54 | "rimraf": "^3.0.2", 55 | "rollup": "^2.52.8", 56 | "rollup-plugin-terser": "^7.0.2", 57 | "rollup-plugin-typescript2": "^0.30.0", 58 | "rollup-plugin-vue": "^5.1.9", 59 | "ttypescript": "^1.5.12", 60 | "typescript": "^4.0.3", 61 | "vue": "^2.6.14", 62 | "vue-template-compiler": "^2.6.14" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | // rollup.config.js 2 | import fs from 'fs' 3 | import path from 'path' 4 | import vue from 'rollup-plugin-vue' 5 | import alias from '@rollup/plugin-alias' 6 | import commonjs from '@rollup/plugin-commonjs' 7 | import resolve from '@rollup/plugin-node-resolve' 8 | import replace from '@rollup/plugin-replace' 9 | import babel from '@rollup/plugin-babel' 10 | import { terser } from 'rollup-plugin-terser' 11 | import ttypescript from 'ttypescript' 12 | import typescript from 'rollup-plugin-typescript2' 13 | import minimist from 'minimist' 14 | 15 | // Get browserslist config and remove ie from es build targets 16 | const esbrowserslist = fs.readFileSync('./.browserslistrc') 17 | .toString() 18 | .split('\n') 19 | .filter((entry) => entry && entry.substring(0, 2) !== 'ie') 20 | 21 | // Extract babel preset-env config, to combine with esbrowserslist 22 | const babelPresetEnvConfig = require('./babel.config') 23 | .presets.filter((entry) => entry[0] === '@babel/preset-env')[0][1] 24 | 25 | const argv = minimist(process.argv.slice(2)) 26 | 27 | const projectRoot = path.resolve(__dirname) 28 | 29 | const baseConfig = { 30 | input: 'src/entry.ts', 31 | plugins: { 32 | preVue: [ 33 | alias({ 34 | entries: [ 35 | { 36 | find: '@', 37 | replacement: `${path.resolve(projectRoot, 'src')}`, 38 | }, 39 | ], 40 | }), 41 | ], 42 | replace: { 43 | 'process.env.NODE_ENV': JSON.stringify('production'), 44 | }, 45 | vue: { 46 | css: true, 47 | template: { 48 | isProduction: true, 49 | }, 50 | }, 51 | postVue: [ 52 | resolve({ 53 | extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'], 54 | }), 55 | commonjs(), 56 | ], 57 | babel: { 58 | exclude: 'node_modules/**', 59 | extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'], 60 | babelHelpers: 'bundled', 61 | }, 62 | }, 63 | } 64 | 65 | // ESM/UMD/IIFE shared settings: externals 66 | // Refer to https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency 67 | const external = [ 68 | // list external dependencies, exactly the way it is written in the import statement. 69 | // eg. 'jquery' 70 | 'vue', 71 | ] 72 | 73 | // UMD/IIFE shared settings: output.globals 74 | // Refer to https://rollupjs.org/guide/en#output-globals for details 75 | const globals = { 76 | // Provide global variable names to replace your external imports 77 | // eg. jquery: '$' 78 | vue: 'Vue', 79 | } 80 | 81 | // Customize configs for individual targets 82 | const buildFormats = [] 83 | if (!argv.format || argv.format === 'es') { 84 | const esConfig = { 85 | ...baseConfig, 86 | input: 'src/entry.esm.ts', 87 | external, 88 | output: { 89 | file: 'dist/vue-emoji-picker.esm.js', 90 | format: 'esm', 91 | exports: 'named', 92 | }, 93 | plugins: [ 94 | replace(baseConfig.plugins.replace), 95 | ...baseConfig.plugins.preVue, 96 | vue(baseConfig.plugins.vue), 97 | ...baseConfig.plugins.postVue, 98 | // Only use typescript for declarations - babel will 99 | // do actual js transformations 100 | typescript({ 101 | typescript: ttypescript, 102 | useTsconfigDeclarationDir: true, 103 | emitDeclarationOnly: true, 104 | }), 105 | babel({ 106 | ...baseConfig.plugins.babel, 107 | presets: [ 108 | [ 109 | '@babel/preset-env', 110 | { 111 | ...babelPresetEnvConfig, 112 | targets: esbrowserslist, 113 | }, 114 | ], 115 | ], 116 | }), 117 | ], 118 | } 119 | buildFormats.push(esConfig) 120 | } 121 | 122 | if (!argv.format || argv.format === 'cjs') { 123 | const umdConfig = { 124 | ...baseConfig, 125 | external, 126 | output: { 127 | compact: true, 128 | file: 'dist/vue-emoji-picker.ssr.js', 129 | format: 'cjs', 130 | name: 'EmojiPicker', 131 | exports: 'auto', 132 | globals, 133 | }, 134 | plugins: [ 135 | replace(baseConfig.plugins.replace), 136 | ...baseConfig.plugins.preVue, 137 | vue({ 138 | ...baseConfig.plugins.vue, 139 | template: { 140 | ...baseConfig.plugins.vue.template, 141 | optimizeSSR: true, 142 | }, 143 | }), 144 | ...baseConfig.plugins.postVue, 145 | babel(baseConfig.plugins.babel), 146 | ], 147 | } 148 | buildFormats.push(umdConfig) 149 | } 150 | 151 | if (!argv.format || argv.format === 'iife') { 152 | const unpkgConfig = { 153 | ...baseConfig, 154 | external, 155 | output: { 156 | compact: true, 157 | file: 'dist/vue-emoji-picker.min.js', 158 | format: 'iife', 159 | name: 'EmojiPicker', 160 | exports: 'auto', 161 | globals, 162 | }, 163 | plugins: [ 164 | replace(baseConfig.plugins.replace), 165 | ...baseConfig.plugins.preVue, 166 | vue(baseConfig.plugins.vue), 167 | ...baseConfig.plugins.postVue, 168 | babel(baseConfig.plugins.babel), 169 | terser({ 170 | output: { 171 | ecma: 5, 172 | }, 173 | }), 174 | ], 175 | } 176 | buildFormats.push(unpkgConfig) 177 | } 178 | 179 | // Export config 180 | export default buildFormats 181 | -------------------------------------------------------------------------------- /shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from 'vue' 2 | 3 | declare global { 4 | namespace JSX { 5 | // tslint:disable no-empty-interface 6 | interface Element extends VNode {} 7 | // tslint:disable no-empty-interface 8 | interface ElementClass extends Vue {} 9 | interface IntrinsicElements { 10 | [elem: string]: any 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue' 3 | export default Vue 4 | } 5 | -------------------------------------------------------------------------------- /src/EmojiPicker.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 140 | -------------------------------------------------------------------------------- /src/emojis.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | 'Frequently used': { 3 | 'thumbs_up': '👍', 4 | '-1': '👎', 5 | 'sob': '😭', 6 | 'confused': '😕', 7 | 'neutral_face': '😐', 8 | 'blush': '😊', 9 | 'heart_eyes': '😍', 10 | }, 11 | 'People': { 12 | 'smile': '😄', 13 | 'smiley': '😃', 14 | 'grinning': '😀', 15 | 'blush': '😊', 16 | 'wink': '😉', 17 | 'heart_eyes': '😍', 18 | 'kissing_heart': '😘', 19 | 'kissing_closed_eyes': '😚', 20 | 'kissing': '😗', 21 | 'kissing_smiling_eyes': '😙', 22 | 'stuck_out_tongue_winking_eye': '😜', 23 | 'stuck_out_tongue_closed_eyes': '😝', 24 | 'stuck_out_tongue': '😛', 25 | 'flushed': '😳', 26 | 'grin': '😁', 27 | 'pensive': '😔', 28 | 'relieved': '😌', 29 | 'unamused': '😒', 30 | 'disappointed': '😞', 31 | 'persevere': '😣', 32 | 'cry': '😢', 33 | 'joy': '😂', 34 | 'sob': '😭', 35 | 'sleepy': '😪', 36 | 'disappointed_relieved': '😥', 37 | 'cold_sweat': '😰', 38 | 'sweat_smile': '😅', 39 | 'sweat': '😓', 40 | 'weary': '😩', 41 | 'tired_face': '😫', 42 | 'fearful': '😨', 43 | 'scream': '😱', 44 | 'angry': '😠', 45 | 'rage': '😡', 46 | 'triumph': '😤', 47 | 'confounded': '😖', 48 | 'laughing': '😆', 49 | 'yum': '😋', 50 | 'mask': '😷', 51 | 'sunglasses': '😎', 52 | 'sleeping': '😴', 53 | 'dizzy_face': '😵', 54 | 'astonished': '😲', 55 | 'worried': '😟', 56 | 'frowning': '😦', 57 | 'anguished': '😧', 58 | 'imp': '👿', 59 | 'open_mouth': '😮', 60 | 'grimacing': '😬', 61 | 'neutral_face': '😐', 62 | 'confused': '😕', 63 | 'hushed': '😯', 64 | 'smirk': '😏', 65 | 'expressionless': '😑', 66 | 'man_with_gua_pi_mao': '👲', 67 | 'man_with_turban': '👳', 68 | 'cop': '👮', 69 | 'construction_worker': '👷', 70 | 'guardsman': '💂', 71 | 'baby': '👶', 72 | 'boy': '👦', 73 | 'girl': '👧', 74 | 'man': '👨', 75 | 'woman': '👩', 76 | 'older_man': '👴', 77 | 'older_woman': '👵', 78 | 'person_with_blond_hair': '👱', 79 | 'angel': '👼', 80 | 'princess': '👸', 81 | 'smiley_cat': '😺', 82 | 'smile_cat': '😸', 83 | 'heart_eyes_cat': '😻', 84 | 'kissing_cat': '😽', 85 | 'smirk_cat': '😼', 86 | 'scream_cat': '🙀', 87 | 'crying_cat_face': '😿', 88 | 'joy_cat': '😹', 89 | 'pouting_cat': '😾', 90 | 'japanese_ogre': '👹', 91 | 'japanese_goblin': '👺', 92 | 'see_no_evil': '🙈', 93 | 'hear_no_evil': '🙉', 94 | 'speak_no_evil': '🙊', 95 | 'skull': '💀', 96 | 'alien': '👽', 97 | 'hankey': '💩', 98 | 'fire': '🔥', 99 | 'sparkles': '✨', 100 | 'star2': '🌟', 101 | 'dizzy': '💫', 102 | 'boom': '💥', 103 | 'anger': '💢', 104 | 'sweat_drops': '💦', 105 | 'droplet': '💧', 106 | 'zzz': '💤', 107 | 'dash': '💨', 108 | 'ear': '👂', 109 | 'eyes': '👀', 110 | 'nose': '👃', 111 | 'tongue': '👅', 112 | 'lips': '👄', 113 | 'thumbs_up': '👍', 114 | '-1': '👎', 115 | 'ok_hand': '👌', 116 | 'facepunch': '👊', 117 | 'fist': '✊', 118 | 'wave': '👋', 119 | 'hand': '✋', 120 | 'open_hands': '👐', 121 | 'point_up_2': '👆', 122 | 'point_down': '👇', 123 | 'point_right': '👉', 124 | 'point_left': '👈', 125 | 'raised_hands': '🙌', 126 | 'pray': '🙏', 127 | 'clap': '👏', 128 | 'muscle': '💪', 129 | 'walking': '🚶', 130 | 'runner': '🏃', 131 | 'dancer': '💃', 132 | 'couple': '👫', 133 | 'family': '👪', 134 | 'couplekiss': '💏', 135 | 'couple_with_heart': '💑', 136 | 'dancers': '👯', 137 | 'ok_woman': '🙆', 138 | 'no_good': '🙅', 139 | 'information_desk_person': '💁', 140 | 'raising_hand': '🙋', 141 | 'massage': '💆', 142 | 'haircut': '💇', 143 | 'nail_care': '💅', 144 | 'bride_with_veil': '👰', 145 | 'person_with_pouting_face': '🙎', 146 | 'person_frowning': '🙍', 147 | 'bow': '🙇', 148 | 'tophat': '🎩', 149 | 'crown': '👑', 150 | 'womans_hat': '👒', 151 | 'athletic_shoe': '👟', 152 | 'mans_shoe': '👞', 153 | 'sandal': '👡', 154 | 'high_heel': '👠', 155 | 'boot': '👢', 156 | 'shirt': '👕', 157 | 'necktie': '👔', 158 | 'womans_clothes': '👚', 159 | 'dress': '👗', 160 | 'running_shirt_with_sash': '🎽', 161 | 'jeans': '👖', 162 | 'kimono': '👘', 163 | 'bikini': '👙', 164 | 'briefcase': '💼', 165 | 'handbag': '👜', 166 | 'pouch': '👝', 167 | 'purse': '👛', 168 | 'eyeglasses': '👓', 169 | 'ribbon': '🎀', 170 | 'closed_umbrella': '🌂', 171 | 'lipstick': '💄', 172 | 'yellow_heart': '💛', 173 | 'blue_heart': '💙', 174 | 'purple_heart': '💜', 175 | 'green_heart': '💚', 176 | 'broken_heart': '💔', 177 | 'heartpulse': '💗', 178 | 'heartbeat': '💓', 179 | 'two_hearts': '💕', 180 | 'sparkling_heart': '💖', 181 | 'revolving_hearts': '💞', 182 | 'cupid': '💘', 183 | 'love_letter': '💌', 184 | 'kiss': '💋', 185 | 'ring': '💍', 186 | 'gem': '💎', 187 | 'bust_in_silhouette': '👤', 188 | 'speech_balloon': '💬', 189 | 'footprints': '👣', 190 | }, 191 | 'Nature': { 192 | 'dog': '🐶', 193 | 'wolf': '🐺', 194 | 'cat': '🐱', 195 | 'mouse': '🐭', 196 | 'hamster': '🐹', 197 | 'rabbit': '🐰', 198 | 'frog': '🐸', 199 | 'tiger': '🐯', 200 | 'koala': '🐨', 201 | 'bear': '🐻', 202 | 'pig': '🐷', 203 | 'pig_nose': '🐽', 204 | 'cow': '🐮', 205 | 'boar': '🐗', 206 | 'monkey_face': '🐵', 207 | 'monkey': '🐒', 208 | 'horse': '🐴', 209 | 'sheep': '🐑', 210 | 'elephant': '🐘', 211 | 'panda_face': '🐼', 212 | 'penguin': '🐧', 213 | 'bird': '🐦', 214 | 'baby_chick': '🐤', 215 | 'hatched_chick': '🐥', 216 | 'hatching_chick': '🐣', 217 | 'chicken': '🐔', 218 | 'snake': '🐍', 219 | 'turtle': '🐢', 220 | 'bug': '🐛', 221 | 'bee': '🐝', 222 | 'ant': '🐜', 223 | 'beetle': '🐞', 224 | 'snail': '🐌', 225 | 'octopus': '🐙', 226 | 'shell': '🐚', 227 | 'tropical_fish': '🐠', 228 | 'fish': '🐟', 229 | 'dolphin': '🐬', 230 | 'whale': '🐳', 231 | 'racehorse': '🐎', 232 | 'dragon_face': '🐲', 233 | 'blowfish': '🐡', 234 | 'camel': '🐫', 235 | 'poodle': '🐩', 236 | 'feet': '🐾', 237 | 'bouquet': '💐', 238 | 'cherry_blossom': '🌸', 239 | 'tulip': '🌷', 240 | 'four_leaf_clover': '🍀', 241 | 'rose': '🌹', 242 | 'sunflower': '🌻', 243 | 'hibiscus': '🌺', 244 | 'maple_leaf': '🍁', 245 | 'leaves': '🍃', 246 | 'fallen_leaf': '🍂', 247 | 'herb': '🌿', 248 | 'ear_of_rice': '🌾', 249 | 'mushroom': '🍄', 250 | 'cactus': '🌵', 251 | 'palm_tree': '🌴', 252 | 'chestnut': '🌰', 253 | 'seedling': '🌱', 254 | 'blossom': '🌼', 255 | 'new_moon': '🌑', 256 | 'first_quarter_moon': '🌓', 257 | 'moon': '🌔', 258 | 'full_moon': '🌕', 259 | 'first_quarter_moon_with_face': '🌛', 260 | 'crescent_moon': '🌙', 261 | 'earth_asia': '🌏', 262 | 'volcano': '🌋', 263 | 'milky_way': '🌌', 264 | 'stars': '🌠', 265 | 'partly_sunny': '⛅', 266 | 'snowman': '⛄', 267 | 'cyclone': '🌀', 268 | 'foggy': '🌁', 269 | 'rainbow': '🌈', 270 | 'ocean': '🌊', 271 | }, 272 | 'Objects': { 273 | 'bamboo': '🎍', 274 | 'gift_heart': '💝', 275 | 'dolls': '🎎', 276 | 'school_satchel': '🎒', 277 | 'mortar_board': '🎓', 278 | 'flags': '🎏', 279 | 'fireworks': '🎆', 280 | 'sparkler': '🎇', 281 | 'wind_chime': '🎐', 282 | 'rice_scene': '🎑', 283 | 'jack_o_lantern': '🎃', 284 | 'ghost': '👻', 285 | 'santa': '🎅', 286 | 'christmas_tree': '🎄', 287 | 'gift': '🎁', 288 | 'tanabata_tree': '🎋', 289 | 'tada': '🎉', 290 | 'confetti_ball': '🎊', 291 | 'balloon': '🎈', 292 | 'crossed_flags': '🎌', 293 | 'crystal_ball': '🔮', 294 | 'movie_camera': '🎥', 295 | 'camera': '📷', 296 | 'video_camera': '📹', 297 | 'vhs': '📼', 298 | 'cd': '💿', 299 | 'dvd': '📀', 300 | 'minidisc': '💽', 301 | 'floppy_disk': '💾', 302 | 'computer': '💻', 303 | 'iphone': '📱', 304 | 'telephone_receiver': '📞', 305 | 'pager': '📟', 306 | 'fax': '📠', 307 | 'satellite': '📡', 308 | 'tv': '📺', 309 | 'radio': '📻', 310 | 'loud_sound': '🔊', 311 | 'bell': '🔔', 312 | 'loudspeaker': '📢', 313 | 'mega': '📣', 314 | 'hourglass_flowing_sand': '⏳', 315 | 'hourglass': '⌛', 316 | 'alarm_clock': '⏰', 317 | 'watch': '⌚', 318 | 'unlock': '🔓', 319 | 'lock': '🔒', 320 | 'lock_with_ink_pen': '🔏', 321 | 'closed_lock_with_key': '🔐', 322 | 'key': '🔑', 323 | 'mag_right': '🔎', 324 | 'bulb': '💡', 325 | 'flashlight': '🔦', 326 | 'electric_plug': '🔌', 327 | 'battery': '🔋', 328 | 'mag': '🔍', 329 | 'bath': '🛀', 330 | 'toilet': '🚽', 331 | 'wrench': '🔧', 332 | 'nut_and_bolt': '🔩', 333 | 'hammer': '🔨', 334 | 'door': '🚪', 335 | 'smoking': '🚬', 336 | 'bomb': '💣', 337 | 'gun': '🔫', 338 | 'hocho': '🔪', 339 | 'pill': '💊', 340 | 'syringe': '💉', 341 | 'moneybag': '💰', 342 | 'yen': '💴', 343 | 'dollar': '💵', 344 | 'credit_card': '💳', 345 | 'money_with_wings': '💸', 346 | 'calling': '📲', 347 | 'e-mail': '📧', 348 | 'inbox_tray': '📥', 349 | 'outbox_tray': '📤', 350 | 'envelope_with_arrow': '📩', 351 | 'incoming_envelope': '📨', 352 | 'mailbox': '📫', 353 | 'mailbox_closed': '📪', 354 | 'postbox': '📮', 355 | 'package': '📦', 356 | 'memo': '📝', 357 | 'page_facing_up': '📄', 358 | 'page_with_curl': '📃', 359 | 'bookmark_tabs': '📑', 360 | 'bar_chart': '📊', 361 | 'chart_with_upwards_trend': '📈', 362 | 'chart_with_downwards_trend': '📉', 363 | 'scroll': '📜', 364 | 'clipboard': '📋', 365 | 'date': '📅', 366 | 'calendar': '📆', 367 | 'card_index': '📇', 368 | 'file_folder': '📁', 369 | 'open_file_folder': '📂', 370 | 'pushpin': '📌', 371 | 'paperclip': '📎', 372 | 'straight_ruler': '📏', 373 | 'triangular_ruler': '📐', 374 | 'closed_book': '📕', 375 | 'green_book': '📗', 376 | 'blue_book': '📘', 377 | 'orange_book': '📙', 378 | 'notebook': '📓', 379 | 'notebook_with_decorative_cover': '📔', 380 | 'ledger': '📒', 381 | 'books': '📚', 382 | 'book': '📖', 383 | 'bookmark': '🔖', 384 | 'name_badge': '📛', 385 | 'newspaper': '📰', 386 | 'art': '🎨', 387 | 'clapper': '🎬', 388 | 'microphone': '🎤', 389 | 'headphones': '🎧', 390 | 'musical_score': '🎼', 391 | 'musical_note': '🎵', 392 | 'notes': '🎶', 393 | 'musical_keyboard': '🎹', 394 | 'violin': '🎻', 395 | 'trumpet': '🎺', 396 | 'saxophone': '🎷', 397 | 'guitar': '🎸', 398 | 'space_invader': '👾', 399 | 'video_game': '🎮', 400 | 'black_joker': '🃏', 401 | 'flower_playing_cards': '🎴', 402 | 'mahjong': '🀄', 403 | 'game_die': '🎲', 404 | 'dart': '🎯', 405 | 'football': '🏈', 406 | 'basketball': '🏀', 407 | 'soccer': '⚽', 408 | 'baseball': '⚾', 409 | 'tennis': '🎾', 410 | '8ball': '🎱', 411 | 'bowling': '🎳', 412 | 'golf': '⛳', 413 | 'checkered_flag': '🏁', 414 | 'trophy': '🏆', 415 | 'ski': '🎿', 416 | 'snowboarder': '🏂', 417 | 'swimmer': '🏊', 418 | 'surfer': '🏄', 419 | 'fishing_pole_and_fish': '🎣', 420 | 'tea': '🍵', 421 | 'sake': '🍶', 422 | 'beer': '🍺', 423 | 'beers': '🍻', 424 | 'cocktail': '🍸', 425 | 'tropical_drink': '🍹', 426 | 'wine_glass': '🍷', 427 | 'fork_and_knife': '🍴', 428 | 'pizza': '🍕', 429 | 'hamburger': '🍔', 430 | 'fries': '🍟', 431 | 'poultry_leg': '🍗', 432 | 'meat_on_bone': '🍖', 433 | 'spaghetti': '🍝', 434 | 'curry': '🍛', 435 | 'fried_shrimp': '🍤', 436 | 'bento': '🍱', 437 | 'sushi': '🍣', 438 | 'fish_cake': '🍥', 439 | 'rice_ball': '🍙', 440 | 'rice_cracker': '🍘', 441 | 'rice': '🍚', 442 | 'ramen': '🍜', 443 | 'stew': '🍲', 444 | 'oden': '🍢', 445 | 'dango': '🍡', 446 | 'egg': '🍳', 447 | 'bread': '🍞', 448 | 'doughnut': '🍩', 449 | 'custard': '🍮', 450 | 'icecream': '🍦', 451 | 'ice_cream': '🍨', 452 | 'shaved_ice': '🍧', 453 | 'birthday': '🎂', 454 | 'cake': '🍰', 455 | 'cookie': '🍪', 456 | 'chocolate_bar': '🍫', 457 | 'candy': '🍬', 458 | 'lollipop': '🍭', 459 | 'honey_pot': '🍯', 460 | 'apple': '🍎', 461 | 'green_apple': '🍏', 462 | 'tangerine': '🍊', 463 | 'cherries': '🍒', 464 | 'grapes': '🍇', 465 | 'watermelon': '🍉', 466 | 'strawberry': '🍓', 467 | 'peach': '🍑', 468 | 'melon': '🍈', 469 | 'banana': '🍌', 470 | 'pineapple': '🍍', 471 | 'sweet_potato': '🍠', 472 | 'eggplant': '🍆', 473 | 'tomato': '🍅', 474 | 'corn': '🌽', 475 | }, 476 | 'Places': { 477 | 'house': '🏠', 478 | 'house_with_garden': '🏡', 479 | 'school': '🏫', 480 | 'office': '🏢', 481 | 'post_office': '🏣', 482 | 'hospital': '🏥', 483 | 'bank': '🏦', 484 | 'convenience_store': '🏪', 485 | 'love_hotel': '🏩', 486 | 'hotel': '🏨', 487 | 'wedding': '💒', 488 | 'church': '⛪', 489 | 'department_store': '🏬', 490 | 'city_sunrise': '🌇', 491 | 'city_sunset': '🌆', 492 | 'japanese_castle': '🏯', 493 | 'european_castle': '🏰', 494 | 'tent': '⛺', 495 | 'factory': '🏭', 496 | 'tokyo_tower': '🗼', 497 | 'japan': '🗾', 498 | 'mount_fuji': '🗻', 499 | 'sunrise_over_mountains': '🌄', 500 | 'sunrise': '🌅', 501 | 'night_with_stars': '🌃', 502 | 'statue_of_liberty': '🗽', 503 | 'bridge_at_night': '🌉', 504 | 'carousel_horse': '🎠', 505 | 'ferris_wheel': '🎡', 506 | 'fountain': '⛲', 507 | 'roller_coaster': '🎢', 508 | 'ship': '🚢', 509 | 'boat': '⛵', 510 | 'speedboat': '🚤', 511 | 'rocket': '🚀', 512 | 'seat': '💺', 513 | 'station': '🚉', 514 | 'bullettrain_side': '🚄', 515 | 'bullettrain_front': '🚅', 516 | 'metro': '🚇', 517 | 'railway_car': '🚃', 518 | 'bus': '🚌', 519 | 'blue_car': '🚙', 520 | 'car': '🚗', 521 | 'taxi': '🚕', 522 | 'truck': '🚚', 523 | 'rotating_light': '🚨', 524 | 'police_car': '🚓', 525 | 'fire_engine': '🚒', 526 | 'ambulance': '🚑', 527 | 'bike': '🚲', 528 | 'barber': '💈', 529 | 'busstop': '🚏', 530 | 'ticket': '🎫', 531 | 'traffic_light': '🚥', 532 | 'construction': '🚧', 533 | 'beginner': '🔰', 534 | 'fuelpump': '⛽', 535 | 'izakaya_lantern': '🏮', 536 | 'slot_machine': '🎰', 537 | 'moyai': '🗿', 538 | 'circus_tent': '🎪', 539 | 'performing_arts': '🎭', 540 | 'round_pushpin': '📍', 541 | 'triangular_flag_on_post': '🚩', 542 | }, 543 | 'Symbols': { 544 | 'keycap_ten': '🔟', 545 | '1234': '🔢', 546 | 'symbols': '🔣', 547 | 'capital_abcd': '🔠', 548 | 'abcd': '🔡', 549 | 'abc': '🔤', 550 | 'arrow_up_small': '🔼', 551 | 'arrow_down_small': '🔽', 552 | 'rewind': '⏪', 553 | 'fast_forward': '⏩', 554 | 'arrow_double_up': '⏫', 555 | 'arrow_double_down': '⏬', 556 | 'ok': '🆗', 557 | 'new': '🆕', 558 | 'up': '🆙', 559 | 'cool': '🆒', 560 | 'free': '🆓', 561 | 'ng': '🆖', 562 | 'signal_strength': '📶', 563 | 'cinema': '🎦', 564 | 'koko': '🈁', 565 | 'u6307': '🈯', 566 | 'u7a7a': '🈳', 567 | 'u6e80': '🈵', 568 | 'u5408': '🈴', 569 | 'u7981': '🈲', 570 | 'ideograph_advantage': '🉐', 571 | 'u5272': '🈹', 572 | 'u55b6': '🈺', 573 | 'u6709': '🈶', 574 | 'u7121': '🈚', 575 | 'restroom': '🚻', 576 | 'mens': '🚹', 577 | 'womens': '🚺', 578 | 'baby_symbol': '🚼', 579 | 'wc': '🚾', 580 | 'no_smoking': '🚭', 581 | 'u7533': '🈸', 582 | 'accept': '🉑', 583 | 'cl': '🆑', 584 | 'sos': '🆘', 585 | 'id': '🆔', 586 | 'no_entry_sign': '🚫', 587 | 'underage': '🔞', 588 | 'no_entry': '⛔', 589 | 'negative_squared_cross_mark': '❎', 590 | 'white_check_mark': '✅', 591 | 'heart_decoration': '💟', 592 | 'vs': '🆚', 593 | 'vibration_mode': '📳', 594 | 'mobile_phone_off': '📴', 595 | 'ab': '🆎', 596 | 'diamond_shape_with_a_dot_inside': '💠', 597 | 'ophiuchus': '⛎', 598 | 'six_pointed_star': '🔯', 599 | 'atm': '🏧', 600 | 'chart': '💹', 601 | 'heavy_dollar_sign': '💲', 602 | 'currency_exchange': '💱', 603 | 'x': '❌', 604 | 'exclamation': '❗', 605 | 'question': '❓', 606 | 'grey_exclamation': '❕', 607 | 'grey_question': '❔', 608 | 'o': '⭕', 609 | 'top': '🔝', 610 | 'end': '🔚', 611 | 'back': '🔙', 612 | 'on': '🔛', 613 | 'soon': '🔜', 614 | 'arrows_clockwise': '🔃', 615 | 'clock12': '🕛', 616 | 'clock1': '🕐', 617 | 'clock2': '🕑', 618 | 'clock3': '🕒', 619 | 'clock4': '🕓', 620 | 'clock5': '🕔', 621 | 'clock6': '🕕', 622 | 'clock7': '🕖', 623 | 'clock8': '🕗', 624 | 'clock9': '🕘', 625 | 'clock10': '🕙', 626 | 'clock11': '🕚', 627 | 'heavy_plus_sign': '➕', 628 | 'heavy_minus_sign': '➖', 629 | 'heavy_division_sign': '➗', 630 | 'white_flower': '💮', 631 | '100': '💯', 632 | 'radio_button': '🔘', 633 | 'link': '🔗', 634 | 'curly_loop': '➰', 635 | 'trident': '🔱', 636 | 'small_red_triangle': '🔺', 637 | 'black_square_button': '🔲', 638 | 'white_square_button': '🔳', 639 | 'red_circle': '🔴', 640 | 'large_blue_circle': '🔵', 641 | 'small_red_triangle_down': '🔻', 642 | 'white_large_square': '⬜', 643 | 'black_large_square': '⬛', 644 | 'large_orange_diamond': '🔶', 645 | 'large_blue_diamond': '🔷', 646 | 'small_orange_diamond': '🔸', 647 | 'small_blue_diamond': '🔹', 648 | }, 649 | } as const 650 | -------------------------------------------------------------------------------- /src/entry.esm.ts: -------------------------------------------------------------------------------- 1 | import _Vue, { PluginObject } from 'vue' 2 | import EmojiPicker from '@/EmojiPicker.vue' 3 | 4 | type InstallableComponent = typeof EmojiPicker & PluginObject 5 | 6 | export { EmojiPicker } 7 | 8 | export default /*#__PURE__*/((): InstallableComponent => { 9 | const installable = EmojiPicker as unknown as InstallableComponent 10 | 11 | installable.install = (Vue: typeof _Vue) => { 12 | Vue.component('EmojiPicker', installable) 13 | } 14 | 15 | return installable 16 | })() 17 | -------------------------------------------------------------------------------- /src/entry.ts: -------------------------------------------------------------------------------- 1 | import component, * as namedExports from '@/entry.esm' 2 | 3 | Object.entries(namedExports).forEach(([exportName, exported]) => { 4 | if (exportName !== 'default') component[exportName] = exported 5 | }) 6 | 7 | export default component as typeof component & Exclude 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "strict": true, 6 | "declaration": true, 7 | "declarationDir": "dist/types", 8 | "noUnusedLocals": true, 9 | "noUnusedParameters": true, 10 | "importHelpers": true, 11 | "moduleResolution": "node", 12 | "experimentalDecorators": true, 13 | "esModuleInterop": true, 14 | "allowSyntheticDefaultImports": true, 15 | "sourceMap": true, 16 | "baseUrl": ".", 17 | "newLine": "lf", 18 | "types": [ 19 | "node", 20 | "vue" 21 | ], 22 | "paths": { 23 | "@/*": [ 24 | "src/*" 25 | ] 26 | }, 27 | "plugins": [ 28 | { 29 | "transform":"@zerollup/ts-transform-paths", 30 | "exclude": ["*"] 31 | } 32 | ], 33 | "lib": [ 34 | "esnext", 35 | "dom", 36 | "dom.iterable", 37 | "scripthost" 38 | ] 39 | }, 40 | "exclude": [ 41 | "node_modules", 42 | "dist" 43 | ] 44 | } 45 | --------------------------------------------------------------------------------