Add custom emoji lazyload

release
mashirozx 2021-10-25 14:15:01 +08:00
parent fe28ab637b
commit 7edf171664
5 changed files with 11423 additions and 10838 deletions

View File

@ -137,7 +137,7 @@
} }
.emoji-mart-category .emoji-mart-emoji:hover:before { .emoji-mart-category .emoji-mart-emoji:hover:before {
z-index: 0; z-index: -1;
content: ""; content: "";
position: absolute; position: absolute;
top: 0; left: 0; top: 0; left: 0;

View File

@ -1,88 +1,89 @@
{ {
"name": "emoji-mart", "name": "emoji-mart-lazyload",
"version": "3.0.1", "version": "3.0.1h",
"description": "Customizable Slack-like emoji picker for React", "description": "Customizable Slack-like emoji picker for React",
"main": "dist/index.js", "main": "dist/index.js",
"module": "dist-es/index.js", "module": "dist-es/index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git@github.com:missive/emoji-mart.git" "url": "git@github.com:mashirozx/emoji-mart.git"
}, },
"keywords": [ "keywords": [
"react", "react",
"emoji", "emoji",
"picker" "picker"
], ],
"author": "Etienne Lemay", "author": "Etienne Lemay",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"bugs": { "bugs": {
"url": "https://github.com/missive/emoji-mart/issues" "url": "https://github.com/mashirozx/emoji-mart/issues"
}, },
"homepage": "https://github.com/missive/emoji-mart", "homepage": "https://github.com/mashirozx/emoji-mart",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.0.0", "@babel/runtime": "^7.0.0",
"prop-types": "^15.6.0" "intersection-observer": "^0.12.0",
}, "prop-types": "^15.6.0"
"peerDependencies": { },
"react": "^0.14.0 || ^15.0.0-0 || ^16.0.0 || ^17.0.0" "peerDependencies": {
}, "react": "^0.14.0 || ^15.0.0-0 || ^16.0.0 || ^17.0.0"
"devDependencies": { },
"@babel/cli": "^7.0.0", "devDependencies": {
"@babel/core": "^7.0.0", "@babel/cli": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.7.6", "@babel/core": "^7.0.0",
"@babel/preset-env": "^7.0.0", "@babel/plugin-transform-runtime": "^7.7.6",
"@babel/preset-react": "7.0.0", "@babel/preset-env": "^7.0.0",
"@storybook/addon-actions": "^3.2.11", "@babel/preset-react": "7.0.0",
"@storybook/addon-knobs": "^3.2.10", "@storybook/addon-actions": "^3.2.11",
"@storybook/addon-links": "^3.2.10", "@storybook/addon-knobs": "^3.2.10",
"@storybook/addon-options": "3.2.10", "@storybook/addon-links": "^3.2.10",
"@storybook/react": "^3.2.11", "@storybook/addon-options": "3.2.10",
"babel-jest": "^24.9.0", "@storybook/react": "^3.2.11",
"babel-loader": "^8.0.0", "babel-jest": "^24.9.0",
"babel-plugin-transform-define": "^2.0.0", "babel-loader": "^8.0.0",
"emoji-datasource": "5.0.1", "babel-plugin-transform-define": "^2.0.0",
"emojilib": "^2.2.1", "emoji-datasource": "5.0.1",
"enzyme": "^3.9.0", "emojilib": "^2.2.1",
"enzyme-adapter-react-16": "^1.11.2", "enzyme": "^3.9.0",
"inflection": "1.10.0", "enzyme-adapter-react-16": "^1.11.2",
"jest": "^24.9.0", "inflection": "1.10.0",
"mkdirp": "0.5.1", "jest": "^24.9.0",
"prettier": "^1.16.4", "mkdirp": "0.5.1",
"react": "^16.0.0", "prettier": "^1.16.4",
"react-dom": "^16.0.0", "react": "^16.0.0",
"react-test-renderer": "^16.8.4", "react-dom": "^16.0.0",
"rimraf": "2.5.2", "react-test-renderer": "^16.8.4",
"size-limit": "^0.11.4", "rimraf": "2.5.2",
"webpack": "^3.6.0" "size-limit": "^0.11.4",
}, "webpack": "^3.6.0"
"scripts": { },
"clean": "rm -rf dist/ dist-es/ dist-modern/", "scripts": {
"build:data": "node scripts/build-data", "clean": "rm -rf dist/ dist-es/ dist-modern/",
"build:dist": "npm run build:cjs && npm run build:es && npm run build:modern", "build:data": "node scripts/build-data",
"build:cjs": "BABEL_ENV=legacy-cjs babel src --out-dir dist --ignore '**/__tests__/*'", "build:dist": "npm run build:cjs && npm run build:es && npm run build:modern",
"build:es": "BABEL_ENV=legacy-es babel src --out-dir dist-es --ignore '**/__tests__/*'", "build:cjs": "BABEL_ENV=legacy-cjs babel src --out-dir dist --ignore '**/__tests__/*'",
"build:modern": "BABEL_ENV=modern babel src --out-dir dist-modern --ignore '**/__tests__/*'", "build:es": "BABEL_ENV=legacy-es babel src --out-dir dist-es --ignore '**/__tests__/*'",
"build:docs": "cp css/emoji-mart.css docs && webpack --config ./docs/webpack.config.js", "build:modern": "BABEL_ENV=modern babel src --out-dir dist-modern --ignore '**/__tests__/*'",
"build": "npm run clean && npm run build:dist", "build:docs": "cp css/emoji-mart.css docs && webpack --config ./docs/webpack.config.js",
"watch": "BABEL_ENV=legacy-cjs babel src --watch --out-dir dist --ignore '**/__tests__/*'", "build": "npm run clean && npm run build:dist",
"start": "npm run watch", "watch": "BABEL_ENV=legacy-cjs babel src --watch --out-dir dist --ignore '**/__tests__/*'",
"react:clean": "rimraf node_modules/{react,react-dom,react-addons-test-utils}", "start": "npm run watch",
"react:14": "npm run react:clean && npm i react@^0.14 react-dom@^0.14 react-addons-test-utils@^0.14 --save-dev", "react:clean": "rimraf node_modules/{react,react-dom,react-addons-test-utils}",
"react:15": "npm run react:clean && npm i react@^15 react-dom@^15 react-addons-test-utils@^15 --save-dev", "react:14": "npm run react:clean && npm i react@^0.14 react-dom@^0.14 react-addons-test-utils@^0.14 --save-dev",
"test": "npm run clean && jest", "react:15": "npm run react:clean && npm i react@^15 react-dom@^15 react-addons-test-utils@^15 --save-dev",
"test:size": "size-limit", "test": "npm run clean && jest",
"test:ssr": "node test/ssr.js", "test:size": "size-limit",
"prepublishOnly": "npm run build", "test:ssr": "node test/ssr.js",
"storybook": "start-storybook -p 6006", "prepublishOnly": "npm run build",
"build-storybook": "build-storybook", "storybook": "start-storybook -p 6006",
"prettier": "prettier --write \"{src,scripts,test,stories}/**/*.js\"", "build-storybook": "build-storybook",
"prettier:check": "prettier --check \"{src,scripts,test,stories}/**/*.js\"", "prettier": "prettier --write \"{src,scripts,test,stories}/**/*.js\"",
"prepare": "npm run build:dist" "prettier:check": "prettier --check \"{src,scripts,test,stories}/**/*.js\"",
}, "prepare": "npm run build:dist"
"size-limit": [ },
{ "size-limit": [
"path": "dist-es/index.js", {
"limit": "82 KB" "path": "dist-es/index.js",
} "limit": "82 KB"
] }
} ]
}

View File

@ -1,248 +1,287 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import frequently from '../utils/frequently' import frequently from '../utils/frequently'
import { getData } from '../utils' import { getData } from '../utils'
import NimbleEmoji from './emoji/nimble-emoji' import NimbleEmoji from './emoji/nimble-emoji'
import NotFound from './not-found' import NotFound from './not-found'
import 'intersection-observer'
export default class Category extends React.Component {
constructor(props) { export default class Category extends React.Component {
super(props) constructor(props) {
super(props)
this.data = props.data
this.setContainerRef = this.setContainerRef.bind(this) this.data = props.data
this.setLabelRef = this.setLabelRef.bind(this) this.setContainerRef = this.setContainerRef.bind(this)
} this.setLabelRef = this.setLabelRef.bind(this)
componentDidMount() { this.imageObserver = new window.IntersectionObserver((entries, observer) => {
this.margin = 0 entries.forEach((entry) => {
this.minMargin = 0 if (entry.isIntersecting) {
const image = entry.target;
this.memoizeSize() image.src = image.dataset.src;
} image.classList.remove("lazy");
this.imageObserver.unobserve(image);
shouldComponentUpdate(nextProps, nextState) { }
var { });
name, });
perLine, }
native,
hasStickyPosition, componentDidMount() {
emojis, this.margin = 0
emojiProps, this.minMargin = 0
} = this.props,
{ skin, size, set } = emojiProps, this.memoizeSize()
{
perLine: nextPerLine, this.lazyloadImages = []
native: nextNative, this.lazyload()
hasStickyPosition: nextHasStickyPosition, }
emojis: nextEmojis,
emojiProps: nextEmojiProps, componentDidUpdate() {
} = nextProps, this.lazyload()
{ skin: nextSkin, size: nextSize, set: nextSet } = nextEmojiProps, }
shouldUpdate = false
componentWillUnmount() {
if (name == 'Recent' && perLine != nextPerLine) { this.removeLazyloadObserver()
shouldUpdate = true }
}
shouldComponentUpdate(nextProps, nextState) {
if (name == 'Search') { var {
shouldUpdate = !(emojis == nextEmojis) name,
} perLine,
native,
if ( hasStickyPosition,
skin != nextSkin || emojis,
size != nextSize || emojiProps,
native != nextNative || } = this.props,
set != nextSet || { skin, size, set } = emojiProps,
hasStickyPosition != nextHasStickyPosition {
) { perLine: nextPerLine,
shouldUpdate = true native: nextNative,
} hasStickyPosition: nextHasStickyPosition,
emojis: nextEmojis,
return shouldUpdate emojiProps: nextEmojiProps,
} } = nextProps,
{ skin: nextSkin, size: nextSize, set: nextSet } = nextEmojiProps,
memoizeSize() { shouldUpdate = false
if (!this.container) {
// probably this is a test environment, e.g. jest if (name == 'Recent' && perLine != nextPerLine) {
this.top = 0 shouldUpdate = true
this.maxMargin = 0 }
return
} if (name == 'Search') {
var parent = this.container.parentElement // shouldUpdate = !(emojis == nextEmojis)
var { top, height } = this.container.getBoundingClientRect() shouldUpdate = true
var { top: parentTop } = parent.getBoundingClientRect() }
var { height: labelHeight } = this.label.getBoundingClientRect()
if (
this.top = top - parentTop + parent.scrollTop skin != nextSkin ||
size != nextSize ||
if (height == 0) { native != nextNative ||
this.maxMargin = 0 set != nextSet ||
} else { hasStickyPosition != nextHasStickyPosition
this.maxMargin = height - labelHeight ) {
} shouldUpdate = true
} }
handleScroll(scrollTop) { return shouldUpdate
var margin = scrollTop - this.top }
margin = margin < this.minMargin ? this.minMargin : margin
margin = margin > this.maxMargin ? this.maxMargin : margin memoizeSize() {
if (!this.container) {
if (margin == this.margin) return // probably this is a test environment, e.g. jest
this.top = 0
if (!this.props.hasStickyPosition) { this.maxMargin = 0
this.label.style.top = `${margin}px` return
} }
var parent = this.container.parentElement
this.margin = margin var { top, height } = this.container.getBoundingClientRect()
return true var { top: parentTop } = parent.getBoundingClientRect()
} var { height: labelHeight } = this.label.getBoundingClientRect()
getEmojis() { this.top = top - parentTop + parent.scrollTop
var { name, emojis, recent, perLine } = this.props
if (height == 0) {
if (name == 'Recent') { this.maxMargin = 0
let { custom } = this.props } else {
let frequentlyUsed = recent || frequently.get(perLine) this.maxMargin = height - labelHeight
}
if (frequentlyUsed.length) { }
emojis = frequentlyUsed
.map((id) => { lazyload() {
const emoji = custom.filter((e) => e.id === id)[0] this.removeLazyloadObserver()
if (emoji) { this.lazyloadImages = this.container.querySelectorAll(".lazy");
return emoji
} this.lazyloadImages.forEach((image) => {
this.imageObserver.observe(image);
return id });
}) }
.filter((id) => !!getData(id, null, null, this.data))
} removeLazyloadObserver() {
this.lazyloadImages.forEach((image) => {
if (emojis.length === 0 && frequentlyUsed.length > 0) { this.imageObserver.unobserve(image);
return null })
} }
}
handleScroll(scrollTop) {
if (emojis) { var margin = scrollTop - this.top
emojis = emojis.slice(0) margin = margin < this.minMargin ? this.minMargin : margin
} margin = margin > this.maxMargin ? this.maxMargin : margin
return emojis if (margin == this.margin) return
}
if (!this.props.hasStickyPosition) {
updateDisplay(display) { this.label.style.top = `${margin}px`
var emojis = this.getEmojis() }
if (!emojis || !this.container) { this.margin = margin
return return true
} }
this.container.style.display = display getEmojis() {
} var { name, emojis, recent, perLine } = this.props
setContainerRef(c) { if (name == 'Recent') {
this.container = c let { custom } = this.props
} let frequentlyUsed = recent || frequently.get(perLine)
setLabelRef(c) { if (frequentlyUsed.length) {
this.label = c emojis = frequentlyUsed
} .map((id) => {
const emoji = custom.filter((e) => e.id === id)[0]
render() { if (emoji) {
var { return emoji
id, }
name,
hasStickyPosition, return id
emojiProps, })
i18n, .filter((id) => !!getData(id, null, null, this.data))
notFound, }
notFoundEmoji,
} = this.props, if (emojis.length === 0 && frequentlyUsed.length > 0) {
emojis = this.getEmojis(), return null
labelStyles = {}, }
labelSpanStyles = {}, }
containerStyles = {}
if (emojis) {
if (!emojis) { emojis = emojis.slice(0)
containerStyles = { }
display: 'none',
} return emojis
} }
if (!hasStickyPosition) { updateDisplay(display) {
labelStyles = { var emojis = this.getEmojis()
height: 28,
} if (!emojis || !this.container) {
return
labelSpanStyles = { }
position: 'absolute',
} this.container.style.display = display
} }
const label = i18n.categories[id] || name setContainerRef(c) {
this.container = c
return ( }
<section
ref={this.setContainerRef} setLabelRef(c) {
className="emoji-mart-category" this.label = c
aria-label={label} }
style={containerStyles}
> render() {
<div var {
style={labelStyles} id,
data-name={name} name,
className="emoji-mart-category-label" hasStickyPosition,
> emojiProps,
<span i18n,
style={labelSpanStyles} notFound,
ref={this.setLabelRef} notFoundEmoji,
aria-hidden={true /* already labeled by the section aria-label */} } = this.props,
> emojis = this.getEmojis(),
{label} labelStyles = {},
</span> labelSpanStyles = {},
</div> containerStyles = {}
<ul className="emoji-mart-category-list"> if (!emojis) {
{emojis && containerStyles = {
emojis.map((emoji) => ( display: 'none',
<li }
key={ }
(emoji.short_names && emoji.short_names.join('_')) || emoji
} if (!hasStickyPosition) {
> labelStyles = {
{NimbleEmoji({ emoji: emoji, data: this.data, ...emojiProps })} height: 28,
</li> }
))}
</ul> labelSpanStyles = {
position: 'absolute',
{emojis && !emojis.length && ( }
<NotFound }
i18n={i18n}
notFound={notFound} const label = i18n.categories[id] || name
notFoundEmoji={notFoundEmoji}
data={this.data} return (
emojiProps={emojiProps} <section
/> ref={this.setContainerRef}
)} className="emoji-mart-category"
</section> aria-label={label}
) style={containerStyles}
} >
} <div
style={labelStyles}
Category.propTypes /* remove-proptypes */ = { data-name={name}
emojis: PropTypes.array, className="emoji-mart-category-label"
hasStickyPosition: PropTypes.bool, >
name: PropTypes.string.isRequired, <span
native: PropTypes.bool.isRequired, style={labelSpanStyles}
perLine: PropTypes.number.isRequired, ref={this.setLabelRef}
emojiProps: PropTypes.object.isRequired, aria-hidden={true /* already labeled by the section aria-label */}
recent: PropTypes.arrayOf(PropTypes.string), >
notFound: PropTypes.func, {label}
notFoundEmoji: PropTypes.string.isRequired, </span>
} </div>
Category.defaultProps = { <ul className="emoji-mart-category-list">
emojis: [], {emojis &&
hasStickyPosition: true, emojis.map((emoji) => (
} <li
key={
(emoji.short_names && emoji.short_names.join('_')) || emoji
}
>
{NimbleEmoji({ emoji: emoji, data: this.data, ...emojiProps, lazy: true })}
</li>
))}
</ul>
{emojis && !emojis.length && (
<NotFound
i18n={i18n}
notFound={notFound}
notFoundEmoji={notFoundEmoji}
data={this.data}
emojiProps={emojiProps}
/>
)}
</section>
)
}
}
Category.propTypes /* remove-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),
notFound: PropTypes.func,
notFoundEmoji: PropTypes.string.isRequired,
}
Category.defaultProps = {
emojis: [],
hasStickyPosition: true,
}

View File

@ -1,222 +1,240 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { getData, getSanitizedData, unifiedToNative } from '../../utils' import { getData, getSanitizedData, unifiedToNative } from '../../utils'
import { uncompress } from '../../utils/data' import { uncompress } from '../../utils/data'
import { EmojiPropTypes } from '../../utils/shared-props' import { EmojiPropTypes } from '../../utils/shared-props'
import { EmojiDefaultProps } from '../../utils/shared-default-props' import { EmojiDefaultProps } from '../../utils/shared-default-props'
const _getData = (props) => { const _getData = (props) => {
var { emoji, skin, set, data } = props var { emoji, skin, set, data } = props
return getData(emoji, skin, set, data) return getData(emoji, skin, set, data)
} }
const _getPosition = (props) => { const _getPosition = (props) => {
var { sheet_x, sheet_y } = _getData(props), var { sheet_x, sheet_y } = _getData(props),
multiplyX = 100 / (props.sheetColumns - 1), multiplyX = 100 / (props.sheetColumns - 1),
multiplyY = 100 / (props.sheetRows - 1) multiplyY = 100 / (props.sheetRows - 1)
return `${multiplyX * sheet_x}% ${multiplyY * sheet_y}%` return `${multiplyX * sheet_x}% ${multiplyY * sheet_y}%`
} }
const _getSanitizedData = (props) => { const _getSanitizedData = (props) => {
var { emoji, skin, set, data } = props var { emoji, skin, set, data } = props
return getSanitizedData(emoji, skin, set, data) return getSanitizedData(emoji, skin, set, data)
} }
const _handleClick = (e, props) => { const _handleClick = (e, props) => {
if (!props.onClick) { if (!props.onClick) {
return return
} }
var { onClick } = props, var { onClick } = props,
emoji = _getSanitizedData(props) emoji = _getSanitizedData(props)
onClick(emoji, e) onClick(emoji, e)
} }
const _handleOver = (e, props) => { const _handleOver = (e, props) => {
if (!props.onOver) { if (!props.onOver) {
return return
} }
var { onOver } = props, var { onOver } = props,
emoji = _getSanitizedData(props) emoji = _getSanitizedData(props)
onOver(emoji, e) onOver(emoji, e)
} }
const _handleLeave = (e, props) => { const _handleLeave = (e, props) => {
if (!props.onLeave) { if (!props.onLeave) {
return return
} }
var { onLeave } = props, var { onLeave } = props,
emoji = _getSanitizedData(props) emoji = _getSanitizedData(props)
onLeave(emoji, e) onLeave(emoji, e)
} }
const _isNumeric = (value) => { const _isNumeric = (value) => {
return !isNaN(value - parseFloat(value)) return !isNaN(value - parseFloat(value))
} }
const _convertStyleToCSS = (style) => { const _convertStyleToCSS = (style) => {
let div = document.createElement('div') let div = document.createElement('div')
for (let key in style) { for (let key in style) {
let value = style[key] let value = style[key]
if (_isNumeric(value)) { if (_isNumeric(value)) {
value += 'px' value += 'px'
} }
div.style[key] = value div.style[key] = value
} }
return div.getAttribute('style') return div.getAttribute('style')
} }
const NimbleEmoji = (props) => { const NimbleEmoji = (props) => {
if (props.data.compressed) { if (props.data.compressed) {
uncompress(props.data) uncompress(props.data)
} }
for (let k in NimbleEmoji.defaultProps) { for (let k in NimbleEmoji.defaultProps) {
if (props[k] == undefined && NimbleEmoji.defaultProps[k] != undefined) { if (props[k] == undefined && NimbleEmoji.defaultProps[k] != undefined) {
props[k] = NimbleEmoji.defaultProps[k] props[k] = NimbleEmoji.defaultProps[k]
} }
} }
let data = _getData(props) let data = _getData(props)
if (!data) { if (!data) {
if (props.fallback) { if (props.fallback) {
return props.fallback(null, props) return props.fallback(null, props)
} else { } else {
return null return null
} }
} }
let { unified, custom, short_names, imageUrl } = data, let { unified, custom, short_names, imageUrl } = data,
style = {}, style = {},
children = props.children, children = props.children,
className = 'emoji-mart-emoji', className = 'emoji-mart-emoji',
nativeEmoji = unified && unifiedToNative(unified), nativeEmoji = unified && unifiedToNative(unified),
// combine the emoji itself and all shortcodes into an accessible label // combine the emoji itself and all shortcodes into an accessible label
label = [nativeEmoji] label = [nativeEmoji]
.concat(short_names) .concat(short_names)
.filter(Boolean) .filter(Boolean)
.join(', '), .join(', '),
title = null title = null
if (!unified && !custom) { if (!unified && !custom) {
if (props.fallback) { if (props.fallback) {
return props.fallback(data, props) return props.fallback(data, props)
} else { } else {
return null return null
} }
} }
if (props.tooltip) { if (props.tooltip) {
title = short_names[0] title = short_names[0]
} }
if (props.native && unified) { if (props.native && unified) {
className += ' emoji-mart-emoji-native' className += ' emoji-mart-emoji-native'
style = { fontSize: props.size } style = { fontSize: props.size }
children = nativeEmoji children = nativeEmoji
if (props.forceSize) { if (props.forceSize) {
style.display = 'inline-block' style.display = 'inline-block'
style.width = props.size style.width = props.size
style.height = props.size style.height = props.size
style.wordBreak = 'keep-all' style.wordBreak = 'keep-all'
} }
} else if (custom) { } else if (custom) {
className += ' emoji-mart-emoji-custom' className += ' emoji-mart-emoji-custom'
style = { style = {
width: props.size, width: props.size,
height: props.size, height: props.size,
display: 'inline-block', display: 'inline-block',
} }
if (data.spriteUrl) { if (data.spriteUrl) {
style = { style = {
...style, ...style,
backgroundImage: `url(${data.spriteUrl})`, backgroundImage: `url(${data.spriteUrl})`,
backgroundSize: `${100 * props.sheetColumns}% ${100 * backgroundSize: `${100 * props.sheetColumns}% ${100 *
props.sheetRows}%`, props.sheetRows}%`,
backgroundPosition: _getPosition(props), backgroundPosition: _getPosition(props),
} }
} else { } else {
style = { style = {
...style, ...style,
backgroundImage: `url(${imageUrl})`, backgroundImage: `url(${imageUrl})`,
backgroundSize: 'contain', backgroundSize: 'contain',
backgroundRepeat: 'no-repeat', backgroundRepeat: 'no-repeat',
backgroundPosition: 'center', backgroundPosition: 'center',
} }
} if(props.lazy){
} else { delete style.backgroundImage
let setHasEmoji = delete style.backgroundSize
data[`has_img_${props.set}`] == undefined || data[`has_img_${props.set}`] delete style.backgroundRepeat
delete style.backgroundPosition
if (!setHasEmoji) { style.objectFit = 'contain'
if (props.fallback) { }
return props.fallback(data, props) }
} else { } else {
return null let setHasEmoji =
} data[`has_img_${props.set}`] == undefined || data[`has_img_${props.set}`]
} else {
style = { if (!setHasEmoji) {
width: props.size, if (props.fallback) {
height: props.size, return props.fallback(data, props)
display: 'inline-block', } else {
backgroundImage: `url(${props.backgroundImageFn( return null
props.set, }
props.sheetSize, } else {
)})`, style = {
backgroundSize: `${100 * props.sheetColumns}% ${100 * width: props.size,
props.sheetRows}%`, height: props.size,
backgroundPosition: _getPosition(props), display: 'inline-block',
} backgroundImage: `url(${props.backgroundImageFn(
} props.set,
} props.sheetSize,
)})`,
var Tag = { backgroundSize: `${100 * props.sheetColumns}% ${100 *
name: 'span', props.sheetRows}%`,
props: {}, backgroundPosition: _getPosition(props),
} }
}
if (props.onClick && props.useButton) { }
Tag.name = 'button'
Tag.props = { var Tag = {
type: 'button', name: 'span',
} props: {},
} }
if (props.html) { if (props.onClick && props.useButton) {
style = _convertStyleToCSS(style) Tag.name = 'button'
return `<${Tag.name} style='${style}' aria-label='${label}' ${ Tag.props = {
title ? `title='${title}'` : '' type: 'button',
} class='${className}'>${children || ''}</${Tag.name}>` }
} else { }
return (
<Tag.name if (props.html) {
onClick={(e) => _handleClick(e, props)} style = _convertStyleToCSS(style)
onMouseEnter={(e) => _handleOver(e, props)} return `<${Tag.name} style='${style}' aria-label='${label}' ${
onMouseLeave={(e) => _handleLeave(e, props)} title ? `title='${title}'` : ''
aria-label={label} } class='${className}'>${children || ''}</${Tag.name}>`
title={title} } else {
className={className} return (
{...Tag.props} <Tag.name
> onClick={(e) => _handleClick(e, props)}
<span style={style}>{children}</span> onMouseEnter={(e) => _handleOver(e, props)}
</Tag.name> onMouseLeave={(e) => _handleLeave(e, props)}
) aria-label={label}
} title={title}
} className={className}
{...Tag.props}
NimbleEmoji.propTypes /* remove-proptypes */ = { >
...EmojiPropTypes, {
data: PropTypes.object.isRequired, custom && !data.spriteUrl && props.lazy
} ?
NimbleEmoji.defaultProps = EmojiDefaultProps <img
style={style}
export default NimbleEmoji className="lazy"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP89B8AAukB8/71MdcAAAAASUVORK5CYII="
data-src={imageUrl}
/>
:
<span style={style}>{children}</span>
}
</Tag.name>
)
}
}
NimbleEmoji.propTypes /* remove-proptypes */ = {
...EmojiPropTypes,
data: PropTypes.object.isRequired,
}
NimbleEmoji.defaultProps = EmojiDefaultProps
export default NimbleEmoji

21085
yarn.lock

File diff suppressed because it is too large Load Diff