2
0
Files
mastodon/app/javascript/mastodon/components/emoji/html.tsx
2025-10-14 09:36:25 +00:00

91 lines
2.2 KiB
TypeScript

import { useMemo } from 'react';
import classNames from 'classnames';
import type { CustomEmojiMapArg } from '@/mastodon/features/emoji/types';
import { isModernEmojiEnabled } from '@/mastodon/utils/environment';
import type {
OnAttributeHandler,
OnElementHandler,
} from '@/mastodon/utils/html';
import { htmlStringToComponents } from '@/mastodon/utils/html';
import { polymorphicForwardRef } from '@/types/polymorphic';
import { AnimateEmojiProvider, CustomEmojiProvider } from './context';
import { textToEmojis } from './index';
export interface EmojiHTMLProps {
htmlString: string;
extraEmojis?: CustomEmojiMapArg;
className?: string;
onElement?: OnElementHandler;
onAttribute?: OnAttributeHandler;
}
export const ModernEmojiHTML = polymorphicForwardRef<'div', EmojiHTMLProps>(
(
{
extraEmojis,
htmlString,
as: asProp = 'div', // Rename for syntax highlighting
className = '',
onElement,
onAttribute,
...props
},
ref,
) => {
const contents = useMemo(
() =>
htmlStringToComponents(htmlString, {
onText: textToEmojis,
onElement,
onAttribute,
}),
[htmlString, onAttribute, onElement],
);
return (
<CustomEmojiProvider emojis={extraEmojis}>
<AnimateEmojiProvider
{...props}
as={asProp}
className={className}
ref={ref}
>
{contents}
</AnimateEmojiProvider>
</CustomEmojiProvider>
);
},
);
ModernEmojiHTML.displayName = 'ModernEmojiHTML';
export const LegacyEmojiHTML = polymorphicForwardRef<'div', EmojiHTMLProps>(
(props, ref) => {
const {
as: asElement,
htmlString,
extraEmojis,
className,
onElement,
onAttribute,
...rest
} = props;
const Wrapper = asElement ?? 'div';
return (
<Wrapper
{...rest}
ref={ref}
dangerouslySetInnerHTML={{ __html: htmlString }}
className={classNames(className, 'animate-parent')}
/>
);
},
);
LegacyEmojiHTML.displayName = 'LegacyEmojiHTML';
export const EmojiHTML = isModernEmojiEnabled()
? ModernEmojiHTML
: LegacyEmojiHTML;