@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
1 lines • 10.7 kB
Source Map (JSON)
{"version":3,"file":"EmojiPicker.mjs","names":["emojiPickerMessages","Flexbox"],"sources":["../../src/EmojiPicker/EmojiPicker.tsx"],"sourcesContent":["'use client';\n\nimport data from '@emoji-mart/data';\nimport Picker from '@emoji-mart/react';\nimport { getLobeIconCDN, toc } from '@lobehub/icons';\nimport { cx, useTheme } from 'antd-style';\nimport chroma from 'chroma-js';\nimport { SmileIcon, TrashIcon, UploadIcon } from 'lucide-react';\nimport { memo, useMemo, useRef, useState } from 'react';\nimport useSWR from 'swr';\nimport useMergeState from 'use-merge-value';\n\nimport ActionIcon from '@/ActionIcon';\nimport Avatar from '@/Avatar';\nimport { Flexbox } from '@/Flex';\nimport emojiPickerMessages from '@/i18n/resources/en/emojiPicker';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport Icon from '@/Icon';\nimport Popover from '@/Popover';\nimport Tabs, { type TabsProps } from '@/Tabs';\nimport Tooltip from '@/Tooltip';\n\nimport AvatarUploader from './AvatarUploader';\nimport { styles } from './style';\nimport { type EmojiPickerProps } from './type';\n\nconst DEFAULT_AVATAR = '🤖';\n\nconst EmojiPicker = memo<EmojiPickerProps>(\n ({\n value,\n defaultAvatar = DEFAULT_AVATAR,\n onChange,\n locale = 'en-US',\n allowUpload,\n allowDelete,\n allowModelAvatar,\n texts,\n onDelete,\n compressSize = 256,\n customEmojis,\n className,\n loading,\n onUpload,\n customTabs = [],\n popupClassName,\n popupStyle,\n customRender,\n open,\n defaultOpen = false,\n onOpenChange,\n popupProps,\n shape,\n contentProps,\n ...rest\n }) => {\n const ref = useRef<HTMLDivElement>(null);\n const { t } = useTranslation(emojiPickerMessages);\n const [visible, setVisible] = useMergeState(defaultOpen, {\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n value: open,\n });\n const [tab, setTab] = useState<'emoji' | 'upload'>('emoji');\n\n const theme = useTheme();\n const pickerCssVariables = useMemo<Record<string, string>>(\n () => ({\n '--emoji-picker-rgb-accent': chroma(theme.colorPrimary).rgb().join(', '),\n '--emoji-picker-rgb-background': chroma(theme.colorBgElevated).rgb().join(', '),\n }),\n [theme.colorPrimary, theme.colorBgElevated],\n );\n\n const { data: i18n } = useSWR(\n locale,\n async () =>\n await import(/* @vite-ignore */ `@emoji-mart/data/i18n/${locale.split('-')[0]}.json`),\n { revalidateOnFocus: false, revalidateOnMount: false },\n );\n\n const [ava, setAva] = useMergeState(defaultAvatar, {\n defaultValue: defaultAvatar,\n onChange,\n value,\n });\n\n const handleAvatarChange = (emoji: string) => {\n setAva(emoji);\n setVisible(false);\n };\n\n // Generate model avatars from @lobehub/icons when allowModelAvatar is enabled\n const mergedCustomEmojis = useMemo(() => {\n if (!allowModelAvatar) return customEmojis;\n\n const modelIcons = toc.filter((item) => item.group !== 'application');\n\n const modelEmojisCategory = {\n id: 'models',\n name: 'Models / Providers',\n emojis: modelIcons.map((item) => ({\n id: item.id.toLowerCase(),\n name: item.title,\n keywords: [item.title, item.id, item.fullTitle],\n skins: [{ src: getLobeIconCDN(item.id, { format: 'avatar', cdn: 'aliyun' }) }],\n })),\n };\n\n return customEmojis ? [modelEmojisCategory, ...customEmojis] : [modelEmojisCategory];\n }, [allowModelAvatar, customEmojis]);\n\n const emojiText = texts?.emoji ?? t('emojiPicker.emoji');\n const uploadText = texts?.upload ?? t('emojiPicker.upload');\n const deleteText = texts?.delete ?? t('emojiPicker.delete');\n\n const hideEmojiTab = typeof allowUpload === 'object' && allowUpload?.enableEmoji === false;\n\n const items: TabsProps['items'] = [\n !hideEmojiTab && {\n key: 'emoji',\n label: (\n <Tooltip title={emojiText}>\n <Icon icon={SmileIcon} size={{ size: 20, strokeWidth: 2.5 }} />\n </Tooltip>\n ),\n },\n allowUpload && {\n key: 'upload',\n label: (\n <Tooltip title={uploadText}>\n <Icon icon={UploadIcon} size={{ size: 20, strokeWidth: 2.5 }} />\n </Tooltip>\n ),\n },\n ...customTabs.map((tab) => ({ key: tab.value, label: tab.label })),\n ].filter(Boolean) as TabsProps['items'];\n\n const showTabs = allowDelete || (items && items.length > 1);\n\n const content = (\n <Flexbox\n className={cx(styles.picker, popupClassName)}\n ref={ref}\n style={{\n minWidth: 310,\n paddingTop: showTabs ? 4 : 0,\n ...pickerCssVariables,\n ...popupStyle,\n }}\n {...contentProps}\n >\n {showTabs && (\n <Flexbox\n horizontal\n align={'center'}\n className={styles.tabs}\n justify={'space-between'}\n paddingInline={10}\n >\n <Tabs\n compact\n activeKey={tab}\n items={items}\n size={'small'}\n onChange={(key) => setTab(key as any)}\n />\n {allowDelete && (\n <ActionIcon\n icon={TrashIcon}\n title={deleteText}\n size={{\n blockSize: 32,\n size: 18,\n }}\n onClick={() => {\n handleAvatarChange(defaultAvatar);\n onDelete?.();\n }}\n />\n )}\n </Flexbox>\n )}\n {tab === 'emoji' && (\n <Picker\n custom={mergedCustomEmojis}\n data={data}\n i18n={i18n}\n icons={'outline'}\n locale={locale.split('-')[0]}\n navPosition={showTabs ? 'bottom' : 'top'}\n previewPosition={'none'}\n skinTonePosition={'none'}\n theme={theme.isDarkMode ? 'dark' : 'light'}\n onEmojiSelect={(e: any) => handleAvatarChange(e.src || e.native)}\n />\n )}\n {tab === 'upload' && (\n <AvatarUploader\n compressSize={compressSize}\n shape={shape}\n texts={texts}\n onChange={handleAvatarChange}\n onUpload={onUpload}\n />\n )}\n {customTabs.map(\n (item) =>\n tab === item.value && (\n <Flexbox key={item.value} padding={10}>\n {item.render(handleAvatarChange)}\n </Flexbox>\n ),\n )}\n </Flexbox>\n );\n\n return (\n <Popover\n className={cx(styles.popover)}\n content={content}\n defaultOpen={defaultOpen}\n open={visible}\n placement={'bottom'}\n trigger={'click'}\n classNames={{\n content: styles.popover,\n root: styles.positioner,\n }}\n onOpenChange={(v) => {\n if (loading) return;\n setVisible(v);\n }}\n {...popupProps}\n >\n {customRender ? (\n customRender(ava)\n ) : (\n <Avatar\n avatar={ava}\n className={cx(styles.root, className)}\n loading={loading}\n shape={shape}\n {...rest}\n />\n )}\n </Popover>\n );\n },\n);\n\nEmojiPicker.displayName = 'EmojiPicker';\n\nexport default EmojiPicker;\n"],"mappings":"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"}