From 31cc0ab2153fc47ff7011d8b02edb2d96f11f013 Mon Sep 17 00:00:00 2001 From: Rena Ryumae Date: Fri, 22 Jun 2018 17:23:42 -0400 Subject: [PATCH] Customizable Category Icons Currently, the default emoji-mart category icons cannot be changed. We propose creating a categories object that uses the emoji-mart category icons on default but otherwise uses custom imgs/svgs passed in by the user --- README.md | 18 ++++++++++++++++++ css/emoji-mart.css | 6 ++++-- src/components/anchors.js | 25 ++++++------------------- src/components/picker/nimble-picker.js | 18 ++++++++++++++++++ src/utils/shared-props.js | 2 ++ stories/index.js | 22 +++++++++++++++++++++- 6 files changed, 69 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 57dc456..a8f7935 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ import { Picker } from 'emoji-mart' | **defaultSkin** | | `1` | Default skin color: `1, 2, 3, 4, 5, 6` | | **style** | | | Inline styles applied to the root element. Useful for positioning | | **title** | | `Emoji Mart™` | The title shown when no emojis are hovered | +| **icons** | | `{}` | [Custom icons](#custom-icons) | #### I18n ```js @@ -234,6 +235,23 @@ const customEmojis = [ ``` +## Custom icons +You can provide custom icons which will override the default icons. + +```js +import { Picker } from 'emoji-mart' + +const customIcons = { + categories: { + recent: () => , + foods: () => , + people: () => + } +} + + +``` + ## Headless search The `Picker` doesn’t have to be mounted for you to take advantage of the advanced search results. diff --git a/css/emoji-mart.css b/css/emoji-mart.css index 93e62d7..9fbdeb6 100644 --- a/css/emoji-mart.css +++ b/css/emoji-mart.css @@ -72,9 +72,11 @@ max-width: 22px; } -.emoji-mart-anchors svg { +.emoji-mart-anchors svg, +.emoji-mart-anchors img { fill: currentColor; - max-height: 18px; + height: 18px; + width: 18px; } .emoji-mart-scroll { diff --git a/src/components/anchors.js b/src/components/anchors.js index e620387..5008d6b 100644 --- a/src/components/anchors.js +++ b/src/components/anchors.js @@ -1,8 +1,6 @@ import React from 'react' import PropTypes from 'prop-types' -import SVGs from '../svgs' - export default class Anchors extends React.PureComponent { constructor(props) { super(props) @@ -18,21 +16,6 @@ export default class Anchors extends React.PureComponent { this.handleClick = this.handleClick.bind(this) } - getSVG(id) { - this.SVGs || (this.SVGs = {}) - - if (this.SVGs[id]) { - return this.SVGs[id] - } else { - let svg = ` - ${SVGs[id]} - ` - - this.SVGs[id] = svg - return svg - } - } - handleClick(e) { var index = e.currentTarget.getAttribute('data-index') var { categories, onAnchorClick } = this.props @@ -41,7 +24,7 @@ export default class Anchors extends React.PureComponent { } render() { - var { categories, onAnchorClick, color, i18n } = this.props, + var { categories, color, i18n, icons } = this.props, { selected } = this.state return ( @@ -65,7 +48,9 @@ export default class Anchors extends React.PureComponent { }`} style={{ color: isSelected ? color : null }} > -
+
+ {icons.categories[id]()} +
{}, + icons: {}, } diff --git a/src/components/picker/nimble-picker.js b/src/components/picker/nimble-picker.js index 20586e1..9cd396f 100644 --- a/src/components/picker/nimble-picker.js +++ b/src/components/picker/nimble-picker.js @@ -3,6 +3,7 @@ import '../../vendor/raf-polyfill' import React from 'react' import PropTypes from 'prop-types' +import SVGs from '../../svgs' import store from '../../utils/store' import frequently from '../../utils/frequently' import { deepMerge, measureScrollbar } from '../../utils' @@ -29,6 +30,21 @@ const I18N = { }, } +const toSVG = (val) => () => ( + +) + +const ICON_FNS = { + categories: Object.keys(SVGs).reduce((acc, cur) => { + acc[cur] = toSVG(SVGs[cur]) + return acc + }, {}), +} + export default class NimblePicker extends React.PureComponent { constructor(props) { super(props) @@ -48,6 +64,7 @@ export default class NimblePicker extends React.PureComponent { this.data = props.data this.i18n = deepMerge(I18N, props.i18n) + this.icons = deepMerge(ICON_FNS, props.icons) this.state = { skin: props.skin || store.get('skin') || props.defaultSkin, firstRender: true, @@ -485,6 +502,7 @@ export default class NimblePicker extends React.PureComponent { color={color} categories={this.categories} onAnchorClick={this.handleAnchorClick} + icons={this.icons} />
diff --git a/src/utils/shared-props.js b/src/utils/shared-props.js index 3bb8083..89b6840 100644 --- a/src/utils/shared-props.js +++ b/src/utils/shared-props.js @@ -71,6 +71,7 @@ const PickerPropTypes = { imageUrl: PropTypes.string.isRequired, }), ), + icons: PropTypes.object, } const PickerDefaultProps = { @@ -96,6 +97,7 @@ const PickerDefaultProps = { emojiTooltip: EmojiDefaultProps.tooltip, autoFocus: false, custom: [], + icons: {}, } export { diff --git a/stories/index.js b/stories/index.js index b0798ec..60a035b 100644 --- a/stories/index.js +++ b/stories/index.js @@ -41,7 +41,27 @@ storiesOf('Picker', module) showPreview={boolean('Show preview', true)} showSkinTones={boolean('Show skin tones', true)} custom={CUSTOM_EMOJIS} - /> + />)) + .add('with-custom-icons', () => ( + , + people: () => Reddit icon, + nature: () => , + foods: () => Jira icon, + activity: () => , + places: () => Stack Overflow icon, + objects: () => Atlassian icon, + symbols: () => HipChat icon, + flags: () => , + custom: () => Trello icon, + } + } + } + /> )); storiesOf('Emoji', module)