+
{children}
);
diff --git a/src/components/emoji/BaseEmojiProps.ts b/src/components/emoji/BaseEmojiProps.ts
new file mode 100644
index 00000000..3f70ee25
--- /dev/null
+++ b/src/components/emoji/BaseEmojiProps.ts
@@ -0,0 +1,13 @@
+import { CustomEmoji } from '../../config/customEmojiConfig';
+import { DataEmoji } from '../../dataUtils/DataTypes';
+import { EmojiStyle } from '../../types/exposedTypes';
+
+export type BaseEmojiProps = {
+ emoji?: DataEmoji | CustomEmoji;
+ emojiStyle: EmojiStyle;
+ unified: string;
+ size?: number;
+ lazyLoad?: boolean;
+ getEmojiUrl?: GetEmojiUrl;
+};
+export type GetEmojiUrl = (unified: string, style: EmojiStyle) => string;
diff --git a/src/components/emoji/ClickableEmojiButton.tsx b/src/components/emoji/ClickableEmojiButton.tsx
new file mode 100644
index 00000000..2d9b997b
--- /dev/null
+++ b/src/components/emoji/ClickableEmojiButton.tsx
@@ -0,0 +1,42 @@
+import clsx from 'clsx';
+import * as React from 'react';
+
+import { ClassNames } from '../../DomUtils/classNames';
+import { Button } from '../atoms/Button';
+import './Emoji.css';
+
+type ClickableEmojiButtonProps = Readonly<{
+ hidden?: boolean;
+ showVariations?: boolean;
+ hiddenOnSearch?: boolean;
+ emojiNames: string[];
+ children: React.ReactNode;
+ hasVariations: boolean;
+ unified?: string;
+}>;
+
+export function ClickableEmojiButton({
+ emojiNames,
+ unified,
+ hidden,
+ hiddenOnSearch,
+ showVariations = true,
+ hasVariations,
+ children
+}: ClickableEmojiButtonProps) {
+ return (
+
+ );
+}
diff --git a/src/components/emoji/Emoji.css b/src/components/emoji/Emoji.css
index f3469dba..1777c700 100644
--- a/src/components/emoji/Emoji.css
+++ b/src/components/emoji/Emoji.css
@@ -30,6 +30,8 @@
.EmojiPickerReact button.epr-emoji .epr-emoji-img {
max-width: var(--epr-emoji-fullsize);
max-height: var(--epr-emoji-fullsize);
+ min-width: var(--epr-emoji-fullsize);
+ min-height: var(--epr-emoji-fullsize);
padding: var(--epr-emoji-padding);
}
diff --git a/src/components/emoji/Emoji.tsx b/src/components/emoji/Emoji.tsx
index f88ddd49..37234730 100644
--- a/src/components/emoji/Emoji.tsx
+++ b/src/components/emoji/Emoji.tsx
@@ -1,23 +1,15 @@
-import clsx from 'clsx';
import * as React from 'react';
-import { ClassNames } from '../../DomUtils/classNames';
import { DataEmoji } from '../../dataUtils/DataTypes';
-import {
- emojiByUnified,
- emojiHasVariations,
- emojiName,
- emojiNames,
- emojiUrlByUnified,
-} from '../../dataUtils/emojiSelectors';
-import { parseNativeEmoji } from '../../dataUtils/parseNativeEmoji';
-import { EmojiStyle } from '../../types/exposedTypes';
-import { Button } from '../atoms/Button';
-import { useEmojisThatFailedToLoadState } from '../context/PickerContext';
+import { emojiHasVariations, emojiNames } from '../../dataUtils/emojiSelectors';
+
import './Emoji.css';
+import { BaseEmojiProps } from './BaseEmojiProps';
+import { ClickableEmojiButton } from './ClickableEmojiButton';
+import { ViewOnlyEmoji } from './ViewOnlyEmoji';
type ClickableEmojiProps = Readonly<
- BaseProps & {
+ BaseEmojiProps & {
hidden?: boolean;
showVariations?: boolean;
hiddenOnSearch?: boolean;
@@ -25,15 +17,6 @@ type ClickableEmojiProps = Readonly<
}
>;
-type BaseProps = {
- emoji?: DataEmoji;
- emojiStyle: EmojiStyle;
- unified: string;
- size?: number;
- lazyLoad?: boolean;
- getEmojiUrl?: GetEmojiUrl;
-};
-
export function ClickableEmoji({
emoji,
unified,
@@ -43,22 +26,18 @@ export function ClickableEmoji({
showVariations = true,
size,
lazyLoad,
- getEmojiUrl,
+ getEmojiUrl
}: ClickableEmojiProps) {
const hasVariations = emojiHasVariations(emoji);
return (
-
- );
-}
-
-export function ViewOnlyEmoji({
- emoji,
- unified,
- emojiStyle,
- size,
- lazyLoad,
- getEmojiUrl = emojiUrlByUnified,
-}: BaseProps) {
- const style = {} as React.CSSProperties;
- if (size) {
- style.width = style.height = style.fontSize = `${size}px`;
- }
-
- const emojiToRender = emoji ? emoji : emojiByUnified(unified);
- if(!emojiToRender) {
- return null
- }
-
- return (
- <>
- {emojiStyle === EmojiStyle.NATIVE ? (
-
- ) : (
-
- )}
- >
- );
-}
-
-function NativeEmoji({
- unified,
- style,
-}: {
- unified: string;
- style: React.CSSProperties;
-}) {
- return (
-
- {parseNativeEmoji(unified)}
-
- );
-}
-
-function EmojiImg({
- emoji,
- unified,
- emojiStyle,
- style,
- lazyLoad = false,
- getEmojiUrl,
-}: {
- emoji: DataEmoji;
- unified: string;
- emojiStyle: EmojiStyle;
- style: React.CSSProperties;
- lazyLoad?: boolean;
- getEmojiUrl: GetEmojiUrl;
-}) {
- const [, setEmojisThatFailedToLoad] = useEmojisThatFailedToLoadState();
-
- return (
-
+
);
-
- function onError() {
- setEmojisThatFailedToLoad((prev) => new Set(prev).add(unified));
- }
}
-
-export type GetEmojiUrl = (unified: string, style: EmojiStyle) => string;
diff --git a/src/components/emoji/EmojiImg.tsx b/src/components/emoji/EmojiImg.tsx
new file mode 100644
index 00000000..22249339
--- /dev/null
+++ b/src/components/emoji/EmojiImg.tsx
@@ -0,0 +1,31 @@
+import clsx from 'clsx';
+import * as React from 'react';
+
+import { ClassNames } from '../../DomUtils/classNames';
+import { EmojiStyle } from '../../types/exposedTypes';
+
+export function EmojiImg({
+ emojiName,
+ style,
+ lazyLoad = false,
+ imgUrl,
+ onError
+}: {
+ emojiName: string;
+ emojiStyle: EmojiStyle;
+ style: React.CSSProperties;
+ lazyLoad?: boolean;
+ imgUrl: string;
+ onError: () => void;
+}) {
+ return (
+
+ );
+}
diff --git a/src/components/emoji/ExportedEmoji.tsx b/src/components/emoji/ExportedEmoji.tsx
index 31c45a0e..45f9e34a 100644
--- a/src/components/emoji/ExportedEmoji.tsx
+++ b/src/components/emoji/ExportedEmoji.tsx
@@ -2,14 +2,15 @@ import * as React from 'react';
import { EmojiStyle } from '../../types/exposedTypes';
-import { GetEmojiUrl, ViewOnlyEmoji } from './Emoji';
+import { GetEmojiUrl } from './BaseEmojiProps';
+import { ViewOnlyEmoji } from './ViewOnlyEmoji';
export function ExportedEmoji({
unified,
size = 32,
emojiStyle = EmojiStyle.APPLE,
lazyLoad = false,
- getEmojiUrl,
+ getEmojiUrl
}: {
unified: string;
emojiStyle?: EmojiStyle;
diff --git a/src/components/emoji/NativeEmoji.tsx b/src/components/emoji/NativeEmoji.tsx
new file mode 100644
index 00000000..f682fb2e
--- /dev/null
+++ b/src/components/emoji/NativeEmoji.tsx
@@ -0,0 +1,23 @@
+import clsx from 'clsx';
+import * as React from 'react';
+
+import { ClassNames } from '../../DomUtils/classNames';
+import { parseNativeEmoji } from '../../dataUtils/parseNativeEmoji';
+
+export function NativeEmoji({
+ unified,
+ style
+}: {
+ unified: string;
+ style: React.CSSProperties;
+}) {
+ return (
+
+ {parseNativeEmoji(unified)}
+
+ );
+}
diff --git a/src/components/emoji/ViewOnlyEmoji.tsx b/src/components/emoji/ViewOnlyEmoji.tsx
new file mode 100644
index 00000000..2685465a
--- /dev/null
+++ b/src/components/emoji/ViewOnlyEmoji.tsx
@@ -0,0 +1,70 @@
+import * as React from 'react';
+
+import {
+ emojiByUnified,
+ emojiName,
+ emojiUrlByUnified
+} from '../../dataUtils/emojiSelectors';
+import { isCustomEmoji } from '../../typeRefinements/typeRefinements';
+import { EmojiStyle } from '../../types/exposedTypes';
+import { useEmojisThatFailedToLoadState } from '../context/PickerContext';
+
+import { BaseEmojiProps } from './BaseEmojiProps';
+import { EmojiImg } from './EmojiImg';
+import { NativeEmoji } from './NativeEmoji';
+
+export function ViewOnlyEmoji({
+ emoji,
+ unified,
+ emojiStyle,
+ size,
+ lazyLoad,
+ getEmojiUrl = emojiUrlByUnified
+}: BaseEmojiProps) {
+ const [, setEmojisThatFailedToLoad] = useEmojisThatFailedToLoadState();
+
+ const style = {} as React.CSSProperties;
+ if (size) {
+ style.width = style.height = style.fontSize = `${size}px`;
+ }
+
+ const emojiToRender = emoji ? emoji : emojiByUnified(unified);
+
+ if (!emojiToRender) {
+ return null;
+ }
+
+ if (isCustomEmoji(emojiToRender)) {
+ return (
+
+ );
+ }
+
+ return (
+ <>
+ {emojiStyle === EmojiStyle.NATIVE ? (
+
+ ) : (
+
+ )}
+ >
+ );
+
+ function onError() {
+ setEmojisThatFailedToLoad(prev => new Set(prev).add(unified));
+ }
+}
diff --git a/src/components/footer/Preview.tsx b/src/components/footer/Preview.tsx
index 26676bf2..0067e3d8 100644
--- a/src/components/footer/Preview.tsx
+++ b/src/components/footer/Preview.tsx
@@ -16,9 +16,9 @@ import { useIsSkinToneInPreview } from '../../hooks/useShouldShowSkinTonePicker'
import Flex from '../Layout/Flex';
import Space from '../Layout/Space';
import { useEmojiVariationPickerState } from '../context/PickerContext';
-import { ViewOnlyEmoji } from '../emoji/Emoji';
import './Preview.css';
import { SkinTonePickerMenu } from '../header/SkinTonePicker';
+import { ViewOnlyEmoji } from '../emoji/ViewOnlyEmoji';
export function Preview() {
const previewConfig = usePreviewConfig();
diff --git a/src/components/navigation/CategoryNavigation.css b/src/components/navigation/CategoryNavigation.css
index b2381842..9f436e49 100644
--- a/src/components/navigation/CategoryNavigation.css
+++ b/src/components/navigation/CategoryNavigation.css
@@ -87,6 +87,9 @@ aside.EmojiPickerReact.epr-main:has(input:placeholder-shown) .epr-category-nav {
.EmojiPickerReact button.epr-cat-btn.epr-icn-suggested {
background-position-x: calc(var(--epr-category-navigation-button-size) * -8);
}
+.EmojiPickerReact button.epr-cat-btn.epr-icn-custom {
+ background-position-x: calc(var(--epr-category-navigation-button-size) * -9);
+}
.EmojiPickerReact button.epr-cat-btn.epr-icn-activities {
background-position-x: calc(var(--epr-category-navigation-button-size) * -4);
}
diff --git a/src/components/navigation/CategoryNavigation.tsx b/src/components/navigation/CategoryNavigation.tsx
index 95e1fe3d..5ec5aab4 100644
--- a/src/components/navigation/CategoryNavigation.tsx
+++ b/src/components/navigation/CategoryNavigation.tsx
@@ -12,6 +12,8 @@ import { useCategoriesConfig } from '../../config/useConfig';
import { useActiveCategoryScrollDetection } from '../../hooks/useActiveCategoryScrollDetection';
import useIsSearchMode from '../../hooks/useIsSearchMode';
import { useScrollCategoryIntoView } from '../../hooks/useScrollCategoryIntoView';
+import { useShouldHideCustomEmojis } from '../../hooks/useShouldHideCustomEmojis';
+import { isCustomCategory } from '../../typeRefinements/typeRefinements';
import { Button } from '../atoms/Button';
import { useCategoryNavigationRef } from '../context/ElementRefContext';
@@ -23,11 +25,17 @@ export function CategoryNavigation() {
const categoriesConfig = useCategoriesConfig();
const CategoryNavigationRef = useCategoryNavigationRef();
+ const hideCustomCategory = useShouldHideCustomEmojis();
return (
{categoriesConfig.map(categoryConfig => {
const category = categoryFromCategoryConfig(categoryConfig);
+
+ if (isCustomCategory(categoryConfig) && hideCustomCategory) {
+ return null;
+ }
+
return (