Add `excludeUnsupportedNativeEmojis` props to Picker

exclude-unsupported-native-emojis
Etienne Lemay 2016-10-05 22:20:14 -04:00
parent ac4feba228
commit ce051bdfcb
5 changed files with 61 additions and 9 deletions

View File

@ -27,6 +27,7 @@ import { Picker } from 'emoji-mart'
| **skin** | | `1` | Default skin color (1-6) |
| **style** | | | Inline styles applied to the root element. Useful for positioning |
| **title** | | `Emoji Mart™` | The title shown when no emojis are hovered |
| **excludeUnsupportedNativeEmojis** | | `false` | Excludes natively unsupported emojis. Useful when using the emojis in a `<textarea>` |
Examples of `emoji` object:
```js

View File

@ -12,6 +12,7 @@ class Example extends React.Component {
skin: 1,
set: 'apple',
hidden: false,
excludeUnsupportedNativeEmojis: false,
}
}
@ -25,6 +26,16 @@ class Example extends React.Component {
this.setState(state)
}
handleCheckbox(e) {
var { currentTarget } = e,
{ checked } = currentTarget,
key = currentTarget.getAttribute('data-key'),
state = {}
state[key] = checked
this.setState(state)
}
render() {
return <div>
<div>
@ -76,6 +87,7 @@ class Example extends React.Component {
<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='7' max='16' value={this.state.perLine} />
<br /> skin<Operator>=</Operator>&#123;<Variable>{this.state.skin}</Variable>&#125; <input type='range' data-key='skin' onChange={this.handleInput.bind(this)} min='1' max='6' value={this.state.skin} />
<br /> excludeUnsupportedNativeEmojis<Operator>=</Operator>&#123;<input type='checkbox' data-key='excludeUnsupportedNativeEmojis' onChange={this.handleCheckbox.bind(this)} checked={this.state.excludeUnsupportedNativeEmojis} />&#125;
<br /> sheetURL<Operator>=</Operator><String>'sheets/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>
@ -88,6 +100,7 @@ class Example extends React.Component {
skin={this.state.skin}
sheetURL={`https://unpkg.com/emoji-mart@0.2.5/sheets/sheet_${this.state.set}_64.png`}
onClick={(emoji) => console.log(emoji)}
excludeUnsupportedNativeEmojis={this.state.excludeUnsupportedNativeEmojis}
/>
}
</div>

View File

@ -1,6 +1,7 @@
import React from 'react'
import frequently from '../utils/frequently'
import {nativeIsSupported} from '../utils'
import {Emoji} from '.'
const LABELS = {
@ -29,9 +30,9 @@ export default class Category extends React.Component {
}
shouldComponentUpdate(nextProps, nextState) {
var { name, perLine, hasStickyPosition, emojis, emojiProps } = this.props,
var { name, perLine, hasStickyPosition, emojis, emojiProps, excludeUnsupportedNativeEmojis } = this.props,
{ skin, size, sheetURL } = emojiProps,
{ perLine: nextPerLine, hasStickyPosition: nextHasStickyPosition, emojis: nextEmojis, emojiProps: nextEmojiProps } = nextProps,
{ perLine: nextPerLine, hasStickyPosition: nextHasStickyPosition, emojis: nextEmojis, emojiProps: nextEmojiProps, excludeUnsupportedNativeEmojis: nextExcludeUnsupportedNativeEmojis } = nextProps,
{ skin: nextSkin, size: nextSize, sheetURL: nextSheetURL } = nextEmojiProps,
shouldUpdate = false
@ -43,7 +44,7 @@ export default class Category extends React.Component {
shouldUpdate = !(emojis == nextEmojis)
}
if (skin != nextSkin || size != nextSize || sheetURL != nextSheetURL || hasStickyPosition != nextHasStickyPosition) {
if (skin != nextSkin || size != nextSize || sheetURL != nextSheetURL || hasStickyPosition != nextHasStickyPosition, excludeUnsupportedNativeEmojis != nextExcludeUnsupportedNativeEmojis) {
shouldUpdate = true
}
@ -109,7 +110,7 @@ export default class Category extends React.Component {
}
render() {
var { name, hasStickyPosition, emojiProps } = this.props,
var { name, hasStickyPosition, excludeUnsupportedNativeEmojis, emojiProps } = this.props,
emojis = this.getEmojis(),
labelStyles = {},
labelSpanStyles = {},
@ -136,13 +137,17 @@ export default class Category extends React.Component {
<span style={labelSpanStyles} ref='label'>{LABELS[name]}</span>
</div>
{emojis && emojis.map((emoji) =>
<Emoji
{emojis && emojis.map((emoji) => {
if (excludeUnsupportedNativeEmojis && !nativeIsSupported(emoji, emojiProps.skin, emojiProps.sheetURL)) {
return null
}
return <Emoji
key={emoji.id || emoji}
emoji={emoji}
{...emojiProps}
/>
)}
})}
{emojis && !emojis.length &&
<div className='emoji-mart-no-results'>
@ -167,6 +172,7 @@ Category.propTypes = {
name: React.PropTypes.string.isRequired,
perLine: React.PropTypes.number.isRequired,
emojiProps: React.PropTypes.object.isRequired,
excludeUnsupportedNativeEmojis: React.PropTypes.bool.isRequired,
}
Category.defaultProps = {

View File

@ -216,7 +216,7 @@ export default class Picker extends React.Component {
}
render() {
var { perLine, emojiSize, sheetURL, style, title, emoji, color } = this.props,
var { perLine, emojiSize, sheetURL, style, title, emoji, color, excludeUnsupportedNativeEmojis } = this.props,
{ skin } = this.state,
width = (perLine * (emojiSize + 12)) + 12 + 2
@ -244,6 +244,7 @@ export default class Picker extends React.Component {
emojis={category.emojis}
perLine={perLine}
hasStickyPosition={this.hasStickyPosition}
excludeUnsupportedNativeEmojis={excludeUnsupportedNativeEmojis}
emojiProps={{
skin: skin,
size: emojiSize,
@ -285,6 +286,7 @@ Picker.propTypes = {
title: React.PropTypes.string,
emoji: React.PropTypes.string,
color: React.PropTypes.string,
excludeUnsupportedNativeEmojis: React.PropTypes.bool,
sheetURL: React.PropTypes.string.isRequired,
}
@ -297,4 +299,5 @@ Picker.defaultProps = {
title: 'Emoji Mart™',
emoji: 'department_store',
color: '#ae65c5',
excludeUnsupportedNativeEmojis: false,
}

View File

@ -5,6 +5,8 @@ const SKINS = [
'1F3FD', '1F3FE', '1F3FF',
]
var blankDataURL, canvas, context
function unifiedToNative(unified) {
var unicodes = unified.split('-'),
codePoints = unicodes.map((u) => `0x${u}`)
@ -12,6 +14,33 @@ function unifiedToNative(unified) {
return String.fromCodePoint(...codePoints)
}
function clearCanvas() {
if (!canvas) {
canvas = document.createElement('canvas')
canvas.width = canvas.height = 2
context = canvas.getContext('2d')
context.font = '2px Arial'
context.textBaseline = 'top'
blankDataURL = canvas.toDataURL()
}
context.clearRect(0, 0, canvas.width, canvas.height)
}
function nativeIsSupported() {
if (typeof document == 'undefined') return true
var data = getSanitizedData(...arguments),
{ native } = data
clearCanvas()
context.fillText(native, 0, 0)
return blankDataURL != canvas.toDataURL()
}
function sanitize(emoji) {
var { name, short_names, skin_tone, skin_variations, emoticons, unified } = emoji,
id = short_names[0],
@ -79,4 +108,4 @@ function intersect(a, b) {
return Array.from(intersection)
}
export { getData, getSanitizedData, intersect }
export { getData, getSanitizedData, intersect, nativeIsSupported }