mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-29 08:09:52 +08:00
feat(core): replace emoji-mart with affine icon picker (#13644)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - New Features - Unified icon picker with consistent rendering across the app. - Picker can auto-close after selection. - “Remove” now clears the icon selection. - Refactor - Icon handling consolidated across editors, navigation, and document titles for consistent behavior. - Picker now opens on the Emoji panel by default. - Style - Adjusted line-height and selectors for icon picker visuals. - Chores - Removed unused emoji-mart dependencies. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -7,6 +7,7 @@ import { RadioGroup, type RadioItem } from '../radio';
|
||||
import * as styles from './icon-picker.css';
|
||||
import { AffineIconPicker } from './picker/affine-icon/affine-icon-picker';
|
||||
import { EmojiPicker } from './picker/emoji/emoji-picker';
|
||||
import { type IconData, IconType } from './type';
|
||||
|
||||
const panels: Array<RadioItem> = [
|
||||
{ value: 'Emoji', className: styles.headerNavItem },
|
||||
@@ -16,17 +17,11 @@ const panels: Array<RadioItem> = [
|
||||
export const IconPicker = ({
|
||||
className,
|
||||
style,
|
||||
}: HTMLAttributes<HTMLDivElement> & {
|
||||
onSelect?: (
|
||||
type: 'emoji' | 'affine-icon',
|
||||
data: { icon?: string; color?: string }
|
||||
) => void;
|
||||
onSelect,
|
||||
}: Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> & {
|
||||
onSelect?: (data?: IconData) => void;
|
||||
}) => {
|
||||
const [activePanel, setActivePanel] = useState<string>('Icons');
|
||||
|
||||
// const ActivePanel = panels.find(
|
||||
// panel => panel.value === activePanel
|
||||
// )?.component;
|
||||
const [activePanel, setActivePanel] = useState<string>('Emoji');
|
||||
|
||||
return (
|
||||
<div className={clsx(styles.container, className)} style={{ ...style }}>
|
||||
@@ -53,7 +48,7 @@ export const IconPicker = ({
|
||||
<Button
|
||||
variant="plain"
|
||||
style={{ color: cssVarV2.text.secondary, fontWeight: 500 }}
|
||||
onClick={() => void 0}
|
||||
onClick={() => onSelect?.()}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
@@ -61,9 +56,17 @@ export const IconPicker = ({
|
||||
</header>
|
||||
<main className={styles.main}>
|
||||
{activePanel === 'Emoji' ? (
|
||||
<EmojiPicker />
|
||||
<EmojiPicker
|
||||
onSelect={emoji => {
|
||||
onSelect?.({ type: IconType.Emoji, unicode: emoji });
|
||||
}}
|
||||
/>
|
||||
) : activePanel === 'Icons' ? (
|
||||
<AffineIconPicker />
|
||||
<AffineIconPicker
|
||||
onSelect={(icon, color) => {
|
||||
onSelect?.({ type: IconType.AffineIcon, name: icon, color });
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
export * from './icon-picker';
|
||||
export * from './renderer';
|
||||
export * from './type';
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
import { AffineIconRenderer } from './renderer/affine-icon';
|
||||
import { type IconData, IconType } from './type';
|
||||
|
||||
export const IconRenderer = ({
|
||||
iconType,
|
||||
icon,
|
||||
data,
|
||||
fallback,
|
||||
}: {
|
||||
iconType: 'emoji' | 'affine-icon';
|
||||
icon: string;
|
||||
data?: IconData;
|
||||
fallback?: ReactNode;
|
||||
}) => {
|
||||
if (iconType === 'emoji') {
|
||||
return icon;
|
||||
}
|
||||
if (iconType === 'affine-icon') {
|
||||
return <AffineIconRenderer name={icon} />;
|
||||
if (!data) {
|
||||
return fallback ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
if (data.type === IconType.Emoji && data.unicode) {
|
||||
return data.unicode;
|
||||
}
|
||||
if (data.type === IconType.AffineIcon && data.name) {
|
||||
return <AffineIconRenderer name={data.name} color={data.color} />;
|
||||
}
|
||||
if (data.type === IconType.Blob) {
|
||||
// Not supported yet
|
||||
return null;
|
||||
}
|
||||
|
||||
return fallback ?? null;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
export enum IconType {
|
||||
Emoji = 'emoji',
|
||||
AffineIcon = 'affine-icon',
|
||||
Blob = 'blob',
|
||||
}
|
||||
|
||||
export type IconData =
|
||||
| {
|
||||
type: IconType.Emoji;
|
||||
unicode: string;
|
||||
}
|
||||
| {
|
||||
type: IconType.AffineIcon;
|
||||
name: string;
|
||||
color: string;
|
||||
}
|
||||
| {
|
||||
type: IconType.Blob;
|
||||
blob: Blob;
|
||||
};
|
||||
Reference in New Issue
Block a user