浏览代码

chore: 优化菜单

xyh 2 年之前
父节点
当前提交
e00244c3c4

+ 11 - 0
packages/app/src/components/font-icon/index.tsx

@@ -0,0 +1,11 @@
+import {FC} from 'react';
+
+type Props = {
+  name: string;
+};
+
+const FontIcon: FC<Props> = function({name}) {
+  return <i className={`fa-solid fa-${name}`} />;
+};
+
+export default FontIcon;

+ 1 - 0
packages/app/src/components/index.tsx

@@ -12,3 +12,4 @@ export {default as Footer} from './footer';
 export {default as Auth} from './authentication';
 export {default as Table} from './table';
 export {default as TableSearchProvider} from './table-search-provider';
+export {default as FontIcon} from './font-icon';

+ 0 - 4
packages/app/src/pages/home/index.module.css

@@ -8,7 +8,3 @@
 .logo {
   width: 100px;
 }
-
-.slider-background {
-  background-color: #fff !important;
-}

+ 2 - 6
packages/app/src/pages/home/index.tsx

@@ -20,12 +20,8 @@ const Home: FC = function() {
       </Layout.Header>
 
       <Layout hasSider>
-        <Layout.Sider
-          className={css.sliderBackground}
-          breakpoint='lg'
-        >
-          <Menu />
-        </Layout.Sider>
+
+        <Menu />
 
         <Layout.Content>
           <Suspense>

+ 17 - 0
packages/app/src/pages/home/menu/hooks.tsx

@@ -3,6 +3,7 @@ import {HOME_PATH} from '@routes';
 import {menuStore} from '@stores';
 import {useQuery} from '@tanstack/react-query';
 import {ParseMenuType, sortMenu} from '@utils';
+import {useEventListener} from 'ahooks';
 import {useEffect, useState} from 'react';
 import {useLocation, useNavigate} from 'react-router-dom';
 import {useStore} from 'zustand';
@@ -81,3 +82,19 @@ export function useOpenKey(menus: ParseMenuType[]) {
 
   return [{openKeys, current}, {onOpenChange, onClick}] as const;
 }
+
+export function useCollapsedMenu() {
+  const [state, setState] = useState(false);
+
+  function onResize() {
+    const width = window.innerWidth;
+
+    setState(width <= 1200);
+  }
+
+  useEventListener('resize', onResize);
+
+  useEffect(onResize, []);
+
+  return state;
+}

+ 9 - 0
packages/app/src/pages/home/menu/index.module.css

@@ -0,0 +1,9 @@
+.slider-background {
+  background-color: #fff !important;
+}
+
+.slider-extend {
+  & :global(.ant-menu-item-icon) {
+    display: none !important;
+  }
+}

+ 21 - 11
packages/app/src/pages/home/menu/index.tsx

@@ -1,21 +1,31 @@
 import {FC} from 'react';
-import {Menu as AntdMenu} from 'antd';
-import {useMenu, useOpenKey} from './hooks';
+import {Menu as AntdMenu, Layout} from 'antd';
+import {useCollapsedMenu, useMenu, useOpenKey} from './hooks';
+import css from './index.module.css';
+import classNames from 'classnames';
 
 const Menu: FC = function() {
   const menus = useMenu();
   const [{openKeys, current}, {onOpenChange, onClick}] = useOpenKey(menus);
+  const collapsed = useCollapsedMenu();
 
   return (
-    <AntdMenu
-      data-testid='menu'
-      mode='inline'
-      items={menus}
-      onOpenChange={onOpenChange}
-      openKeys={openKeys}
-      onClick={onClick}
-      selectedKeys={current}
-    />
+    <Layout.Sider
+      className={css.sliderBackground}
+      collapsed={collapsed}
+    >
+      <AntdMenu
+        data-testid='menu'
+        mode='inline'
+        items={menus}
+        onOpenChange={onOpenChange}
+        openKeys={openKeys}
+        onClick={onClick}
+        selectedKeys={current}
+        className={classNames({[css.sliderExtend]: !collapsed})}
+      />
+    </Layout.Sider>
+
   );
 };
 

+ 0 - 6
packages/app/src/pages/menu-id/table/modal/Info.tsx

@@ -24,12 +24,6 @@ const Info: FC<Props> = function({id}) {
         label='菜单路径'
         control={control}
       />
-      <ModalField
-        name='menuIcon'
-        label='菜单图标'
-        control={control}
-        required={false}
-      />
       <ModalField
         name='menuOrderBy'
         width='300px'

+ 2 - 4
packages/app/src/pages/menu-id/table/modal/hooks.ts

@@ -11,7 +11,6 @@ type FormState = {
   menuName: string;
   menuUrl: string;
   menuOrderBy: string;
-  menuIcon: string;
 };
 
 const validate = object({
@@ -49,13 +48,13 @@ export function useFormState(
     visible && clearErrors();
   }, [clearErrors, visible]);
 
-  const onSubmit = handleSubmit(function({menuName, menuUrl, menuOrderBy, menuIcon}) {
+  const onSubmit = handleSubmit(function({menuName, menuUrl, menuOrderBy}) {
     const params: AddMenuParams = {
       name: menuName,
       url: menuUrl,
       pId: pid ?? '0',
       orderBy: menuOrderBy,
-      img: menuIcon,
+      img: '',
     };
 
     isEdit
@@ -84,6 +83,5 @@ export function useFormValues(id: string) {
     setValue('menuUrl', data?.url ?? '');
     setValue('menuName', data?.name ?? '');
     setValue('menuOrderBy', data?.orderBy ?? '0');
-    setValue('menuIcon', data?.img ?? '');
   }, [data, setValue]);
 }

+ 9 - 0
packages/app/src/pages/menu/table/hooks.tsx

@@ -8,6 +8,7 @@ import {Button, message} from 'antd';
 import {ColumnsType} from 'antd/es/table';
 import {useContextSection, useQueryTableList} from '@hooks';
 import {deleteConfirm} from '@utils';
+import {FontIcon} from '@components';
 
 export function useList() {
   const params = useContextSection(
@@ -81,6 +82,14 @@ export function useHandle(refetch: () => void) {
     {title: '菜单名称', dataIndex: 'name', key: 'name'},
     {title: '菜单路径', dataIndex: 'url', key: 'url'},
     {title: '菜单排序', dataIndex: 'orderBy', key: 'orderBy'},
+    {
+      title: '图标',
+      dataIndex: 'img',
+      key: 'img',
+      render(_, {img}) {
+        return <FontIcon name={img} />;
+      },
+    },
     {
       title: '操作',
       dataIndex: 'id',

+ 0 - 1
packages/app/src/pages/menu/table/modal/Info.tsx

@@ -27,7 +27,6 @@ const Info: FC<Props> = function({id}) {
         name='menuIcon'
         label='菜单图标'
         control={control}
-        required={false}
       />
       <ModalField
         name='menuOrderBy'

+ 1 - 0
packages/app/src/pages/menu/table/modal/hooks.ts

@@ -34,6 +34,7 @@ export function useFormState(
       menuName: '',
       menuUrl: '',
       menuOrderBy: '0',
+      menuIcon: '',
     },
     resolver: yupResolver(validate),
   });

+ 2 - 1
packages/app/src/utils/sortMenu/index.tsx

@@ -1,3 +1,4 @@
+import {FontIcon} from '@components';
 import {TreeRoleMenuData} from '@models';
 import {ReactNode} from 'react';
 
@@ -23,7 +24,7 @@ export function sortMenu(menus: TreeRoleMenuData[]) {
       label: name,
       pid: pId,
       url,
-      icon: img && <i className={`fa-solid fa-${img}`} />,
+      icon: img && <FontIcon name={img} />,
     };
 
     pId === '0'