Przeglądaj źródła

feat: 增加scrollbar样式

xyh 2 lat temu
rodzic
commit
34ab96e19d

+ 2 - 0
packages/app/package.json

@@ -24,6 +24,7 @@
     "fast-deep-equal": "^3.1.3",
     "klona": "^2.0.6",
     "lodash-es": "^4.17.21",
+    "overlayscrollbars": "^2.2.0",
     "react": "^18.2.0",
     "react-contexify": "^6.0.0",
     "react-dom": "^18.2.0",
@@ -32,6 +33,7 @@
     "react-modal": "^3.16.1",
     "react-router-dom": "^6.8.0",
     "use-context-selector": "^1.4.1",
+    "yup": "^1.2.0",
     "zod": "^3.21.4",
     "zustand": "^4.3.7"
   },

+ 1 - 0
packages/app/src/hooks/index.ts

@@ -19,3 +19,4 @@ export * from './use-table-filter-event';
 export * from './use-upload';
 export * from './use-table-title';
 export * from './use-table-row-select';
+export * from './use-scroll-bar';

+ 24 - 0
packages/app/src/hooks/use-scroll-bar/index.ts

@@ -0,0 +1,24 @@
+import {OverlayScrollbars} from 'overlayscrollbars';
+import {useEffect} from 'react';
+
+export function useScrollBar(selector: string) {
+  useEffect(function() {
+    const el = document.querySelector(selector);
+    if (!el) return;
+
+    const scrollbar = OverlayScrollbars(
+      el as HTMLElement,
+      {
+        scrollbars: {
+          autoHide: 'leave',
+          autoHideDelay: 100,
+        },
+        update: {
+          debounce: [0, 100],
+        },
+      },
+    );
+
+    return () => scrollbar.destroy();
+  }, [selector]);
+}

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

@@ -1,3 +1,4 @@
+import 'overlayscrollbars/overlayscrollbars.css';
 import 'react-contexify/ReactContexify.css';
 import '@styles/index.css';
 import {createRoot} from 'react-dom/client';

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

@@ -19,8 +19,6 @@
   z-index: 2;
   flex: 1;
   overflow: auto;
-  /* stylelint-disable-next-line declaration-block-no-duplicate-properties */
-  overflow: overlay;
   background-color: transparent !important;
   border-inline: unset !important;
 
@@ -28,29 +26,6 @@
     border-inline-end: unset;
   }
 
-  &::-webkit-scrollbar {
-    display: none;
-    width: 6px;
-    background-color: transparent;
-    border-radius: 6px;
-    transition: all 500ms linear;
-  }
-
-  &:hover::-webkit-scrollbar {
-    display: block;
-  }
-
-  &::-webkit-scrollbar-thumb {
-    cursor: pointer;
-    background-color: #ccc;
-    border-radius: 6px;
-    transition: background-color 500ms linear;
-
-    &:hover {
-      background-color: var(--primary-color);
-    }
-  }
-
   & :global(.ant-menu-item-icon) {
     color: #bbb !important;
   }

+ 4 - 0
packages/app/src/pages/home/menu/index.tsx

@@ -4,6 +4,7 @@ import {useCollapsedMenu, useMenu, useMenuState} from './hooks';
 import css from './index.module.css';
 import {MenuFoldOutlined} from '@ant-design/icons';
 import classNames from 'classnames';
+import {useScrollBar} from '@hooks';
 
 const Menu: FC = function() {
   const menus = useMenu();
@@ -13,6 +14,8 @@ const Menu: FC = function() {
     {onOpenChange, onClick},
   ] = useMenuState(collapsed);
 
+  useScrollBar('#menu_list');
+
   return (
     <Layout.Sider width={240} className={css.slider} collapsed={collapsed}>
       <div
@@ -37,6 +40,7 @@ const Menu: FC = function() {
         openKeys={openKeys}
         className={css.sliderMenus}
         onClick={onClick}
+        id="menu_list"
       />
 
     </Layout.Sider>

+ 1 - 0
packages/app/src/styles/index.css

@@ -1,6 +1,7 @@
 @import url('./variable.css');
 @import url('./antd.css');
 @import url('./modal.css');
+@import url('./scrollbar.css');
 
 * {
   box-sizing: border-box;

+ 5 - 0
packages/app/src/styles/scrollbar.css

@@ -0,0 +1,5 @@
+.os-scrollbar {
+  --os-handle-bg: rgb(0 0 0 / 30%);
+  --os-handle-bg-hover: rgb(0 0 0 / 40%);
+  --os-handle-bg-active: rgb(0 0 0 / 50%);
+}

+ 36 - 0
pnpm-lock.yaml

@@ -158,6 +158,9 @@ importers:
       lodash-es:
         specifier: ^4.17.21
         version: 4.17.21
+      overlayscrollbars:
+        specifier: ^2.2.0
+        version: 2.2.0
       react:
         specifier: ^18.2.0
         version: 18.2.0
@@ -182,6 +185,9 @@ importers:
       use-context-selector:
         specifier: ^1.4.1
         version: 1.4.1(react-dom@18.2.0)(react@18.2.0)(scheduler@0.23.0)
+      yup:
+        specifier: ^1.2.0
+        version: 1.2.0
       zod:
         specifier: ^3.21.4
         version: 3.21.4
@@ -7377,6 +7383,10 @@ packages:
     resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==}
     dev: true
 
+  /overlayscrollbars@2.2.0:
+    resolution: {integrity: sha512-Sx7gI2TEx+TFvFXJq4BUYM5R4bfWQR2ertdxyzAQ589ouPKKifMBU0/opdCb1bUC7x6sMiSNI1u9ngC0RbMnBg==}
+    dev: false
+
   /p-limit@1.3.0:
     resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==}
     engines: {node: '>=4'}
@@ -8588,6 +8598,10 @@ packages:
       object-assign: 4.1.1
       react-is: 16.13.1
 
+  /property-expr@2.0.5:
+    resolution: {integrity: sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==}
+    dev: false
+
   /proxy-addr@2.0.7:
     resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
     engines: {node: '>= 0.10'}
@@ -10415,6 +10429,10 @@ packages:
     engines: {node: '>=4'}
     dev: true
 
+  /tiny-case@1.0.3:
+    resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==}
+    dev: false
+
   /tinybench@2.5.0:
     resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==}
     dev: true
@@ -10459,6 +10477,10 @@ packages:
     engines: {node: '>=0.6'}
     dev: true
 
+  /toposort@2.0.2:
+    resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==}
+    dev: false
+
   /totalist@1.1.0:
     resolution: {integrity: sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==}
     engines: {node: '>=6'}
@@ -10609,6 +10631,11 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /type-fest@2.19.0:
+    resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
+    engines: {node: '>=12.20'}
+    dev: false
+
   /type-is@1.6.18:
     resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
     engines: {node: '>= 0.6'}
@@ -11383,6 +11410,15 @@ packages:
     engines: {node: '>=12.20'}
     dev: true
 
+  /yup@1.2.0:
+    resolution: {integrity: sha512-PPqYKSAXjpRCgLgLKVGPA33v5c/WgEx3wi6NFjIiegz90zSwyMpvTFp/uGcVnnbx6to28pgnzp/q8ih3QRjLMQ==}
+    dependencies:
+      property-expr: 2.0.5
+      tiny-case: 1.0.3
+      toposort: 2.0.2
+      type-fest: 2.19.0
+    dev: false
+
   /zod@3.21.4:
     resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==}
     dev: false