emoji-picker-react 4.20.2 → 4.20.5

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.
Files changed (39) hide show
  1. package/README.md +1 -1
  2. package/dist/Stylesheet/stylesheet.d.ts +1 -1
  3. package/dist/components/body/EmojiCategory.d.ts +2 -1
  4. package/dist/components/emoji/Emoji.d.ts +2 -1
  5. package/dist/components/header/SkinTonePicker/BtnSkinToneVariation.d.ts +2 -1
  6. package/dist/emoji-picker-react.cjs.development.js +157 -42
  7. package/dist/emoji-picker-react.cjs.development.js.map +1 -1
  8. package/dist/emoji-picker-react.cjs.production.min.js +1 -1
  9. package/dist/emoji-picker-react.cjs.production.min.js.map +1 -1
  10. package/dist/emoji-picker-react.esm.js +121 -6
  11. package/dist/emoji-picker-react.esm.js.map +1 -1
  12. package/llms.txt +1 -1
  13. package/package.json +8 -2
  14. package/src/DomUtils/elementPositionInRow.ts +11 -0
  15. package/src/Stylesheet/stylesheet.tsx +1 -1
  16. package/src/components/Layout/Flex.tsx +1 -1
  17. package/src/components/Layout/Space.tsx +1 -1
  18. package/src/components/Reactions/BtnPlus.tsx +1 -1
  19. package/src/components/Reactions/Reactions.tsx +21 -1
  20. package/src/components/atoms/Button.tsx +1 -1
  21. package/src/components/body/Body.tsx +1 -1
  22. package/src/components/body/EmojiCategory.tsx +10 -2
  23. package/src/components/body/EmojiList.tsx +12 -2
  24. package/src/components/body/EmojiVariationPicker.tsx +1 -1
  25. package/src/components/emoji/ClickableEmojiButton.tsx +1 -1
  26. package/src/components/emoji/Emoji.tsx +3 -0
  27. package/src/components/emoji/EmojiImg.tsx +1 -1
  28. package/src/components/emoji/NativeEmoji.tsx +1 -1
  29. package/src/components/footer/Preview.tsx +1 -1
  30. package/src/components/header/Header.tsx +1 -1
  31. package/src/components/header/Search/BtnClearSearch.tsx +1 -1
  32. package/src/components/header/Search/IcnSearch.tsx +1 -1
  33. package/src/components/header/Search/Search.tsx +1 -1
  34. package/src/components/header/SkinTonePicker/BtnSkinToneVariation.tsx +4 -1
  35. package/src/components/header/SkinTonePicker/SkinTonePicker.tsx +7 -1
  36. package/src/components/main/PickerMain.tsx +1 -1
  37. package/src/components/navigation/CategoryButton.tsx +1 -1
  38. package/src/components/navigation/CategoryNavigation.tsx +1 -1
  39. package/src/hooks/useKeyboardNavigation.ts +81 -1
package/README.md CHANGED
@@ -57,7 +57,7 @@ See [PROPS.md](PROPS.md) for the complete props reference.
57
57
 
58
58
  ## Styling
59
59
 
60
- No stylesheet import needed. All styles are scoped via [Flairup](https://github.com/ealush/flairup) — generated class names are hashed, so the picker's CSS won't leak into or clash with your app's styles.
60
+ No stylesheet import needed. All styles are scoped via [ShipStyles](https://github.com/ealush/shipstyles) — generated class names are hashed, so the picker's CSS won't leak into or clash with your app's styles.
61
61
 
62
62
  Restyle the picker by overriding [CSS variables](CSS_VARIABLES.md) on `.EmojiPickerReact`:
63
63
 
@@ -1,5 +1,5 @@
1
- import { Styles } from 'flairup';
2
1
  import * as React from 'react';
2
+ import { Styles } from 'shipstyles';
3
3
  export declare const stylesheet: {
4
4
  create: <K extends string>(styles: Partial<{ [k in K]: Partial<{
5
5
  '.'?: string | string[] | undefined;
@@ -6,6 +6,7 @@ declare type Props = Readonly<{
6
6
  hidden?: boolean;
7
7
  hiddenOnSearch?: boolean;
8
8
  height?: number;
9
+ emojisPerRow?: number;
9
10
  }>;
10
- export declare function EmojiCategory({ categoryConfig, children, hidden, hiddenOnSearch, height, }: Props): JSX.Element;
11
+ export declare function EmojiCategory({ categoryConfig, children, hidden, hiddenOnSearch, height, emojisPerRow, }: Props): JSX.Element;
11
12
  export {};
@@ -7,8 +7,9 @@ declare type ClickableEmojiProps = Readonly<BaseEmojiProps & {
7
7
  hiddenOnSearch?: boolean;
8
8
  emoji: DataEmoji;
9
9
  className?: string;
10
+ buttonClassName?: string;
10
11
  noBackground?: boolean;
11
12
  style?: React.CSSProperties;
12
13
  }>;
13
- export declare function ClickableEmoji({ emoji, unified, hidden, hiddenOnSearch, emojiStyle, showVariations, size, lazyLoad, getEmojiUrl, className, noBackground, style, }: ClickableEmojiProps): JSX.Element;
14
+ export declare function ClickableEmoji({ emoji, unified, hidden, hiddenOnSearch, emojiStyle, showVariations, size, lazyLoad, getEmojiUrl, className, buttonClassName, noBackground, style, }: ClickableEmojiProps): JSX.Element;
14
15
  export {};
@@ -6,6 +6,7 @@ declare type Props = {
6
6
  isActive: boolean;
7
7
  skinToneVariation: SkinTones;
8
8
  style?: React.CSSProperties;
9
+ tabIndex?: number;
9
10
  };
10
- export declare function BtnSkinToneVariation({ isOpen, onClick, isActive, skinToneVariation, style, }: Props): JSX.Element;
11
+ export declare function BtnSkinToneVariation({ isOpen, onClick, isActive, skinToneVariation, style, tabIndex, }: Props): JSX.Element;
11
12
  export {};
@@ -6,7 +6,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau
6
6
 
7
7
  var React = require('react');
8
8
  var React__default = _interopDefault(React);
9
- var flairup = require('flairup');
9
+ var shipstyles = require('shipstyles');
10
10
 
11
11
  function _arrayLikeToArray(r, a) {
12
12
  (null == a || a > r.length) && (a = r.length);
@@ -96,7 +96,7 @@ function asSelectors() {
96
96
  }).join('');
97
97
  }
98
98
 
99
- var stylesheet = /*#__PURE__*/flairup.createSheet('epr', null);
99
+ var stylesheet = /*#__PURE__*/shipstyles.createSheet('epr', null);
100
100
  var hidden = {
101
101
  display: 'none',
102
102
  opacity: '0',
@@ -27900,6 +27900,7 @@ function useKeyboardNavigation() {
27900
27900
  useSearchInputKeyboardEvents();
27901
27901
  useSkinTonePickerKeyboardEvents();
27902
27902
  useCategoryNavigationKeyboardEvents();
27903
+ useReactionsKeyboardEvents();
27903
27904
  useBodyKeyboardEvents();
27904
27905
  }
27905
27906
  function usePickerMainKeyboardEvents() {
@@ -28105,6 +28106,65 @@ function useCategoryNavigationKeyboardEvents() {
28105
28106
  };
28106
28107
  }, [CategoryNavigationRef, BodyRef, onKeyDown]);
28107
28108
  }
28109
+ // Arrow keys move between reaction buttons (and the expand button)
28110
+ // while the reactions bar has focus. The bar lives outside the scroll
28111
+ // body, so the body handler never sees these events.
28112
+ // https://github.com/ealush/emoji-picker-react/issues/411
28113
+ function useReactionsKeyboardEvents() {
28114
+ var ReactionsRef = useReactionsRef();
28115
+ // The reactions bar mounts late when the user collapses the full
28116
+ // picker, so the listener effect must rerun when it opens.
28117
+ var _useReactionsModeStat = useReactionsModeState(),
28118
+ reactionsOpen = _useReactionsModeStat[0];
28119
+ var onKeyDown = React.useMemo(function () {
28120
+ return function onKeyDown(event) {
28121
+ var key = event.key;
28122
+ var current = ReactionsRef.current;
28123
+ if (!current) {
28124
+ return;
28125
+ }
28126
+ var delta = reactionFocusDelta(key);
28127
+ if (delta !== 0 && focusReactionSibling(current, delta)) {
28128
+ event.preventDefault();
28129
+ }
28130
+ };
28131
+ },
28132
+ // reactionsOpen: the bar mounts late on collapse, and the new
28133
+ // callback identity reinstalls the listener effect below.
28134
+ [ReactionsRef, reactionsOpen]);
28135
+ React.useEffect(function () {
28136
+ var current = ReactionsRef.current;
28137
+ if (!current) {
28138
+ return;
28139
+ }
28140
+ current.addEventListener('keydown', onKeyDown);
28141
+ return function () {
28142
+ current.removeEventListener('keydown', onKeyDown);
28143
+ };
28144
+ }, [ReactionsRef, onKeyDown]);
28145
+ }
28146
+ function reactionFocusDelta(key) {
28147
+ switch (key) {
28148
+ case KeyboardEvents.ArrowRight:
28149
+ case KeyboardEvents.ArrowDown:
28150
+ return 1;
28151
+ case KeyboardEvents.ArrowLeft:
28152
+ case KeyboardEvents.ArrowUp:
28153
+ return -1;
28154
+ default:
28155
+ return 0;
28156
+ }
28157
+ }
28158
+ function focusReactionSibling(root, delta) {
28159
+ var buttons = Array.from(root.querySelectorAll('button'));
28160
+ var activeIndex = buttons.indexOf(getActiveElement());
28161
+ var sibling = activeIndex === -1 ? null : buttons[activeIndex + delta];
28162
+ if (!sibling) {
28163
+ return false;
28164
+ }
28165
+ focusElement(sibling);
28166
+ return true;
28167
+ }
28108
28168
  function useBodyKeyboardEvents() {
28109
28169
  var BodyRef = useBodyRef();
28110
28170
  var goUpFromBody = useGoUpFromBody();
@@ -28327,7 +28387,7 @@ function PickerRootElement(_ref2) {
28327
28387
  height = _ref3.height,
28328
28388
  styleProps = _objectWithoutPropertiesLoose(_ref3, _excluded$1);
28329
28389
  return React.createElement("aside", {
28330
- className: flairup.cx(styles.main, styles.baseVariables, theme === exports.Theme.DARK && styles.darkTheme, theme === exports.Theme.AUTO && styles.autoThemeDark, (_cx = {}, _cx[ClassNames.searchActive] = searchModeActive, _cx), reactionsMode && styles.reactionsMenu, className),
28390
+ className: shipstyles.cx(styles.main, styles.baseVariables, theme === exports.Theme.DARK && styles.darkTheme, theme === exports.Theme.AUTO && styles.autoThemeDark, (_cx = {}, _cx[ClassNames.searchActive] = searchModeActive, _cx), reactionsMode && styles.reactionsMenu, className),
28331
28391
  ref: PickerMainRef,
28332
28392
  style: _extends({}, styleProps, !reactionsMode && {
28333
28393
  height: height,
@@ -28480,9 +28540,20 @@ var styles = /*#__PURE__*/stylesheet.create({
28480
28540
  });
28481
28541
 
28482
28542
  function elementCountInRow(parent, element) {
28543
+ var _parent$dataset;
28483
28544
  if (!parent || !element) {
28484
28545
  return 0;
28485
28546
  }
28547
+ // The virtualized layout positions emojis with a fixed per-row count that
28548
+ // is rendered onto the category content element. That count is the single
28549
+ // source of truth: deriving it again from fractional rect widths can be
28550
+ // off by one (e.g. category padding shrinking the content box), which
28551
+ // makes arrow-up/arrow-down drift sideways by a column.
28552
+ // https://github.com/ealush/emoji-picker-react/issues/502
28553
+ var declared = Number((_parent$dataset = parent.dataset) == null ? void 0 : _parent$dataset.emojisPerRow);
28554
+ if (Number.isInteger(declared) && declared > 0) {
28555
+ return declared;
28556
+ }
28486
28557
  var parentWidth = parent.getBoundingClientRect().width;
28487
28558
  var elementWidth = element.getBoundingClientRect().width;
28488
28559
  return Math.floor(parentWidth / elementWidth);
@@ -28889,7 +28960,7 @@ function Button(props) {
28889
28960
  return React.createElement("button", Object.assign({
28890
28961
  type: "button"
28891
28962
  }, props, {
28892
- className: flairup.cx(styles$1.button, props.className)
28963
+ className: shipstyles.cx(styles$1.button, props.className)
28893
28964
  }), props.children);
28894
28965
  }
28895
28966
  var styles$1 = /*#__PURE__*/stylesheet.create({
@@ -28922,7 +28993,7 @@ function ClickableEmojiButton(_ref) {
28922
28993
  noBackground = _ref$noBackground === void 0 ? false : _ref$noBackground,
28923
28994
  style = _ref.style;
28924
28995
  return React.createElement(Button, {
28925
- className: flairup.cx(styles$2.emoji, hidden && commonStyles.hidden, hiddenOnSearch && commonInteractionStyles.hiddenOnSearch, (_cx = {}, _cx[ClassNames.visible] = !hidden && !hiddenOnSearch, _cx), !!(hasVariations && showVariations) && styles$2.hasVariations, noBackground && styles$2.noBackground, className),
28996
+ className: shipstyles.cx(styles$2.emoji, hidden && commonStyles.hidden, hiddenOnSearch && commonInteractionStyles.hiddenOnSearch, (_cx = {}, _cx[ClassNames.visible] = !hidden && !hiddenOnSearch, _cx), !!(hasVariations && showVariations) && styles$2.hasVariations, noBackground && styles$2.noBackground, className),
28926
28997
  "data-unified": unified,
28927
28998
  "aria-label": getAriaLabel(emojiNames),
28928
28999
  "data-full-name": emojiNames,
@@ -29010,7 +29081,7 @@ function EmojiImg(_ref) {
29010
29081
  return React.createElement("img", {
29011
29082
  src: imgUrl,
29012
29083
  alt: emojiName,
29013
- className: flairup.cx(styles$3.emojiImag, emojiStyles.external, emojiStyles.common, className),
29084
+ className: shipstyles.cx(styles$3.emojiImag, emojiStyles.external, emojiStyles.common, className),
29014
29085
  loading: lazyLoad ? 'lazy' : 'eager',
29015
29086
  onError: onError,
29016
29087
  style: style
@@ -29032,7 +29103,7 @@ function NativeEmoji(_ref) {
29032
29103
  style = _ref.style,
29033
29104
  className = _ref.className;
29034
29105
  return React.createElement("span", {
29035
- className: flairup.cx(
29106
+ className: shipstyles.cx(
29036
29107
  // Order matters: cx() lets the later class win same-property
29037
29108
  // conflicts, so the zeroing reset must come first and the real
29038
29109
  // font-size last — otherwise the emoji renders at 0px.
@@ -29120,6 +29191,7 @@ function ClickableEmoji(_ref) {
29120
29191
  lazyLoad = _ref.lazyLoad,
29121
29192
  getEmojiUrl = _ref.getEmojiUrl,
29122
29193
  className = _ref.className,
29194
+ buttonClassName = _ref.buttonClassName,
29123
29195
  _ref$noBackground = _ref.noBackground,
29124
29196
  noBackground = _ref$noBackground === void 0 ? false : _ref$noBackground,
29125
29197
  style = _ref.style;
@@ -29132,7 +29204,8 @@ function ClickableEmoji(_ref) {
29132
29204
  emojiNames: emojiNames(emoji),
29133
29205
  unified: unified,
29134
29206
  noBackground: noBackground,
29135
- style: style
29207
+ style: style,
29208
+ className: buttonClassName
29136
29209
  }, React.createElement(ViewOnlyEmoji, {
29137
29210
  unified: unified,
29138
29211
  emoji: emoji,
@@ -29153,7 +29226,7 @@ function BtnPlus() {
29153
29226
  "aria-label": "Show all Emojis",
29154
29227
  title: "Show all Emojis",
29155
29228
  tabIndex: 0,
29156
- className: flairup.cx(styles$5.plusSign),
29229
+ className: shipstyles.cx(styles$5.plusSign),
29157
29230
  onClick: function onClick() {
29158
29231
  return setReactionsMode(false);
29159
29232
  }
@@ -29220,7 +29293,7 @@ function Reactions() {
29220
29293
  return null;
29221
29294
  }
29222
29295
  return React.createElement("ul", {
29223
- className: flairup.cx(styles$6.list, !reactionsOpen && commonStyles.hidden),
29296
+ className: shipstyles.cx(styles$6.list, !reactionsOpen && commonStyles.hidden),
29224
29297
  ref: ReactionsRef,
29225
29298
  "aria-label": "Reactions"
29226
29299
  }, reactions.map(function (reaction) {
@@ -29235,7 +29308,8 @@ function Reactions() {
29235
29308
  emojiStyle: emojiStyle,
29236
29309
  unified: reaction,
29237
29310
  showVariations: false,
29238
- className: flairup.cx(styles$6.emojiButton),
29311
+ className: shipstyles.cx(styles$6.emojiButton),
29312
+ buttonClassName: shipstyles.cx(styles$6.reactionButton),
29239
29313
  noBackground: true,
29240
29314
  getEmojiUrl: getEmojiUrl
29241
29315
  }));
@@ -29251,6 +29325,24 @@ var styles$6 = /*#__PURE__*/stylesheet.create({
29251
29325
  alignItems: 'center',
29252
29326
  height: '100%'
29253
29327
  },
29328
+ reactionButton: {
29329
+ // Every picker button sets outline: none, and reaction buttons also
29330
+ // suppress the focus background, so keyboard focus was invisible.
29331
+ // Focus mirrors the hover treatment (scale plus a soft circular
29332
+ // wash, no outline ring): the scale transform on the inner image
29333
+ // alone is clipped by the button's overflow: hidden, and does
29334
+ // nothing on inline native emoji, so the button itself carries the
29335
+ // effect. Scoped to the reactions bar so grid focus treatment is
29336
+ // untouched.
29337
+ // https://github.com/ealush/emoji-picker-react/issues/473
29338
+ ':focus-visible': {
29339
+ transform: 'scale(1.2)',
29340
+ transition: 'background-color 0.2s, transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.5)',
29341
+ backgroundColor: 'var(--epr-hover-bg-color-reduced-opacity)',
29342
+ borderRadius: '50%',
29343
+ outline: 'none'
29344
+ }
29345
+ },
29254
29346
  emojiButton: {
29255
29347
  ':hover': {
29256
29348
  transform: 'scale(1.2)'
@@ -29474,20 +29566,24 @@ function EmojiCategory(_ref) {
29474
29566
  children = _ref.children,
29475
29567
  hidden = _ref.hidden,
29476
29568
  hiddenOnSearch = _ref.hiddenOnSearch,
29477
- height = _ref.height;
29569
+ height = _ref.height,
29570
+ emojisPerRow = _ref.emojisPerRow;
29478
29571
  var category = categoryFromCategoryConfig(categoryConfig);
29479
29572
  var categoryName = categoryNameFromCategoryConfig(categoryConfig);
29480
29573
  return React.createElement("li", {
29481
- className: flairup.cx(styles$7.category, hidden && commonStyles.hidden, hiddenOnSearch && commonInteractionStyles.hiddenOnSearch),
29574
+ className: shipstyles.cx(styles$7.category, hidden && commonStyles.hidden, hiddenOnSearch && commonInteractionStyles.hiddenOnSearch),
29482
29575
  "data-name": category,
29576
+ role: "rowgroup",
29483
29577
  "aria-label": categoryName
29484
29578
  }, React.createElement("h2", {
29485
- className: flairup.cx(styles$7.label)
29579
+ className: shipstyles.cx(styles$7.label)
29486
29580
  }, categoryName), React.createElement("div", {
29487
- className: flairup.cx(styles$7.categoryContent),
29581
+ className: shipstyles.cx(styles$7.categoryContent),
29488
29582
  style: {
29489
29583
  height: height
29490
- }
29584
+ },
29585
+ role: "row",
29586
+ "data-emojis-per-row": emojisPerRow
29491
29587
  }, children));
29492
29588
  }
29493
29589
  var styles$7 = /*#__PURE__*/stylesheet.create({
@@ -29589,9 +29685,19 @@ function EmojiList(_ref) {
29589
29685
  var getEmojisByCategory = useGetEmojisByCategory();
29590
29686
  var labelHeight = getLabelHeight(EmojiListRef.current);
29591
29687
  var topOffset = 0;
29688
+ // role="grid" makes screen readers switch out of virtual-cursor mode so
29689
+ // arrow keys reach the picker's keyboard handler. Each category is one
29690
+ // rowgroup: visual rows shift under virtualization, so the category is
29691
+ // the only stable row unit. Emoji buttons intentionally keep their
29692
+ // native button role for activation semantics.
29693
+ // https://github.com/ealush/emoji-picker-react/issues/508
29694
+ // The list markup is kept for a backwards-compatible DOM structure;
29695
+ // the grid role override is intentional (see below).
29696
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
29592
29697
  return React.createElement("ul", {
29593
- className: flairup.cx(styles$8.emojiList),
29594
- ref: EmojiListRef
29698
+ className: shipstyles.cx(styles$8.emojiList),
29699
+ ref: EmojiListRef,
29700
+ role: "grid"
29595
29701
  }, React.createElement(MeasureEmoji, null), categories.map(function (categoryConfig) {
29596
29702
  var category = categoryFromCategoryConfig(categoryConfig);
29597
29703
  var currentOffset = topOffset;
@@ -29637,6 +29743,7 @@ function RenderCategory(_ref2) {
29637
29743
  return React.createElement(EmojiCategory, {
29638
29744
  categoryConfig: categoryConfig,
29639
29745
  height: dimensions == null ? void 0 : dimensions.categoryHeight,
29746
+ emojisPerRow: dimensions == null ? void 0 : dimensions.emojisPerRow,
29640
29747
  // Indicates that there are no visible emojis
29641
29748
  // Hence, the category should be hidden
29642
29749
  hidden: !emojis.length && virtualizedCounter === 0
@@ -29688,7 +29795,7 @@ function EmojiVariationPicker() {
29688
29795
  }
29689
29796
  return React.createElement("div", {
29690
29797
  ref: VariationPickerRef,
29691
- className: flairup.cx(styles$9.variationPicker, getMenuDirection() === Direction.Down && styles$9.pointingUp, visible && styles$9.visible),
29798
+ className: shipstyles.cx(styles$9.variationPicker, getMenuDirection() === Direction.Down && styles$9.pointingUp, visible && styles$9.visible),
29692
29799
  style: {
29693
29800
  top: top
29694
29801
  }
@@ -29702,7 +29809,7 @@ function EmojiVariationPicker() {
29702
29809
  getEmojiUrl: getEmojiUrl
29703
29810
  });
29704
29811
  }) : null, React.createElement("div", {
29705
- className: flairup.cx(styles$9.pointer),
29812
+ className: shipstyles.cx(styles$9.pointer),
29706
29813
  style: pointerStyle
29707
29814
  }));
29708
29815
  }
@@ -29821,7 +29928,7 @@ function Body() {
29821
29928
  useMouseDownHandlers(BodyRef, MOUSE_EVENT_SOURCE.PICKER);
29822
29929
  useOnMouseMove();
29823
29930
  return React.createElement("div", {
29824
- className: flairup.cx(styles$a.body, commonInteractionStyles.hiddenOnReactions),
29931
+ className: shipstyles.cx(styles$a.body, commonInteractionStyles.hiddenOnReactions),
29825
29932
  ref: BodyRef
29826
29933
  }, React.createElement(EmojiVariationPicker, null), React.createElement(EmojiList, {
29827
29934
  scrollTop: scrollTop
@@ -29948,7 +30055,7 @@ function Flex(_ref) {
29948
30055
  direction = _ref$direction === void 0 ? FlexDirection.ROW : _ref$direction;
29949
30056
  return React.createElement("div", {
29950
30057
  style: _extends({}, style),
29951
- className: flairup.cx(styles$b.flex, className, styles$b[direction])
30058
+ className: shipstyles.cx(styles$b.flex, className, styles$b[direction])
29952
30059
  }, children);
29953
30060
  }
29954
30061
  var styles$b = /*#__PURE__*/stylesheet.create((_stylesheet$create = {
@@ -29969,7 +30076,7 @@ function Space(_ref) {
29969
30076
  style: _extends({
29970
30077
  flex: 1
29971
30078
  }, style),
29972
- className: flairup.cx(className)
30079
+ className: shipstyles.cx(className)
29973
30080
  });
29974
30081
  }
29975
30082
 
@@ -30003,11 +30110,13 @@ function BtnSkinToneVariation(_ref) {
30003
30110
  onClick = _ref.onClick,
30004
30111
  isActive = _ref.isActive,
30005
30112
  skinToneVariation = _ref.skinToneVariation,
30006
- style = _ref.style;
30113
+ style = _ref.style,
30114
+ tabIndex = _ref.tabIndex;
30007
30115
  return React.createElement(Button, {
30008
30116
  style: style,
30009
30117
  onClick: onClick,
30010
- className: flairup.cx("epr-tone-" + skinToneVariation, styles$c.tone, !isOpen && styles$c.closedTone, isActive && styles$c.active),
30118
+ tabIndex: tabIndex,
30119
+ className: shipstyles.cx("epr-tone-" + skinToneVariation, styles$c.tone, !isOpen && styles$c.closedTone, isActive && styles$c.active),
30011
30120
  "aria-pressed": isActive,
30012
30121
  "aria-label": "Skin tone " + skinTonesNamed[skinToneVariation]
30013
30122
  });
@@ -30099,7 +30208,7 @@ function SkinTonePicker(_ref) {
30099
30208
  var expandedSize = isOpen ? fullWidth : ITEM_SIZE + 'px';
30100
30209
  var vertical = direction === SkinTonePickerDirection.VERTICAL;
30101
30210
  return React.createElement(Relative, {
30102
- className: flairup.cx(styles$d.skinTones, vertical && styles$d.vertical, isOpen && styles$d.open, vertical && isOpen && styles$d.verticalShadow),
30211
+ className: shipstyles.cx(styles$d.skinTones, vertical && styles$d.vertical, isOpen && styles$d.open, vertical && isOpen && styles$d.verticalShadow),
30103
30212
  style: vertical ? {
30104
30213
  flexBasis: expandedSize,
30105
30214
  height: expandedSize
@@ -30107,7 +30216,7 @@ function SkinTonePicker(_ref) {
30107
30216
  flexBasis: expandedSize
30108
30217
  }
30109
30218
  }, React.createElement("div", {
30110
- className: flairup.cx(styles$d.select),
30219
+ className: shipstyles.cx(styles$d.select),
30111
30220
  ref: SkinTonePickerRef
30112
30221
  }, skinToneVariations.map(function (skinToneVariation, i) {
30113
30222
  var active = skinToneVariation === activeSkinTone;
@@ -30115,8 +30224,14 @@ function SkinTonePicker(_ref) {
30115
30224
  key: skinToneVariation,
30116
30225
  skinToneVariation: skinToneVariation,
30117
30226
  isOpen: isOpen,
30227
+ // Roving tabindex: when the fan is closed the inactive tones
30228
+ // are invisible (opacity: 0, stacked), so they must not be
30229
+ // reachable via Tab. The active tone stays tabbable to open
30230
+ // the fan from the keyboard.
30231
+ // https://github.com/ealush/emoji-picker-react/issues/492
30232
+ tabIndex: isOpen || active ? 0 : -1,
30118
30233
  style: {
30119
- transform: flairup.cx(vertical ? "translateY(-" + i * (isOpen ? ITEM_SIZE : 0) + "px)" : "translateX(-" + i * (isOpen ? ITEM_SIZE : 0) + "px)", isOpen && active && 'scale(1.3)')
30234
+ transform: shipstyles.cx(vertical ? "translateY(-" + i * (isOpen ? ITEM_SIZE : 0) + "px)" : "translateX(-" + i * (isOpen ? ITEM_SIZE : 0) + "px)", isOpen && active && 'scale(1.3)')
30120
30235
  },
30121
30236
  isActive: active,
30122
30237
  onClick: function onClick() {
@@ -30184,7 +30299,7 @@ function Preview() {
30184
30299
  return null;
30185
30300
  }
30186
30301
  return React.createElement(Flex, {
30187
- className: flairup.cx(styles$e.preview, commonInteractionStyles.hiddenOnReactions, reactionsOpen && styles$e.hideOnReactions)
30302
+ className: shipstyles.cx(styles$e.preview, commonInteractionStyles.hiddenOnReactions, reactionsOpen && styles$e.hideOnReactions)
30188
30303
  }, React.createElement(PreviewBody, null), React.createElement(Space, null), isSkinToneInPreview ? React.createElement(SkinTonePickerMenu, null) : null);
30189
30304
  }
30190
30305
  function PreviewBody() {
@@ -30215,16 +30330,16 @@ function PreviewBody() {
30215
30330
  emojiStyle: emojiStyle,
30216
30331
  size: 45,
30217
30332
  getEmojiUrl: getEmojiUrl,
30218
- className: flairup.cx(styles$e.emoji)
30333
+ className: shipstyles.cx(styles$e.emoji)
30219
30334
  }) : defaultEmoji ? React.createElement(ViewOnlyEmoji, {
30220
30335
  unified: emojiUnified(defaultEmoji),
30221
30336
  emoji: defaultEmoji,
30222
30337
  emojiStyle: emojiStyle,
30223
30338
  size: 45,
30224
30339
  getEmojiUrl: getEmojiUrl,
30225
- className: flairup.cx(styles$e.emoji)
30340
+ className: shipstyles.cx(styles$e.emoji)
30226
30341
  }) : null), React.createElement("div", {
30227
- className: flairup.cx(styles$e.label)
30342
+ className: shipstyles.cx(styles$e.label)
30228
30343
  }, show ? emojiName(emoji) : defaultText));
30229
30344
  }
30230
30345
  }
@@ -30354,7 +30469,7 @@ function CategoryButton(_ref) {
30354
30469
  var hasCustomIcon = icon != null;
30355
30470
  return React.createElement(Button, {
30356
30471
  tabIndex: allowNavigation ? 0 : -1,
30357
- className: flairup.cx(styles$f.catBtn, commonInteractionStyles.categoryBtn, hasCustomIcon ? styles$f.customIcon : "epr-icn-" + category, (_cx = {}, _cx[ClassNames.active] = isActiveCategory, _cx)),
30472
+ className: shipstyles.cx(styles$f.catBtn, commonInteractionStyles.categoryBtn, hasCustomIcon ? styles$f.customIcon : "epr-icn-" + category, (_cx = {}, _cx[ClassNames.active] = isActiveCategory, _cx)),
30358
30473
  onClick: onClick,
30359
30474
  "aria-label": categoryNameFromCategoryConfig(categoryConfig),
30360
30475
  "aria-selected": isActiveCategory,
@@ -30458,7 +30573,7 @@ function CategoryNavigation() {
30458
30573
  var CategoryNavigationRef = useCategoryNavigationRef();
30459
30574
  var hideCustomCategory = useShouldHideCustomEmojis();
30460
30575
  return React.createElement("div", {
30461
- className: flairup.cx(styles$g.nav),
30576
+ className: shipstyles.cx(styles$g.nav),
30462
30577
  role: "tablist",
30463
30578
  "aria-label": "Category navigation",
30464
30579
  id: "epr-category-nav-id",
@@ -30516,12 +30631,12 @@ function BtnClearSearch() {
30516
30631
  var clearSearch = useClearSearch();
30517
30632
  var searchClearButtonLabel = useSearchClearButtonLabelConfig();
30518
30633
  return React.createElement(Button, {
30519
- className: flairup.cx(styles$h.btnClearSearch, commonInteractionStyles.visibleOnSearchOnly),
30634
+ className: shipstyles.cx(styles$h.btnClearSearch, commonInteractionStyles.visibleOnSearchOnly),
30520
30635
  onClick: clearSearch,
30521
30636
  "aria-label": searchClearButtonLabel,
30522
30637
  title: searchClearButtonLabel
30523
30638
  }, React.createElement("div", {
30524
- className: flairup.cx(styles$h.icnClearnSearch)
30639
+ className: shipstyles.cx(styles$h.icnClearnSearch)
30525
30640
  }));
30526
30641
  }
30527
30642
  var HoverDark = {
@@ -30575,7 +30690,7 @@ var SVGMagnifier = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZG
30575
30690
 
30576
30691
  function IcnSearch() {
30577
30692
  return React.createElement("div", {
30578
- className: flairup.cx(styles$i.icnSearch)
30693
+ className: shipstyles.cx(styles$i.icnSearch)
30579
30694
  });
30580
30695
  }
30581
30696
  var styles$i = /*#__PURE__*/stylesheet.create(/*#__PURE__*/_extends({
@@ -30604,7 +30719,7 @@ function SearchContainer() {
30604
30719
  return null;
30605
30720
  }
30606
30721
  return React.createElement(Flex, {
30607
- className: flairup.cx(styles$j.overlay)
30722
+ className: shipstyles.cx(styles$j.overlay)
30608
30723
  }, React.createElement(Search, null), isSkinToneInSearch ? React.createElement(SkinTonePicker, null) : null);
30609
30724
  }
30610
30725
  function Search() {
@@ -30619,13 +30734,13 @@ function Search() {
30619
30734
  var input = SearchInputRef == null ? void 0 : SearchInputRef.current;
30620
30735
  var value = input == null ? void 0 : input.value;
30621
30736
  return React.createElement(Relative, {
30622
- className: flairup.cx(styles$j.searchContainer)
30737
+ className: shipstyles.cx(styles$j.searchContainer)
30623
30738
  }, React.createElement("input", {
30624
30739
  // eslint-disable-next-line jsx-a11y/no-autofocus
30625
30740
  autoFocus: autoFocus,
30626
30741
  "aria-label": 'Type to search for an emoji',
30627
30742
  onFocus: closeAllOpenToggles,
30628
- className: flairup.cx(styles$j.search),
30743
+ className: shipstyles.cx(styles$j.search),
30629
30744
  type: "text",
30630
30745
  "aria-controls": "epr-search-id",
30631
30746
  placeholder: placeholder,
@@ -30636,7 +30751,7 @@ function Search() {
30636
30751
  ref: SearchInputRef
30637
30752
  }), searchTerm ? React.createElement("div", {
30638
30753
  role: "status",
30639
- className: flairup.cx('epr-status-search-results', styles$j.visuallyHidden),
30754
+ className: shipstyles.cx('epr-status-search-results', styles$j.visuallyHidden),
30640
30755
  "aria-live": "polite",
30641
30756
  id: "epr-search-id",
30642
30757
  "aria-atomic": "true"
@@ -30725,7 +30840,7 @@ var styles$j = /*#__PURE__*/stylesheet.create(/*#__PURE__*/_extends({
30725
30840
 
30726
30841
  function Header() {
30727
30842
  return React.createElement(Relative, {
30728
- className: flairup.cx('epr-header', commonInteractionStyles.hiddenOnReactions)
30843
+ className: shipstyles.cx('epr-header', commonInteractionStyles.hiddenOnReactions)
30729
30844
  }, React.createElement(SearchContainer, null), React.createElement(CategoryNavigation, null));
30730
30845
  }
30731
30846