Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
EtienneLem committed Jun 1, 2016
0 parents commit e108b00
Show file tree
Hide file tree
Showing 20 changed files with 686 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .babelrc
@@ -0,0 +1,3 @@
{
"presets": ["es2015", "react"]
}
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
node_modules/
build/
data/
dist/
lib/
94 changes: 94 additions & 0 deletions css/emoji-picker.css
@@ -0,0 +1,94 @@
.emoji-picker,
.emoji-picker * {
box-sizing: border-box;
}

.emoji-picker {
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
font-size: 16px;
display: inline-block;
color: #222427;
border: 1px solid rgba(0, 0, 0, .15);
border-radius: 5px;
}

.emoji-picker-bar {
background-color: #f4f4f4;
padding: 12px;
}
.emoji-picker-bar:first-child {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.emoji-picker-bar:last-child {
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}

.emoji-picker-scroll {
overflow: scroll;
max-height: 270px;
padding: 6px;
border: solid rgba(0, 0, 0, .15);
border-width: 1px 0;
}

.emoji-picker-search {
font-size: 16px;
display: block;
width: 100%;
padding: .2em .6em;
border-radius: 25px;
border: 1px solid rgba(0, 0, 0, .15);
outline: 0;
}

.emoji-picker-category .emoji-picker-emoji:hover {
background-color: #b7e887;
}

.emoji-picker-category-label {
font-weight: bold;
padding: 5px 6px;
background-color: rgba(255, 255, 255, .95);
}

.emoji-picker-emoji {
display: inline-block;
padding: 4px 6px;
border-radius: 5px;
}

.emoji-picker-preview {
position: relative;
height: 70px;
}

.emoji-picker-preview-emoji,
.emoji-picker-preview-data {
position: absolute;
top: 12px;
}

.emoji-picker-preview-emoji {
left: 12px;
}

.emoji-picker-preview-data {
top: 50%;
left: 68px; right: 12px;
transform: translateY(-50%);
word-break: break-word;
}

.emoji-picker-preview-name {
font-size: 14px;
}

.emoji-picker-preview-shortname {
font-size: 12px;
color: #888;
}
.emoji-picker-preview-shortname + .emoji-picker-preview-shortname {
margin-left: .5em;
}
Binary file added example/images/sheet-apple-64.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/images/sheet-emojione-64.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/images/sheet-google-64.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/images/sheet-twitter-64.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions example/index.html
@@ -0,0 +1,10 @@
<html>
<head>
<title>EmojiPicker</title>
<link rel="stylesheet" href="../css/emoji-picker.css">
</head>
<body>
<div></div>
<script src="../build/example.js"></script>
</body>
</html>
96 changes: 96 additions & 0 deletions example/index.js
@@ -0,0 +1,96 @@
import React from 'react'
import ReactDOM from 'react-dom'

import {Picker} from '../src'

class Example extends React.Component {
constructor(props) {
super(props)
this.state = {
emojiSize: 24,
perLine: 9,
set: 'apple',
}
}

handleInput(e) {
var { currentTarget } = e,
{ value } = currentTarget,
key = currentTarget.getAttribute('data-key'),
state = {}

state[key] = parseInt(value)
this.setState(state)
}

render() {
return <div>
<h1>EmojiPicker</h1>

<div>
{['Apple', 'Google', 'Twitter', 'EmojiOne'].map((set) => {
var value = set.toLowerCase(),
props = { disabled: value == this.state.set }

return <button
key={value}
value={value}
onClick={() => this.setState({ set: value })}
{...props}>
{set}
</button>
})}
</div>

<pre style={{
fontSize: 18,
display: 'inline-block',
verticalAlign: 'top',
margin: '1em',
width: '460px',
}}>
<Operator>import</Operator> &#123;Picker&#125; <Operator>from</Operator> <String>'emoji-picker'</String>
<br />
<br /><Operator>&lt;</Operator><Variable>Picker</Variable>
<br /> emojiSize<Operator>=</Operator>&#123;<Variable>{this.state.emojiSize}</Variable>&#125; <input type='range' data-key='emojiSize' onChange={this.handleInput.bind(this)} min='16' max='64' value={this.state.emojiSize} />
<br /> perLine<Operator>=</Operator>&#123;<Variable>{this.state.perLine}</Variable>&#125; {this.state.perLine < 10 ? ' ' : ' '} <input type='range' data-key='perLine' onChange={this.handleInput.bind(this)} min='5' max='16' value={this.state.perLine} />
<br /> sheetURL<Operator>=</Operator><String>'images/sheet-{this.state.set}-64.png'</String>
<br /> onClick<Operator>=</Operator>&#123;(<Variable>emoji</Variable>) => console.log(<Variable>emoji</Variable>)&#125;
<br /><Operator>/&gt;</Operator>
</pre>

<Picker
emojiSize={this.state.emojiSize}
perLine={this.state.perLine}
sheetURL={`images/sheet-${this.state.set}-64.png`}
onClick={(emoji) => console.log(emoji)}
/>
</div>
}
}

class Operator extends React.Component {
render() {
return <span style={{color: '#a71d5d'}}>
{this.props.children}
</span>
}
}

class Variable extends React.Component {
render() {
return <span style={{color: '#0086b3'}}>
{this.props.children}
</span>
}
}

class String extends React.Component {
render() {
return <span style={{color: '#183691'}}>
{this.props.children}
</span>
}
}

ReactDOM.render(<Example />, document.querySelector('div'))
27 changes: 27 additions & 0 deletions example/webpack.config.js
@@ -0,0 +1,27 @@
var path = require('path')

module.exports = {
entry: path.resolve('example/index.js'),
output: {
path: path.resolve('build'),
filename: 'example.js',
},

module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [
path.resolve('src'),
path.resolve('data'),
path.resolve('example'),
],
},
],
},

resolve: {
extensions: ['', '.js'],
},
}
50 changes: 50 additions & 0 deletions package.json
@@ -0,0 +1,50 @@
{
"name": "emoji-picker",
"version": "0.0.1",
"description": "",
"main": "dist/emoji-picker.js",
"repository": {
"type": "git",
"url": "git@github.com:missive/emoji-picker.git"
},
"keywords": [
"react",
"emoji",
"picker"
],
"author": "Etienne Lemay",
"license": "ISC",
"bugs": {
"url": "https://github.com/missive/emoji-picker/issues"
},
"homepage": "https://github.com/missive/emoji-picker",
"dependencies": {},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0-0"
},
"devDependencies": {
"babel-core": "6.7.2",
"babel-loader": "6.2.4",
"babel-preset-es2015": "6.6.0",
"babel-preset-react": "6.5.0",
"emoji-data": "git://github.com/missive/emoji-data.git#01aeccb3adf6cdfaab6e13892f7688740047ff32",
"inflection": "1.10.0",
"mkdirp": "0.5.1",
"react": "0.14.7",
"react-dom": "0.14.7",
"rimraf": "2.5.2",
"webpack": "1.12.14"
},
"scripts": {
"clean": "rimraf build/ data/ dist/",
"build:data": "node scripts/build-data",
"build:example": "node scripts/build-example",
"build:dist": "node scripts/build-dist",
"build": "npm run build:data && npm run build:dist",
"react:clean": "rimraf node_modules/{react,react-dom,react-addons-test-utils}",
"react:14": "npm run react:clean && npm i react@^0.14 react-dom@^0.14 react-addons-test-utils@^0.14",
"react:15": "npm run react:clean && npm i react@^15 react-dom@^15 react-addons-test-utils@^15",
"test": "echo \"Error: no test specified\" && exit 1",
"prepublish": "npm run clean && npm run build"
}
}
55 changes: 55 additions & 0 deletions scripts/build-data.js
@@ -0,0 +1,55 @@
var fs = require('fs')
var emojiData = require('emoji-data')
var inflection = require('inflection')
var mkdirp = require('mkdirp')

var categories = ['People', 'Nature', 'Foods', 'Activity', 'Places', 'Objects', 'Symbols', 'Flags', 'Skins']
var data = { categories: [], emojis: {} }
var categoriesIndex = {}

categories.forEach((category, i) => {
data.categories[i] = { name: category, emojis: [] }
categoriesIndex[category] = i
})

emojiData.sort((a, b) => {
var aTest = a.sort_order || a.short_name
var bTest = b.sort_order || b.short_name

return aTest - bTest
})

emojiData.forEach((datum) => {
var category = datum.category,
shortName = datum.short_name,
categoryIndex

if (!category) {
if (/^skin/.test(shortName)) category = 'Skins'
if (/^flag/.test(shortName)) category = 'Flags'
if (/^(left_speech_bubble|keycap_star|eject)$/.test(shortName)) category = 'Symbols'
}

if (!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')
}

categoryIndex = categoriesIndex[category]
data.categories[categoryIndex].emojis.push(datum.short_name)
data.emojis[datum.short_name] = datum
})

mkdirp('data', (err) => {
if (err) throw err

fs.writeFile('data/index.js', `export default ${JSON.stringify(data)}`, (err) => {
if (err) throw err
})
})
44 changes: 44 additions & 0 deletions scripts/build-dist.js
@@ -0,0 +1,44 @@
var path = require('path')
var extend = require('util')._extend
var webpack = require('webpack')

var configs = ['development', 'production'].map((env) => {
var configPath = '../src/webpack.config.js',
config = require(configPath)

delete require.cache[require.resolve(configPath)]

if (env === 'production') {
config.output.filename = config.output.filename.replace(/\.js$/, '.min.js')
config.plugins.push(
new webpack.optimize.UglifyJsPlugin({
compressor: { warnings: false }
})
)
}

return config
})

webpack(configs, (err, stats) => {
if (err) throw err

console.log(
stats.toString({
colors: true,
hash: true,
version: false,
timings: true,
assets: true,
chunks: false,
chunkModules: false,
modules: false,
children: false,
cached: false,
reasons: false,
source: false,
errorDetails: false,
chunkOrigins: false,
})
)
})

0 comments on commit e108b00

Please sign in to comment.