Update theme handling [Fix #404]
- Defaults to “light” - “auto” picks light/dark based on `prefers-color-scheme: dark` media query (and actually updates automatically)dependabot/npm_and_yarn/websocket-extensions-0.1.4
parent
c41fc5ec7a
commit
d1138c00e8
|
@ -29,7 +29,6 @@ import { Picker } from 'emoji-mart'
|
|||
| **autoFocus** | | `false` | Auto focus the search input when mounted |
|
||||
| **color** | | `#ae65c5` | The top bar anchors select and hover color |
|
||||
| **emoji** | | `department_store` | The emoji shown when no emojis are hovered, set to an empty string to show nothing |
|
||||
| **darkMode** | | varies | Dark mode (boolean). `true` by default if the browser reports [`prefers-color-scheme: dark`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme). |
|
||||
| **include** | | `[]` | Only load included categories. Accepts [I18n categories keys](#i18n). Order will be respected, except for the `recent` category which will always be the first. |
|
||||
| **exclude** | | `[]` | Don't load excluded categories. Accepts [I18n categories keys](#i18n). |
|
||||
| **custom** | | `[]` | [Custom emojis](#custom-emojis) |
|
||||
|
@ -43,6 +42,7 @@ import { Picker } from 'emoji-mart'
|
|||
| **i18n** | | [`{…}`](#i18n) | [An object](#i18n) containing localized strings |
|
||||
| **native** | | `false` | Renders the native unicode emoji |
|
||||
| **set** | | `apple` | The emoji set: `'apple', 'google', 'twitter', 'facebook'` |
|
||||
| **theme** | | `light` | The picker theme: `'auto', 'light', 'dark'` |
|
||||
| **sheetSize** | | `64` | The emoji [sheet size](#sheet-sizes): `16, 20, 32, 64` |
|
||||
| **backgroundImageFn** | | ```((set, sheetSize) => …)``` | A Fn that returns that image sheet to use for emojis. Useful for avoiding a request if you have the sheet locally. |
|
||||
| **emojisToShowFilter** | | ```((emoji) => true)``` | A Fn to choose whether an emoji should be displayed or not |
|
||||
|
|
|
@ -1539,6 +1539,7 @@ var PickerPropTypes = {
|
|||
showSkinTones: _propTypes["default"].bool,
|
||||
emojiTooltip: EmojiPropTypes.tooltip,
|
||||
useButton: EmojiPropTypes.useButton,
|
||||
theme: _propTypes["default"].oneOf(['auto', 'light', 'dark']),
|
||||
include: _propTypes["default"].arrayOf(_propTypes["default"].string),
|
||||
exclude: _propTypes["default"].arrayOf(_propTypes["default"].string),
|
||||
recent: _propTypes["default"].arrayOf(_propTypes["default"].string),
|
||||
|
@ -1602,6 +1603,7 @@ var PickerDefaultProps = {
|
|||
emoji: 'department_store',
|
||||
color: '#ae65c5',
|
||||
set: EmojiDefaultProps.set,
|
||||
theme: 'light',
|
||||
skin: null,
|
||||
defaultSkin: EmojiDefaultProps.skin,
|
||||
"native": EmojiDefaultProps["native"],
|
||||
|
@ -1610,7 +1612,6 @@ var PickerDefaultProps = {
|
|||
emojisToShowFilter: null,
|
||||
showPreview: true,
|
||||
showSkinTones: true,
|
||||
darkMode: !!(typeof matchMedia === 'function' && matchMedia('(prefers-color-scheme: dark)').matches),
|
||||
emojiTooltip: EmojiDefaultProps.tooltip,
|
||||
useButton: EmojiDefaultProps.useButton,
|
||||
autoFocus: false,
|
||||
|
@ -2621,6 +2622,8 @@ function (_React$PureComponent) {
|
|||
_this.setPreviewRef = _this.setPreviewRef.bind((0, _assertThisInitialized2["default"])(_this));
|
||||
_this.handleSkinChange = _this.handleSkinChange.bind((0, _assertThisInitialized2["default"])(_this));
|
||||
_this.handleKeyDown = _this.handleKeyDown.bind((0, _assertThisInitialized2["default"])(_this));
|
||||
_this.handleDarkMatchMediaChange = _this.handleDarkMatchMediaChange.bind((0, _assertThisInitialized2["default"])(_this));
|
||||
_this.state.theme = _this.getPreferredTheme();
|
||||
return _this;
|
||||
}
|
||||
|
||||
|
@ -2650,6 +2653,10 @@ function (_React$PureComponent) {
|
|||
this.SEARCH_CATEGORY.emojis = null;
|
||||
clearTimeout(this.leaveTimeout);
|
||||
clearTimeout(this.firstRenderTimeout);
|
||||
|
||||
if (this.darkMatchMedia) {
|
||||
this.darkMatchMedia.removeListener(this.handleDarkMatchMediaChange);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "testStickyPosition",
|
||||
|
@ -2661,6 +2668,27 @@ function (_React$PureComponent) {
|
|||
});
|
||||
this.hasStickyPosition = !!stickyTestElement.style.position.length;
|
||||
}
|
||||
}, {
|
||||
key: "getPreferredTheme",
|
||||
value: function getPreferredTheme() {
|
||||
if (this.props.theme != 'auto') return this.props.theme;
|
||||
if (typeof matchMedia !== 'function') return _sharedDefaultProps.PickerDefaultProps.theme;
|
||||
|
||||
if (!this.darkMatchMedia) {
|
||||
this.darkMatchMedia = matchMedia('(prefers-color-scheme: dark)');
|
||||
this.darkMatchMedia.addListener(this.handleDarkMatchMediaChange);
|
||||
}
|
||||
|
||||
if (this.darkMatchMedia.media.match(/^not/)) return _sharedDefaultProps.PickerDefaultProps.theme;
|
||||
return this.darkMatchMedia.matches ? 'dark' : 'light';
|
||||
}
|
||||
}, {
|
||||
key: "handleDarkMatchMediaChange",
|
||||
value: function handleDarkMatchMediaChange() {
|
||||
this.setState({
|
||||
theme: this.getPreferredTheme()
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "handleEmojiOver",
|
||||
value: function handleEmojiOver(emoji) {
|
||||
|
@ -2972,14 +3000,15 @@ function (_React$PureComponent) {
|
|||
skinEmoji = _this$props.skinEmoji,
|
||||
notFound = _this$props.notFound,
|
||||
notFoundEmoji = _this$props.notFoundEmoji,
|
||||
darkMode = _this$props.darkMode,
|
||||
skin = this.state.skin,
|
||||
_this$state = this.state,
|
||||
skin = _this$state.skin,
|
||||
theme = _this$state.theme,
|
||||
width = perLine * (emojiSize + 12) + 12 + 2 + (0, _utils.measureScrollbar)();
|
||||
return _react["default"].createElement("section", {
|
||||
style: _objectSpread({
|
||||
width: width
|
||||
}, style),
|
||||
className: "emoji-mart ".concat(darkMode ? 'emoji-mart-dark' : ''),
|
||||
className: "emoji-mart emoji-mart-".concat(theme),
|
||||
"aria-label": title,
|
||||
onKeyDown: this.handleKeyDown
|
||||
}, _react["default"].createElement("div", {
|
||||
|
@ -3708,6 +3737,7 @@ class Example extends __WEBPACK_IMPORTED_MODULE_1_react___default.a.Component {
|
|||
this.state = {
|
||||
native: true,
|
||||
set: 'apple',
|
||||
theme: 'auto',
|
||||
emoji: 'point_up',
|
||||
title: 'Pick your emoji…',
|
||||
custom: CUSTOM_EMOJIS,
|
||||
|
@ -3747,28 +3777,17 @@ class Example extends __WEBPACK_IMPORTED_MODULE_1_react___default.a.Component {
|
|||
}, props), set);
|
||||
})), __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement("div", {
|
||||
className: "row-small sets"
|
||||
}, "Theme:\xA0", __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement("button", {
|
||||
disabled: this.state.darkMode == undefined,
|
||||
onClick: () => {
|
||||
this.setState({
|
||||
darkMode: undefined
|
||||
});
|
||||
}
|
||||
}, "auto"), __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement("button", {
|
||||
disabled: this.state.darkMode == false,
|
||||
onClick: () => {
|
||||
this.setState({
|
||||
darkMode: false
|
||||
});
|
||||
}
|
||||
}, "light"), __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement("button", {
|
||||
disabled: this.state.darkMode,
|
||||
onClick: () => {
|
||||
this.setState({
|
||||
darkMode: true
|
||||
});
|
||||
}
|
||||
}, "dark")), __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement("div", {
|
||||
}, "Theme:\xA0", ['auto', 'light', 'dark'].map(theme => {
|
||||
return __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement("button", {
|
||||
key: theme,
|
||||
disabled: theme == this.state.theme,
|
||||
onClick: () => {
|
||||
this.setState({
|
||||
theme
|
||||
});
|
||||
}
|
||||
}, theme);
|
||||
})), __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement("div", {
|
||||
className: "row"
|
||||
}, __WEBPACK_IMPORTED_MODULE_1_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_3__dist__["Picker"], __WEBPACK_IMPORTED_MODULE_0__babel_runtime_helpers_extends___default()({}, this.state, {
|
||||
onSelect: console.log
|
||||
|
|
|
@ -42,6 +42,7 @@ class Example extends React.Component {
|
|||
this.state = {
|
||||
native: true,
|
||||
set: 'apple',
|
||||
theme: 'auto',
|
||||
emoji: 'point_up',
|
||||
title: 'Pick your emoji…',
|
||||
custom: CUSTOM_EMOJIS,
|
||||
|
@ -88,30 +89,19 @@ class Example extends React.Component {
|
|||
|
||||
<div className="row-small sets">
|
||||
Theme:
|
||||
<button
|
||||
disabled={this.state.darkMode == undefined}
|
||||
onClick={() => {
|
||||
this.setState({ darkMode: undefined })
|
||||
}}
|
||||
>
|
||||
auto
|
||||
</button>
|
||||
<button
|
||||
disabled={this.state.darkMode == false}
|
||||
onClick={() => {
|
||||
this.setState({ darkMode: false })
|
||||
}}
|
||||
>
|
||||
light
|
||||
</button>
|
||||
<button
|
||||
disabled={this.state.darkMode}
|
||||
onClick={() => {
|
||||
this.setState({ darkMode: true })
|
||||
}}
|
||||
>
|
||||
dark
|
||||
</button>
|
||||
{['auto', 'light', 'dark'].map((theme) => {
|
||||
return (
|
||||
<button
|
||||
key={theme}
|
||||
disabled={theme == this.state.theme}
|
||||
onClick={() => {
|
||||
this.setState({ theme })
|
||||
}}
|
||||
>
|
||||
{theme}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
|
|
|
@ -196,6 +196,9 @@ export default class NimblePicker extends React.PureComponent {
|
|||
this.setPreviewRef = this.setPreviewRef.bind(this)
|
||||
this.handleSkinChange = this.handleSkinChange.bind(this)
|
||||
this.handleKeyDown = this.handleKeyDown.bind(this)
|
||||
this.handleDarkMatchMediaChange = this.handleDarkMatchMediaChange.bind(this)
|
||||
|
||||
this.state.theme = this.getPreferredTheme()
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(props, state) {
|
||||
|
@ -232,6 +235,10 @@ export default class NimblePicker extends React.PureComponent {
|
|||
|
||||
clearTimeout(this.leaveTimeout)
|
||||
clearTimeout(this.firstRenderTimeout)
|
||||
|
||||
if (this.darkMatchMedia) {
|
||||
this.darkMatchMedia.removeListener(this.handleDarkMatchMediaChange)
|
||||
}
|
||||
}
|
||||
|
||||
testStickyPosition() {
|
||||
|
@ -246,6 +253,23 @@ export default class NimblePicker extends React.PureComponent {
|
|||
this.hasStickyPosition = !!stickyTestElement.style.position.length
|
||||
}
|
||||
|
||||
getPreferredTheme() {
|
||||
if (this.props.theme != 'auto') return this.props.theme
|
||||
if (typeof matchMedia !== 'function') return PickerDefaultProps.theme
|
||||
|
||||
if (!this.darkMatchMedia) {
|
||||
this.darkMatchMedia = matchMedia('(prefers-color-scheme: dark)')
|
||||
this.darkMatchMedia.addListener(this.handleDarkMatchMediaChange)
|
||||
}
|
||||
|
||||
if (this.darkMatchMedia.media.match(/^not/)) return PickerDefaultProps.theme
|
||||
return this.darkMatchMedia.matches ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
handleDarkMatchMediaChange() {
|
||||
this.setState({ theme: this.getPreferredTheme() })
|
||||
}
|
||||
|
||||
handleEmojiOver(emoji) {
|
||||
var { preview } = this
|
||||
if (!preview) {
|
||||
|
@ -529,15 +553,14 @@ export default class NimblePicker extends React.PureComponent {
|
|||
skinEmoji,
|
||||
notFound,
|
||||
notFoundEmoji,
|
||||
darkMode,
|
||||
} = this.props,
|
||||
{ skin } = this.state,
|
||||
{ skin, theme } = this.state,
|
||||
width = perLine * (emojiSize + 12) + 12 + 2 + measureScrollbar()
|
||||
|
||||
return (
|
||||
<section
|
||||
style={{ width: width, ...style }}
|
||||
className={`emoji-mart ${darkMode ? 'emoji-mart-dark' : ''}`}
|
||||
className={`emoji-mart emoji-mart-${theme}`}
|
||||
aria-label={title}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
>
|
||||
|
|
|
@ -24,6 +24,7 @@ const PickerDefaultProps = {
|
|||
emoji: 'department_store',
|
||||
color: '#ae65c5',
|
||||
set: EmojiDefaultProps.set,
|
||||
theme: 'light',
|
||||
skin: null,
|
||||
defaultSkin: EmojiDefaultProps.skin,
|
||||
native: EmojiDefaultProps.native,
|
||||
|
@ -32,10 +33,6 @@ const PickerDefaultProps = {
|
|||
emojisToShowFilter: null,
|
||||
showPreview: true,
|
||||
showSkinTones: true,
|
||||
darkMode: !!(
|
||||
typeof matchMedia === 'function' &&
|
||||
matchMedia('(prefers-color-scheme: dark)').matches
|
||||
),
|
||||
emojiTooltip: EmojiDefaultProps.tooltip,
|
||||
useButton: EmojiDefaultProps.useButton,
|
||||
autoFocus: false,
|
||||
|
|
|
@ -41,6 +41,7 @@ const PickerPropTypes = {
|
|||
showSkinTones: PropTypes.bool,
|
||||
emojiTooltip: EmojiPropTypes.tooltip,
|
||||
useButton: EmojiPropTypes.useButton,
|
||||
theme: PropTypes.oneOf(['auto', 'light', 'dark']),
|
||||
include: PropTypes.arrayOf(PropTypes.string),
|
||||
exclude: PropTypes.arrayOf(PropTypes.string),
|
||||
recent: PropTypes.arrayOf(PropTypes.string),
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
import data from '../data/all.json'
|
||||
import '../css/emoji-mart.css'
|
||||
|
||||
const THEMES = ['auto', 'light', 'dark']
|
||||
const SETS = ['apple', 'google', 'twitter', 'facebook']
|
||||
const CUSTOM_EMOJIS = [
|
||||
{
|
||||
|
@ -51,7 +52,7 @@ storiesOf('Picker', module)
|
|||
onSelect={action('selected')}
|
||||
onSkinChange={action('skin changed')}
|
||||
native={boolean('Unicode', true)}
|
||||
darkMode={boolean('Dark mode', false)}
|
||||
theme={select('Theme', THEMES, THEMES[0])}
|
||||
set={select('Emoji pack', SETS, SETS[0])}
|
||||
emojiSize={number('Emoji size', 24)}
|
||||
perLine={number('Per line', 9)}
|
||||
|
|
Loading…
Reference in New Issue