From b74edf100c8688d5a3dad30987f42cd1444376b6 Mon Sep 17 00:00:00 2001 From: dark Date: Thu, 2 May 2024 21:28:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DIconPicker=E4=B8=BA=E7=A9=BA?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=EF=BC=8C=E4=BC=9A=E6=97=A0=E9=99=90?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/icon/action/ActionIcon.tsx | 11 ++++++----- src/components/icon/picker/context.tsx | 10 +++++++--- src/components/icon/picker/index.tsx | 24 ++++++++++++++---------- src/pages/system/menus/index.tsx | 5 ++++- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/components/icon/action/ActionIcon.tsx b/src/components/icon/action/ActionIcon.tsx index 5e1f90c..8f3ab9e 100644 --- a/src/components/icon/action/ActionIcon.tsx +++ b/src/components/icon/action/ActionIcon.tsx @@ -1,6 +1,6 @@ import type { ButtonProps, TooltipProps } from 'antd' import { Button, Tooltip } from 'antd' -import type { CSSProperties, FC } from 'react' +import { CSSProperties, FC, memo } from 'react' import { ConfigProvider } from '@/components/config-provider' import { useStyles } from './style' @@ -47,7 +47,7 @@ export interface ActionIconProps extends Omit { bordered?: boolean; } -const BaseActionIcon: FC = ({ +const BaseActionIcon: FC = memo(({ placement, title, icon, @@ -91,9 +91,9 @@ const BaseActionIcon: FC = ({ )} ) -} +}) -const ActionIcon = (props: ActionIconProps) => { +const ActionIcon = memo((props: ActionIconProps) => { const { size } = props || {} const { theme: token } = useStyles({ size }) @@ -110,5 +110,6 @@ const ActionIcon = (props: ActionIconProps) => { ) -} +}) + export default ActionIcon \ No newline at end of file diff --git a/src/components/icon/picker/context.tsx b/src/components/icon/picker/context.tsx index fc6ca7f..874ba4a 100644 --- a/src/components/icon/picker/context.tsx +++ b/src/components/icon/picker/context.tsx @@ -2,11 +2,13 @@ import { IconUnit, ReactIcon } from '../types.ts' import { antdIconList, parkIconList } from './icons.ts' import { createContext, ProviderProps, useContext, useReducer, useMemo, useCallback } from 'react' +export const ICON_RESET = Symbol.for('ICON_RESET') + export interface State { /** * @title 图标单元 */ - icon?: IconUnit; + icon?: IconUnit | typeof ICON_RESET ; /** * @title 是否显示表单 */ @@ -80,11 +82,12 @@ type Actions = { isEmptyIconParkList: boolean; } + // 创建reducer函数 -const reducer = (state: State, action: Action) => { +const reducer = (state: State, action: Action): State => { switch (action.type) { case 'resetIcon': - return { ...state, icon: undefined } + return { ...state, icon: ICON_RESET } case 'togglePanel': return { ...state, open: action.payload ?? !state.open } case 'selectIcon': @@ -100,6 +103,7 @@ const reducer = (state: State, action: Action) => { } } + export const PickerContextProvider = ({ value: propValue, children }: ProviderProps) => { const [ state, dispatch ] = useReducer(reducer, { diff --git a/src/components/icon/picker/index.tsx b/src/components/icon/picker/index.tsx index fcd72ee..20adc13 100644 --- a/src/components/icon/picker/index.tsx +++ b/src/components/icon/picker/index.tsx @@ -1,23 +1,27 @@ import { Popover, PopoverProps } from 'antd' -import { FC, useEffect } from 'react' +import { FC, memo, useEffect } from 'react' import Display from './Display.tsx' import PickerPanel from './PickerPanel' -import { PickerContextProvider, usePickerContext } from './context.tsx' - +import { ICON_RESET, PickerContextProvider, usePickerContext } from './context.tsx' +import { IconUnit } from '@/components/icon/types.ts' interface PickerProps extends Partial { value?: string, onChange?: (value: string) => void, } -const IconPicker: FC = (props: PickerProps) => { +const IconPicker: FC = memo((props: PickerProps) => { const { state, actions: { selectIcon, togglePanel } } = usePickerContext() const { value, onChange } = props useEffect(() => { - if (onChange) { - onChange(state.icon ? `${state.icon.type}:${state.icon.componentName}` : '') + if (onChange && state.icon) { + if (state.icon === ICON_RESET) { + return onChange('') + } + const icon = state.icon as IconUnit + onChange(state.icon ? `${icon.type}:${icon.componentName}` : '') } }, [ state.icon ]) @@ -26,7 +30,7 @@ const IconPicker: FC = (props: PickerProps) => { if (value) { const [ type, componentName ] = value.split(':') selectIcon({ type, componentName } as any) - }else{ + } else { selectIcon(null as any) } }, [ value ]) @@ -47,10 +51,10 @@ const IconPicker: FC = (props: PickerProps) => { ) -} +}) -export default (props: PickerProps) => { +export default memo((props: PickerProps) => { return -} \ No newline at end of file +}) \ No newline at end of file diff --git a/src/pages/system/menus/index.tsx b/src/pages/system/menus/index.tsx index df27645..c03ccb6 100644 --- a/src/pages/system/menus/index.tsx +++ b/src/pages/system/menus/index.tsx @@ -151,7 +151,10 @@ const Menus = () => { label={t('system.menus.form.name', '别名')} name={'name'}> - + { + return prev.icon !== next.icon + }}>