emoji-picker-react 4.0.0-rc.32 → 4.0.0-rc.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,6 +37,7 @@ function App() {
37
37
  - Skin tone change
38
38
  - Different emoji sets (Google, Apple, Facebook, Twitter)
39
39
  - Native Emoji support
40
+ - Emoji Component To Render Emojis in your app
40
41
 
41
42
  # Props
42
43
 
@@ -169,6 +170,32 @@ The list of possible variables is quite extensive, but the main ones you may wan
169
170
  - `--epr-bg-color`: The background color of the picker. When changing it, you should also change `--epr-category-label-bg-color` as they are usually the same color.
170
171
  - `--epr-text-color`: The text color in the picker.
171
172
 
173
+ # Rendering Output Emojis in Your App
174
+
175
+ The picker exports an `Emoji` component. The emoji component is the same used within the picker, so it will render the same way as the emojis in the picker. You can choose to render emojis either as native, or as images.
176
+
177
+ ## Props
178
+
179
+ | Name | Type | Default | Description |
180
+ | ------------ | ------------ | ------------------ | ------------------------------------------------------------------------------------------- |
181
+ | `unified` | string | "" | The unified code of the emoji. |
182
+ | `size` | number | 32 | The size of the emoji. |
183
+ | `emojiStyle` | `EmojiStyle` | `EmojiStyle.APPLE` | The emoji style to use. Can be either `apple`, `google`, `facebook`, `twitter` or `native`. |
184
+ | `lazyLoad` | boolean | `false` | Whether to lazy load the emoji. image |
185
+
186
+ ```js
187
+ import { Emoji, EmojiStyle } from 'emoji-picker-react';
188
+
189
+ export function MyApp() {
190
+ return (
191
+ <p>
192
+ My Favorite emoji is:
193
+ <Emoji unified="1f423" size="25" />
194
+ </p>
195
+ );
196
+ }
197
+ ```
198
+
172
199
  # Troubleshooting
173
200
 
174
201
  ## Error Boundary
@@ -8,6 +8,7 @@ export declare enum ClassNames {
8
8
  category = "epr-emoji-category",
9
9
  label = "epr-emoji-category-label",
10
10
  categoryContent = "epr-emoji-category-content",
11
- emojiHasVariatios = "epr-emoji-has-variations"
11
+ emojiHasVariatios = "epr-emoji-has-variations",
12
+ external = "__EmojiPicker__"
12
13
  }
13
14
  export declare function asSelectors(...classNames: ClassNames[]): string;
@@ -8,10 +8,11 @@ declare type ClickableEmojiProps = Readonly<BaseProps & {
8
8
  showVariations?: boolean;
9
9
  emojiRef?: EmojiRef;
10
10
  hiddenOnSearch?: boolean;
11
+ emoji: DataEmoji;
11
12
  }>;
12
13
  declare type BaseProps = {
14
+ emoji?: DataEmoji;
13
15
  emojiStyle: EmojiStyle;
14
- emoji: DataEmoji;
15
16
  unified: string;
16
17
  size?: number;
17
18
  lazyLoad?: boolean;
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import { EmojiStyle } from '../../types/exposedTypes';
3
+ export declare function ExportedEmoji({ unified, size, emojiStyle, lazyLoad }: {
4
+ unified: string;
5
+ emojiStyle?: EmojiStyle;
6
+ size?: number;
7
+ lazyLoad?: boolean;
8
+ }): JSX.Element | null;
@@ -1,4 +1,4 @@
1
- import { Categories } from "../config/categoryConfig";
1
+ import { Categories } from '../config/categoryConfig';
2
2
  import { EmojiStyle, SkinTones } from '../types/exposedTypes';
3
3
  import { DataEmoji, DataEmojis } from './DataTypes';
4
4
  export declare function emojiNames(emoji: DataEmoji): string[];
@@ -1,4 +1,4 @@
1
- .EmojiPickerReact button.epr-emoji{align-items:center;border-radius:8px;box-sizing:border-box;display:flex;height:var(--epr-emoji-fullsize);justify-content:center;max-height:var(--epr-emoji-fullsize);max-width:var(--epr-emoji-fullsize);overflow:hidden;position:relative;width:var(--epr-emoji-fullsize)}.EmojiPickerReact button.epr-emoji.epr-emoji-has-variations:after{border-bottom:4px solid var(--epr-emoji-variation-indicator-color);border-left:4px solid transparent;border-right:4px solid transparent;bottom:1px;content:"";display:block;height:0;position:absolute;right:0;transform:rotate(135deg);width:0;z-index:var(--epr-emoji-variations-indictator-z-index)}.EmojiPickerReact button.epr-emoji .epr-emoji-img{max-height:var(--epr-emoji-fullsize);max-width:var(--epr-emoji-fullsize);padding:var(--epr-emoji-padding)}.EmojiPickerReact button.epr-emoji .epr-emoji-native{padding:var(--epr-emoji-padding)}.EmojiPickerReact button.epr-emoji>*{align-self:center;display:block;justify-self:center}.EmojiPickerReact button.epr-emoji.epr-emoji-has-variations:hover:after{border-bottom:4px solid var(--epr-emoji-variation-indicator-color-hover)}.EmojiPickerReact .epr-emoji-img{font-size:0}.EmojiPickerReact .epr-emoji-native{align-self:center;font-family:Segoe UI Emoji,Segoe UI Symbol,Segoe UI,Apple Color Emoji,Twemoji Mozilla,Noto Color Emoji,Android Emoji,Times,Symbola,Aegyptus,Code2000,Code2001,Code2002,Musica,serif,LastResort;font-size:var(--epr-emoji-size);justify-self:center;letter-spacing:0;line-height:100%;position:relative;text-align:center}.EmojiPickerReact button.epr-emoji:hover>*{background-color:var(--epr-emoji-hover-color)}.EmojiPickerReact button.epr-emoji:focus>*{background-color:var(--epr-focus-bg-color)}
1
+ .EmojiPickerReact button.epr-emoji{align-items:center;border-radius:8px;box-sizing:border-box;display:flex;height:var(--epr-emoji-fullsize);justify-content:center;max-height:var(--epr-emoji-fullsize);max-width:var(--epr-emoji-fullsize);overflow:hidden;position:relative;width:var(--epr-emoji-fullsize)}.EmojiPickerReact button.epr-emoji.epr-emoji-has-variations:after{border-bottom:4px solid var(--epr-emoji-variation-indicator-color);border-left:4px solid transparent;border-right:4px solid transparent;bottom:1px;content:"";display:block;height:0;position:absolute;right:0;transform:rotate(135deg);width:0;z-index:var(--epr-emoji-variations-indictator-z-index)}.EmojiPickerReact button.epr-emoji .epr-emoji-img{max-height:var(--epr-emoji-fullsize);max-width:var(--epr-emoji-fullsize);padding:var(--epr-emoji-padding)}.EmojiPickerReact button.epr-emoji .epr-emoji-native{padding:var(--epr-emoji-padding)}.EmojiPickerReact button.epr-emoji>*{align-self:center;display:block;justify-self:center}.EmojiPickerReact button.epr-emoji.epr-emoji-has-variations:hover:after{border-bottom:4px solid var(--epr-emoji-variation-indicator-color-hover)}.__EmojiPicker__.epr-emoji-img{font-size:0}.__EmojiPicker__.epr-emoji-native{align-self:center;font-family:Segoe UI Emoji,Segoe UI Symbol,Segoe UI,Apple Color Emoji,Twemoji Mozilla,Noto Color Emoji,Android Emoji,Times,Symbola,Aegyptus,Code2000,Code2001,Code2002,Musica,serif,LastResort;font-size:var(--epr-emoji-size);justify-self:center;letter-spacing:0;line-height:100%;position:relative;text-align:center}.EmojiPickerReact button.epr-emoji:hover>*{background-color:var(--epr-emoji-hover-color)}.EmojiPickerReact button.epr-emoji:focus>*{background-color:var(--epr-focus-bg-color)}
2
2
  .EmojiPickerReact li.epr-emoji-category>.epr-emoji-category-content{grid-gap:0;display:grid;grid-template-columns:repeat(auto-fill,var(--epr-emoji-fullsize));justify-content:space-between;margin:var(--epr-category-padding);position:relative}.EmojiPickerReact li.epr-emoji-category:not(:has(.epr-visible)){display:none}.EmojiPickerReact li.epr-emoji-category>.epr-emoji-category-label{align-items:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);background-color:var(--epr-category-label-bg-color);color:var(--epr-category-label-text-color);display:flex;font-weight:700;height:var(--epr-category-label-height);padding:var(--epr-category-label-padding);position:-webkit-sticky;position:sticky;text-transform:capitalize;top:0;width:100%;z-index:var(--epr-category-label-z-index)}
3
3
  .EmojiPickerReact ul.epr-emoji-list{list-style:none;margin:0;padding:0}
4
4
  .EmojiPickerReact .epr-emoji-variation-picker{align-items:center;background:var(--epr-emoji-variation-picker-bg-color);border:1px solid var(--epr-picker-border-color);border-radius:3px;box-shadow:0 2px 5px rgba(0,0,0,.2);display:flex;height:0;height:var(--epr-emoji-variation-picker-height);justify-content:space-around;left:15px;opacity:0;padding:5px;pointer-events:none;position:absolute;right:15px;top:0;top:-100%;transform:scale(.9);transition:transform .1s ease-out,opacity .2s ease-out;visibility:hidden;z-index:var(--epr-skin-variation-picker-z-index)}.EmojiPickerReact .epr-emoji-variation-picker.pointing-up{transform:scale(.9);transform-origin:center 0}.EmojiPickerReact .epr-emoji-variation-picker.visible{opacity:1;pointer-events:all;transform:scale(1);visibility:visible}.EmojiPickerReact .epr-emoji-variation-picker .EmojiPickerReact .epr-emoji-variation-picker button.epr-emoji:hover{background:none}.EmojiPickerReact .epr-emoji-variation-picker .epr-emoji-pointer{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='50' height='15' xml:space='preserve'%3E%3Cg stroke-miterlimit='10'%3E%3Cpath fill='%23FFF' stroke='%23E8E7E7' d='m1.86-.43 9.83 11.53c.59.69 1.56.69 2.14 0L23.66-.43'/%3E%3Cpath fill='%23010202' stroke='%23151617' d='m26.86-.43 9.83 11.53c.59.69 1.56.69 2.14 0L48.66-.43'/%3E%3C/g%3E%3C/svg%3E");background-position:0 0;background-repeat:no-repeat;background-size:50px 15px;content:"";height:15px;position:absolute;top:-10px;width:25px}.EmojiPickerReact.epr-dark-theme .epr-emoji-variation-picker .epr-emoji-pointer{background-position:-25px 0}.EmojiPickerReact .epr-emoji-variation-picker .epr-emoji-pointer{top:100%;transform:translateX(-18px)}.EmojiPickerReact .epr-emoji-variation-picker.pointing-up .epr-emoji-pointer{top:0;transform:rotate(180deg) translateY(100%) translateX(18px)}
@@ -14989,7 +14989,12 @@ function emojiByUnified(unified) {
14989
14989
  return;
14990
14990
  }
14991
14991
 
14992
- return allEmojisByUnified[unified];
14992
+ if (allEmojisByUnified[unified]) {
14993
+ return allEmojisByUnified[unified];
14994
+ }
14995
+
14996
+ var withoutSkinTone = unifiedWithoutSkinTone(unified);
14997
+ return allEmojisByUnified[withoutSkinTone];
14993
14998
  }
14994
14999
  var allEmojis = /*#__PURE__*/Object.values(emojis).flat();
14995
15000
  var allEmojisByUnified = {};
@@ -15232,6 +15237,7 @@ var ClassNames;
15232
15237
  ClassNames["label"] = "epr-emoji-category-label";
15233
15238
  ClassNames["categoryContent"] = "epr-emoji-category-content";
15234
15239
  ClassNames["emojiHasVariatios"] = "epr-emoji-has-variations";
15240
+ ClassNames["external"] = "__EmojiPicker__";
15235
15241
  })(ClassNames || (ClassNames = {}));
15236
15242
 
15237
15243
  function asSelectors() {
@@ -15613,26 +15619,6 @@ function setsuggested(emoji, skinTone) {
15613
15619
  }
15614
15620
  }
15615
15621
 
15616
- function preloadEmoji(emoji, emojiStyle) {
15617
- var unified = emojiUnified(emoji);
15618
-
15619
- if (preloadedEmojs.has(unified)) {
15620
- return;
15621
- }
15622
-
15623
- emojiVariations(emoji).forEach(function (variation) {
15624
- var emojiUrl = emojiUrlByUnified(emojiStyle, variation);
15625
- preloadImage(emojiUrl);
15626
- });
15627
- preloadedEmojs.add(unified);
15628
- }
15629
- var preloadedEmojs = /*#__PURE__*/new Set();
15630
-
15631
- function preloadImage(url) {
15632
- var image = new Image();
15633
- image.src = url;
15634
- }
15635
-
15636
15622
  function useCloseAllOpenToggles() {
15637
15623
  var _useEmojiVariationPic = useEmojiVariationPickerState(),
15638
15624
  variationPicker = _useEmojiVariationPic[0],
@@ -15824,7 +15810,6 @@ function useSetVariationPicker() {
15824
15810
 
15825
15811
  function useMouseDownHandlers(BodyRef) {
15826
15812
  var mouseDownTimerRef = React.useRef();
15827
- var preloading = React.useRef(false);
15828
15813
  var setVariationPicker = useSetVariationPicker();
15829
15814
  var disallowClickRef = useDisallowClickRef();
15830
15815
 
@@ -15837,7 +15822,6 @@ function useMouseDownHandlers(BodyRef) {
15837
15822
  activeSkinTone = _useActiveSkinToneSta[0];
15838
15823
 
15839
15824
  var onEmojiClick = useOnEmojiClickConfig();
15840
- var emojiStyle = useEmojiStyleConfig();
15841
15825
 
15842
15826
  var _useUpdateSuggested = useUpdateSuggested(),
15843
15827
  updateSuggested = _useUpdateSuggested[1];
@@ -15863,7 +15847,7 @@ function useMouseDownHandlers(BodyRef) {
15863
15847
  onEmojiClick(emojiClickOutput(emoji, skinToneToUse), event);
15864
15848
  }, [activeSkinTone, closeAllOpenToggles, disallowClickRef, onEmojiClick, updateSuggested]);
15865
15849
  var onMouseDown = React.useCallback(function onMouseDown(event) {
15866
- var _window, _window2;
15850
+ var _window;
15867
15851
 
15868
15852
  if (mouseDownTimerRef.current) {
15869
15853
  clearTimeout(mouseDownTimerRef.current);
@@ -15876,24 +15860,15 @@ function useMouseDownHandlers(BodyRef) {
15876
15860
  return;
15877
15861
  }
15878
15862
 
15879
- preloading.current = true;
15880
- (_window = window) == null ? void 0 : _window.setTimeout(function () {
15881
- if (preloading.current) {
15882
- preloadEmoji(emoji, emojiStyle);
15883
- preloading.current = false;
15884
- }
15885
- }, 50);
15886
- mouseDownTimerRef.current = (_window2 = window) == null ? void 0 : _window2.setTimeout(function () {
15863
+ mouseDownTimerRef.current = (_window = window) == null ? void 0 : _window.setTimeout(function () {
15887
15864
  disallowClickRef.current = true;
15888
15865
  mouseDownTimerRef.current = undefined;
15889
15866
  closeAllOpenToggles();
15890
15867
  setVariationPicker(event.target);
15891
15868
  setEmojiVariationPicker(emoji);
15892
15869
  }, 500);
15893
- }, [disallowClickRef, closeAllOpenToggles, setVariationPicker, emojiStyle, setEmojiVariationPicker]);
15870
+ }, [disallowClickRef, closeAllOpenToggles, setVariationPicker, setEmojiVariationPicker]);
15894
15871
  var onMouseUp = React.useCallback(function onMouseUp() {
15895
- preloading.current = false;
15896
-
15897
15872
  if (mouseDownTimerRef.current) {
15898
15873
  clearTimeout(mouseDownTimerRef.current);
15899
15874
  mouseDownTimerRef.current = undefined;
@@ -16231,6 +16206,10 @@ function useIsEmojiHidden() {
16231
16206
  };
16232
16207
  }
16233
16208
 
16209
+ function asEmoji(emoji) {
16210
+ return emoji;
16211
+ }
16212
+
16234
16213
  function ClickableEmoji(_ref) {
16235
16214
  var _clsx;
16236
16215
 
@@ -16271,13 +16250,14 @@ function ViewOnlyEmoji(_ref2) {
16271
16250
  style.width = style.height = style.fontSize = size + "px";
16272
16251
  }
16273
16252
 
16253
+ var emojiToRender = emoji ? emoji : emojiByUnified(unified);
16274
16254
  return React.createElement(React.Fragment, null, emojiStyle === exports.EmojiStyle.NATIVE ? React.createElement(NativeEmoji, {
16275
16255
  unified: unified,
16276
16256
  style: style
16277
16257
  }) : React.createElement(EmojiImg, {
16278
16258
  unified: unified,
16279
16259
  style: style,
16280
- emoji: emoji,
16260
+ emoji: asEmoji(emojiToRender),
16281
16261
  emojiStyle: emojiStyle,
16282
16262
  lazyLoad: lazyLoad
16283
16263
  }));
@@ -16287,7 +16267,7 @@ function NativeEmoji(_ref3) {
16287
16267
  var unified = _ref3.unified,
16288
16268
  style = _ref3.style;
16289
16269
  return React.createElement("span", {
16290
- className: "epr-emoji-native",
16270
+ className: clsx(ClassNames.external, 'epr-emoji-native'),
16291
16271
  "data-unified": unified,
16292
16272
  style: style
16293
16273
  }, parseNativeEmoji(unified));
@@ -16307,7 +16287,7 @@ function EmojiImg(_ref4) {
16307
16287
  return React.createElement("img", {
16308
16288
  src: emojiUrlByUnified(emojiStyle, unified),
16309
16289
  alt: emojiName(emoji),
16310
- className: "epr-emoji-img",
16290
+ className: clsx(ClassNames.external, 'epr-emoji-img'),
16311
16291
  loading: lazyLoad ? 'lazy' : 'eager',
16312
16292
  onError: onError,
16313
16293
  style: style
@@ -16447,10 +16427,6 @@ function RenderCategory(_ref) {
16447
16427
  }, emojis);
16448
16428
  }
16449
16429
 
16450
- function asEmoji(emoji) {
16451
- return emoji;
16452
- }
16453
-
16454
16430
  var Direction;
16455
16431
 
16456
16432
  (function (Direction) {
@@ -17372,6 +17348,69 @@ function hasModifier(event) {
17372
17348
  return metaKey || ctrlKey || altKey;
17373
17349
  }
17374
17350
 
17351
+ function preloadEmoji(emoji, emojiStyle) {
17352
+ if (!emoji) {
17353
+ return;
17354
+ }
17355
+
17356
+ if (emojiStyle === exports.EmojiStyle.NATIVE) {
17357
+ return;
17358
+ }
17359
+
17360
+ var unified = emojiUnified(emoji);
17361
+
17362
+ if (preloadedEmojs.has(unified)) {
17363
+ return;
17364
+ }
17365
+
17366
+ emojiVariations(emoji).forEach(function (variation) {
17367
+ var emojiUrl = emojiUrlByUnified(emojiStyle, variation);
17368
+ preloadImage(emojiUrl);
17369
+ });
17370
+ preloadedEmojs.add(unified);
17371
+ }
17372
+ var preloadedEmojs = /*#__PURE__*/new Set();
17373
+
17374
+ function preloadImage(url) {
17375
+ var image = new Image();
17376
+ image.src = url;
17377
+ }
17378
+
17379
+ function useOnFocus() {
17380
+ var BodyRef = useBodyRef();
17381
+ var emojiStyle = useEmojiStyleConfig();
17382
+ React.useEffect(function () {
17383
+ if (emojiStyle === exports.EmojiStyle.NATIVE) {
17384
+ return;
17385
+ }
17386
+
17387
+ var bodyRef = BodyRef.current;
17388
+ bodyRef == null ? void 0 : bodyRef.addEventListener('focusin', onFocus);
17389
+ return function () {
17390
+ bodyRef == null ? void 0 : bodyRef.removeEventListener('focusin', onFocus);
17391
+ };
17392
+
17393
+ function onFocus(event) {
17394
+ var button = buttonFromTarget(event.target);
17395
+
17396
+ if (!button) {
17397
+ return;
17398
+ }
17399
+
17400
+ var _emojiFromElement = emojiFromElement(button),
17401
+ emoji = _emojiFromElement[0];
17402
+
17403
+ if (!emoji) {
17404
+ return;
17405
+ }
17406
+
17407
+ if (emojiHasVariations(emoji)) {
17408
+ preloadEmoji(emoji, emojiStyle);
17409
+ }
17410
+ }
17411
+ }, [BodyRef, emojiStyle]);
17412
+ }
17413
+
17375
17414
  function PickerMain(_ref) {
17376
17415
  var children = _ref.children;
17377
17416
  return React.createElement(PickerContextProvider, null, React.createElement(PickerRootElement, null, children));
@@ -17385,6 +17424,7 @@ function PickerRootElement(_ref2) {
17385
17424
  var searchModeActive = useIsSearchMode();
17386
17425
  var PickerMainRef = usePickerMainRef();
17387
17426
  useKeyboardNavigation();
17427
+ useOnFocus();
17388
17428
  return React.createElement("aside", {
17389
17429
  className: clsx('EmojiPickerReact', 'epr-main', (_clsx = {}, _clsx[ClassNames.searchActive] = searchModeActive, _clsx['epr-dark-theme'] = theme === exports.Theme.DARK, _clsx)),
17390
17430
  ref: PickerMainRef
@@ -17432,9 +17472,31 @@ var ErrorBoundary = /*#__PURE__*/function (_React$Component) {
17432
17472
  return ErrorBoundary;
17433
17473
  }(React.Component);
17434
17474
 
17475
+ function ExportedEmoji(_ref) {
17476
+ var unified = _ref.unified,
17477
+ _ref$size = _ref.size,
17478
+ size = _ref$size === void 0 ? 32 : _ref$size,
17479
+ _ref$emojiStyle = _ref.emojiStyle,
17480
+ emojiStyle = _ref$emojiStyle === void 0 ? exports.EmojiStyle.APPLE : _ref$emojiStyle,
17481
+ _ref$lazyLoad = _ref.lazyLoad,
17482
+ lazyLoad = _ref$lazyLoad === void 0 ? false : _ref$lazyLoad;
17483
+
17484
+ if (!unified) {
17485
+ return null;
17486
+ }
17487
+
17488
+ return React.createElement(ViewOnlyEmoji, {
17489
+ unified: unified,
17490
+ size: size,
17491
+ emojiStyle: emojiStyle,
17492
+ lazyLoad: lazyLoad
17493
+ });
17494
+ }
17495
+
17435
17496
  function EmojiPicker$1(props) {
17436
17497
  return React.createElement(ErrorBoundary, null, React.createElement(EmojiPicker, Object.assign({}, props)));
17437
17498
  }
17438
17499
 
17500
+ exports.Emoji = ExportedEmoji;
17439
17501
  exports.default = EmojiPicker$1;
17440
17502
  //# sourceMappingURL=emoji-picker-react.cjs.development.js.map