diff --git a/.eslintrc.js b/.eslintrc.js index bacfcf1..4dea87a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,24 +1,27 @@ module.exports = { - "parser": "@typescript-eslint/parser", - "env": { - "browser": true, - "es6": true, - "node": true, - "jest": true - }, - "extends": ["eslint:recommended", "plugin:prettier/recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended"], - "globals": { - "Atomics": "readonly", - "SharedArrayBuffer": "readonly" - }, - "parserOptions": { - "ecmaVersion": 2018, - "sourceType": "module" - }, - "rules": { - "no-console": "error" - }, - "plugins": [ - "@typescript-eslint" - ] -}; \ No newline at end of file + parser: '@typescript-eslint/parser', + env: { + browser: true, + es6: true, + node: true, + jest: true + }, + extends: [ + 'eslint:recommended', + 'plugin:prettier/recommended', + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended' + ], + globals: { + Atomics: 'readonly', + SharedArrayBuffer: 'readonly' + }, + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module' + }, + rules: { + 'no-console': 'error' + }, + plugins: ['@typescript-eslint'] +}; diff --git a/.prettierrc b/.prettierrc index 92cde39..6450e3d 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,3 +1,5 @@ { - "singleQuote": true + "arrowParens": "avoid", + "singleQuote": true, + "trailingComma": "none" } \ No newline at end of file diff --git a/examples/src/index.js b/examples/src/index.js index 725ec4b..3f99fbe 100644 --- a/examples/src/index.js +++ b/examples/src/index.js @@ -1,6 +1,6 @@ hljs.initHighlightingOnLoad(); -var EmojiButton = require('@joeattardi/emoji-button'); +import { EmojiButton } from '@joeattardi/emoji-button'; window.addEventListener('DOMContentLoaded', function () { var button = document.querySelector('#native-button'); diff --git a/src/categoryButtons.test.ts b/src/categoryButtons.test.ts index c8a64a0..c294def 100644 --- a/src/categoryButtons.test.ts +++ b/src/categoryButtons.test.ts @@ -40,7 +40,7 @@ describe('CategoryButtons', () => { test('should only render specified categories if they are specified', () => { const container = new CategoryButtons( { - categories: ['smileys', 'animals'], + categories: ['smileys', 'animals'] }, emitter, i18n @@ -56,7 +56,7 @@ describe('CategoryButtons', () => { const container = new CategoryButtons( { categories: ['smileys', 'animals'], - showRecents: true, + showRecents: true }, emitter, i18n diff --git a/src/categoryButtons.ts b/src/categoryButtons.ts index ed01e45..07015b0 100644 --- a/src/categoryButtons.ts +++ b/src/categoryButtons.ts @@ -22,7 +22,7 @@ const categoryIcons: { [key in I18NCategory]: string } = { travel: icons.building, objects: icons.lightbulb, symbols: icons.music, - flags: icons.flag, + flags: icons.flag }; export class CategoryButtons { @@ -56,7 +56,7 @@ export class CategoryButtons { }); }); - container.addEventListener('keydown', (event) => { + container.addEventListener('keydown', event => { switch (event.key) { case 'ArrowRight': this.events.emit( diff --git a/src/emoji.test.ts b/src/emoji.test.ts index 91887a2..323aa3a 100644 --- a/src/emoji.test.ts +++ b/src/emoji.test.ts @@ -11,7 +11,7 @@ describe('Emoji', () => { emoji: '😄', name: 'smile', category: 0, - version: '11.0', + version: '11.0' }; const options: EmojiButtonOptions = { showRecents: true, style: 'native' }; @@ -24,15 +24,15 @@ describe('Emoji', () => { expect(element.innerHTML).toEqual(testEmoji.emoji); }); - test('should emit the EMOJI event when clicked', (done) => { + test('should emit the EMOJI event when clicked', done => { const emoji = new Emoji(testEmoji, false, false, events, options); const element = emoji.render(); - events.on(EMOJI, (e) => { + events.on(EMOJI, e => { expect(e).toEqual({ emoji: testEmoji, showVariants: false, - button: element, + button: element }); done(); }); @@ -40,11 +40,11 @@ describe('Emoji', () => { element.dispatchEvent(new MouseEvent('click')); }); - test('should emit the SHOW_PREVIEW event on mouseover if showPreview is true', (done) => { + test('should emit the SHOW_PREVIEW event on mouseover if showPreview is true', done => { const emoji = new Emoji(testEmoji, false, true, events, options); const element = emoji.render(); - events.on(SHOW_PREVIEW, (e) => { + events.on(SHOW_PREVIEW, e => { expect(e).toEqual(testEmoji); done(); }); @@ -52,7 +52,7 @@ describe('Emoji', () => { element.dispatchEvent(new MouseEvent('mouseover')); }); - test('should emit the HIDE_PREVIEW event on mouseout if showPreview is true', (done) => { + test('should emit the HIDE_PREVIEW event on mouseout if showPreview is true', done => { const emoji = new Emoji(testEmoji, false, true, events, options); const element = emoji.render(); diff --git a/src/emoji.ts b/src/emoji.ts index 3af83ad..c298891 100644 --- a/src/emoji.ts +++ b/src/emoji.ts @@ -12,7 +12,7 @@ const CLASS_EMOJI = 'emoji-picker__emoji'; // Options for twemoji.parse(emoji, twemojiOptions) const twemojiOptions = { ext: '.svg', - folder: 'svg', + folder: 'svg' }; export class Emoji { @@ -59,7 +59,7 @@ export class Emoji { this.events.emit(EMOJI, { emoji: this.emoji, showVariants: this.showVariants, - button: this.emojiButton, + button: this.emojiButton }); } diff --git a/src/emojiArea.test.ts b/src/emojiArea.test.ts index cee86c4..be31bb4 100644 --- a/src/emojiArea.test.ts +++ b/src/emojiArea.test.ts @@ -10,7 +10,7 @@ const emitter = new Emitter(); describe('EmojiArea', () => { test('renders an emoji list for each category', () => { const emojiArea = new EmojiArea(emitter, i18n, { - emojiVersion: '11.0', + emojiVersion: '11.0' }).render(); const containers = emojiArea.querySelectorAll('.emoji-picker__container'); @@ -28,7 +28,7 @@ describe('EmojiArea', () => { test('only renders emoji lists for specified categories', () => { const emojiArea = new EmojiArea(emitter, i18n, { emojiVersion: '11.0', - categories: ['smileys', 'animals'], + categories: ['smileys', 'animals'] }).render(); const containers = emojiArea.querySelectorAll('.emoji-picker__container'); @@ -48,7 +48,7 @@ describe('EmojiArea', () => { const emojiArea = new EmojiArea(emitter, i18n, { emojiVersion: '11.0', categories: ['smileys', 'animals'], - showRecents: true, + showRecents: true }).render(); const containers = emojiArea.querySelectorAll('.emoji-picker__container'); diff --git a/src/emojiArea.ts b/src/emojiArea.ts index ca60914..41deadb 100644 --- a/src/emojiArea.ts +++ b/src/emojiArea.ts @@ -11,13 +11,13 @@ import { I18NStrings, EmojiButtonOptions, EmojiRecord, - RecentEmoji, + RecentEmoji } from './types'; import { createElement } from './util'; import { load } from './recent'; const emojiCategories: { [key: string]: EmojiRecord[] } = {}; -emojiData.emoji.forEach((emoji) => { +emojiData.emoji.forEach(emoji => { let categoryList = emojiCategories[emojiData.categories[emoji.category]]; if (!categoryList) { categoryList = emojiCategories[emojiData.categories[emoji.category]] = []; @@ -69,14 +69,14 @@ export class EmojiArea { emojiCategories.recents = load(); } - this.categories.forEach((category) => + this.categories.forEach(category => this.addCategory(category, emojiCategories[category]) ); requestAnimationFrame(() => { this.headerOffsets = Array.prototype.map.call( this.headers, - (header) => header.offsetTop + header => header.offsetTop ) as number[]; this.selectCategory('smileys', false); @@ -271,7 +271,7 @@ export class EmojiArea { return; } let closestHeaderIndex = this.headerOffsets.findIndex( - (offset) => offset > Math.round(this.emojis.scrollTop) + offset => offset > Math.round(this.emojis.scrollTop) ); if (closestHeaderIndex === 0) { diff --git a/src/emojiContainer.test.ts b/src/emojiContainer.test.ts index f4081b0..1938379 100644 --- a/src/emojiContainer.test.ts +++ b/src/emojiContainer.test.ts @@ -6,13 +6,13 @@ describe('EmojiContainer', () => { test('should render all the given emojis', () => { const emojis = [ { emoji: '⚡️', version: '12.1', name: 'zap', category: 0 }, - { emoji: '👍', version: '12.1', name: 'thumbs up', category: 0 }, + { emoji: '👍', version: '12.1', name: 'thumbs up', category: 0 } ]; const events = new Emitter(); const container = new EmojiContainer(emojis, false, events, { - emojiVersion: '12.1', + emojiVersion: '12.1' }).render(); expect(container.querySelectorAll('.emoji-picker__emoji').length).toBe(2); }); diff --git a/src/emojiContainer.ts b/src/emojiContainer.ts index 3451482..a6f87aa 100644 --- a/src/emojiContainer.ts +++ b/src/emojiContainer.ts @@ -17,7 +17,7 @@ export class EmojiContainer { private options: EmojiButtonOptions ) { this.emojis = emojis.filter( - (e) => + e => !(e as EmojiRecord).version || parseFloat((e as EmojiRecord).version as string) <= parseFloat(options.emojiVersion as string) @@ -26,7 +26,7 @@ export class EmojiContainer { render(): HTMLElement { const emojiContainer = createElement('div', CLASS_EMOJI_CONTAINER); - this.emojis.forEach((emoji) => + this.emojis.forEach(emoji => emojiContainer.appendChild( new Emoji( emoji, diff --git a/src/i18n.ts b/src/i18n.ts index aaaaa18..fdda660 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -12,7 +12,7 @@ export const i18n: I18NStrings = { travel: 'Travel & Places', objects: 'Objects', symbols: 'Symbols', - flags: 'Flags', + flags: 'Flags' }, - notFound: 'No emojis found', + notFound: 'No emojis found' }; diff --git a/src/icons.ts b/src/icons.ts index 6c16ebe..168e55a 100644 --- a/src/icons.ts +++ b/src/icons.ts @@ -7,14 +7,14 @@ import { faMusic, faSearch, faTimes, - faUser, + faUser } from '@fortawesome/free-solid-svg-icons'; import { faBuilding, faFlag, faFrown, faLightbulb, - faSmile, + faSmile } from '@fortawesome/free-regular-svg-icons'; library.add( diff --git a/src/index.ts b/src/index.ts index 349d67b..d2f9559 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,7 +11,7 @@ import { EMOJI, SHOW_SEARCH_RESULTS, HIDE_SEARCH_RESULTS, - HIDE_VARIANT_POPUP, + HIDE_VARIANT_POPUP } from './events'; import { EmojiPreview } from './preview'; import { Search } from './search'; @@ -29,7 +29,7 @@ const CLASS_PICKER_CONTENT = 'emoji-picker__content'; // Options for twemoji.parse(emoji, twemojiOptions) const twemojiOptions = { ext: '.svg', - folder: 'svg', + folder: 'svg' }; const DEFAULT_OPTIONS: EmojiButtonOptions = { @@ -53,15 +53,15 @@ const DEFAULT_OPTIONS: EmojiButtonOptions = { 'travel', 'objects', 'symbols', - 'flags', + 'flags' ], style: 'native', emojisPerRow: 8, rows: 6, - emojiSize: '1.8em', + emojiSize: '1.8em' }; -export default class EmojiButton { +export class EmojiButton { pickerVisible: boolean; private events = new Emitter(); @@ -90,7 +90,7 @@ export default class EmojiButton { this.i18n = { ...i18n, - ...options.i18n, + ...options.i18n }; this.onDocumentClick = this.onDocumentClick.bind(this); @@ -131,7 +131,7 @@ export default class EmojiButton { initialFocus: this.options.showSearch && this.options.autoFocusSearch ? '.emoji-picker__search' - : '.emoji-picker__emoji[tabindex="0"]', + : '.emoji-picker__emoji[tabindex="0"]' }); const pickerContent = createElement('div', CLASS_PICKER_CONTENT); @@ -142,7 +142,7 @@ export default class EmojiButton { this.i18n, this.options, emojiData.emoji, - (this.options.categories || []).map((category) => + (this.options.categories || []).map(category => emojiData.categories.indexOf(category) ) ).render(); @@ -183,7 +183,7 @@ export default class EmojiButton { EMOJI, ({ emoji, - showVariants, + showVariants }: { emoji: EmojiRecord; showVariants: boolean; @@ -319,7 +319,7 @@ export default class EmojiButton { document.body.appendChild(this.overlay); } else { this.popper = createPopper(referenceEl, this.wrapper, { - placement: options.position || this.options.position, + placement: options.position || this.options.position }); } diff --git a/src/preview.ts b/src/preview.ts index 6a619a0..13f1fd6 100644 --- a/src/preview.ts +++ b/src/preview.ts @@ -13,7 +13,7 @@ const CLASS_PREVIEW_NAME = 'emoji-picker__preview-name'; // Options for twemoji.parse(emoji, twemojiOptions) const twemojiOptions = { ext: '.svg', - folder: 'svg', + folder: 'svg' }; export class EmojiPreview { diff --git a/src/recent.ts b/src/recent.ts index e151acc..e9556cd 100644 --- a/src/recent.ts +++ b/src/recent.ts @@ -5,7 +5,7 @@ const LOCAL_STORAGE_KEY = 'emojiPicker.recent'; export function load(): Array { const recentJson = localStorage.getItem(LOCAL_STORAGE_KEY); const recents = recentJson ? JSON.parse(recentJson) : []; - return recents.filter((recent) => !!recent.emoji); + return recents.filter(recent => !!recent.emoji); } export function save( @@ -17,7 +17,7 @@ export function save( const recent = { emoji: emoji.emoji, name: emoji.name, - key: (emoji as RecentEmoji).key || emoji.name, + key: (emoji as RecentEmoji).key || emoji.name }; localStorage.setItem( @@ -25,9 +25,7 @@ export function save( JSON.stringify( [ recent, - ...recents.filter( - (r: RecentEmoji) => !!r.emoji && r.key !== recent.key - ), + ...recents.filter((r: RecentEmoji) => !!r.emoji && r.key !== recent.key) ].slice(0, options.recentsCount) ) ); diff --git a/src/search.test.ts b/src/search.test.ts index 22ba529..c5ede10 100644 --- a/src/search.test.ts +++ b/src/search.test.ts @@ -9,7 +9,7 @@ import { EmojiButtonOptions, EmojiRecord } from './types'; describe('Search', () => { const emojis: EmojiRecord[] = [ { category: 0, emoji: '⚡️', name: 'zap', version: '12.1' }, - { category: 1, emoji: '😀', name: 'grinning', version: '12.1' }, + { category: 1, emoji: '😀', name: 'grinning', version: '12.1' } ]; const options: EmojiButtonOptions = { emojiVersion: '12.1', style: 'native' }; @@ -23,8 +23,8 @@ describe('Search', () => { searchField = search.querySelector('.emoji-picker__search'); }); - test('should render search results', (done) => { - events.on(SHOW_SEARCH_RESULTS, (searchResultsContainer) => { + test('should render search results', done => { + events.on(SHOW_SEARCH_RESULTS, searchResultsContainer => { const searchResults = searchResultsContainer.querySelectorAll( '.emoji-picker__emoji' ); @@ -37,9 +37,9 @@ describe('Search', () => { searchField.dispatchEvent(new KeyboardEvent('keyup')); }); - test('should not show search results for the unselected categories', (done) => { + test('should not show search results for the unselected categories', done => { search = new Search(events, i18n, options, emojis, [0]).render(); - events.on(SHOW_SEARCH_RESULTS, (searchResultsContainer) => { + events.on(SHOW_SEARCH_RESULTS, searchResultsContainer => { const searchResults = searchResultsContainer.querySelectorAll( '.emoji-picker__emoji' ); @@ -51,8 +51,8 @@ describe('Search', () => { searchField.dispatchEvent(new KeyboardEvent('keyup')); }); - test('should render a not found message when there are no results', (done) => { - events.on(SHOW_SEARCH_RESULTS, (searchResultsContainer) => { + test('should render a not found message when there are no results', done => { + events.on(SHOW_SEARCH_RESULTS, searchResultsContainer => { expect( searchResultsContainer.classList.contains( 'emoji-picker__search-not-found' diff --git a/src/search.ts b/src/search.ts index 1a06280..232520b 100644 --- a/src/search.ts +++ b/src/search.ts @@ -7,7 +7,7 @@ import { HIDE_PREVIEW, HIDE_VARIANT_POPUP, SHOW_SEARCH_RESULTS, - HIDE_SEARCH_RESULTS, + HIDE_SEARCH_RESULTS } from './events'; import { createElement } from './util'; import { I18NStrings, EmojiButtonOptions, EmojiRecord } from './types'; @@ -55,7 +55,7 @@ export class Search { ) { this.emojisPerRow = this.options.emojisPerRow || 8; this.emojiData = emojiData.filter( - (e) => + e => e.version && parseFloat(e.version) <= parseFloat(options.emojiVersion as string) && e.category !== undefined && @@ -166,7 +166,7 @@ export class Search { this.searchIcon.innerHTML = icons.times; this.searchIcon.style.cursor = 'pointer'; const searchResults = this.emojiData.filter( - (emoji) => + emoji => emoji.name .toLowerCase() .indexOf(this.searchField.value.toLowerCase()) >= 0 @@ -188,7 +188,7 @@ export class Search { ) as HTMLElement).tabIndex = 0; this.focusedEmojiIndex = 0; - this.resultsContainer.addEventListener('keydown', (event) => + this.resultsContainer.addEventListener('keydown', event => this.handleResultsKeydown(event) ); diff --git a/src/variantPopup.test.ts b/src/variantPopup.test.ts index 1477195..9129abb 100644 --- a/src/variantPopup.test.ts +++ b/src/variantPopup.test.ts @@ -8,7 +8,7 @@ describe('VariantPopup', () => { category: 0, emoji: '👍', variations: ['👍🏻', '👍🏿'], - version: '11.0', + version: '11.0' }; let events; diff --git a/src/variantPopup.ts b/src/variantPopup.ts index a6962c7..34fbe2c 100644 --- a/src/variantPopup.ts +++ b/src/variantPopup.ts @@ -60,7 +60,7 @@ export class VariantPopup { { name: this.emoji.name, emoji: variation, - key: this.emoji.name + index, + key: this.emoji.name + index }, false, false, @@ -78,7 +78,7 @@ export class VariantPopup { setTimeout(() => firstEmoji.focus()); - this.popup.addEventListener('keydown', (event) => { + this.popup.addEventListener('keydown', event => { if (event.key === 'ArrowRight') { this.setFocusedEmoji( Math.min(