refactor: improve EmojiPicker type safety and code organization

- Add proper type declarations for emoji-picker custom element
- Define EmojiPickerElement and EmojiClickEvent interfaces
- Replace @ts-ignore with proper TypeScript types
- Separate dataSource initialization into its own useEffect
- Use local emoji data from emoji-picker-element-data

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
beyondkmp 2025-11-20 10:19:36 +08:00
parent 77529b3cd3
commit 9210386508

View File

@ -1,33 +1,62 @@
import 'emoji-picker-element'
import TwemojiCountryFlagsWoff2 from '@renderer/assets/fonts/country-flag-fonts/TwemojiCountryFlags.woff2?url'
import { useTheme } from '@renderer/context/ThemeProvider'
import { polyfillCountryFlagEmojis } from 'country-flag-emoji-polyfill'
import emojiData from 'emoji-picker-element-data/en/emojibase/data.json'
import type { FC } from 'react'
import { useEffect, useRef } from 'react'
interface EmojiPickerElement extends HTMLElement {
dataSource: typeof emojiData
}
interface EmojiClickEvent extends CustomEvent {
detail: {
unicode?: string
emoji?: { unicode: string }
}
}
interface Props {
onEmojiClick: (emoji: string) => void
}
declare module 'react' {
namespace JSX {
interface IntrinsicElements {
'emoji-picker': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement> & { class?: string }, HTMLElement>
}
}
}
const EmojiPicker: FC<Props> = ({ onEmojiClick }) => {
const { theme } = useTheme()
const ref = useRef<HTMLDivElement>(null)
const ref = useRef<EmojiPickerElement>(null)
useEffect(() => {
polyfillCountryFlagEmojis('Twemoji Mozilla', TwemojiCountryFlagsWoff2)
}, [])
// 初始化 dataSource
useEffect(() => {
if (ref.current) {
ref.current.dataSource = emojiData
}
}, [])
// 事件监听
useEffect(() => {
const refValue = ref.current
if (refValue) {
const handleEmojiClick = (event: any) => {
const handleEmojiClick = (event: Event) => {
event.stopPropagation()
onEmojiClick(event.detail.unicode || event.detail.emoji.unicode)
const emojiEvent = event as EmojiClickEvent
onEmojiClick(emojiEvent.detail.unicode || emojiEvent.detail.emoji?.unicode || '')
}
// 添加事件监听器
refValue.addEventListener('emoji-click', handleEmojiClick)
// 清理事件监听器
return () => {
refValue.removeEventListener('emoji-click', handleEmojiClick)
}
@ -35,7 +64,6 @@ const EmojiPicker: FC<Props> = ({ onEmojiClick }) => {
return
}, [onEmojiClick])
// @ts-ignore next-line
return <emoji-picker ref={ref} class={theme === 'dark' ? 'dark' : 'light'} style={{ border: 'none' }} />
}