feat(fe/styles): add dark theme

This commit is contained in:
hexxa 2022-03-19 16:31:39 +08:00 committed by Hexxa
parent 4cdfddc090
commit 916520bed1
15 changed files with 430 additions and 50 deletions

378
public/static/css/dark.css Normal file
View file

@ -0,0 +1,378 @@
@charset "utf-8";
/* ids */
#root-frame {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.theme-dark #breadcrumb {
width: 100%;
}
.theme-dark #breadcrumb .location-item {
margin: 0 0.5rem 0 0;
display: inline-block;
line-height: 3rem;
}
.theme-dark #breadcrumb .item {
margin: 0 0.5rem 0 0;
max-width: 6rem;
display: inline-block;
line-height: 3rem;
}
.theme-dark #breadcrumb .content {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
overflow-wrap: break-word;
display: block;
}
.theme-dark #space-used {
text-align: right;
line-height: 3rem;
font-size: 1.4rem;
}
.theme-dark #sharing-list .desc {
/* background-color: #ecf0f1; */
font-size: 1.2rem;
margin: 1rem 0;
/* color: #697384; */
padding: 1rem;
border: dashed 1px #95a5a6;
overflow-wrap: break-word;
}
.theme-dark #bg {
/* background: url("/static/img/textured_paper.png") repeat fixed center; */
background-color: rgb(22 22 24);
color: #ccc;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: scroll;
}
.theme-dark #top-bar {
padding: 1rem 2rem 1rem 2rem;
position: relative;
z-index: 2;
backdrop-filter: blur(9.5px);
-webkit-backdrop-filter: blur(9.5px);
}
.theme-dark #top-menu {
background: #242424;
opacity: 0.8;
box-shadow: 0 5px 30px 0 rgba(31, 38, 135, 0.1);
backdrop-filter: blur(9.5px);
color: #16a085;
padding: 0.5rem 1rem;
-webkit-backdrop-filter: blur(9.5px);
position: relative;
z-index: 1;
}
.theme-dark #top-menu button {
background: transparent;
}
.theme-dark .qrcode {
padding: 1rem;
background-color: #ecf0f1;
display: inline-block;
background: rgba(255, 255, 255, 0.8);
box-shadow: 0 5px 30px 0 rgb(31 38 135 / 10%);
backdrop-filter: blur(9.5px);
}
.theme-dark .qrcode-container {
height: 3rem;
}
.theme-dark .qrcode-icon {
height: 3rem;
}
.theme-dark .qrcode-child-container {
position: relative;
z-index: 50;
}
.theme-dark .qrcode-child {
position: absolute;
}
.theme-dark .container-center {
margin: 2rem auto auto auto;
width: 96%;
max-width: 80rem;
z-index: 9;
}
.theme-dark .layer {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: url("/static/img/textured_paper.png") repeat fixed center;
overflow: scroll;
z-index: 100;
}
.theme-dark #login-layer {
z-index: 200;
}
.theme-dark #loading-layer {
z-index: 201;
}
.theme-dark #loading-container {
background-color: rgba(255, 255, 255, 1);
border-radius: 3rem;
padding: 0.5rem;
position: fixed;
right: 2rem;
bottom: 2rem;
z-index: 201;
height: 5rem;
width: 5rem;
}
.theme-dark #settings-layer {
z-index: 100;
}
.theme-dark #tail {
font-size: 1.2rem;
text-align: center;
margin: 4rem auto;
}
.theme-dark input {
font-size: 1.2rem;
color: #999;
background-color: rgb(64 64 64);
border: solid 1px #95a5a6;
}
.container-padding {
padding: 1.5rem;
}
.theme-dark #panes #title {
text-transform: capitalize;
}
.theme-dark #pane-login {
max-width: 48rem;
padding: 2rem;
}
.theme-dark #pane-login #title {
font-size: 2rem;
text-align: center;
}
.theme-dark #pane-login .login-container {
margin: 2rem;
}
.theme-dark #pane-login .input-wrap {
width: 100%;
background-color: #eaebf6;
margin: 2rem 0 0 0;
border-radius: 0.6rem;
line-height: 4rem;
}
.theme-dark #pane-login #captcha-input {
width: calc(100% - 1rem);
}
.theme-dark #pane-login #captcha {
width: calc(100% - 1rem);
background-color: #eaebf6;
border: solid 1px #eaebf6;
margin: 2rem 0 0 0;
border-radius: 0.6rem;
height: 3.8rem;
}
.theme-dark #pane-login input,
.theme-dark #pane-login input:hover,
.theme-dark #pane-login input:focus,
.theme-dark #pane-login input:active {
width: 100%;
padding: 0;
border: none;
margin: 0 1rem;
background-color: transparent;
outline: none;
box-shadow: none;
}
.theme-dark #btn-login {
background-color: #1abc9c;
color: #fff;
width: 100%;
margin-top: 2rem;
height: 4rem;
}
.theme-dark #layers {
height: 0;
z-index: 3;
}
.theme-dark #root-container {
max-width: 80rem;
width: 96%;
text-align: left;
margin: 3rem auto 8rem auto;
}
/* +composition */
.theme-dark .container {
width: 100%;
background-color: #242424;
border-radius: 0.8rem;
box-shadow: 0 5px 30px 0 rgb(31 38 135 / 10%);
margin: auto auto 2rem auto;
}
.theme-dark .info {
border: dashed 1px #95a5a6;
font-size: 1.4rem;
padding: 1rem;
margin: 1rem 0 0 0;
background-color: black;
white-space: nowrap;
overflow: auto;
}
.theme-dark .badge {
border: none;
border-radius: 0.5rem;
font-weight: bold;
font-size: 1.2rem;
padding: 1rem 1rem;
line-height: 1.2rem;
display: inline-block;
}
.theme-dark .progress-grey {
background-color: #ecf0f6;
width: 100%;
height: 0.3rem;
}
.theme-dark .progress-green {
background-color: #1abc9c;
height: 100%;
transition: width 300ms;
}
.theme-dark .col-l {
float: left;
width: 70%;
overflow-wrap: break-word;
}
.theme-dark .col-r {
float: right;
width: 30%;
text-align: right;
}
.theme-dark .error-inline {
font-size: 1.4rem;
padding: 1rem;
color: #f1c40f;
margin: 1rem 0 0 0;
background-color: #2c3e50;
white-space: nowrap;
overflow: auto;
}
.theme-dark .label {
font-size: 1.2rem;
line-height: 1.8rem;
color: #7f8c8d;
padding-left: 0.5rem;
}
.theme-dark .error {
font-size: 1.4rem;
padding: 1rem;
color: #f1c40f;
margin: 1rem 0 0 0;
background-color: #2c3e50;
overflow-wrap: break-word;
}
.theme-dark .hr {
height: 1px;
margin: 1rem 0;
background-color: #333;
}
/* +colors */
.theme-dark .major-font {
color: #ccc;
}
.theme-dark .minor-font {
color: white;
}
.theme-dark .normal-font {
color: #999;
}
.theme-dark .focus-font {
color: #16a085;
}
.theme-dark .error-font {
color: #f1c40f;
}
.theme-dark .major-bg {
background-color: #242424;
}
.theme-dark .normal-bg {
background-color: #697384;
}
.theme-dark .focus-bg {
background-color: #16a085;
}
.theme-dark .minor-bg {
background-color: #333;
}
.theme-dark ::placeholder {
color: #95a5a6;
}
.theme-dark a {
color: #16a085;
}
.theme-dark a:hover {
color: cc#2ecc71;
}
.theme-dark input:focus {
opacity: 0.8;
box-shadow: 0 0.1rem 1rem rgba(22, 160, 133, 0.1);
}
.theme-dark .button-default {
color: #999;
background-color: rgb(64 64 64);
}

View file

@ -153,7 +153,6 @@
}
.theme-default #tail {
color: #34495e;
font-size: 1.2rem;
text-align: center;
margin: 4rem auto;
@ -332,16 +331,16 @@
/* +colors */
.theme-default .dark-font {
.theme-default .minor-font {
color: #34495e;
}
.theme-default .light-font {
.theme-default .major-font {
color: #95a5a6;
}
.theme-default .normal-font {
color: #697384;
}
.theme-default .highlight-font {
.theme-default .focus-font {
color: #16a085;
}
.theme-default .error-font {
@ -351,16 +350,16 @@
.theme-default .lightest-bg {
background-color: white;
}
.theme-default .light-bg {
.theme-default .major-bg {
background-color: #f6f6f6;
}
.theme-default .normal-bg {
background-color: #ecf0f6;
}
.theme-default .highlight-bg {
.theme-default .focus-bg {
background-color: #16a085;
}
.theme-default .dark-bg {
.theme-default .minor-bg {
background-color: #2c3e50;
}
.theme-default button {

View file

@ -19,7 +19,7 @@
<link rel="stylesheet" href="/static/css/colors.css" />
<link rel="stylesheet" href="/static/css/default.css" />
<link rel="stylesheet" href="/static/css/white.css" />
<link rel="stylesheet" href="/static/css/black.css" />
<link rel="stylesheet" href="/static/css/dark.css" />
<!-- <link
rel="apple-touch-icon"
sizes="57x57"

View file

@ -19,7 +19,7 @@
<link rel="stylesheet" href="/static/css/colors.css" />
<link rel="stylesheet" href="/static/css/default.css" />
<link rel="stylesheet" href="/static/css/white.css" />
<link rel="stylesheet" href="/static/css/black.css" />
<link rel="stylesheet" href="/static/css/dark.css" />
<!-- <link
rel="apple-touch-icon"
sizes="57x57"

View file

@ -16,7 +16,7 @@ export const BtnList = (props: Props) => {
props.titleIcon != null ? (
getIconWithProps(props.titleIcon, {
size: "3rem",
className: "black-font margin-r-m",
className: "major-font margin-r-m",
})
) : (
<span></span>

View file

@ -43,7 +43,7 @@ export class Tabs extends React.Component<Props, State, {}> {
const titleIcon =
this.props.titleIcon != null
? getIcon(this.props.titleIcon, "2rem", "black")
? getIcon(this.props.titleIcon, "2rem", "major")
: null;
const options = this.props.ui.control.options.get(this.props.targetControl);
const tabs = options.map((option: string) => {
@ -51,10 +51,10 @@ export class Tabs extends React.Component<Props, State, {}> {
? this.props.tabIcons.get(option)
: defaultIconProps;
const iconColor = displaying === option ? iconProps.color : "black0";
const iconColor = displaying === option ? iconProps.color : "major";
const icon = getIcon(iconProps.name, iconProps.size, iconColor);
const fontColor =
displaying === option ? `${colorClass(iconColor)}-font` : "black0-font";
displaying === option ? `${colorClass(iconColor)}-font` : "major-font";
return (
<button
@ -62,7 +62,7 @@ export class Tabs extends React.Component<Props, State, {}> {
onClick={() => {
this.setTab(this.props.targetControl, option);
}}
className="float-l margin-r-m normal-bg"
className="float-l margin-r-m minor-bg"
>
<Flexbox
children={List([

View file

@ -8,7 +8,7 @@ export interface Props {
export const Card = (props: Props) => {
return (
<div className="padding-m float-l">
<div className="title-l black0-font">{props.value}</div>
<div className="title-l">{props.value}</div>
<div className="desc-m">{props.name}</div>
</div>
);

View file

@ -205,7 +205,7 @@ export class UserForm extends React.Component<
render() {
const foldedClass = this.state.folded ? "hidden" : "";
const foldIconColor = this.state.folded ? "black-font" : "highlight-font";
const foldIconColor = this.state.folded ? "major-font" : "focus-font";
const resetUsedSpace = () => {
this.resetUsedSpace(this.props.id);
};

View file

@ -384,7 +384,7 @@ export class PaneSettings extends React.Component<Props, State, {}> {
type="text"
onChange={this.changeLanPackURL}
value={this.props.login.preferences.lanPackURL}
className="dark-font"
className="minor-font"
style={{ width: "20rem" }}
placeholder={this.props.msg.pkg.get("settings.lanPackURL")}
/>

View file

@ -484,14 +484,14 @@ export class FilesPanel extends React.Component<Props, State, {}> {
? `${dirPath}${item.name}`
: `${dirPath}/${item.name}`;
const selectedIconColor = isSelected ? "highlight-font" : "dark-font";
const selectedIconColor = isSelected ? "focus-font" : "minor-font";
const descIconColor = this.state.showDetail.has(item.name)
? "highlight-font"
: "light-font";
? "focus-font"
: "major-font";
const icon = item.isDir ? (
<RiFolder2Fill size="2rem" className="yellow0-font margin-r-m" />
) : (
<RiFile2Fill size="2rem" className="highlight-font margin-r-m" />
<RiFile2Fill size="2rem" className="focus-font margin-r-m" />
);
const modTimeDate = new Date(item.modTime);
@ -504,14 +504,14 @@ export class FilesPanel extends React.Component<Props, State, {}> {
<span className="clickable" onClick={() => this.gotoChild(item.name)}>
{item.name}
</span>
<span className="light-font">{` - ${modTimeFormatted}`}</span>
<span className="major-font">{` - ${modTimeFormatted}`}</span>
</span>
) : (
<span className="title-m-wrap">
<a className="clickable" href={downloadPath} target="_blank">
{item.name}
</a>
<span className="light-font">{` - ${modTimeFormatted}`}</span>
<span className="major-font">{` - ${modTimeFormatted}`}</span>
</span>
);
@ -552,21 +552,21 @@ export class FilesPanel extends React.Component<Props, State, {}> {
? "margin-t-m padding-m"
: "no-height";
const desc = (
<div className={`${descStateClass} desc light-font light-bg`}>
<div className={`${descStateClass} desc major-font minor-bg`}>
<div className="column">
<div className="card">
<span className="title-m dark-font">{pathTitle}</span>
<span className="title-m minor-font">{pathTitle}</span>
<span className="font-s work-break-all">{absDownloadURL}</span>
</div>
</div>
<div className="column">
<div className="card">
<span className="title-m dark-font">{modTimeTitle}</span>
<span className="title-m minor-font">{modTimeTitle}</span>
<span className="font-s work-break-all">{modTimeFormatted}</span>
</div>
<div className="card">
<span className="title-m dark-font">{sizeTitle}</span>
<span className="title-m minor-font">{sizeTitle}</span>
<span className="font-s work-break-all">{itemSize}</span>
</div>
</div>
@ -575,11 +575,11 @@ export class FilesPanel extends React.Component<Props, State, {}> {
<div className="card">
<Flexbox
children={List([
<span className="title-m dark-font">SHA1</span>,
<span className="title-m minor-font">SHA1</span>,
<RiRestartFill
onClick={() => this.generateHash(itemPath)}
size={"2rem"}
className={`dark-font ${shareModeClass}`}
className={`minor-font ${shareModeClass}`}
/>,
])}
childrenStyles={List([{}, { justifyContent: "flex-end" }])}
@ -593,7 +593,7 @@ export class FilesPanel extends React.Component<Props, State, {}> {
const cells = List<React.ReactNode>([
<div className="icon-s">{icon}</div>,
<div>{name}</div>,
<div className="title-m light-font padding-l-s">{itemSize}</div>,
<div className="title-m major-font padding-l-s">{itemSize}</div>,
<div className="txt-align-r">{op}</div>,
]);
@ -645,7 +645,7 @@ export class FilesPanel extends React.Component<Props, State, {}> {
<Container>
<Title
title={this.props.msg.pkg.get("endpoints")}
iconColor="black"
iconColor="major"
iconName="RiGridFill"
/>
<div className="hr"></div>
@ -694,7 +694,7 @@ export class FilesPanel extends React.Component<Props, State, {}> {
<div>
<button
onClick={this.mkDir}
className="inline-block highlight-bg white-font margin-r-m"
className="inline-block focus-bg white-font margin-r-m"
>
{this.props.msg.pkg.get("browser.folder.add")}
</button>
@ -710,7 +710,7 @@ export class FilesPanel extends React.Component<Props, State, {}> {
<div>
<button
onClick={this.onClickUpload}
className="highlight-bg white-font"
className="focus-bg white-font"
>
{this.props.msg.pkg.get("browser.upload")}
</button>
@ -784,12 +784,12 @@ export class FilesPanel extends React.Component<Props, State, {}> {
const rowsViewColorClass =
this.props.ui.control.controls.get(filesViewCtrl) === "rows"
? "highlight-font"
: "black-font";
? "focus-font"
: "major-font";
const tableViewColorClass =
this.props.ui.control.controls.get(filesViewCtrl) === "table"
? "highlight-font"
: "black-font";
? "focus-font"
: "major-font";
const itemListPane = (
<div>
@ -820,7 +820,7 @@ export class FilesPanel extends React.Component<Props, State, {}> {
<button
type="button"
onClick={this.addSharing}
className="highlight-bg white-font margin-r-m"
className="focus-bg white-font margin-r-m"
>
{this.props.msg.pkg.get("browser.share.add")}
</button>

View file

@ -100,7 +100,7 @@ export class SharingsPanel extends React.Component<Props, State, {}> {
const row1 = (
<div>
<div className="col-l">
<span className="title-m-wrap dark-font">{dirPath}</span>
<span className="title-m-wrap minor-font">{dirPath}</span>
</div>
<div className="col-r">
@ -133,7 +133,7 @@ export class SharingsPanel extends React.Component<Props, State, {}> {
const elem = (
<div className="margin-t-m margin-b-m" key={dirPath}>
{row1}
<div className="desc">{sharingURL}</div>
<div className="desc minor-bg major-font">{sharingURL}</div>
<div className="hr"></div>
</div>
);
@ -166,7 +166,7 @@ export class SharingsPanel extends React.Component<Props, State, {}> {
<Title
title={this.props.msg.pkg.get("browser.share.title")}
iconName="RiShareBoxLine"
iconColor="black"
iconColor="major"
/>
);

View file

@ -193,7 +193,7 @@ export class UploadingsPanel extends React.Component<Props, State, {}> {
<Title
title={this.props.msg.pkg.get("browser.upload.title")}
iconName="RiUploadCloudFill"
iconColor="black"
iconColor="major"
/>
);

View file

@ -52,8 +52,8 @@ export class RootFrame extends React.Component<Props, State, {}> {
render() {
const bgStyle = this.makeBgStyle();
const themeBlack = "theme-black";
const theme = themeBlack;
const themeDark = "theme-dark";
const theme = themeDark;
const fontSizeClass = "font-m";
const displaying = this.props.ui.control.controls.get(controlName);
@ -64,7 +64,7 @@ export class RootFrame extends React.Component<Props, State, {}> {
return (
<div id="root-frame" className={`${theme} ${fontSizeClass}`}>
<div id="bg" style={bgStyle}>
<div id="bg" style={{}}>
<Layers
login={this.props.login}
admin={this.props.admin}
@ -88,17 +88,17 @@ export class RootFrame extends React.Component<Props, State, {}> {
filesPanel: {
name: "RiFolder2Fill",
size: "1.6rem",
color: "highlight",
color: "focus",
},
uploadingsPanel: {
name: "RiUploadCloudFill",
size: "1.6rem",
color: "highlight",
color: "focus",
},
sharingsPanel: {
name: "RiShareBoxLine",
size: "1.6rem",
color: "highlight",
color: "focus",
},
})}
ui={this.props.ui}

View file

@ -55,7 +55,7 @@ export class TopBar extends React.Component<Props, State, {}> {
: "";
return (
<div id="top-bar" className="highlight-font light-bg">
<div id="top-bar" className="focus-font major-bg">
<Flexbox
children={List([
<a

View file

@ -30,8 +30,11 @@ export const colors = Set<string>([
"black1",
"dark",
"light",
"major",
"minor",
"focus",
"normal",
"highlight",
"focus",
"error",
]);