Commit a0e4c368 authored by timel's avatar timel

feat: overlay scrollbar

parent 7bf7b8fa
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
"google-protobuf": "^3.21.2", "google-protobuf": "^3.21.2",
"idb-keyval": "^6.2.1", "idb-keyval": "^6.2.1",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"overlayscrollbars-react": "^0.5.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-animated-numbers": "^0.16.0", "react-animated-numbers": "^0.16.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
...@@ -16559,6 +16560,21 @@ ...@@ -16559,6 +16560,21 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/overlayscrollbars": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-2.2.1.tgz",
"integrity": "sha512-5oMxq4UCiEVLiOSvovbX8p+P2NtPosjHC0KkIcaobnYuxGwMyTOwBCtBdqO1tXrrA02VVrNzuIjGMLisO2mIwg==",
"peer": true
},
"node_modules/overlayscrollbars-react": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/overlayscrollbars-react/-/overlayscrollbars-react-0.5.1.tgz",
"integrity": "sha512-0xw9J1CT/cQ+ELYy3hudG6nY1H5dgJ1DdVW3d8aZwqx6wyHNZV4nsBQXUxoHmPo3dmlJ5MvOLzpKWA4X6nL4QA==",
"peerDependencies": {
"overlayscrollbars": "^2.0.0",
"react": ">=16.8.0"
}
},
"node_modules/p-defer": { "node_modules/p-defer": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
...@@ -41284,6 +41300,18 @@ ...@@ -41284,6 +41300,18 @@
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g=="
}, },
"overlayscrollbars": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-2.2.1.tgz",
"integrity": "sha512-5oMxq4UCiEVLiOSvovbX8p+P2NtPosjHC0KkIcaobnYuxGwMyTOwBCtBdqO1tXrrA02VVrNzuIjGMLisO2mIwg==",
"peer": true
},
"overlayscrollbars-react": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/overlayscrollbars-react/-/overlayscrollbars-react-0.5.1.tgz",
"integrity": "sha512-0xw9J1CT/cQ+ELYy3hudG6nY1H5dgJ1DdVW3d8aZwqx6wyHNZV4nsBQXUxoHmPo3dmlJ5MvOLzpKWA4X6nL4QA==",
"requires": {}
},
"p-defer": { "p-defer": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
...@@ -15,7 +15,9 @@ ...@@ -15,7 +15,9 @@
* *
* */ * */
import "u-reset.css"; import "u-reset.css";
import "overlayscrollbars/overlayscrollbars.css";
import "@/styles/core.scss"; import "@/styles/core.scss";
import "@/styles/inject.scss";
import { ProConfigProvider } from "@ant-design/pro-provider"; import { ProConfigProvider } from "@ant-design/pro-provider";
import { ConfigProvider, theme } from "antd"; import { ConfigProvider, theme } from "antd";
......
@charset "utf-8"; @charset "utf-8";
@import url("https://fonts.font.im/css2?family=Electrolize&display=swap"); @import url("https://fonts.font.im/css2?family=Electrolize&display=swap");
@import "./antd.scss";
body { body {
color-scheme: dark; color-scheme: dark;
......
// 全局修改 antd 样式 // 全局修改模块内的样式,如 antd 样式、OverlayScrollbars 样式
.ant-btn { .ant-btn {
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -9,3 +9,10 @@ ...@@ -9,3 +9,10 @@
.ant-wave { .ant-wave {
color: hsla(0, 0%, 100%, 0.3); color: hsla(0, 0%, 100%, 0.3);
} }
// OverlayScrollbars 样式
.os-theme-light {
--os-handle-bg: rgba(255, 255, 255, 0.22);
--os-handle-bg-hover: rgba(255, 255, 255, 0.44);
--os-handle-bg-active: rgba(255, 255, 255, 0.66);
}
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
.deck-select-container { .deck-select-container {
max-height: 100%; max-height: 100%;
min-height: 100%; min-height: 100%;
@include utils.scrollbar;
padding-bottom: 1rem; padding-bottom: 1rem;
} }
} }
...@@ -53,7 +52,6 @@ ...@@ -53,7 +52,6 @@
justify-content: space-between; justify-content: space-between;
} }
.deck-zone { .deck-zone {
@include utils.scrollbar;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
...@@ -96,8 +94,6 @@ ...@@ -96,8 +94,6 @@
} }
.search-cards-container { .search-cards-container {
overflow-y: scroll;
@include utils.scrollbar;
.search-cards { .search-cards {
--card-width: 80px; --card-width: 80px;
display: grid; display: grid;
......
...@@ -19,8 +19,8 @@ import { useEffect, useState } from "react"; ...@@ -19,8 +19,8 @@ import { useEffect, useState } from "react";
import { useSnapshot } from "valtio"; import { useSnapshot } from "valtio";
import { deckStore, type IDeck } from "@/stores"; import { deckStore, type IDeck } from "@/stores";
import { Background, ScrollableArea, YgoCard } from "@/ui/Shared";
import { Background, YgoCard } from "@/ui/Shared";
import { CardDetail } from "./CardDetail"; import { CardDetail } from "./CardDetail";
import { DeckSelect } from "./DeckSelect"; import { DeckSelect } from "./DeckSelect";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
...@@ -42,7 +42,7 @@ export const Component: React.FC = () => { ...@@ -42,7 +42,7 @@ export const Component: React.FC = () => {
<Background /> <Background />
<div className={styles.layout} style={{ width: "100%" }}> <div className={styles.layout} style={{ width: "100%" }}>
<div className={styles.sider}> <div className={styles.sider}>
<div className={styles["deck-select-container"]}> <ScrollableArea className={styles["deck-select-container"]}>
<DeckSelect <DeckSelect
decks={snapDecks.decks} decks={snapDecks.decks}
selected={selectedDeck.deckName} selected={selectedDeck.deckName}
...@@ -53,7 +53,7 @@ export const Component: React.FC = () => { ...@@ -53,7 +53,7 @@ export const Component: React.FC = () => {
onDownload={(id) => console.log(id)} onDownload={(id) => console.log(id)}
onAdd={() => console.log("add")} onAdd={() => console.log("add")}
/> />
</div> </ScrollableArea>
<CardDetail code={123} open={false} onClose={() => {}} /> <CardDetail code={123} open={false} onClose={() => {}} />
</div> </div>
<div className={styles.content}> <div className={styles.content}>
...@@ -106,7 +106,7 @@ const Deck: React.FC<{ ...@@ -106,7 +106,7 @@ const Deck: React.FC<{
</Button> </Button>
</Space> </Space>
</Space> </Space>
<div className={styles["deck-zone"]}> <ScrollableArea className={styles["deck-zone"]}>
{(["main", "extra", "side"] as const).map((type) => ( {(["main", "extra", "side"] as const).map((type) => (
<div className={styles[type]}> <div className={styles[type]}>
<div className={styles["card-continer"]}> <div className={styles["card-continer"]}>
...@@ -118,7 +118,7 @@ const Deck: React.FC<{ ...@@ -118,7 +118,7 @@ const Deck: React.FC<{
</div> </div>
</div> </div>
))} ))}
</div> </ScrollableArea>
</div> </div>
</div> </div>
); );
...@@ -150,13 +150,13 @@ const CardSelect: React.FC = () => { ...@@ -150,13 +150,13 @@ const CardSelect: React.FC = () => {
重置 重置
</Button> </Button>
</div> </div>
<div className={styles["search-cards-container"]}> <ScrollableArea className={styles["search-cards-container"]}>
<div className={styles["search-cards"]}> <div className={styles["search-cards"]}>
{Array.from({ length: 60 }).map((_, i) => ( {Array.from({ length: 60 }).map((_, i) => (
<div className={styles.card} key={i} /> <div className={styles.card} key={i} />
))} ))}
</div> </div>
</div> </ScrollableArea>
</div> </div>
</div> </div>
); );
......
...@@ -2,26 +2,6 @@ ...@@ -2,26 +2,6 @@
line-height: 1.6; line-height: 1.6;
font-size: 14px; font-size: 14px;
max-height: calc(100% - 237px); max-height: calc(100% - 237px);
overflow-y: overlay;
&:hover {
&::-webkit-scrollbar-thumb {
background: #535353;
}
}
& > div {
margin-bottom: 6px;
}
&::-webkit-scrollbar {
/*滚动条整体样式*/
width: 6px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
}
&::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
background: #5353533b;
cursor: pointer;
}
.maro-item { .maro-item {
display: flex; display: flex;
......
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
export const ScrollableArea: React.FC<
React.ComponentProps<typeof OverlayScrollbarsComponent>
> = ({ options, children, ...rest }) => (
<OverlayScrollbarsComponent
options={{
scrollbars: {
autoHide: "scroll",
theme: "os-theme-light",
},
overflow: {
x: "hidden",
y: "scroll",
},
...options,
}}
defer
{...rest}
>
{children}
</OverlayScrollbarsComponent>
);
export * from "./Background"; export * from "./Background";
export * from "./css"; export * from "./css";
export * from "./IconFont"; export * from "./IconFont";
export * from "./Scrollbar";
export * from "./Select"; export * from "./Select";
export * from "./SpecialButton"; export * from "./SpecialButton";
export * from "./YgoCard"; export * from "./YgoCard";
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
overflow-y: scroll; overflow-y: scroll;
scroll-behavior: smooth; scroll-behavior: smooth;
max-height: 85vh; max-height: 85vh;
@include utils.scrollbar;
.item { .item {
vertical-align: baseline; vertical-align: baseline;
.name { .name {
......
...@@ -4,8 +4,8 @@ import { useSnapshot } from "valtio"; ...@@ -4,8 +4,8 @@ import { useSnapshot } from "valtio";
import { sendChat } from "@/api"; import { sendChat } from "@/api";
import { chatStore, roomStore } from "@/stores"; import { chatStore, roomStore } from "@/stores";
import { IconFont, ScrollableArea } from "@/ui/Shared";
import { IconFont } from "../Shared";
import styles from "./Chat.module.scss"; import styles from "./Chat.module.scss";
interface ChatItem { interface ChatItem {
...@@ -42,11 +42,11 @@ export const Chat: React.FC = () => { ...@@ -42,11 +42,11 @@ export const Chat: React.FC = () => {
return ( return (
<div className={styles.chat}> <div className={styles.chat}>
<div className={styles.dialogs}> <ScrollableArea className={styles.dialogs}>
{chatlist.map((item, idx) => ( {chatlist.map((item, idx) => (
<DialogItem key={idx} {...item} /> <DialogItem key={idx} {...item} />
))} ))}
</div> </ScrollableArea>
<div className={styles.input}> <div className={styles.input}>
<Input.TextArea <Input.TextArea
bordered={false} bordered={false}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment