Implement search

exclude-unsupported-native-emojis
Etienne Lemay 2016-05-31 14:39:30 -04:00
parent 21bb9eb63e
commit c3f1c6c661
4 changed files with 93 additions and 13 deletions

View File

@ -27,7 +27,7 @@
.emoji-picker-scroll {
overflow: scroll;
max-height: 270px;
height: 270px;
padding: 0 6px 6px 6px;
border: solid #d9d9d9;
border-width: 1px 0;

View File

@ -18,7 +18,8 @@
"url": "https://github.com/missive/emoji-picker/issues"
},
"homepage": "https://github.com/missive/emoji-picker",
"dependencies": {},
"dependencies": {
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0-0"
},
@ -29,6 +30,7 @@
"babel-preset-react": "6.5.0",
"emoji-data": "git://github.com/missive/emoji-data.git#01aeccb3adf6cdfaab6e13892f7688740047ff32",
"inflection": "1.10.0",
"lunr": "0.7.1",
"mkdirp": "0.5.1",
"react": "0.14.7",
"react-dom": "0.14.7",

View File

@ -3,9 +3,23 @@ import React from 'react'
import data from '../../data'
import Preview from './preview'
import Category from './category'
import Search from './search'
export default class Picker extends React.Component {
componentWillMount() {
constructor(props) {
super(props)
this.testStickyPosition()
this.state = {
categories: data.categories,
}
}
componentDidUpdate() {
this.handleScroll()
}
testStickyPosition() {
var stickyTestElement = document.createElement('div')
for (let prefix of ['', '-webkit-', '-ms-', '-moz-', '-o-']) {
stickyTestElement.style.position = `${prefix}sticky`
@ -14,10 +28,6 @@ export default class Picker extends React.Component {
this.hasStickyPosition = !!stickyTestElement.style.position.length
}
componentDidUpdate() {
this.handleScroll()
}
handleEmojiOver(emoji) {
var { preview } = this.refs
preview.setState({ emoji: emoji })
@ -28,7 +38,7 @@ export default class Picker extends React.Component {
scrollTop = target.scrollTop
if (!this.hasStickyPosition) {
Array(data.categories.length).fill().forEach((_, i) => {
Array(this.state.categories.length).fill().forEach((_, i) => {
var category = this.refs[`category-${i}`]
if (category) {
category.handleScroll(scrollTop)
@ -37,6 +47,17 @@ export default class Picker extends React.Component {
}
}
handleSearch(emojis) {
if (emojis == null) {
this.setState({ categories: data.categories })
} else {
this.setState({ categories: [{
name: 'Search Results',
emojis: emojis,
}]})
}
}
render() {
var { perLine, emojiSize, sheetURL } = this.props
@ -46,13 +67,11 @@ export default class Picker extends React.Component {
</div>
<div ref="scroll" className='emoji-picker-scroll' onScroll={this.handleScroll.bind(this)}>
<input
type='text'
placeholder='Search'
className='emoji-picker-search'
<Search
onSearch={this.handleSearch.bind(this)}
/>
{data.categories.map((category, i) => {
{this.state.categories.map((category, i) => {
if (category.name == 'Skins') return null
return <Category
ref={`category-${i}`}

59
src/components/search.js Normal file
View File

@ -0,0 +1,59 @@
import React from 'react'
import lunr from 'lunr'
import data from '../../data'
export default class Search extends React.Component {
constructor(props) {
super(props)
this.buildIndex()
}
buildIndex() {
this.index = lunr(function() {
this.field('short_name', { boost: 2 })
this.field('name')
this.ref('short_name')
})
for (let emoji in data.emojis) {
let emojiData = data.emojis[emoji],
{ short_name, name } = emojiData
this.index.add({ short_name, name })
}
}
handleChange() {
var { input } = this.refs,
value = input.value,
results = null
if (value.length) {
results = this.index.search(value).map((result) =>
result.ref
)
}
this.props.onSearch(results)
}
render() {
return <input
ref='input'
type='text'
onChange={this.handleChange.bind(this)}
placeholder='Search'
className='emoji-picker-search'
/>
}
}
Search.propTypes = {
onSearch: React.PropTypes.func,
}
Search.defaultProps = {
onSearch: (() => {}),
}