chore: 提示面板封装

This commit is contained in:
streakingman 2022-10-09 23:11:58 +08:00
parent 557a6a705a
commit 84fa8483d9
7 changed files with 155 additions and 102 deletions

View File

@ -9,4 +9,7 @@ module.exports = {
'stylelint-config-standard-scss',
'stylelint-config-prettier-scss',
],
rules: {
'selector-class-pattern': '^[a-z][a-zA-Z0-9]+$',
},
};

View File

@ -0,0 +1,63 @@
.panel {
position: fixed;
width: 36px;
height: 36px;
border-radius: 18px;
transition: 0.3s;
padding: 16px;
background-color: rgb(0 0 0/ 50%);
color: white;
overflow: hidden;
backdrop-filter: blur(8px);
box-sizing: border-box;
cursor: pointer;
font-size: 14px;
> * {
opacity: 0;
}
&.leftBottom {
left: 8px;
bottom: 8px;
}
.closeBtn {
position: absolute;
border-radius: 8px;
background-color: rgb(0 0 0/20%);
width: 36px;
height: 36px;
right: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
transform: scale(0);
color: white;
cursor: pointer;
user-select: none;
}
&.open {
height: 100px;
border-radius: 8px;
cursor: default;
z-index: 5 !important;
@media screen and (max-width: 500px) {
width: calc(100% - 16px);
}
@media screen and (min-width: 501px) {
width: 500px;
}
> * {
opacity: 1;
}
.closeBtn {
transform: scale(1);
}
}
}

View File

@ -0,0 +1,48 @@
import React, { FC, ReactNode, useState } from 'react';
import style from './FixedAnimateScalePanel.module.scss';
import classNames from 'classnames';
export const FixedAnimateScalePanel: FC<{
children: ReactNode;
className?: string;
openClassName?: string;
closeClassName?: string;
initOpen?: boolean;
}> = ({
children,
className,
openClassName,
closeClassName,
initOpen = false,
}) => {
const [open, setOpen] = useState<boolean>(initOpen);
return (
<div
onClick={() => !open && setOpen(true)}
className={classNames(
style.panel,
open && style.open,
className,
open ? openClassName : closeClassName
)}
>
{children}
<div className={style.closeBtn} onClick={() => setOpen(false)}>
<svg
width="13"
height="14"
viewBox="0 0 13 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M4.9498 7.04945L0 11.9993L1.41421 13.4135L6.36401 8.46367L11.3138 13.4135L12.728 11.9993L7.77823 7.04945L12.7279 2.09976L11.3137 0.685547L6.36401 5.63524L1.41432 0.685547L0.0001055 2.09976L4.9498 7.04945Z"
fill="#888888"
/>
</svg>
</div>
</div>
);
};

View File

@ -1,24 +1,9 @@
/* 可封装 */
.info {
position: fixed;
left: 8px;
bottom: 8px;
transition: 0.3s;
padding: 16px;
width: 36px;
height: 36px;
border-radius: 18px;
background: rgb(0 0 0/ 50%);
color: white;
overflow: hidden;
backdrop-filter: blur(8px);
box-sizing: border-box;
cursor: pointer;
font-size: 14px;
p {
margin: 0;
opacity: 0;
transition: 0.6s;
}
@ -33,42 +18,13 @@
font-size: 24px;
font-weight: 900;
transition: 0.2s;
}
.close {
position: absolute;
border-radius: 8px;
background-color: rgb(0 0 0/20%);
width: 36px;
height: 36px;
right: 0;
top: 0;
line-height: 36px;
text-align: center;
transform: scale(0);
color: white;
cursor: pointer;
user-select: none;
opacity: 1;
}
&.open {
height: 100px;
border-radius: 8px;
@media screen and (max-width: 500px) {
width: calc(100% - 70px);
}
@media screen and (min-width: 501px) {
width: 500px;
}
p {
opacity: 1;
}
.close {
transform: scale(1);
}
.icon {
transform: scale(0);

View File

@ -1,12 +1,11 @@
import React, { CSSProperties, FC, useState } from 'react';
import React, { FC } from 'react';
import style from './Info.module.scss';
import classNames from 'classnames';
import { FixedAnimateScalePanel } from './FixedAnimateScalePanel';
export const Info: FC = () => {
const [open, setOpen] = useState(false);
return (
<div
onClick={() => !open && setOpen(true)}
className={classNames(style.info, open && style.open)}
<FixedAnimateScalePanel
className={style.info}
openClassName={style.open}
>
<div className={style.icon}>i</div>
<p>
@ -16,11 +15,27 @@ export const Info: FC = () => {
target="_blank"
rel="noreferrer"
>
DISCO
DISCO
</a>
<a
href="https://music.163.com/#/song?id=135022"
target="_blank"
rel="noreferrer"
>
</a>
<a
href="https://y.qq.com/n/ryqq/songDetail/0020Nusb3QJGn9"
target="_blank"
rel="noreferrer"
>
</a>
</p>
<p>
-{'>'}-{'>'}
<a
href="https://play.google.com/store/apps/details?id=tile.master.connect.matching.game"
target="_blank"
@ -28,11 +43,16 @@ export const Info: FC = () => {
>
3 Tiles
</a>
-{'>'}
<a
href="https://www.bilibili.com/video/BV1zT411N7RT"
target="_blank"
rel="noreferrer"
>
</a>
</p>
<p></p>
<div className={style.close} onClick={() => setOpen(false)}>
X
</div>
</div>
</FixedAnimateScalePanel>
);
};

View File

@ -12,14 +12,9 @@
}
}
.info {
position: fixed;
.personalInfo {
right: 8px;
top: 8px;
padding: 4px;
width: 36px;
height: 36px;
border-radius: 18px;
animation: gradient 4s ease infinite;
background-image: linear-gradient(
-45deg,
@ -30,12 +25,8 @@
);
background-size: 400% 400%;
background-position: 0 0;
box-sizing: border-box;
transition: 0.4s;
backdrop-filter: blur(8px);
z-index: 9;
overflow: hidden;
color: white;
* {
transition: 0.6s;
@ -47,28 +38,13 @@
font-weight: 900;
}
.close {
position: absolute;
border-radius: 8px;
background-color: rgb(0 0 0/20%);
width: 36px;
height: 36px;
right: 0;
top: 0;
line-height: 36px;
text-align: center;
transform: scale(0);
color: white;
cursor: pointer;
user-select: none;
}
.github {
&Icon {
position: absolute;
right: 6px;
top: 6px;
cursor: pointer;
opacity: 1 !important;
}
&Link {
@ -93,18 +69,8 @@
}
&.open {
height: 100px;
border-radius: 8px;
@media screen and (max-width: 500px) {
width: calc(100% - 16px);
}
@media screen and (min-width: 501px) {
width: 500px;
}
.close {
transform: scale(1);
width: calc(100% - 60px) !important;
}
.github {

View File

@ -1,6 +1,7 @@
import React, { FC, useState } from 'react';
import style from './PersonalInfo.module.scss';
import classNames from 'classnames';
import { FixedAnimateScalePanel } from './FixedAnimateScalePanel';
const GithubIcon: FC = () => {
return (
@ -63,19 +64,15 @@ export const BiliBiliLink: FC = () => {
};
export const PersonalInfo: FC = () => {
const [open, setOpen] = useState(false);
return (
<div
onClick={() => !open && setOpen(true)}
className={classNames(style.info, open && style.open)}
<FixedAnimateScalePanel
className={style.personalInfo}
openClassName={style.open}
>
<GithubIcon />
<GithubLink />
<BiliBiliIcon />
<BiliBiliLink />
<div className={style.close} onClick={() => setOpen(false)}>
X
</div>
</div>
</FixedAnimateScalePanel>
);
};