Restructure data and components
parent
2f5fe6164e
commit
2e97b1faa6
|
@ -3,4 +3,3 @@ dist/
|
||||||
dist-es/
|
dist-es/
|
||||||
stats.json
|
stats.json
|
||||||
report.html
|
report.html
|
||||||
/src/data/data.js
|
|
||||||
|
|
65
README.md
65
README.md
|
@ -73,32 +73,36 @@ categories: {
|
||||||
#### Sheet sizes
|
#### Sheet sizes
|
||||||
Sheets are served from [unpkg](https://unpkg.com), a global CDN that serves files published to [npm](https://www.npmjs.com).
|
Sheets are served from [unpkg](https://unpkg.com), a global CDN that serves files published to [npm](https://www.npmjs.com).
|
||||||
|
|
||||||
| Set | sheetSize | Size |
|
| Set | Size (`sheetSize: 16`) | Size (`sheetSize: 20`) | Size (`sheetSize: 32`) | Size (`sheetSize: 64`) |
|
||||||
| --------- | --------- | -------- |
|
| --------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- |
|
||||||
| apple | 16 | 334 KB |
|
| apple | 334 KB | 459 KB | 1.08 MB | 2.94 MB |
|
||||||
| apple | 20 | 459 KB |
|
| emojione | 315 KB | 435 KB | 1020 KB | 2.33 MB |
|
||||||
| apple | 32 | 1.08 MB |
|
| facebook | 322 KB | 439 KB | 1020 KB | 2.50 MB |
|
||||||
| apple | 64 | 2.94 MB |
|
| google | 301 KB | 409 KB | 907 KB | 2.17 MB |
|
||||||
| emojione | 16 | 315 KB |
|
| messenger | 325 KB | 449 MB | 1.05 MB | 2.69 MB |
|
||||||
| emojione | 20 | 435 KB |
|
| twitter | 288 KB | 389 KB | 839 KB | 1.82 MB |
|
||||||
| emojione | 32 | 1020 KB |
|
|
||||||
| emojione | 64 | 2.33 MB |
|
#### Datasets
|
||||||
| facebook | 16 | 322 KB |
|
While all sets are available by default, you may want to include only a single set data to reduce the size of your bundle.
|
||||||
| facebook | 20 | 439 KB |
|
|
||||||
| facebook | 32 | 1020 KB |
|
| Set | Size |
|
||||||
| facebook | 64 | 2.5 MB |
|
| --------- | ------ |
|
||||||
| google | 16 | 301 KB |
|
| all | 551 KB |
|
||||||
| google | 20 | 409 KB |
|
| apple | 465 KB |
|
||||||
| google | 32 | 907 KB |
|
| emojione | 226 KB |
|
||||||
| google | 64 | 2.17 MB |
|
| facebook | 405 KB |
|
||||||
| messenger | 16 | 325 KB |
|
| google | 450 KB |
|
||||||
| messenger | 20 | 449 MB |
|
| messenger | 197 KB |
|
||||||
| messenger | 32 | 1.05 MB |
|
| twitter | 466 KB |
|
||||||
| messenger | 64 | 2.69 MB |
|
|
||||||
| twitter | 16 | 288 KB |
|
To use these data files (or any other custom data), use the `NimblePicker` component:
|
||||||
| twitter | 20 | 389 KB |
|
|
||||||
| twitter | 32 | 839 KB |
|
```js
|
||||||
| twitter | 64 | 1.82 MB |
|
import data from 'emoji-mart/data/messenger.json'
|
||||||
|
import { NimblePicker } from 'emoji-mart'
|
||||||
|
|
||||||
|
<NimblePicker set='messenger' data={data} />
|
||||||
|
```
|
||||||
|
|
||||||
#### Examples of `emoji` object:
|
#### Examples of `emoji` object:
|
||||||
```js
|
```js
|
||||||
|
@ -240,6 +244,15 @@ emojiIndex.search('christmas').map((o) => o.native)
|
||||||
// => [🎄, 🎅🏼, 🔔, 🎁, ⛄️, ❄️]
|
// => [🎄, 🎅🏼, 🔔, 🎁, ⛄️, ❄️]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### With custom data
|
||||||
|
```js
|
||||||
|
import data from 'emoji-mart/datasets/messenger'
|
||||||
|
import { NimbleEmojiIndex } from 'emoji-mart'
|
||||||
|
|
||||||
|
let emojiIndex = new NimbleEmojiIndex(data)
|
||||||
|
emojiIndex.search('christmas')
|
||||||
|
```
|
||||||
|
|
||||||
## Storage
|
## Storage
|
||||||
By default EmojiMart will store user chosen skin and frequently used emojis in `localStorage`. That can however be overwritten should you want to store these in your own storage.
|
By default EmojiMart will store user chosen skin and frequently used emojis in `localStorage`. That can however be overwritten should you want to store these in your own storage.
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -60,13 +60,13 @@
|
||||||
"webpack": "^3.6.0"
|
"webpack": "^3.6.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rm -rf dist/ dist-es/ src/data/data.js",
|
"clean": "rm -rf dist/ dist-es/",
|
||||||
"build:data": "node scripts/build-data",
|
"build:data": "node scripts/build-data",
|
||||||
"build:dist": "npm run build:cjs && npm run build:es",
|
"build:dist": "npm run build:cjs && npm run build:es",
|
||||||
"build:cjs": "BABEL_ENV=cjs babel src --out-dir dist --copy-files",
|
"build:cjs": "BABEL_ENV=cjs babel src --out-dir dist --copy-files",
|
||||||
"build:es": "babel src --out-dir dist-es --copy-files",
|
"build:es": "babel src --out-dir dist-es --copy-files",
|
||||||
"build:docs": "cp css/emoji-mart.css docs && webpack --config ./docs/webpack.config.js",
|
"build:docs": "cp css/emoji-mart.css docs && webpack --config ./docs/webpack.config.js",
|
||||||
"build": "npm run clean && npm run build:data && npm run build:dist",
|
"build": "npm run clean && npm run build:dist",
|
||||||
"watch": "BABEL_ENV=cjs babel src --watch --out-dir dist --copy-files",
|
"watch": "BABEL_ENV=cjs babel src --watch --out-dir dist --copy-files",
|
||||||
"start": "npm run watch",
|
"start": "npm run watch",
|
||||||
"stats": "webpack --config ./spec/webpack.config.js --json > spec/stats.json",
|
"stats": "webpack --config ./spec/webpack.config.js --json > spec/stats.json",
|
||||||
|
|
|
@ -1,112 +1,11 @@
|
||||||
var fs = require('fs'),
|
const build = require('./build')
|
||||||
emojiData = require('emoji-datasource'),
|
const sets = ['apple', 'emojione', 'facebook', 'google', 'messenger', 'twitter']
|
||||||
emojiLib = require('emojilib'),
|
|
||||||
inflection = require('inflection'),
|
|
||||||
mkdirp = require('mkdirp')
|
|
||||||
|
|
||||||
var data = { categories: [], emojis: {}, skins: {}, aliases: {} },
|
build({ output: 'data/all.json' })
|
||||||
categoriesIndex = {}
|
|
||||||
|
|
||||||
var categories = [
|
sets.forEach((set) => {
|
||||||
['Smileys & People', 'people'],
|
build({
|
||||||
['Animals & Nature', 'nature'],
|
output: `data/${set}.json`,
|
||||||
['Food & Drink', 'foods'],
|
sets: [set],
|
||||||
['Activities', 'activity'],
|
|
||||||
['Travel & Places', 'places'],
|
|
||||||
['Objects', 'objects'],
|
|
||||||
['Symbols', 'symbols'],
|
|
||||||
['Flags', 'flags'],
|
|
||||||
]
|
|
||||||
|
|
||||||
categories.forEach((category, i) => {
|
|
||||||
let [name, id] = category
|
|
||||||
data.categories[i] = { id: id, name: name, emojis: [] }
|
|
||||||
categoriesIndex[name] = i
|
|
||||||
})
|
|
||||||
|
|
||||||
emojiData.sort((a, b) => {
|
|
||||||
var aTest = a.sort_order || a.short_name,
|
|
||||||
bTest = b.sort_order || b.short_name
|
|
||||||
|
|
||||||
return aTest - bTest
|
|
||||||
})
|
|
||||||
|
|
||||||
emojiData.forEach((datum) => {
|
|
||||||
var category = datum.category,
|
|
||||||
keywords = [],
|
|
||||||
categoryIndex
|
|
||||||
|
|
||||||
if (!datum.category) {
|
|
||||||
throw new Error('“' + datum.short_name + '” doesn’t have a category')
|
|
||||||
}
|
|
||||||
|
|
||||||
datum.name || (datum.name = datum.short_name.replace(/\-/g, ' '))
|
|
||||||
datum.name = inflection.titleize(datum.name || '')
|
|
||||||
|
|
||||||
if (!datum.name) {
|
|
||||||
throw new Error('“' + datum.short_name + '” doesn’t have a name')
|
|
||||||
}
|
|
||||||
|
|
||||||
datum.emoticons = datum.texts || []
|
|
||||||
datum.text = datum.text || ''
|
|
||||||
delete datum.texts
|
|
||||||
|
|
||||||
if (emojiLib.lib[datum.short_name]) {
|
|
||||||
datum.keywords = emojiLib.lib[datum.short_name].keywords
|
|
||||||
}
|
|
||||||
|
|
||||||
if (datum.category == 'Skin Tones') {
|
|
||||||
data.skins[datum.short_name] = datum
|
|
||||||
} else {
|
|
||||||
categoryIndex = categoriesIndex[category]
|
|
||||||
data.categories[categoryIndex].emojis.push(datum.short_name)
|
|
||||||
data.emojis[datum.short_name] = datum
|
|
||||||
}
|
|
||||||
|
|
||||||
datum.short_names.forEach((short_name, i) => {
|
|
||||||
if (i == 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data.aliases[short_name] = datum.short_name
|
|
||||||
})
|
})
|
||||||
|
|
||||||
datum.short_names = datum.short_names.filter((i) => i !== datum.short_name)
|
|
||||||
datum.sheet = [datum.sheet_x, datum.sheet_y]
|
|
||||||
|
|
||||||
if (datum.text === '') delete datum.text
|
|
||||||
if (datum.added_in === '6.0') delete datum.added_in
|
|
||||||
|
|
||||||
delete datum.docomo
|
|
||||||
delete datum.au
|
|
||||||
delete datum.softbank
|
|
||||||
delete datum.google
|
|
||||||
delete datum.image
|
|
||||||
delete datum.short_name
|
|
||||||
delete datum.category
|
|
||||||
delete datum.sort_order
|
|
||||||
delete datum.sheet_x
|
|
||||||
delete datum.sheet_y
|
|
||||||
|
|
||||||
for (let key in datum) {
|
|
||||||
let value = datum[key]
|
|
||||||
|
|
||||||
if (Array.isArray(value) && !value.length) {
|
|
||||||
delete datum[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
var flags = data.categories[categoriesIndex['Flags']]
|
|
||||||
flags.emojis = flags.emojis
|
|
||||||
.filter((flag) => {
|
|
||||||
// Until browsers support Flag UN
|
|
||||||
if (flag == 'flag-un') return
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
.sort()
|
|
||||||
|
|
||||||
const stringified = JSON.stringify(data).replace(/\"([A-Za-z_]+)\":/g, '$1:')
|
|
||||||
fs.writeFile('src/data/data.js', `export default ${stringified}`, (err) => {
|
|
||||||
if (err) throw err
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
var fs = require('fs'),
|
||||||
|
emojiLib = require('emojilib'),
|
||||||
|
inflection = require('inflection'),
|
||||||
|
mkdirp = require('mkdirp')
|
||||||
|
|
||||||
|
var { compress } = require('../src/utils/data')
|
||||||
|
|
||||||
|
var categories = [
|
||||||
|
['Smileys & People', 'people'],
|
||||||
|
['Animals & Nature', 'nature'],
|
||||||
|
['Food & Drink', 'foods'],
|
||||||
|
['Activities', 'activity'],
|
||||||
|
['Travel & Places', 'places'],
|
||||||
|
['Objects', 'objects'],
|
||||||
|
['Symbols', 'symbols'],
|
||||||
|
['Flags', 'flags'],
|
||||||
|
]
|
||||||
|
|
||||||
|
var sets = ['apple', 'emojione', 'facebook', 'google', 'messenger', 'twitter']
|
||||||
|
|
||||||
|
module.exports = (options) => {
|
||||||
|
delete require.cache[require.resolve('emoji-datasource')]
|
||||||
|
var emojiData = require('emoji-datasource')
|
||||||
|
|
||||||
|
var data = { compressed: true, categories: [], emojis: {}, aliases: {} },
|
||||||
|
categoriesIndex = {}
|
||||||
|
|
||||||
|
categories.forEach((category, i) => {
|
||||||
|
let [name, id] = category
|
||||||
|
data.categories[i] = { id: id, name: name, emojis: [] }
|
||||||
|
categoriesIndex[name] = i
|
||||||
|
})
|
||||||
|
|
||||||
|
emojiData.sort((a, b) => {
|
||||||
|
var aTest = a.sort_order || a.short_name,
|
||||||
|
bTest = b.sort_order || b.short_name
|
||||||
|
|
||||||
|
return aTest - bTest
|
||||||
|
})
|
||||||
|
|
||||||
|
emojiData.forEach((datum) => {
|
||||||
|
var category = datum.category,
|
||||||
|
keywords = [],
|
||||||
|
categoryIndex
|
||||||
|
|
||||||
|
if (!datum.category) {
|
||||||
|
throw new Error('“' + datum.short_name + '” doesn’t have a category')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.sets) {
|
||||||
|
var keepEmoji = false
|
||||||
|
|
||||||
|
options.sets.forEach((set) => {
|
||||||
|
if (keepEmoji) return
|
||||||
|
if (datum[`has_img_${set}`]) {
|
||||||
|
keepEmoji = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!keepEmoji) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sets.forEach((set) => {
|
||||||
|
if (options.sets.length == 1 || options.sets.indexOf(set) == -1) {
|
||||||
|
var key = `has_img_${set}`
|
||||||
|
delete datum[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
datum.name || (datum.name = datum.short_name.replace(/\-/g, ' '))
|
||||||
|
datum.name = inflection.titleize(datum.name || '')
|
||||||
|
|
||||||
|
if (!datum.name) {
|
||||||
|
throw new Error('“' + datum.short_name + '” doesn’t have a name')
|
||||||
|
}
|
||||||
|
|
||||||
|
datum.emoticons = datum.texts || []
|
||||||
|
datum.text = datum.text || ''
|
||||||
|
delete datum.texts
|
||||||
|
|
||||||
|
if (emojiLib.lib[datum.short_name]) {
|
||||||
|
datum.keywords = emojiLib.lib[datum.short_name].keywords
|
||||||
|
}
|
||||||
|
|
||||||
|
if (datum.category != 'Skin Tones') {
|
||||||
|
categoryIndex = categoriesIndex[category]
|
||||||
|
data.categories[categoryIndex].emojis.push(datum.short_name)
|
||||||
|
data.emojis[datum.short_name] = datum
|
||||||
|
}
|
||||||
|
|
||||||
|
datum.short_names.forEach((short_name, i) => {
|
||||||
|
if (i == 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data.aliases[short_name] = datum.short_name
|
||||||
|
})
|
||||||
|
|
||||||
|
delete datum.docomo
|
||||||
|
delete datum.au
|
||||||
|
delete datum.softbank
|
||||||
|
delete datum.google
|
||||||
|
delete datum.image
|
||||||
|
delete datum.category
|
||||||
|
delete datum.sort_order
|
||||||
|
|
||||||
|
compress(datum)
|
||||||
|
})
|
||||||
|
|
||||||
|
var flags = data.categories[categoriesIndex['Flags']]
|
||||||
|
flags.emojis = flags.emojis
|
||||||
|
.filter((flag) => {
|
||||||
|
// Until browsers support Flag UN
|
||||||
|
if (flag == 'flag-un') return
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
.sort()
|
||||||
|
|
||||||
|
fs.writeFile(options.output, JSON.stringify(data), (err) => {
|
||||||
|
if (err) throw err
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import SVGs from '../../svgs'
|
import SVGs from '../svgs'
|
||||||
|
|
||||||
export default class Anchors extends React.PureComponent {
|
export default class Anchors extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
|
@ -1,16 +1,11 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import frequently from '../../utils/frequently'
|
import frequently from '../utils/frequently'
|
||||||
import { getData } from '../../utils'
|
import { getData } from '../utils'
|
||||||
import { NimbleEmoji } from '..'
|
import { NimbleEmoji } from '.'
|
||||||
|
|
||||||
import {
|
export default class Category extends React.Component {
|
||||||
CategoryPropTypes,
|
|
||||||
CategoryDefaultProps,
|
|
||||||
} from '../../utils/shared-props'
|
|
||||||
|
|
||||||
export default class NimbleCategory extends React.Component {
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
|
@ -217,8 +212,17 @@ export default class NimbleCategory extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NimbleCategory.propTypes = {
|
Category.propTypes = {
|
||||||
...CategoryPropTypes,
|
emojis: PropTypes.array,
|
||||||
data: PropTypes.object.isRequired,
|
hasStickyPosition: PropTypes.bool,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
native: PropTypes.bool.isRequired,
|
||||||
|
perLine: PropTypes.number.isRequired,
|
||||||
|
emojiProps: PropTypes.object.isRequired,
|
||||||
|
recent: PropTypes.arrayOf(PropTypes.string),
|
||||||
|
}
|
||||||
|
|
||||||
|
Category.defaultProps = {
|
||||||
|
emojis: [],
|
||||||
|
hasStickyPosition: true,
|
||||||
}
|
}
|
||||||
NimbleCategory.defaultProps = CategoryDefaultProps
|
|
|
@ -1,17 +0,0 @@
|
||||||
import React from 'react'
|
|
||||||
import data from '../../data'
|
|
||||||
import NimbleCategory from './nimble-category'
|
|
||||||
|
|
||||||
import {
|
|
||||||
CategoryPropTypes,
|
|
||||||
CategoryDefaultProps,
|
|
||||||
} from '../../utils/shared-props'
|
|
||||||
|
|
||||||
export default class Category extends React.Component {
|
|
||||||
render() {
|
|
||||||
return <NimbleCategory {...this.props} {...this.state} />
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Category.propTypes = { ...CategoryPropTypes }
|
|
||||||
Category.defaultProps = { ...CategoryDefaultProps, data }
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import data from '../../data'
|
import data from '../../../data/all.json'
|
||||||
import NimbleEmoji from './nimble-emoji'
|
import NimbleEmoji from './nimble-emoji'
|
||||||
|
|
||||||
import { EmojiPropTypes, EmojiDefaultProps } from '../../utils/shared-props'
|
import { EmojiPropTypes, EmojiDefaultProps } from '../../utils/shared-props'
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import { getData, getSanitizedData, unifiedToNative } from '../../utils'
|
import { getData, getSanitizedData, unifiedToNative } from '../../utils'
|
||||||
|
import { uncompress } from '../../utils/data'
|
||||||
import { EmojiPropTypes, EmojiDefaultProps } from '../../utils/shared-props'
|
import { EmojiPropTypes, EmojiDefaultProps } from '../../utils/shared-props'
|
||||||
|
|
||||||
const SHEET_COLUMNS = 52
|
const SHEET_COLUMNS = 52
|
||||||
|
@ -74,6 +75,10 @@ const _convertStyleToCSS = (style) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const NimbleEmoji = (props) => {
|
const NimbleEmoji = (props) => {
|
||||||
|
if (props.data.compressed) {
|
||||||
|
uncompress(props.data)
|
||||||
|
}
|
||||||
|
|
||||||
for (let k in NimbleEmoji.defaultProps) {
|
for (let k in NimbleEmoji.defaultProps) {
|
||||||
if (props[k] == undefined && NimbleEmoji.defaultProps[k] != undefined) {
|
if (props[k] == undefined && NimbleEmoji.defaultProps[k] != undefined) {
|
||||||
props[k] = NimbleEmoji.defaultProps[k]
|
props[k] = NimbleEmoji.defaultProps[k]
|
||||||
|
@ -119,7 +124,8 @@ const NimbleEmoji = (props) => {
|
||||||
backgroundSize: 'contain',
|
backgroundSize: 'contain',
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let setHasEmoji = _getData(props)[`has_img_${props.set}`]
|
let setHasEmoji =
|
||||||
|
data[`has_img_${props.set}`] == undefined || data[`has_img_${props.set}`]
|
||||||
|
|
||||||
if (!setHasEmoji) {
|
if (!setHasEmoji) {
|
||||||
if (props.fallback) {
|
if (props.fallback) {
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
export { default as Anchors } from './anchors/anchors'
|
export { default as Anchors } from './anchors'
|
||||||
|
export { default as Category } from './category'
|
||||||
export { default as Category } from './category/category'
|
export { default as Preview } from './preview'
|
||||||
export { default as NimbleCategory } from './category/nimble-category'
|
export { default as Search } from './search'
|
||||||
|
export { default as Skins } from './skins'
|
||||||
|
|
||||||
export { default as Emoji } from './emoji/emoji'
|
export { default as Emoji } from './emoji/emoji'
|
||||||
export { default as NimbleEmoji } from './emoji/nimble-emoji'
|
export { default as NimbleEmoji } from './emoji/nimble-emoji'
|
||||||
|
|
||||||
export { default as Picker } from './picker/picker'
|
export { default as Picker } from './picker/picker'
|
||||||
export { default as NimblePicker } from './picker/nimble-picker'
|
export { default as NimblePicker } from './picker/nimble-picker'
|
||||||
|
|
||||||
export { default as Preview } from './preview/preview'
|
|
||||||
export { default as NimblePreview } from './preview/nimble-preview'
|
|
||||||
|
|
||||||
export { default as Search } from './search/search'
|
|
||||||
export { default as NimbleSearch } from './search/nimble-search'
|
|
||||||
|
|
||||||
export { default as Skins } from './skins/skins'
|
|
||||||
|
|
|
@ -6,9 +6,10 @@ import PropTypes from 'prop-types'
|
||||||
import store from '../../utils/store'
|
import store from '../../utils/store'
|
||||||
import frequently from '../../utils/frequently'
|
import frequently from '../../utils/frequently'
|
||||||
import { deepMerge, measureScrollbar } from '../../utils'
|
import { deepMerge, measureScrollbar } from '../../utils'
|
||||||
|
import { uncompress } from '../../utils/data'
|
||||||
import { PickerPropTypes, PickerDefaultProps } from '../../utils/shared-props'
|
import { PickerPropTypes, PickerDefaultProps } from '../../utils/shared-props'
|
||||||
|
|
||||||
import { Anchors, NimbleCategory, NimblePreview, NimbleSearch } from '..'
|
import { Anchors, Category, Preview, Search } from '..'
|
||||||
|
|
||||||
const I18N = {
|
const I18N = {
|
||||||
search: 'Search',
|
search: 'Search',
|
||||||
|
@ -41,6 +42,10 @@ export default class NimblePicker extends React.PureComponent {
|
||||||
anchor: false,
|
anchor: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (props.data.compressed) {
|
||||||
|
uncompress(props.data)
|
||||||
|
}
|
||||||
|
|
||||||
this.data = props.data
|
this.data = props.data
|
||||||
this.i18n = deepMerge(I18N, props.i18n)
|
this.i18n = deepMerge(I18N, props.i18n)
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -483,7 +488,7 @@ export default class NimblePicker extends React.PureComponent {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<NimbleSearch
|
<Search
|
||||||
ref={this.setSearchRef}
|
ref={this.setSearchRef}
|
||||||
onSearch={this.handleSearch}
|
onSearch={this.handleSearch}
|
||||||
data={this.data}
|
data={this.data}
|
||||||
|
@ -502,7 +507,7 @@ export default class NimblePicker extends React.PureComponent {
|
||||||
>
|
>
|
||||||
{this.getCategories().map((category, i) => {
|
{this.getCategories().map((category, i) => {
|
||||||
return (
|
return (
|
||||||
<NimbleCategory
|
<Category
|
||||||
ref={this.setCategoryRef.bind(this, `category-${i}`)}
|
ref={this.setCategoryRef.bind(this, `category-${i}`)}
|
||||||
key={category.name}
|
key={category.name}
|
||||||
id={category.id}
|
id={category.id}
|
||||||
|
@ -541,7 +546,7 @@ export default class NimblePicker extends React.PureComponent {
|
||||||
|
|
||||||
{showPreview && (
|
{showPreview && (
|
||||||
<div className="emoji-mart-bar">
|
<div className="emoji-mart-bar">
|
||||||
<NimblePreview
|
<Preview
|
||||||
ref={this.setPreviewRef}
|
ref={this.setPreviewRef}
|
||||||
data={this.data}
|
data={this.data}
|
||||||
title={title}
|
title={title}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import data from '../../data'
|
import data from '../../../data/all.json'
|
||||||
import NimblePicker from './nimble-picker'
|
import NimblePicker from './nimble-picker'
|
||||||
|
|
||||||
import { PickerPropTypes, PickerDefaultProps } from '../../utils/shared-props'
|
import { PickerPropTypes, PickerDefaultProps } from '../../utils/shared-props'
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import { getData } from '../../utils'
|
import { getData } from '../utils'
|
||||||
import { NimbleEmoji, Skins } from '..'
|
import { NimbleEmoji, Skins } from '.'
|
||||||
import { PreviewPropTypes, PreviewDefaultProps } from '../../utils/shared-props'
|
|
||||||
|
|
||||||
export default class NimblePreview extends React.PureComponent {
|
export default class Preview extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
|
@ -92,8 +91,15 @@ export default class NimblePreview extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NimblePreview.propTypes = {
|
Preview.propTypes = {
|
||||||
...PreviewPropTypes,
|
showSkinTones: PropTypes.bool,
|
||||||
data: PropTypes.object.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
|
emoji: PropTypes.string.isRequired,
|
||||||
|
emojiProps: PropTypes.object.isRequired,
|
||||||
|
skinsProps: PropTypes.object.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
Preview.defaultProps = {
|
||||||
|
showSkinTones: true,
|
||||||
|
onChange: () => {},
|
||||||
}
|
}
|
||||||
NimblePreview.defaultProps = PreviewDefaultProps
|
|
|
@ -1,15 +0,0 @@
|
||||||
import React from 'react'
|
|
||||||
|
|
||||||
import data from '../../data'
|
|
||||||
import NimblePreview from './nimble-preview'
|
|
||||||
|
|
||||||
import { PreviewPropTypes, PreviewDefaultProps } from '../../utils/shared-props'
|
|
||||||
|
|
||||||
export default class Preview extends React.PureComponent {
|
|
||||||
render() {
|
|
||||||
return <NimblePreview {...this.props} {...this.state} />
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Preview.propTypes = PreviewPropTypes
|
|
||||||
Preview.defaultProps = { ...PreviewDefaultProps, data }
|
|
|
@ -1,10 +1,9 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
import NimbleEmojiIndex from '../../utils/emoji-index/nimble-emoji-index'
|
import NimbleEmojiIndex from '../utils/emoji-index/nimble-emoji-index'
|
||||||
import { SearchPropTypes, SearchDefaultProps } from '../../utils/shared-props'
|
|
||||||
|
|
||||||
export default class NimbleSearch extends React.PureComponent {
|
export default class Search extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
|
@ -53,8 +52,16 @@ export default class NimbleSearch extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NimbleSearch.propTypes = {
|
Search.propTypes = {
|
||||||
...SearchPropTypes,
|
onSearch: PropTypes.func,
|
||||||
data: PropTypes.object.isRequired,
|
maxResults: PropTypes.number,
|
||||||
|
emojisToShowFilter: PropTypes.func,
|
||||||
|
autoFocus: PropTypes.bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
Search.defaultProps = {
|
||||||
|
onSearch: () => {},
|
||||||
|
maxResults: 75,
|
||||||
|
emojisToShowFilter: null,
|
||||||
|
autoFocus: false,
|
||||||
}
|
}
|
||||||
NimbleSearch.defaultProps = SearchDefaultProps
|
|
|
@ -1,15 +0,0 @@
|
||||||
import React from 'react'
|
|
||||||
|
|
||||||
import data from '../../data'
|
|
||||||
import NimbleSearch from './nimble-search'
|
|
||||||
|
|
||||||
import { SearchPropTypes, SearchDefaultProps } from '../../utils/shared-props'
|
|
||||||
|
|
||||||
export default class Search extends React.PureComponent {
|
|
||||||
render() {
|
|
||||||
return <NimbleSearch {...this.props} {...this.state} />
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Search.propTypes = SearchPropTypes
|
|
||||||
Search.defaultProps = { ...SearchDefaultProps, data }
|
|
|
@ -1,30 +0,0 @@
|
||||||
import buildSearch from '../utils/build-search'
|
|
||||||
import data from './data'
|
|
||||||
|
|
||||||
function uncompress(list) {
|
|
||||||
for (var short_name in list) {
|
|
||||||
var datum = list[short_name]
|
|
||||||
|
|
||||||
if (!datum.short_names) datum.short_names = []
|
|
||||||
datum.short_names.unshift(short_name)
|
|
||||||
|
|
||||||
datum.sheet_x = datum.sheet[0]
|
|
||||||
datum.sheet_y = datum.sheet[1]
|
|
||||||
delete datum.sheet
|
|
||||||
|
|
||||||
if (!datum.text) datum.text = ''
|
|
||||||
if (datum.added_in !== null && !datum.added_in) datum.added_in = '6.0'
|
|
||||||
|
|
||||||
datum.search = buildSearch({
|
|
||||||
short_names: datum.short_names,
|
|
||||||
name: datum.name,
|
|
||||||
keywords: datum.keywords,
|
|
||||||
emoticons: datum.emoticons,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uncompress(data.emojis)
|
|
||||||
uncompress(data.skins)
|
|
||||||
|
|
||||||
export default data
|
|
|
@ -8,7 +8,6 @@ export {
|
||||||
Emoji,
|
Emoji,
|
||||||
NimbleEmoji,
|
NimbleEmoji,
|
||||||
Category,
|
Category,
|
||||||
NimbleCategory,
|
|
||||||
} from './components'
|
} from './components'
|
||||||
|
|
||||||
export { NimbleEmojiIndex } from './utils/emoji-index/nimble-emoji-index'
|
export { NimbleEmojiIndex } from './utils/emoji-index/nimble-emoji-index'
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
export default (data) => {
|
|
||||||
const search = []
|
|
||||||
|
|
||||||
var addToSearch = (strings, split) => {
|
|
||||||
if (!strings) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
;(Array.isArray(strings) ? strings : [strings]).forEach((string) => {
|
|
||||||
;(split ? string.split(/[-|_|\s]+/) : [string]).forEach((s) => {
|
|
||||||
s = s.toLowerCase()
|
|
||||||
|
|
||||||
if (search.indexOf(s) == -1) {
|
|
||||||
search.push(s)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
addToSearch(data.short_names, true)
|
|
||||||
addToSearch(data.name, true)
|
|
||||||
addToSearch(data.keywords, false)
|
|
||||||
addToSearch(data.emoticons, false)
|
|
||||||
|
|
||||||
return search.join(',')
|
|
||||||
}
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
const mapping = {
|
||||||
|
name: 'a',
|
||||||
|
unified: 'b',
|
||||||
|
non_qualified: 'c',
|
||||||
|
has_img_apple: 'd',
|
||||||
|
has_img_google: 'e',
|
||||||
|
has_img_twitter: 'f',
|
||||||
|
has_img_emojione: 'g',
|
||||||
|
has_img_facebook: 'h',
|
||||||
|
has_img_messenger: 'i',
|
||||||
|
keywords: 'j',
|
||||||
|
sheet: 'k',
|
||||||
|
emoticons: 'l',
|
||||||
|
text: 'm',
|
||||||
|
short_names: 'n',
|
||||||
|
added_in: 'o',
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildSearch = (emoji) => {
|
||||||
|
const search = []
|
||||||
|
|
||||||
|
var addToSearch = (strings, split) => {
|
||||||
|
if (!strings) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
;(Array.isArray(strings) ? strings : [strings]).forEach((string) => {
|
||||||
|
;(split ? string.split(/[-|_|\s]+/) : [string]).forEach((s) => {
|
||||||
|
s = s.toLowerCase()
|
||||||
|
|
||||||
|
if (search.indexOf(s) == -1) {
|
||||||
|
search.push(s)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
addToSearch(emoji.short_names, true)
|
||||||
|
addToSearch(emoji.name, true)
|
||||||
|
addToSearch(emoji.keywords, false)
|
||||||
|
addToSearch(emoji.emoticons, false)
|
||||||
|
|
||||||
|
return search.join(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
const compress = (emoji) => {
|
||||||
|
emoji.short_names = emoji.short_names.filter((short_name) => {
|
||||||
|
return short_name !== emoji.short_name
|
||||||
|
})
|
||||||
|
delete emoji.short_name
|
||||||
|
|
||||||
|
emoji.sheet = [emoji.sheet_x, emoji.sheet_y]
|
||||||
|
delete emoji.sheet_x
|
||||||
|
delete emoji.sheet_y
|
||||||
|
|
||||||
|
emoji.added_in = parseInt(emoji.added_in)
|
||||||
|
if (emoji.added_in === 6) {
|
||||||
|
delete emoji.added_in
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let key in mapping) {
|
||||||
|
emoji[mapping[key]] = emoji[key]
|
||||||
|
delete emoji[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let key in emoji) {
|
||||||
|
let value = emoji[key]
|
||||||
|
|
||||||
|
if (Array.isArray(value) && !value.length) {
|
||||||
|
delete emoji[key]
|
||||||
|
} else if (typeof value === 'string' && !value.length) {
|
||||||
|
delete emoji[key]
|
||||||
|
} else if (value === null) {
|
||||||
|
delete emoji[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const uncompress = (data) => {
|
||||||
|
data.compressed = false
|
||||||
|
|
||||||
|
for (let id in data.emojis) {
|
||||||
|
let emoji = data.emojis[id]
|
||||||
|
|
||||||
|
for (let key in mapping) {
|
||||||
|
emoji[key] = emoji[mapping[key]]
|
||||||
|
delete emoji[mapping[key]]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!emoji.short_names) emoji.short_names = []
|
||||||
|
emoji.short_names.unshift(id)
|
||||||
|
|
||||||
|
emoji.sheet_x = emoji.sheet[0]
|
||||||
|
emoji.sheet_y = emoji.sheet[1]
|
||||||
|
delete emoji.sheet
|
||||||
|
|
||||||
|
if (!emoji.text) emoji.text = ''
|
||||||
|
|
||||||
|
if (!emoji.added_in) emoji.added_in = 6
|
||||||
|
emoji.added_in = emoji.added_in.toFixed(1)
|
||||||
|
|
||||||
|
emoji.search = buildSearch(emoji)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { buildSearch, compress, uncompress }
|
|
@ -1,4 +1,4 @@
|
||||||
import data from '../../data'
|
import data from '../../../data/all.json'
|
||||||
import NimbleEmojiIndex from './nimble-emoji-index'
|
import NimbleEmojiIndex from './nimble-emoji-index'
|
||||||
|
|
||||||
const emojiIndex = new NimbleEmojiIndex(data)
|
const emojiIndex = new NimbleEmojiIndex(data)
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import { getData, getSanitizedData, intersect } from '..'
|
import { getData, getSanitizedData, intersect } from '..'
|
||||||
|
import { uncompress } from '../data'
|
||||||
|
|
||||||
export default class NimbleEmojiIndex {
|
export default class NimbleEmojiIndex {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
|
if (data.compressed) {
|
||||||
|
uncompress(data)
|
||||||
|
}
|
||||||
|
|
||||||
this.data = data || {}
|
this.data = data || {}
|
||||||
this.originalPool = {}
|
this.originalPool = {}
|
||||||
this.index = {}
|
this.index = {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import buildSearch from './build-search'
|
import { buildSearch } from './data'
|
||||||
import stringFromCodePoint from '../polyfills/stringFromCodePoint'
|
import stringFromCodePoint from '../polyfills/stringFromCodePoint'
|
||||||
|
|
||||||
const _JSON = JSON
|
const _JSON = JSON
|
||||||
|
@ -113,7 +113,10 @@ function getData(emoji, skin, set, data) {
|
||||||
delete emojiData.variations
|
delete emojiData.variations
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variationData[`has_img_${set}`]) {
|
if (
|
||||||
|
variationData[`has_img_${set}`] == undefined ||
|
||||||
|
variationData[`has_img_${set}`]
|
||||||
|
) {
|
||||||
emojiData.skin_tone = skin
|
emojiData.skin_tone = skin
|
||||||
|
|
||||||
for (let k in variationData) {
|
for (let k in variationData) {
|
||||||
|
|
|
@ -1,20 +1,5 @@
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
const CategoryPropTypes = {
|
|
||||||
emojis: PropTypes.array,
|
|
||||||
hasStickyPosition: PropTypes.bool,
|
|
||||||
name: PropTypes.string.isRequired,
|
|
||||||
native: PropTypes.bool.isRequired,
|
|
||||||
perLine: PropTypes.number.isRequired,
|
|
||||||
emojiProps: PropTypes.object.isRequired,
|
|
||||||
recent: PropTypes.arrayOf(PropTypes.string),
|
|
||||||
}
|
|
||||||
|
|
||||||
const CategoryDefaultProps = {
|
|
||||||
emojis: [],
|
|
||||||
hasStickyPosition: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
const EmojiPropTypes = {
|
const EmojiPropTypes = {
|
||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
onOver: PropTypes.func,
|
onOver: PropTypes.func,
|
||||||
|
@ -111,42 +96,9 @@ const PickerDefaultProps = {
|
||||||
custom: [],
|
custom: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
const PreviewPropTypes = {
|
|
||||||
showSkinTones: PropTypes.bool,
|
|
||||||
title: PropTypes.string.isRequired,
|
|
||||||
emoji: PropTypes.string.isRequired,
|
|
||||||
emojiProps: PropTypes.object.isRequired,
|
|
||||||
skinsProps: PropTypes.object.isRequired,
|
|
||||||
}
|
|
||||||
|
|
||||||
const PreviewDefaultProps = {
|
|
||||||
showSkinTones: true,
|
|
||||||
onChange: () => {},
|
|
||||||
}
|
|
||||||
|
|
||||||
const SearchPropTypes = {
|
|
||||||
onSearch: PropTypes.func,
|
|
||||||
maxResults: PropTypes.number,
|
|
||||||
emojisToShowFilter: PropTypes.func,
|
|
||||||
autoFocus: PropTypes.bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
const SearchDefaultProps = {
|
|
||||||
onSearch: () => {},
|
|
||||||
maxResults: 75,
|
|
||||||
emojisToShowFilter: null,
|
|
||||||
autoFocus: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
CategoryPropTypes,
|
|
||||||
CategoryDefaultProps,
|
|
||||||
EmojiPropTypes,
|
EmojiPropTypes,
|
||||||
EmojiDefaultProps,
|
EmojiDefaultProps,
|
||||||
PickerPropTypes,
|
PickerPropTypes,
|
||||||
PickerDefaultProps,
|
PickerDefaultProps,
|
||||||
PreviewPropTypes,
|
|
||||||
PreviewDefaultProps,
|
|
||||||
SearchPropTypes,
|
|
||||||
SearchDefaultProps,
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue