@lobehub/chat 0.96.8 → 0.96.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/.github/workflows/release.yml +3 -0
  2. package/CHANGELOG.md +25 -0
  3. package/CODE_OF_CONDUCT.md +21 -21
  4. package/CONTRIBUTING.md +1 -1
  5. package/README.md +26 -9
  6. package/README.zh-CN.md +29 -12
  7. package/docs/Deploy-with-Azure-OpenAI.md +6 -6
  8. package/docs/Home.md +14 -2
  9. package/docs/Lighthouse.md +8 -8
  10. package/docs/Plugin-Development.md +3 -3
  11. package/docs/Plugin-Development.zh-CN.md +3 -3
  12. package/docs/Usage-Agents.md +195 -0
  13. package/docs/Usage-Agents.zh-CN.md +196 -0
  14. package/docs/Usage-Topics.md +31 -0
  15. package/docs/Usage-Topics.zh-CN.md +31 -0
  16. package/docs/_Sidebar.md +10 -2
  17. package/locales/en_US/chat.json +8 -2
  18. package/locales/ja_JP/chat.json +7 -1
  19. package/locales/ko_KR/chat.json +7 -1
  20. package/locales/ru_RU/chat.json +7 -1
  21. package/locales/zh_CN/chat.json +5 -1
  22. package/locales/zh_TW/chat.json +7 -1
  23. package/next.config.mjs +9 -1
  24. package/package.json +6 -7
  25. package/scripts/readmeWorkflow/const.ts +19 -0
  26. package/scripts/readmeWorkflow/index.ts +12 -0
  27. package/scripts/readmeWorkflow/syncAgentIndex.ts +47 -0
  28. package/scripts/readmeWorkflow/syncPluginIndex.ts +43 -0
  29. package/scripts/readmeWorkflow/utlis.ts +52 -0
  30. package/src/app/chat/(desktop)/features/ChatHeader.tsx +11 -1
  31. package/src/app/chat/(desktop)/features/SessionList.tsx +1 -1
  32. package/src/app/chat/(desktop)/features/SideBar.tsx +1 -1
  33. package/src/app/chat/(mobile)/features/ChatHeader.tsx +2 -6
  34. package/src/app/chat/(mobile)/features/TopicList.tsx +1 -1
  35. package/src/app/chat/features/Conversation/ChatList/Actions/Error.tsx +1 -7
  36. package/src/app/chat/features/Conversation/ChatList/Actions/User.tsx +0 -1
  37. package/src/app/chat/features/Conversation/ChatList/Actions/index.ts +48 -0
  38. package/src/app/chat/features/Conversation/ChatList/Messages/index.ts +27 -0
  39. package/src/app/chat/features/Conversation/ChatList/index.tsx +7 -29
  40. package/src/app/chat/features/{TopicListContent/SystemRole/Header.tsx → SidebarHeader/index.tsx} +9 -8
  41. package/src/app/chat/features/{TopicListContent/SystemRole → SystemRole}/index.tsx +45 -16
  42. package/src/app/chat/features/TopicListContent/Header.tsx +86 -0
  43. package/src/app/chat/features/TopicListContent/Topic/SkeletonList.tsx +1 -1
  44. package/src/app/chat/features/TopicListContent/TopicSearchBar/index.tsx +8 -3
  45. package/src/app/chat/features/TopicListContent/index.tsx +18 -7
  46. package/src/app/settings/features/SideBar/index.tsx +1 -1
  47. package/src/features/AgentInfo/index.tsx +3 -1
  48. package/src/features/AgentSetting/AgentMeta/index.tsx +5 -1
  49. package/src/features/PluginDevModal/MetaForm.tsx +4 -3
  50. package/src/layout/GlobalLayout/Locale.tsx +12 -2
  51. package/src/locales/default/chat.ts +5 -1
  52. package/src/store/global/initialState.ts +2 -0
  53. package/src/store/global/slices/common.ts +7 -0
  54. package/src/store/session/slices/chat/actions/topic.ts +30 -0
  55. package/src/store/session/slices/chat/selectors/index.ts +2 -1
  56. package/src/store/session/slices/chat/selectors/topic.ts +4 -0
  57. package/src/components/EmojiPicker/index.tsx +0 -56
  58. package/src/components/EmojiPicker/style.ts +0 -30
  59. /package/src/app/chat/features/{TopicListContent/SystemRole → SystemRole}/style.ts +0 -0
@@ -0,0 +1,86 @@
1
+ import { ActionIcon, Icon } from '@lobehub/ui';
2
+ import { App, Dropdown, MenuProps } from 'antd';
3
+ import { MoreHorizontal, Search, Trash } from 'lucide-react';
4
+ import { memo, useMemo, useState } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { Flexbox } from 'react-layout-kit';
7
+
8
+ import { useSessionStore } from '@/store/session';
9
+ import { topicSelectors } from '@/store/session/selectors';
10
+
11
+ import SidebarHeader from '../SidebarHeader';
12
+ import TopicSearchBar from './TopicSearchBar';
13
+
14
+ const Header = memo(() => {
15
+ const { t } = useTranslation('chat');
16
+ const [topicLength, removeUnstarredTopic, removeAllTopic] = useSessionStore((s) => [
17
+ topicSelectors.currentTopicLength(s),
18
+ s.removeUnstarredTopic,
19
+ s.removeAllTopic,
20
+ ]);
21
+
22
+ const [showSearch, setShowSearch] = useState(false);
23
+ const { modal } = App.useApp();
24
+
25
+ const items = useMemo<MenuProps['items']>(
26
+ () => [
27
+ {
28
+ icon: <Icon icon={Trash} />,
29
+ key: 'deleteUnstarred',
30
+ label: t('topic.removeUnstarred'),
31
+ onClick: () => {
32
+ modal.confirm({
33
+ centered: true,
34
+ okButtonProps: { danger: true },
35
+ onOk: removeUnstarredTopic,
36
+ title: t('topic.confirmRemoveUnstarred', { ns: 'chat' }),
37
+ });
38
+ },
39
+ },
40
+ {
41
+ danger: true,
42
+ icon: <Icon icon={Trash} />,
43
+ key: 'deleteAll',
44
+ label: t('topic.removeAll'),
45
+ onClick: () => {
46
+ modal.confirm({
47
+ centered: true,
48
+ okButtonProps: { danger: true },
49
+ onOk: removeAllTopic,
50
+ title: t('topic.confirmRemoveAll', { ns: 'chat' }),
51
+ });
52
+ },
53
+ },
54
+ ],
55
+ [],
56
+ );
57
+
58
+ return showSearch ? (
59
+ <Flexbox padding={'12px 16px 4px'}>
60
+ <TopicSearchBar onClear={() => setShowSearch(false)} />
61
+ </Flexbox>
62
+ ) : (
63
+ <SidebarHeader
64
+ actions={
65
+ <>
66
+ <ActionIcon icon={Search} onClick={() => setShowSearch(true)} size={'small'} />
67
+ <Dropdown
68
+ arrow={false}
69
+ menu={{
70
+ items: items,
71
+ onClick: ({ domEvent }) => {
72
+ domEvent.stopPropagation();
73
+ },
74
+ }}
75
+ trigger={['click']}
76
+ >
77
+ <ActionIcon icon={MoreHorizontal} size={'small'} />
78
+ </Dropdown>
79
+ </>
80
+ }
81
+ title={`${t('topic.title')} ${topicLength > 1 ? topicLength + 1 : ''}`}
82
+ />
83
+ );
84
+ });
85
+
86
+ export default Header;
@@ -4,7 +4,7 @@ import { Flexbox } from 'react-layout-kit';
4
4
 
5
5
  const SkeletonList = memo(() => {
6
6
  return (
7
- <Flexbox gap={8} style={{ marginTop: 8 }}>
7
+ <Flexbox gap={8} paddingInline={10} style={{ marginTop: 8 }}>
8
8
  {Array.from({ length: 8 }).map((_, i) => (
9
9
  <Skeleton
10
10
  active
@@ -5,14 +5,19 @@ import { useTranslation } from 'react-i18next';
5
5
 
6
6
  import { useSessionStore } from '@/store/session';
7
7
 
8
- const TopicSearchBar = memo(() => {
8
+ const TopicSearchBar = memo<{ onClear?: () => void }>(({ onClear }) => {
9
9
  const { t } = useTranslation('chat');
10
10
  const [keywords] = useSessionStore((s) => [s.topicSearchKeywords]);
11
11
  const { mobile } = useResponsive();
12
12
  return (
13
13
  <SearchBar
14
- allowClear
15
- onChange={(e) => useSessionStore.setState({ topicSearchKeywords: e.target.value })}
14
+ autoFocus
15
+ onBlur={() => {
16
+ if (keywords === '') onClear?.();
17
+ }}
18
+ onChange={(e) => {
19
+ useSessionStore.setState({ topicSearchKeywords: e.target.value });
20
+ }}
16
21
  placeholder={t('topic.searchPlaceholder')}
17
22
  spotlight={!mobile}
18
23
  type={mobile ? 'block' : 'ghost'}
@@ -1,19 +1,30 @@
1
+ import { memo } from 'react';
1
2
  import { Flexbox } from 'react-layout-kit';
2
3
 
4
+ import TopicSearchBar from '@/app/chat/features/TopicListContent/TopicSearchBar';
5
+
6
+ import Header from './Header';
3
7
  import { Topic } from './Topic';
4
- import TopicSearchBar from './TopicSearchBar';
5
8
 
6
- const TopicListContent = () => {
9
+ const TopicListContent = memo<{ mobile?: boolean }>(({ mobile }) => {
7
10
  return (
8
11
  <Flexbox height={'100%'} style={{ overflow: 'hidden' }}>
9
- <Flexbox padding={16}>
10
- <TopicSearchBar />
11
- </Flexbox>
12
- <Flexbox gap={16} paddingInline={16} style={{ overflowY: 'auto', position: 'relative' }}>
12
+ {mobile ? (
13
+ <Flexbox padding={'12px 16px'}>
14
+ <TopicSearchBar />
15
+ </Flexbox>
16
+ ) : (
17
+ <Header />
18
+ )}
19
+ <Flexbox
20
+ gap={16}
21
+ paddingInline={mobile ? 16 : 8}
22
+ style={{ overflowY: 'auto', paddingTop: 6, position: 'relative' }}
23
+ >
13
24
  <Topic />
14
25
  </Flexbox>
15
26
  </Flexbox>
16
27
  );
17
- };
28
+ });
18
29
 
19
30
  export default TopicListContent;
@@ -31,7 +31,7 @@ const SideBar = memo(() => {
31
31
  </div>
32
32
  </Flexbox>
33
33
  <UpgradeAlert />
34
- <Flexbox gap={2} style={{ paddingInline: 6 }}>
34
+ <Flexbox gap={2} style={{ paddingInline: 8 }}>
35
35
  <List />
36
36
  </Flexbox>
37
37
  </DraggablePanelBody>
@@ -26,11 +26,12 @@ const useStyles = createStyles(({ css, token, stylish }) => ({
26
26
 
27
27
  export interface AgentInfoProps {
28
28
  meta?: MetaData;
29
+ onAvatarClick?: () => void;
29
30
  style?: CSSProperties;
30
31
  systemRole?: string;
31
32
  }
32
33
 
33
- const AgentInfo = memo<AgentInfoProps>(({ systemRole, style, meta }) => {
34
+ const AgentInfo = memo<AgentInfoProps>(({ systemRole, style, meta, onAvatarClick }) => {
34
35
  const { styles, theme } = useStyles();
35
36
 
36
37
  if (!meta) return;
@@ -43,6 +44,7 @@ const AgentInfo = memo<AgentInfoProps>(({ systemRole, style, meta }) => {
43
44
  avatar={meta.avatar}
44
45
  background={meta.backgroundColor || theme.colorFillTertiary}
45
46
  className={styles.avatar}
47
+ onClick={onAvatarClick}
46
48
  size={100}
47
49
  />
48
50
  )}
@@ -8,6 +8,7 @@ import { memo, useMemo } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
 
10
10
  import { FORM_STYLE } from '@/const/layoutTokens';
11
+ import { settingsSelectors, useGlobalStore } from '@/store/global';
11
12
 
12
13
  import { useStore } from '../store';
13
14
  import { SessionLoadingState } from '../store/initialState';
@@ -15,16 +16,18 @@ import AutoGenerateInput from './AutoGenerateInput';
15
16
  import AutoGenerateSelect from './AutoGenerateSelect';
16
17
  import BackgroundSwatches from './BackgroundSwatches';
17
18
 
18
- const EmojiPicker = dynamic(() => import('@/components/EmojiPicker'), { ssr: false });
19
+ const EmojiPicker = dynamic(() => import('@lobehub/ui/es/EmojiPicker'), { ssr: false });
19
20
 
20
21
  const AgentMeta = memo(() => {
21
22
  const { t } = useTranslation('setting');
23
+
22
24
  const [hasSystemRole, updateMeta, autocompleteMeta, autocompleteAllMeta] = useStore((s) => [
23
25
  !!s.config.systemRole,
24
26
  s.setAgentMeta,
25
27
  s.autocompleteMeta,
26
28
  s.autocompleteAllMeta,
27
29
  ]);
30
+ const locale = useGlobalStore(settingsSelectors.currentLanguage);
28
31
  const loading = useStore((s) => s.autocompleteLoading);
29
32
  const meta = useStore((s) => s.meta, isEqual);
30
33
 
@@ -77,6 +80,7 @@ const AgentMeta = memo(() => {
77
80
  children: (
78
81
  <EmojiPicker
79
82
  backgroundColor={meta.backgroundColor}
83
+ locale={locale}
80
84
  onChange={(avatar) => updateMeta({ avatar })}
81
85
  value={meta.avatar}
82
86
  />
@@ -4,13 +4,14 @@ import dynamic from 'next/dynamic';
4
4
  import { memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
+ import { settingsSelectors, useGlobalStore } from '@/store/global';
7
8
  import { pluginSelectors, usePluginStore } from '@/store/plugin';
8
9
 
9
- const EmojiPicker = dynamic(() => import('@/components/EmojiPicker'), { ssr: false });
10
+ const EmojiPicker = dynamic(() => import('@lobehub/ui/es/EmojiPicker'), { ssr: false });
10
11
 
11
12
  const MetaForm = memo<{ form: FormInstance; mode?: 'edit' | 'create' }>(({ form, mode }) => {
12
13
  const isEditMode = mode === 'edit';
13
-
14
+ const locale = useGlobalStore(settingsSelectors.currentLanguage);
14
15
  const { t } = useTranslation('plugin');
15
16
  const [plugins] = usePluginStore((s) => [pluginSelectors.pluginList(s).map((i) => i.identifier)]);
16
17
 
@@ -65,7 +66,7 @@ const MetaForm = memo<{ form: FormInstance; mode?: 'edit' | 'create' }>(({ form,
65
66
  name: 'homepage',
66
67
  },
67
68
  {
68
- children: <EmojiPicker defaultAvatar={'🧩'} />,
69
+ children: <EmojiPicker defaultAvatar={'🧩'} locale={locale} />,
69
70
  desc: t('dev.meta.avatar.desc'),
70
71
  label: t('dev.meta.avatar.label'),
71
72
  name: ['meta', 'avatar'],
@@ -1,5 +1,5 @@
1
1
  import { ConfigProvider } from 'antd';
2
- import Zh_CN from 'antd/locale/zh_CN';
2
+ import defaultLocale from 'antd/locale/en_US';
3
3
  import { PropsWithChildren, memo, useState } from 'react';
4
4
 
5
5
  import { createI18nNext } from '@/locales/create';
@@ -12,6 +12,7 @@ interface LocaleLayoutProps extends PropsWithChildren {
12
12
  }
13
13
 
14
14
  const InnerLocale = memo<LocaleLayoutProps>(({ children, lang }) => {
15
+ const [locale, setLocale] = useState(defaultLocale);
15
16
  const [i18n] = useState(createI18nNext(lang));
16
17
 
17
18
  // if run on server side, init i18n instance everytime
@@ -26,13 +27,22 @@ const InnerLocale = memo<LocaleLayoutProps>(({ children, lang }) => {
26
27
  });
27
28
  }
28
29
 
30
+ const getLocale = async (localeName: string) => {
31
+ setLocale((await import(`antd/locale/${localeName}.js`)) as any);
32
+ };
33
+
29
34
  useOnFinishHydrationGlobal((s) => {
30
35
  if (s.settings.language === 'auto') {
31
36
  switchLang('auto');
32
37
  }
38
+
39
+ if (lang?.includes('-') && lang !== 'en-US') {
40
+ const localeName = lang?.replace('-', '_');
41
+ getLocale(localeName);
42
+ }
33
43
  }, []);
34
44
 
35
- return <ConfigProvider locale={Zh_CN}>{children}</ConfigProvider>;
45
+ return <ConfigProvider locale={locale}>{children}</ConfigProvider>;
36
46
  });
37
47
 
38
48
  // const Locale = memo<LocaleLayoutProps>((props) => (
@@ -46,11 +46,15 @@ export default {
46
46
  used: '使用',
47
47
  },
48
48
  topic: {
49
+ confirmRemoveAll: '即将删除全部话题,删除后将不可恢复,请谨慎操作。',
49
50
  confirmRemoveTopic: '即将删除该话题,删除后将不可恢复,请谨慎操作。',
51
+ confirmRemoveUnstarred: '即将删除未收藏话题,删除后将不可恢复,请谨慎操作。',
50
52
  defaultTitle: '默认话题',
53
+ removeAll: '删除全部话题',
54
+ removeUnstarred: '删除未收藏话题',
51
55
  saveCurrentMessages: '将当前会话保存为话题',
52
56
  searchPlaceholder: '搜索话题...',
53
- title: '话题',
57
+ title: '话题列表',
54
58
  },
55
59
  translate: {
56
60
  clear: '删除翻译',
@@ -26,6 +26,7 @@ export interface GlobalPreference {
26
26
  sessionsWidth: number;
27
27
  showChatSideBar?: boolean;
28
28
  showSessionPanel?: boolean;
29
+ showSystemRole?: boolean;
29
30
  }
30
31
 
31
32
  export interface GlobalState {
@@ -54,6 +55,7 @@ export const initialState: GlobalState = {
54
55
  sessionsWidth: 320,
55
56
  showChatSideBar: true,
56
57
  showSessionPanel: true,
58
+ showSystemRole: false,
57
59
  },
58
60
  settings: DEFAULT_SETTINGS,
59
61
  settingsTab: SettingsTabs.Common,
@@ -24,6 +24,7 @@ export interface CommonAction {
24
24
  switchSideBar: (key: SidebarTabKey) => void;
25
25
  toggleChatSideBar: (visible?: boolean) => void;
26
26
  toggleMobileTopic: (visible?: boolean) => void;
27
+ toggleSystemRole: (visible?: boolean) => void;
27
28
  updateGuideState: (guide: Partial<Guide>) => void;
28
29
  updatePreference: (preference: Partial<GlobalPreference>, action?: string) => void;
29
30
  useCheckLatestVersion: () => SWRResponse<string>;
@@ -50,6 +51,12 @@ export const createCommonSlice: StateCreator<
50
51
 
51
52
  get().updatePreference({ mobileShowTopic }, t('toggleMobileTopic', newValue) as string);
52
53
  },
54
+ toggleSystemRole: (newValue) => {
55
+ const showSystemRole =
56
+ typeof newValue === 'boolean' ? newValue : !get().preference.mobileShowTopic;
57
+
58
+ get().updatePreference({ showSystemRole }, t('toggleMobileTopic', newValue) as string);
59
+ },
53
60
  updateGuideState: (guide) => {
54
61
  const { updatePreference } = get();
55
62
  const nextGuide = merge(get().preference.guide, guide);
@@ -18,11 +18,19 @@ export interface ChatTopicAction {
18
18
  * @param payload - 要分发的主题
19
19
  */
20
20
  dispatchTopic: (payload: ChatTopicDispatch) => void;
21
+ /**
22
+ * 移出所有话题
23
+ */
24
+ removeAllTopic: () => void;
21
25
  /**
22
26
  * 移除话题
23
27
  * @param id
24
28
  */
25
29
  removeTopic: (id: string) => void;
30
+ /**
31
+ * 移出所有未标记的话题
32
+ */
33
+ removeUnstarredTopic: () => void;
26
34
  /**
27
35
  * 将当前消息保存为主题
28
36
  */
@@ -54,6 +62,17 @@ export const chatTopic: StateCreator<
54
62
 
55
63
  get().dispatchSession({ id: activeId, topics, type: 'updateSessionTopic' });
56
64
  },
65
+ removeAllTopic: () => {
66
+ const { removeTopic, toggleTopic } = get();
67
+ const topics = topicSelectors.currentTopics(get());
68
+
69
+ for (const { id } of topics) {
70
+ removeTopic(id);
71
+ }
72
+
73
+ // 切换到默认 topic
74
+ toggleTopic();
75
+ },
57
76
  removeTopic: (id) => {
58
77
  const { dispatchTopic, dispatchMessage, toggleTopic } = get();
59
78
 
@@ -72,6 +91,17 @@ export const chatTopic: StateCreator<
72
91
  // 切换到默认 topic
73
92
  toggleTopic();
74
93
  },
94
+ removeUnstarredTopic: () => {
95
+ const { removeTopic, toggleTopic } = get();
96
+ const topics = topicSelectors.currentTopics(get());
97
+
98
+ for (const { id, favorite } of topics) {
99
+ if (!favorite) removeTopic(id);
100
+ }
101
+
102
+ // 切换到默认 topic
103
+ toggleTopic();
104
+ },
75
105
  saveToTopic: async () => {
76
106
  const session = sessionSelectors.currentSession(get());
77
107
  if (!session) return;
@@ -7,7 +7,7 @@ import {
7
7
  getFunctionMessageProps,
8
8
  getMessageById,
9
9
  } from './chat';
10
- import { currentTopics, getTopicMessages } from './topic';
10
+ import { currentTopicLength, currentTopics, getTopicMessages } from './topic';
11
11
 
12
12
  export const chatSelectors = {
13
13
  chatsMessageString,
@@ -20,6 +20,7 @@ export const chatSelectors = {
20
20
  };
21
21
 
22
22
  export const topicSelectors = {
23
+ currentTopicLength,
23
24
  currentTopics,
24
25
  getTopicMessages,
25
26
  };
@@ -18,6 +18,10 @@ export const currentTopics = (s: SessionStore): ChatTopic[] => {
18
18
  return [...favTopics, ...defaultTopics];
19
19
  };
20
20
 
21
+ export const currentTopicLength = (s: SessionStore): number => {
22
+ return currentTopics(s).length;
23
+ };
24
+
21
25
  export const getTopicMessages = (topicId: string) => (s: SessionStore) => {
22
26
  const session = sessionSelectors.currentSession(s);
23
27
  if (!session) return [];
@@ -1,56 +0,0 @@
1
- import data from '@emoji-mart/data';
2
- import i18n from '@emoji-mart/data/i18n/zh.json';
3
- import Picker from '@emoji-mart/react';
4
- import { Avatar } from '@lobehub/ui';
5
- import { Popover } from 'antd';
6
- import { memo } from 'react';
7
- import useMergeState from 'use-merge-value';
8
-
9
- import { DEFAULT_AVATAR, DEFAULT_BACKGROUND_COLOR } from '@/const/meta';
10
-
11
- import { useStyles } from './style';
12
-
13
- export interface EmojiPickerProps {
14
- backgroundColor?: string;
15
- defaultAvatar?: string;
16
- onChange?: (emoji: string) => void;
17
- value?: string;
18
- }
19
-
20
- const EmojiPicker = memo<EmojiPickerProps>(
21
- ({ value, defaultAvatar, backgroundColor = DEFAULT_BACKGROUND_COLOR, onChange }) => {
22
- const { styles } = useStyles();
23
-
24
- const [ava, setAva] = useMergeState(DEFAULT_AVATAR, {
25
- defaultValue: defaultAvatar,
26
- onChange,
27
- value,
28
- });
29
-
30
- return (
31
- <Popover
32
- content={
33
- <div className={styles.picker}>
34
- <Picker
35
- data={data}
36
- i18n={i18n}
37
- locale={'zh'}
38
- onEmojiSelect={(e: any) => setAva(e.native)}
39
- skinTonePosition={'none'}
40
- theme={'auto'}
41
- />
42
- </div>
43
- }
44
- placement={'left'}
45
- rootClassName={styles.popover}
46
- trigger={'click'}
47
- >
48
- <div className={styles.avatar} style={{ width: 'fit-content' }}>
49
- <Avatar avatar={ava} background={backgroundColor} size={44} />
50
- </div>
51
- </Popover>
52
- );
53
- },
54
- );
55
-
56
- export default EmojiPicker;
@@ -1,30 +0,0 @@
1
- import { createStyles } from 'antd-style';
2
- import chroma from 'chroma-js';
3
-
4
- export const useStyles = createStyles(({ css, token, prefixCls }) => ({
5
- avatar: css`
6
- border-radius: 50%;
7
- transition:
8
- scale 400ms ${token.motionEaseOut},
9
- box-shadow 100ms ${token.motionEaseOut};
10
-
11
- &:hover {
12
- box-shadow: 0 0 0 3px ${token.colorText};
13
- }
14
-
15
- &:active {
16
- scale: 0.8;
17
- }
18
- `,
19
- picker: css`
20
- em-emoji-picker {
21
- --rgb-accent: ${chroma(token.colorPrimary) .rgb() .join(',')};
22
- --shadow: none;
23
- }
24
- `,
25
- popover: css`
26
- .${prefixCls}-popover-inner {
27
- padding: 0;
28
- }
29
- `,
30
- }));