mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-05 12:29:44 +08:00
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:
parent
77529b3cd3
commit
9210386508
@ -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' }} />
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user