Add skin picker

release
Etienne Lemay 2016-06-08 20:22:06 -04:00
parent a36142649b
commit f8165922b5
6 changed files with 158 additions and 8 deletions

View File

@ -126,9 +126,11 @@
}
.emoji-picker-preview-emoji,
.emoji-picker-preview-data {
.emoji-picker-preview-data,
.emoji-picker-preview-skins {
position: absolute;
top: 12px;
top: 50%;
transform: translateY(-50%);
}
.emoji-picker-preview-emoji {
@ -136,12 +138,15 @@
}
.emoji-picker-preview-data {
top: 50%;
left: 68px; right: 12px;
transform: translateY(-50%);
word-break: break-word;
}
.emoji-picker-preview-skins {
right: 30px;
text-align: right;
}
.emoji-picker-preview-name {
font-size: 14px;
}
@ -167,3 +172,74 @@
font-size: 26px;
font-weight: 500;
}
.emoji-picker-skin-current {
display: inline-block;
padding: 2px;
border-radius: 100%;
border: 1px solid #d9d9d9;
}
.emoji-picker-skin-swatches {
padding: 2px 0;
border: 1px solid #d9d9d9;
border-radius: 12px;
background-color: #fff;
}
.emoji-picker-skin-swatches-opened .emoji-picker-skin-swatch {
width: 16px;
padding: 0 2px;
}
.emoji-picker-skin-swatches-opened .emoji-picker-skin-swatch-selected:after {
opacity: .75;
}
.emoji-picker-skin-swatch {
display: inline-block;
width: 0;
vertical-align: middle;
transition-property: width, padding;
transition-duration: .125s;
transition-timing-function: ease-out;
}
.emoji-picker-skin-swatch:nth-child(1) { transition-delay: 0 }
.emoji-picker-skin-swatch:nth-child(2) { transition-delay: .03s }
.emoji-picker-skin-swatch:nth-child(3) { transition-delay: .06s }
.emoji-picker-skin-swatch:nth-child(4) { transition-delay: .09s }
.emoji-picker-skin-swatch:nth-child(5) { transition-delay: .12s }
.emoji-picker-skin-swatch:nth-child(6) { transition-delay: .15s }
.emoji-picker-skin-swatch-selected {
position: relative;
width: 16px;
padding: 0 2px;
}
.emoji-picker-skin-swatch-selected:after {
content: "";
position: absolute;
top: 50%; left: 50%;
width: 4px; height: 4px;
margin: -2px 0 0 -2px;
background-color: #fff;
border-radius: 100%;
pointer-events: none;
opacity: 0;
transition: opacity .2s ease-out;
}
.emoji-picker-skin {
display: inline-block;
width: 100%; padding-top: 100%;
max-width: 12px;
border-radius: 100%;
}
.emoji-picker-skin-tone-1 { background-color: #ffc93a }
.emoji-picker-skin-tone-2 { background-color: #fadcbc }
.emoji-picker-skin-tone-3 { background-color: #e0bb95 }
.emoji-picker-skin-tone-4 { background-color: #bf8f68 }
.emoji-picker-skin-tone-5 { background-color: #9b643d }
.emoji-picker-skin-tone-6 { background-color: #594539 }

View File

@ -54,7 +54,7 @@ class Example extends React.Component {
<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='6' max='16' value={this.state.perLine} />
<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 /> 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;

View File

@ -4,3 +4,4 @@ export {default as Emoji} from './emoji'
export {default as Picker} from './picker'
export {default as Preview} from './preview'
export {default as Search} from './search'
export {default as Skins} from './skins'

View File

@ -16,9 +16,14 @@ export default class Picker extends React.Component {
this.state = {
categories: DEFAULT_CATEGORIES,
skin: props.skin,
}
}
componentWillReceiveProps(props) {
this.setState({ skin: props.skin })
}
componentDidUpdate() {
this.handleScroll()
}
@ -114,8 +119,13 @@ export default class Picker extends React.Component {
}
}
handleSkinChange(skin) {
this.setState({ skin: skin })
}
render() {
var { skin, perLine, emojiSize, sheetURL } = this.props,
var { perLine, emojiSize, sheetURL } = this.props,
{ skin } = this.state,
width = (perLine * (emojiSize + 12)) + 12 + 2
return <div style={{width: width}} className='emoji-picker'>
@ -158,6 +168,10 @@ export default class Picker extends React.Component {
size: 38,
sheetURL: sheetURL,
}}
skinsProps={{
skin: skin,
onChange: this.handleSkinChange.bind(this)
}}
/>
</div>
</div>

View File

@ -1,5 +1,5 @@
import React from 'react'
import {Emoji} from '.'
import {Emoji, Skins} from '.'
export default class Preview extends React.Component {
constructor(props) {
@ -9,7 +9,7 @@ export default class Preview extends React.Component {
render() {
var { emoji } = this.state,
{ emojiProps } = this.props
{ emojiProps, skinsProps } = this.props
if (emoji) {
return <div className='emoji-picker-preview'>
@ -44,6 +44,12 @@ export default class Preview extends React.Component {
EmojiPicker
</span>
</div>
<div className='emoji-picker-preview-skins'>
<Skins
{...skinsProps}
/>
</div>
</div>
}
}
@ -51,4 +57,5 @@ export default class Preview extends React.Component {
Preview.propTypes = {
emojiProps: React.PropTypes.object.isRequired,
skinsProps: React.PropTypes.object.isRequired,
}

52
src/components/skins.js Normal file
View File

@ -0,0 +1,52 @@
import React from 'react'
export default class Skins extends React.Component {
constructor(props) {
super(props)
this.state = {
opened: false,
}
}
handleClick(skin) {
var { onChange } = this.props
if (!this.state.opened) {
this.setState({ opened: true })
} else {
onChange(skin)
this.setState({ opened: false })
}
}
render() {
var { skin } = this.props,
{ opened } = this.state
return <div>
<div className={`emoji-picker-skin-swatches ${opened ? 'emoji-picker-skin-swatches-opened' : ''}`}>
{Array(6).fill().map((_, i) => {
var skinTone = i + 1,
selected = skinTone == skin
return <span key={`skin-tone-${skinTone}`} className={`emoji-picker-skin-swatch ${selected ? 'emoji-picker-skin-swatch-selected' : ''}`}>
<span
onClick={() => this.handleClick(skinTone)}
className={`emoji-picker-skin emoji-picker-skin-tone-${skinTone}`}>
</span>
</span>
})}
</div>
</div>
}
}
Skins.propTypes = {
onChange: React.PropTypes.func,
skin: React.PropTypes.number.isRequired,
}
Skins.defaultProps = {
onChange: (() => {}),
}