From e8bde550a39f278703d24c8d52010939dbe71781 Mon Sep 17 00:00:00 2001 From: Dreamacro <305009791@qq.com> Date: Wed, 26 Sep 2018 00:39:14 +0800 Subject: [PATCH] Add: setting page --- .stylelintrc | 5 +- package-lock.json | 5 ++ package.json | 1 + src/components/ButtonSelect/index.tsx | 43 +++++++++++++++++ src/components/ButtonSelect/style.scss | 41 ++++++++++++++++ src/components/Col/index.tsx | 37 +++++++++++++++ src/components/Row/index.tsx | 38 +++++++++++++++ src/components/Row/style.scss | 65 ++++++++++++++++++++++++++ src/components/Switch/index.tsx | 2 +- src/components/Switch/style.scss | 8 ++-- src/components/index.ts | 3 ++ src/containers/Settings/index.tsx | 62 ++++++++++++++++++++++-- src/containers/Settings/style.scss | 21 ++++++--- src/styles/variables.scss | 2 +- 14 files changed, 316 insertions(+), 17 deletions(-) create mode 100644 src/components/ButtonSelect/index.tsx create mode 100644 src/components/ButtonSelect/style.scss create mode 100644 src/components/Col/index.tsx create mode 100644 src/components/Row/index.tsx create mode 100644 src/components/Row/style.scss diff --git a/.stylelintrc b/.stylelintrc index c230c9c..a7b2a9f 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -2,7 +2,10 @@ "extends": "stylelint-config-standard", "rules": { "indentation": 4, - "font-family-no-missing-generic-family-keyword": null + "font-family-no-missing-generic-family-keyword": null, + "at-rule-no-unknown": [true, { + "ignoreAtRules": ["for", "function", "if", "each", "include", "mixin"] + }] }, "ignoreFiles": [ "**/*.ts", diff --git a/package-lock.json b/package-lock.json index 9d1cdff..9d85834 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2888,6 +2888,11 @@ "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", "dev": true }, + "dayjs": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.7.5.tgz", + "integrity": "sha512-OzkAcosqOgWgQF+dQTXO/iaSGa3hMs/sSkfzkxwWpZXqJEbaA0V6O1V+Ew2tGBlTz1r7Rb7opU3w8ympWb9d2Q==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", diff --git a/package.json b/package.json index da02ca6..250171d 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ }, "dependencies": { "classnames": "^2.2.6", + "dayjs": "^1.7.5", "i18next": "^11.9.0", "i18next-browser-languagedetector": "^2.2.3", "ini": "^1.3.5", diff --git a/src/components/ButtonSelect/index.tsx b/src/components/ButtonSelect/index.tsx new file mode 100644 index 0000000..1e23e01 --- /dev/null +++ b/src/components/ButtonSelect/index.tsx @@ -0,0 +1,43 @@ +import * as React from 'react' +import { BaseComponentProps } from '@models/BaseProps' +import classnames from 'classnames' +import './style.scss' + +export interface ButtonSelectOptions { + label: string, + value: any +} + +export interface ButtonSelectProps extends BaseComponentProps { + // options + options: ButtonSelectOptions[] + + // active value + value: any + + // select callback + onSelect?: (value: any) => void +} + +export class ButtonSelect extends React.Component { + + render () { + const { options, value, onSelect } = this.props + + return ( +
+ { + options.map(option => ( + + )) + } +
+ ) + } + +} diff --git a/src/components/ButtonSelect/style.scss b/src/components/ButtonSelect/style.scss new file mode 100644 index 0000000..68574fb --- /dev/null +++ b/src/components/ButtonSelect/style.scss @@ -0,0 +1,41 @@ +@import '~@styles/variables'; + +.button-select { + display: flex; + flex-direction: row; + + .button-select-options { + height: 30px; + padding: 0 15px; + color: $color-primary-darken; + font-size: 12px; + line-height: 30px; + background: $color-white; + border: 1px solid $color-primary-lightly; + border-right: none; + transition: all 300ms ease; + cursor: pointer; + outline: 0; + display: block; + } + + .button-select-options:first-child { + border-radius: 3px 0 0 3px; + } + + .button-select-options:last-child { + border-radius: 0 3px 3px 0; + border-right: 1px solid $color-primary-lightly; + } + + .button-select-options.actived { + background: $color-primary; + color: $color-white; + border-color: $color-primary; + box-shadow: 0 2px 5px rgba($color: $color-primary, $alpha: 0.5); + + &:active { + box-shadow: none; + } + } +} diff --git a/src/components/Col/index.tsx b/src/components/Col/index.tsx new file mode 100644 index 0000000..f4032c9 --- /dev/null +++ b/src/components/Col/index.tsx @@ -0,0 +1,37 @@ +import * as React from 'react' +import { BaseComponentProps } from '@models/BaseProps' +import classnames from 'classnames' + +interface ColProps extends BaseComponentProps { + // left offset + offset?: number + + // flex order + order?: number + + span?: number +} + +export const Col: React.SFC = props => { + const { + offset = 0, + order = 0, + span = 1, + className, + style: s, + children + } = props + + const style = Object.assign({}, { order }, s) + + return ( +
+ { children } +
+ ) +} diff --git a/src/components/Row/index.tsx b/src/components/Row/index.tsx new file mode 100644 index 0000000..21bf802 --- /dev/null +++ b/src/components/Row/index.tsx @@ -0,0 +1,38 @@ +import * as React from 'react' +import { BaseComponentProps } from '@models/BaseProps' +import classnames from 'classnames' +import './style.scss' + +interface RowProps extends BaseComponentProps { + // grid column + gutter?: number + + // row align + align?: 'top' | 'middle' | 'bottom' + + // column justify + justify?: 'start' | 'end' | 'center' | 'space-around' | 'space-between' +} + +export const Row: React.SFC = props => { + const { + gutter = 24, + align = 'top', + justify = 'start', + className, + style, + children + } = props + + return ( +
+ { children } +
+ ) +} diff --git a/src/components/Row/style.scss b/src/components/Row/style.scss new file mode 100644 index 0000000..8611822 --- /dev/null +++ b/src/components/Row/style.scss @@ -0,0 +1,65 @@ +@import '~@styles/variables'; + +$padding: 12px; + +.row { + width: 100%; + display: flex; + flex-direction: row; +} + +// gutter +@for $i from 1 through 24 { + .row-gutter-#{$i} { + padding: $padding $padding / 2; + + .column { + padding: 0 $padding / 2; + display: flex; + } + + @for $c from 1 through 24 { + .column-span-#{$c} { + width: (100% / $i) * $c; + } + + .column-offset-#{$c} { + margin-left: (100% / $i) * $c; + } + } + } +} + +// align +.row-align-top { + align-items: flex-start; +} + +.row-align-middle { + align-items: center; +} + +.row-align-bottom { + align-items: flex-end; +} + +// justify +.row-justify-start { + justify-content: flex-start; +} + +.row-justify-end { + justify-content: flex-end; +} + +.row-justify-center { + justify-content: center; +} + +.row-justify-space-around { + justify-content: space-around; +} + +.row-justify-space-between { + justify-content: space-between; +} diff --git a/src/components/Switch/index.tsx b/src/components/Switch/index.tsx index dcec38f..8a88da1 100644 --- a/src/components/Switch/index.tsx +++ b/src/components/Switch/index.tsx @@ -28,7 +28,7 @@ export class Switch extends React.Component { return (
- +
) } diff --git a/src/components/Switch/style.scss b/src/components/Switch/style.scss index 0d75a19..82aeb9e 100644 --- a/src/components/Switch/style.scss +++ b/src/components/Switch/style.scss @@ -1,9 +1,9 @@ @import '~@styles/variables'; -$height: 14px; -$switch-radius: 16px; +$height: 16px; +$switch-radius: 18px; $switch-offset: 2px; -$width: 28px; +$width: 32px; .switch { display: inline-block; @@ -43,7 +43,7 @@ $width: 28px; width: $switch-radius; border-radius: $switch-radius / 2; background-color: #fff; - box-shadow: 0 0 8px rgba($color-primary-dark, 0.25); + box-shadow: 0 0 8px rgba($color-primary-dark, 0.4); transition: transform 0.3s ease; transform: translateX($width - $switch-radius + $switch-offset); } diff --git a/src/components/index.ts b/src/components/index.ts index 99db18f..f1e6ad4 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -2,3 +2,6 @@ export * from './Header' export * from './Icon' export * from './Switch' export * from './Card' +export * from './Row' +export * from './Col' +export * from './ButtonSelect' diff --git a/src/containers/Settings/index.tsx b/src/containers/Settings/index.tsx index 4c032ce..ec60523 100644 --- a/src/containers/Settings/index.tsx +++ b/src/containers/Settings/index.tsx @@ -1,21 +1,77 @@ import * as React from 'react' -import { Header, Card } from '@components' +import { Header, Card, Row, Col, Switch, ButtonSelect, ButtonSelectOptions } from '@components' import { translate } from 'react-i18next' import { I18nProps } from '@i18n' +import './style.scss' class Settings extends React.Component { state = { - startAtLogin: false + startAtLogin: false, + language: 'en', + setAsSystemProxy: true, + allowConnectFromLan: true } + languageOptions: ButtonSelectOptions[] = [ + { label: '中文', value: 'zh' }, + { label: 'English', value: 'en' } + ] + render () { const { t } = this.props + const { + startAtLogin, + language, + setAsSystemProxy, + allowConnectFromLan + } = this.state return (
- + + + + {t('labels.startAtLogin')} + + + this.setState({ startAtLogin })} + /> + + + {t('labels.language')} + + + this.setState({ language })} + /> + + + + + {t('labels.setAsSystemProxy')} + + + this.setState({ setAsSystemProxy })} + /> + + + {t('labels.allowConnectFromLan')} + + + this.setState({ allowConnectFromLan })} + /> + +
) diff --git a/src/containers/Settings/style.scss b/src/containers/Settings/style.scss index c53e635..ac13277 100644 --- a/src/containers/Settings/style.scss +++ b/src/containers/Settings/style.scss @@ -1,12 +1,19 @@ @import '~@styles/variables'; -.proxies-list { - margin: 10px 0; - display: flex; - flex-wrap: wrap; - list-style: none; +.settings-card { + margin-top: 25px; + padding: 20px 0; - li { - margin: 20px 15px 20px 0; + .column { + align-items: center; + } + + .value-column { + justify-content: flex-end; + } + + .label { + font-size: 14px; + color: $color-primary-darken; } } diff --git a/src/styles/variables.scss b/src/styles/variables.scss index c940f91..4271d6e 100644 --- a/src/styles/variables.scss +++ b/src/styles/variables.scss @@ -8,7 +8,7 @@ $color-primary: #57befc; $color-primary-dark: #2c8af8; $color-primary-darken: #54759a; $color-primary-light: #7fcae4; -$color-primary-lightly: #b4ddf5; +$color-primary-lightly: #e4eaef; // common colors $color-gray: #d8dee2;