Files
mastodon/app/javascript/flavours/glitch/components/emoji/html.tsx
Echo 7430e3c74d [Glitch] Emoji Component
Port c12b8f51c1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2025-10-01 19:40:20 +02:00

62 lines
1.7 KiB
TypeScript

import { useMemo } from 'react';
import type { ComponentPropsWithoutRef, ElementType } from 'react';
import classNames from 'classnames';
import type { CustomEmojiMapArg } from '@/flavours/glitch/features/emoji/types';
import { isModernEmojiEnabled } from '@/flavours/glitch/utils/environment';
import { htmlStringToComponents } from '@/flavours/glitch/utils/html';
import { AnimateEmojiProvider, CustomEmojiProvider } from './context';
import { textToEmojis } from './index';
type EmojiHTMLProps<Element extends ElementType = 'div'> = Omit<
ComponentPropsWithoutRef<Element>,
'dangerouslySetInnerHTML' | 'className'
> & {
htmlString: string;
extraEmojis?: CustomEmojiMapArg;
as?: Element;
className?: string;
};
export const ModernEmojiHTML = ({
extraEmojis,
htmlString,
as: asProp = 'div', // Rename for syntax highlighting
shallow,
className = '',
...props
}: EmojiHTMLProps<ElementType>) => {
const contents = useMemo(
() => htmlStringToComponents(htmlString, { onText: textToEmojis }),
[htmlString],
);
return (
<CustomEmojiProvider emojis={extraEmojis}>
<AnimateEmojiProvider {...props} as={asProp} className={className}>
{contents}
</AnimateEmojiProvider>
</CustomEmojiProvider>
);
};
export const LegacyEmojiHTML = <Element extends ElementType>(
props: EmojiHTMLProps<Element>,
) => {
const { as: asElement, htmlString, extraEmojis, className, ...rest } = props;
const Wrapper = asElement ?? 'div';
return (
<Wrapper
{...rest}
dangerouslySetInnerHTML={{ __html: htmlString }}
className={classNames(className, 'animate-parent')}
/>
);
};
export const EmojiHTML = isModernEmojiEnabled()
? ModernEmojiHTML
: LegacyEmojiHTML;