summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHaishan <[email protected]>2019-12-27 13:12:49 +0800
committerHaishan <[email protected]>2019-12-27 16:29:46 +0800
commitaca578cb9dfdaed33f91c62ffdf3ef1a456c6a72 (patch)
tree0db1a3f2646ec28841ba59d00e89f156432a9afb /src
parent45c3c7b8b4793ca3b6cd8366baaf035346a6d745 (diff)
refactor: abstract ButtonWithIcon as a button enhancer
Diffstat (limited to 'src')
-rw-r--r--src/components/Button.js18
-rw-r--r--src/components/Button.module.css14
-rw-r--r--src/components/Connections.js8
-rw-r--r--src/components/Proxies.js6
-rw-r--r--src/components/ProxyProvider.js10
-rw-r--r--src/components/Root.css116
-rw-r--r--src/components/Rules.js8
-rw-r--r--src/components/StyleGuide.js19
8 files changed, 149 insertions, 50 deletions
diff --git a/src/components/Button.js b/src/components/Button.js
index d9bcd22..ce83153 100644
--- a/src/components/Button.js
+++ b/src/components/Button.js
@@ -6,10 +6,11 @@ const noop = () => {};
const { memo, forwardRef } = React;
-function Button({ children, label, onClick = noop }, ref) {
+function Button({ children, label, text, start, onClick = noop }, ref) {
return (
<button className={s0.btn} ref={ref} onClick={onClick}>
- {children || label}
+ {start ? <span className={s0.btnStart}>{start}</span> : null}
+ {children || label || text}
</button>
);
}
@@ -22,17 +23,4 @@ export function ButtonPlain({ children, label, onClick = noop }) {
);
}
-function WithIcon({ text, icon, onClick = noop }, ref) {
- return (
- <button className={s0.btn} ref={ref} onClick={onClick}>
- <div className={s0.withIconWrapper}>
- {icon}
- <span className={s0.txt}>{text}</span>
- </div>
- </button>
- );
-}
-
-export const ButtonWithIcon = memo(forwardRef(WithIcon));
-
export default memo(forwardRef(Button));
diff --git a/src/components/Button.module.css b/src/components/Button.module.css
index c232a66..809e133 100644
--- a/src/components/Button.module.css
+++ b/src/components/Button.module.css
@@ -1,11 +1,14 @@
.btn {
-webkit-appearance: none;
outline: none;
+ user-select: none;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
color: var(--color-btn-fg);
background: var(--color-btn-bg);
border: 1px solid #555;
border-radius: 100px;
- user-select: none;
&:focus {
border-color: var(--color-focus-blue);
}
@@ -42,10 +45,9 @@
}
}
-.withIconWrapper {
- display: flex;
+.btnStart {
+ margin-right: 5px;
+ display: inline-flex;
align-items: center;
- .txt {
- margin-left: 5px;
- }
+ justify-content: center;
}
diff --git a/src/components/Connections.js b/src/components/Connections.js
index c07de0a..b2617a6 100644
--- a/src/components/Connections.js
+++ b/src/components/Connections.js
@@ -6,7 +6,7 @@ import { useStoreState } from '../misc/store';
import { getClashAPIConfig } from '../ducks/app';
import { X as IconClose } from 'react-feather';
import SvgYacd from './SvgYacd';
-import { ButtonWithIcon } from './Button';
+import Button from './Button';
import ModalCloseAllConnections from './ModalCloseAllConnections';
import * as connAPI from '../api/connections';
@@ -89,11 +89,7 @@ function Conn() {
</div>
</div>
<div className="fabgrp">
- <ButtonWithIcon
- text="Close"
- icon={iconClose}
- onClick={openCloseAllModal}
- />
+ <Button text="Close" start={iconClose} onClick={openCloseAllModal} />
</div>
<ModalCloseAllConnections
isOpen={isCloseAllModalOpen}
diff --git a/src/components/Proxies.js b/src/components/Proxies.js
index eb0f78b..01be151 100644
--- a/src/components/Proxies.js
+++ b/src/components/Proxies.js
@@ -5,7 +5,7 @@ import { connect } from './StateProvider';
import ContentHeader from './ContentHeader';
import ProxyGroup from './ProxyGroup';
-import { ButtonWithIcon } from './Button';
+import Button from './Button';
import { Zap } from 'react-feather';
import ProxyProviderList from './ProxyProviderList';
@@ -45,9 +45,9 @@ function Proxies({ dispatch, groupNames, proxies, delay, proxyProviders }) {
<ContentHeader title="Proxies" />
<div>
<div className="fabgrp">
- <ButtonWithIcon
+ <Button
text="Test Latency"
- icon={icon}
+ start={icon}
onClick={requestDelayAllFn}
/>
</div>
diff --git a/src/components/ProxyProvider.js b/src/components/ProxyProvider.js
index 3a0b2ef..9561907 100644
--- a/src/components/ProxyProvider.js
+++ b/src/components/ProxyProvider.js
@@ -10,7 +10,7 @@ import { getClashAPIConfig } from '../ducks/app';
import { connect } from './StateProvider';
import { SectionNameType } from './shared/Basic';
import { ProxyList, ProxyListSummaryView } from './ProxyGroup';
-import { ButtonWithIcon, ButtonPlain } from './Button';
+import Button, { ButtonPlain } from './Button';
import {
updateProviderByName,
@@ -69,12 +69,8 @@ function ProxyProvider({ item, dispatch }: Props) {
<Collapsible2 isOpen={isCollapsibleOpen}>
<ProxyList all={item.proxies} />
<div className={s.actionFooter}>
- <ButtonWithIcon
- text="Update"
- icon={<Refresh />}
- onClick={updateProvider}
- />
- <ButtonWithIcon
+ <Button text="Update" start={<Refresh />} onClick={updateProvider} />
+ <Button
text="Health Check"
icon={<Zap size={16} />}
onClick={healthcheckProvider}
diff --git a/src/components/Root.css b/src/components/Root.css
index 3622d57..3c91bcb 100644
--- a/src/components/Root.css
+++ b/src/components/Root.css
@@ -133,3 +133,119 @@ body.light {
right: 20px;
bottom: 20px;
}
+
+.dot_loading,
+.dot_loading:before,
+.dot_loading:after {
+ display: inline-block;
+ vertical-align: middle;
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background-color: rgba(0, 0, 0, 0.3);
+ font-size: 0;
+}
+.dot_loading {
+ position: relative;
+ animation: dot2 1.6s step-start infinite;
+ &:before {
+ content: '';
+ position: absolute;
+ left: -12px;
+ background-color: rgba(0, 0, 0, 0.1);
+ animation: dot1 1.6s step-start infinite;
+ }
+ &:after {
+ content: '';
+ position: absolute;
+ right: -12px;
+ background-color: rgba(0, 0, 0, 0.5);
+ animation: dot3 1.6s step-start infinite;
+ }
+}
+
+@keyframes dot1 {
+ 0%,
+ 100% {
+ background-color: rgba(0, 0, 0, 0.1);
+ }
+ 30% {
+ background-color: rgba(0, 0, 0, 0.5);
+ }
+ 60% {
+ background-color: rgba(0, 0, 0, 0.3);
+ }
+}
+@keyframes dot2 {
+ 0%,
+ 100% {
+ background-color: rgba(0, 0, 0, 0.3);
+ }
+ 30% {
+ background-color: rgba(0, 0, 0, 0.1);
+ }
+ 60% {
+ background-color: rgba(0, 0, 0, 0.5);
+ }
+}
+@keyframes dot3 {
+ 0%,
+ 100% {
+ background-color: rgba(0, 0, 0, 0.5);
+ }
+ 30% {
+ background-color: rgba(0, 0, 0, 0.3);
+ }
+ 60% {
+ background-color: rgba(0, 0, 0, 0.1);
+ }
+}
+
+.dot_loading_white {
+ background-color: rgba(255, 255, 255, 0.3);
+ animation: dotw2 1.6s step-start infinite;
+ &:before {
+ background-color: rgba(255, 255, 255, 0.5);
+ animation: dotw1 1.6s step-start infinite;
+ }
+ &:after {
+ background-color: rgba(255, 255, 255, 0.1);
+ animation: dotw3 1.6s step-start infinite;
+ }
+}
+@keyframes dotw1 {
+ 0%,
+ 100% {
+ background-color: rgba(255, 255, 255, 0.5);
+ }
+ 30% {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+ 60% {
+ background-color: rgba(255, 255, 255, 0.3);
+ }
+}
+@keyframes dotw2 {
+ 0%,
+ 100% {
+ background-color: rgba(255, 255, 255, 0.3);
+ }
+ 30% {
+ background-color: rgba(255, 255, 255, 0.5);
+ }
+ 60% {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+}
+@keyframes dotw3 {
+ 0%,
+ 100% {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+ 30% {
+ background-color: rgba(255, 255, 255, 0.3);
+ }
+ 60% {
+ background-color: rgba(255, 255, 255, 0.5);
+ }
+}
diff --git a/src/components/Rules.js b/src/components/Rules.js
index e881443..a5528ad 100644
--- a/src/components/Rules.js
+++ b/src/components/Rules.js
@@ -1,6 +1,6 @@
import React from 'react';
import { useActions, useStoreState } from '../misc/store';
-import { ButtonWithIcon } from './Button';
+import Button from './Button';
import { FixedSizeList as List, areEqual } from 'react-window';
import { RotateCw } from 'react-feather';
@@ -64,11 +64,7 @@ export default function Rules() {
</List>
</div>
<div className="fabgrp">
- <ButtonWithIcon
- text="Refresh"
- icon={refreshIcon}
- onClick={fetchRules}
- />
+ <Button text="Refresh" start={refreshIcon} onClick={fetchRules} />
</div>
</div>
);
diff --git a/src/components/StyleGuide.js b/src/components/StyleGuide.js
index 7b6f53d..63afb54 100644
--- a/src/components/StyleGuide.js
+++ b/src/components/StyleGuide.js
@@ -1,10 +1,11 @@
import React, { PureComponent } from 'react';
-import PropTypes from 'prop-types';
+
+import { Zap } from 'react-feather';
import ToggleSwitch from './ToggleSwitch';
import Input from './Input';
import Switch from './Switch';
-import Button from './Button';
+import Button, { ButtonWithIcon, ButtonPlain } from './Button';
// import Modal from 'c/Modal';
// import APIConfig from 'c/APIConfig';
// import Proxy from 'c/Proxy';
@@ -28,10 +29,9 @@ const optionsRule = [
}
];
-const Pane = ({ children }) => <div style={paneStyle}>{children}</div>;
-Pane.propTypes = {
- children: PropTypes.element
-};
+const Pane = ({ children, style }) => (
+ <div style={{ ...paneStyle, ...style }}>{children}</div>
+);
class StyleGuide extends PureComponent {
render() {
@@ -52,7 +52,12 @@ class StyleGuide extends PureComponent {
/>
</Pane>
<Pane>
- <Button label="Test Latency" />
+ <Button label="Test Lxatency" />
+ <Button text="Test Lxatency" start={<Zap size={17} />} />
+ <ButtonPlain label="Plain" />
+ </Pane>
+ <Pane style={{ paddingLeft: 20 }}>
+ <div className="dot_loading dot_loading_white" />
</Pane>
</div>
);