emoji-mart-lazyload/src/components/category.js

224 lines
4.9 KiB
JavaScript
Raw Normal View History

2016-05-31 14:36:52 +00:00
import React from 'react'
import PropTypes from 'prop-types'
2016-07-07 18:22:02 +00:00
2016-07-20 18:45:28 +00:00
import frequently from '../utils/frequently'
import { getData } from '../utils'
2016-10-27 03:27:55 +00:00
import { Emoji } from '.'
2016-05-31 14:36:52 +00:00
export default class Category extends React.Component {
constructor(props) {
super(props)
this.setContainerRef = this.setContainerRef.bind(this)
this.setLabelRef = this.setLabelRef.bind(this)
}
2016-05-31 16:35:08 +00:00
componentDidMount() {
this.parent = this.container.parentNode
2016-05-31 14:36:52 +00:00
2016-05-31 16:35:08 +00:00
this.margin = 0
this.minMargin = 0
this.memoizeSize()
}
2016-05-31 14:36:52 +00:00
2016-07-08 17:56:29 +00:00
shouldComponentUpdate(nextProps, nextState) {
2017-10-07 04:02:02 +00:00
var {
name,
perLine,
native,
hasStickyPosition,
emojis,
emojiProps,
} = this.props,
{ skin, size, set } = emojiProps,
{
perLine: nextPerLine,
native: nextNative,
hasStickyPosition: nextHasStickyPosition,
emojis: nextEmojis,
emojiProps: nextEmojiProps,
} = nextProps,
{ skin: nextSkin, size: nextSize, set: nextSet } = nextEmojiProps,
shouldUpdate = false
2016-07-08 17:56:29 +00:00
if (name == 'Recent' && perLine != nextPerLine) {
shouldUpdate = true
}
if (name == 'Search') {
shouldUpdate = !(emojis == nextEmojis)
}
2017-10-07 04:02:02 +00:00
if (
skin != nextSkin ||
size != nextSize ||
native != nextNative ||
set != nextSet ||
hasStickyPosition != nextHasStickyPosition
) {
2016-07-08 17:56:29 +00:00
shouldUpdate = true
}
return shouldUpdate
2016-05-31 16:35:08 +00:00
}
memoizeSize() {
var { top, height } = this.container.getBoundingClientRect()
var { top: parentTop } = this.parent.getBoundingClientRect()
var { height: labelHeight } = this.label.getBoundingClientRect()
this.top = top - parentTop + this.parent.scrollTop
if (height == 0) {
this.maxMargin = 0
2016-06-02 15:26:48 +00:00
} else {
this.maxMargin = height - labelHeight
2016-06-02 15:26:48 +00:00
}
2016-05-31 16:35:08 +00:00
}
handleScroll(scrollTop) {
var margin = scrollTop - this.top
margin = margin < this.minMargin ? this.minMargin : margin
margin = margin > this.maxMargin ? this.maxMargin : margin
if (margin == this.margin) return
2016-06-02 15:26:48 +00:00
if (!this.props.hasStickyPosition) {
this.label.style.top = `${margin}px`
}
2016-05-31 16:35:08 +00:00
this.margin = margin
2016-06-02 15:26:48 +00:00
return true
2016-05-31 14:36:52 +00:00
}
getEmojis() {
var { name, emojis, recent, perLine } = this.props
2016-05-31 14:36:52 +00:00
2016-07-07 18:22:02 +00:00
if (name == 'Recent') {
let { custom } = this.props
let frequentlyUsed = recent || frequently.get(perLine)
2016-05-31 16:35:08 +00:00
2016-07-07 18:22:02 +00:00
if (frequentlyUsed.length) {
2017-11-08 03:09:40 +00:00
emojis = frequentlyUsed
.map(id => {
const emoji = custom.filter(e => e.id === id)[0]
if (emoji) {
return emoji
}
return id
})
.filter(id => !!getData(id))
}
if (emojis.length === 0 && frequentlyUsed.length > 0) {
2017-11-08 03:09:40 +00:00
return null
2016-05-31 16:35:08 +00:00
}
}
2016-07-07 18:22:02 +00:00
if (emojis) {
emojis = emojis.slice(0)
}
return emojis
}
updateDisplay(display) {
var emojis = this.getEmojis()
if (!emojis) {
return
}
this.container.style.display = display
}
setContainerRef(c) {
this.container = c
}
setLabelRef(c) {
this.label = c
}
render() {
var { id, name, hasStickyPosition, emojiProps, i18n } = this.props,
2017-10-07 04:02:02 +00:00
emojis = this.getEmojis(),
labelStyles = {},
labelSpanStyles = {},
containerStyles = {}
if (!emojis) {
2016-06-02 15:26:48 +00:00
containerStyles = {
display: 'none',
2016-06-02 15:26:48 +00:00
}
}
2016-07-07 18:22:02 +00:00
if (!hasStickyPosition) {
labelStyles = {
height: 28,
}
labelSpanStyles = {
position: 'absolute',
}
}
2017-10-07 04:02:02 +00:00
return (
<div
ref={this.setContainerRef}
className={`emoji-mart-category ${emojis && !emojis.length
? 'emoji-mart-no-results'
: ''}`}
style={containerStyles}
>
<div
style={labelStyles}
data-name={name}
className="emoji-mart-category-label"
>
<span style={labelSpanStyles} ref={this.setLabelRef}>
{i18n.categories[id]}
2017-10-07 04:02:02 +00:00
</span>
</div>
2017-10-07 04:02:02 +00:00
{emojis && emojis.map(emoji => Emoji({ emoji: emoji, ...emojiProps }))}
{emojis &&
!emojis.length && (
<div>
<div>
{Emoji({
...emojiProps,
size: 38,
emoji: 'sleuth_or_spy',
onOver: null,
onLeave: null,
onClick: null,
})}
</div>
<div className="emoji-mart-no-results-label">{i18n.notfound}</div>
</div>
)}
</div>
)
2016-05-31 14:36:52 +00:00
}
}
Category.propTypes = {
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),
2016-05-31 14:36:52 +00:00
}
Category.defaultProps = {
emojis: [],
2016-05-31 16:35:08 +00:00
hasStickyPosition: true,
2016-05-31 14:36:52 +00:00
}