mirror of
https://github.com/aljazceru/rabbit.git
synced 2025-12-17 14:04:21 +01:00
81 lines
2.0 KiB
TypeScript
81 lines
2.0 KiB
TypeScript
import { createMemo } from 'solid-js';
|
|
|
|
import { Picker } from 'emoji-mart';
|
|
|
|
import usePopup, { type UsePopup, type UsePopupProps } from '@/components/utils/usePopup';
|
|
import useConfig from '@/core/useConfig';
|
|
|
|
// https://github.com/missive/emoji-mart/blob/main/packages/emoji-mart/src/utils.ts#L26
|
|
export type EmojiData = {
|
|
id: string;
|
|
name: string;
|
|
native?: string;
|
|
src?: string;
|
|
unified: string;
|
|
keywords: string[];
|
|
shortcodes: string;
|
|
};
|
|
|
|
type UseEmojiPickerProps = Omit<UsePopupProps, 'popup'> & {
|
|
onEmojiSelect?: (emoji: EmojiData) => void;
|
|
customEmojis?: boolean;
|
|
};
|
|
|
|
const useEmojiPicker = (propsProvider: () => UseEmojiPickerProps) => {
|
|
const { config } = useConfig();
|
|
|
|
const props = createMemo(propsProvider);
|
|
|
|
let popup: UsePopup | undefined;
|
|
|
|
const pickerElement = () => {
|
|
const customEmojis = Object.entries(config().customEmojis).map(([name, { url }]) => ({
|
|
id: name,
|
|
name,
|
|
keywords: [name],
|
|
skins: [{ src: url }],
|
|
}));
|
|
const picker = new Picker({
|
|
data: async () => {
|
|
const response = await fetch('https://cdn.jsdelivr.net/npm/@emoji-mart/data');
|
|
return response.json();
|
|
},
|
|
/*
|
|
// TODO uncomment if this is fixed: https://github.com/missive/emoji-mart/issues/794
|
|
i18n: async () => {
|
|
const response = await fetch('https://cdn.jsdelivr.net/npm/@emoji-mart/data/i18n/ja.json');
|
|
return response.json();
|
|
},
|
|
locale: 'ja',
|
|
*/
|
|
custom: [
|
|
{
|
|
id: 'custom',
|
|
name: 'Custom Emojis',
|
|
emojis: customEmojis,
|
|
},
|
|
],
|
|
autoFocus: false,
|
|
theme: 'light',
|
|
onEmojiSelect: (emoji: EmojiData) => {
|
|
console.log(emoji);
|
|
props().onEmojiSelect?.(emoji);
|
|
popup?.close();
|
|
},
|
|
});
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
return picker as any as HTMLElement;
|
|
};
|
|
|
|
popup = usePopup(() => ({
|
|
position: 'bottom',
|
|
...props(),
|
|
popup: () => pickerElement(),
|
|
}));
|
|
|
|
return popup;
|
|
};
|
|
|
|
export default useEmojiPicker;
|