mirror of
https://github.com/woodchen-ink/clash-and-dashboard.git
synced 2025-07-18 14:01:56 +08:00
Migration: base component
This commit is contained in:
parent
658a26c2fc
commit
73d992ae94
1306
package-lock.json
generated
1306
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
30
package.json
30
package.json
@ -33,11 +33,11 @@
|
||||
"@babel/preset-env": "^7.4.5",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@types/classnames": "^2.2.8",
|
||||
"@types/node": "^12.0.8",
|
||||
"@types/react": "^16.8.19",
|
||||
"@types/node": "^12.0.10",
|
||||
"@types/react": "^16.8.22",
|
||||
"@types/react-dom": "^16.8.4",
|
||||
"@types/react-i18next": "^8.1.0",
|
||||
"@types/react-router-dom": "^4.3.3",
|
||||
"@types/react-router-dom": "^4.3.4",
|
||||
"@types/react-sortable-hoc": "^0.6.5",
|
||||
"@types/react-virtualized": "^9.21.2",
|
||||
"@types/yaml": "^1.0.2",
|
||||
@ -53,20 +53,20 @@
|
||||
"offline-plugin": "^5.0.7",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"react-addons-test-utils": "^15.6.2",
|
||||
"react-hot-loader": "^4.11.0",
|
||||
"sass": "^1.21.0",
|
||||
"react-hot-loader": "^4.12.0",
|
||||
"sass": "^1.22.2",
|
||||
"sass-loader": "^7.1.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"stylelint": "^10.1.0",
|
||||
"stylelint-config-standard": "^18.3.0",
|
||||
"stylelint-webpack-plugin": "^0.10.5",
|
||||
"tslint": "^5.17.0",
|
||||
"tslint": "^5.18.0",
|
||||
"tslint-config-standard": "^8.0.1",
|
||||
"tslint-loader": "^3.6.0",
|
||||
"webpack": "^4.33.0",
|
||||
"webpack-cli": "^3.3.4",
|
||||
"webpack": "^4.35.2",
|
||||
"webpack-cli": "^3.3.5",
|
||||
"webpack-dev-middleware": "^3.7.0",
|
||||
"webpack-dev-server": "^3.7.1",
|
||||
"webpack-dev-server": "^3.7.2",
|
||||
"webpack-merge": "^4.2.1",
|
||||
"webpack-pwa-manifest": "^4.0.0"
|
||||
},
|
||||
@ -74,20 +74,20 @@
|
||||
"axios": "^0.19.0",
|
||||
"classnames": "^2.2.6",
|
||||
"dayjs": "^1.8.14",
|
||||
"eventemitter3": "^3.1.2",
|
||||
"i18next": "^11.10.0",
|
||||
"i18next-browser-languagedetector": "^2.2.4",
|
||||
"eventemitter3": "^4.0.0",
|
||||
"i18next": "^17.0.6",
|
||||
"i18next-browser-languagedetector": "^3.0.1",
|
||||
"mobx": "^5.10.1",
|
||||
"mobx-react": "^6.0.3",
|
||||
"mobx-react": "^6.1.1",
|
||||
"mobx-react-router": "^4.0.7",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-i18next": "^7.12.0",
|
||||
"react-i18next": "^10.11.2",
|
||||
"react-router-dom": "^5.0.1",
|
||||
"react-sortable-hoc": "^1.9.1",
|
||||
"react-virtualized": "^9.21.1",
|
||||
"terser-webpack-plugin": "^1.3.0",
|
||||
"typescript": "^3.5.1",
|
||||
"typescript": "^3.5.2",
|
||||
"yaml": "^1.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -10,28 +10,20 @@ interface AlertProps extends BaseComponentProps {
|
||||
inside?: boolean
|
||||
}
|
||||
|
||||
export class Alert extends React.Component<AlertProps, {}> {
|
||||
|
||||
static defaultProps: AlertProps = {
|
||||
message: '',
|
||||
type: 'info',
|
||||
inside: false
|
||||
}
|
||||
|
||||
iconMap = {
|
||||
const iconMap = {
|
||||
success: 'check',
|
||||
info: 'info',
|
||||
warning: 'info',
|
||||
error: 'close'
|
||||
}
|
||||
|
||||
render () {
|
||||
const { message, type, inside, children, className, style } = this.props
|
||||
}
|
||||
|
||||
export function Alert (props: AlertProps) {
|
||||
const { message = '', type = 'info', inside = false, children, className, style } = props
|
||||
const classname = classnames('alert', `alert-${inside ? 'note' : 'box'}-${type}`, className)
|
||||
return (
|
||||
<div className={classnames('alert', `alert-${inside ? 'note' : 'box'}-${type}`, className)} style={style}>
|
||||
<div className={classname} style={style}>
|
||||
<span className="alert-icon">
|
||||
<Icon type={this.iconMap[type]} size={26} />
|
||||
<Icon type={iconMap[type]} size={26} />
|
||||
</span>
|
||||
{
|
||||
message
|
||||
@ -40,6 +32,4 @@ export class Alert extends React.Component<AlertProps, {}> {
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import * as React from 'react'
|
||||
import classnames from 'classnames'
|
||||
import { BaseComponentProps } from '@models'
|
||||
import { noop } from '@lib/helper'
|
||||
import './style.scss'
|
||||
|
||||
interface ButtonProps extends BaseComponentProps {
|
||||
@ -8,23 +9,15 @@ interface ButtonProps extends BaseComponentProps {
|
||||
onClick?: React.MouseEventHandler<HTMLButtonElement>
|
||||
}
|
||||
|
||||
export class Button extends React.Component<ButtonProps, {}> {
|
||||
|
||||
static defaultProps: ButtonProps = {
|
||||
type: 'normal',
|
||||
onClick: () => {}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { type, onClick, children, className, style } = this.props
|
||||
export function Button (props: ButtonProps) {
|
||||
const { type = 'normal', onClick = noop, children, className, style } = props
|
||||
const classname = classnames('button', `button-${type}`, className)
|
||||
|
||||
return (
|
||||
<button
|
||||
className={classnames('button', `button-${type}`, className)}
|
||||
className={classname}
|
||||
style={style}
|
||||
onClick={onClick}
|
||||
>{children}</button>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,10 +19,8 @@ export interface ButtonSelectProps extends BaseComponentProps {
|
||||
onSelect?: (value: any) => void
|
||||
}
|
||||
|
||||
export class ButtonSelect extends React.Component<ButtonSelectProps, {}> {
|
||||
|
||||
render () {
|
||||
const { options, value, onSelect } = this.props
|
||||
export function ButtonSelect (props: ButtonSelectProps) {
|
||||
const { options, value, onSelect } = props
|
||||
|
||||
return (
|
||||
<div className="button-select">
|
||||
@ -39,6 +37,4 @@ export class ButtonSelect extends React.Component<ButtonSelectProps, {}> {
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import * as React from 'react'
|
||||
import { BaseComponentProps } from '@models/BaseProps'
|
||||
import { noop } from '@lib/helper'
|
||||
import classnames from 'classnames'
|
||||
import './style.scss'
|
||||
|
||||
interface InputProps extends BaseComponentProps {
|
||||
value?: string | number
|
||||
disabled?: boolean
|
||||
align?: 'left' | 'center' | 'right'
|
||||
inside?: boolean
|
||||
autoFocus?: boolean
|
||||
@ -14,34 +14,23 @@ interface InputProps extends BaseComponentProps {
|
||||
onBlur?: (event?: React.FocusEvent<HTMLInputElement>) => void
|
||||
}
|
||||
|
||||
export class Input extends React.Component<InputProps, {}> {
|
||||
static defaultProps: InputProps = {
|
||||
value: '',
|
||||
disabled: false,
|
||||
align: 'center',
|
||||
inside: false,
|
||||
autoFocus: false,
|
||||
type: 'text',
|
||||
onChange: () => {},
|
||||
onBlur: () => {}
|
||||
}
|
||||
|
||||
render () {
|
||||
export function Input (props: InputProps) {
|
||||
const {
|
||||
className,
|
||||
style,
|
||||
value,
|
||||
align,
|
||||
inside,
|
||||
autoFocus,
|
||||
type,
|
||||
onChange,
|
||||
onBlur
|
||||
} = this.props
|
||||
value = '',
|
||||
align = 'center',
|
||||
inside = false,
|
||||
autoFocus = false,
|
||||
type = 'text',
|
||||
onChange = noop,
|
||||
onBlur = noop
|
||||
} = props
|
||||
const classname = classnames('input', `input-align-${align}`, { 'input-inside': inside }, className)
|
||||
|
||||
return (
|
||||
<input
|
||||
className={classnames('input', `input-align-${align}`, { 'input-inside': inside }, className)}
|
||||
className={classname}
|
||||
style={style}
|
||||
value={value}
|
||||
autoFocus={autoFocus}
|
||||
@ -50,5 +39,4 @@ export class Input extends React.Component<InputProps, {}> {
|
||||
onBlur={onBlur}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import * as React from 'react'
|
||||
import { BaseComponentProps } from '@models/BaseProps'
|
||||
import { Icon } from '@components'
|
||||
import { noop } from '@lib/helper'
|
||||
import classnames from 'classnames'
|
||||
import './style.scss'
|
||||
|
||||
@ -10,26 +11,19 @@ interface SwitchProps extends BaseComponentProps {
|
||||
onChange?: (checked: boolean) => void
|
||||
}
|
||||
|
||||
export class Switch extends React.Component<SwitchProps, {}> {
|
||||
static defaultProps: SwitchProps = {
|
||||
checked: false,
|
||||
disabled: false,
|
||||
onChange: () => {}
|
||||
}
|
||||
export function Switch (props: SwitchProps) {
|
||||
const { className, checked = false, disabled = false, onChange = noop } = props
|
||||
const classname = classnames('switch', { checked, disabled }, className)
|
||||
|
||||
handleClick = () => {
|
||||
if (!this.props.disabled) {
|
||||
this.props.onChange(!this.props.checked)
|
||||
function handleClick () {
|
||||
if (!disabled) {
|
||||
onChange(!checked)
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { className, checked, disabled } = this.props
|
||||
|
||||
return (
|
||||
<div className={classnames('switch', { checked, disabled }, className)} onClick={this.handleClick}>
|
||||
<div className={classname} onClick={handleClick}>
|
||||
<Icon className="switch-icon" type="check" size={20} style={{ fontWeight: 'bold' }} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as React from 'react'
|
||||
import { translate } from 'react-i18next'
|
||||
import React, { useState, useRef, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { BaseComponentProps, I18nProps } from '@models'
|
||||
import { noop } from '@lib/helper'
|
||||
import classnames from 'classnames'
|
||||
@ -13,33 +13,22 @@ interface TagsProps extends BaseComponentProps, I18nProps {
|
||||
canClick: boolean
|
||||
}
|
||||
|
||||
interface TagsState {
|
||||
expand: boolean
|
||||
showExtend: boolean
|
||||
ulRef: React.RefObject<HTMLUListElement>
|
||||
}
|
||||
export function Tags (props: TagsProps) {
|
||||
const { className, data, onClick, select, canClick } = props
|
||||
|
||||
class TagsClass extends React.Component<TagsProps, TagsState> {
|
||||
state: TagsState = {
|
||||
expand: false,
|
||||
showExtend: true,
|
||||
ulRef: React.createRef<HTMLUListElement>()
|
||||
}
|
||||
const { t } = useTranslation()
|
||||
const [expand, setExpand] = useState(false)
|
||||
|
||||
toggleExtend = () => {
|
||||
this.setState({ expand: !this.state.expand })
|
||||
}
|
||||
const ulRef = useRef<HTMLUListElement>()
|
||||
const showExtend = useMemo(() => ulRef.current.offsetHeight > 30, [ulRef])
|
||||
|
||||
componentDidMount () {
|
||||
this.setState({ showExtend: this.state.ulRef.current.offsetHeight > 30 })
|
||||
}
|
||||
|
||||
render () {
|
||||
const { t, className, data, onClick, select, canClick } = this.props
|
||||
const { expand } = this.state
|
||||
const rowHeight = this.state.expand ? 'auto' : this.props.rowHeight
|
||||
const handleClick = canClick ? onClick : noop
|
||||
|
||||
function toggleExtend () {
|
||||
setExpand(!expand)
|
||||
}
|
||||
|
||||
const tags = data
|
||||
.map(t => {
|
||||
const tagClass = classnames({ 'tags-selected': select === t, 'can-click': canClick })
|
||||
@ -52,16 +41,13 @@ class TagsClass extends React.Component<TagsProps, TagsState> {
|
||||
|
||||
return (
|
||||
<div className={classnames('tags-container', className)} style={{ height: rowHeight }}>
|
||||
<ul ref={this.state.ulRef} className={classnames('tags', { expand })}>
|
||||
<ul ref={ulRef} className={classnames('tags', { expand })}>
|
||||
{ tags }
|
||||
</ul>
|
||||
{
|
||||
this.state.showExtend &&
|
||||
<span className="tags-expand" onClick={this.toggleExtend}>{ this.state.expand ? t('collapseText') : t('expandText') }</span>
|
||||
showExtend &&
|
||||
<span className="tags-expand" onClick={toggleExtend}>{ expand ? t('collapseText') : t('expandText') }</span>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const Tags = translate(['Proxies'])(TagsClass)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as React from 'react'
|
||||
import { translate } from 'react-i18next'
|
||||
import { withTranslation } from 'react-i18next'
|
||||
import { inject, observer } from 'mobx-react'
|
||||
import { storeKeys } from '@lib/createStore'
|
||||
import { Modal, Input, Row, Col, Alert } from '@components'
|
||||
@ -93,4 +93,4 @@ class ExternalController extends React.Component<ExternalControllerModalProps, E
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(['Settings'])(ExternalController)
|
||||
export default withTranslation(['Settings'])(ExternalController)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as EventEmitter from 'eventemitter3'
|
||||
import EventEmitter from 'eventemitter3'
|
||||
|
||||
export enum Action {
|
||||
SPEED_NOTIFY = 'speed-notify'
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { to } from '@lib/helper'
|
||||
import * as EventEmitter from 'eventemitter3'
|
||||
import EventEmitter from 'eventemitter3'
|
||||
|
||||
export interface Config {
|
||||
url: string
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { CSSProperties } from 'react'
|
||||
import { CSSProperties, ReactNode } from 'react'
|
||||
import { RouteComponentProps } from 'react-router'
|
||||
import { RouterStore, ConfigStore } from '@stores'
|
||||
|
||||
@ -19,5 +19,6 @@ export interface BaseProps extends BaseComponentProps {
|
||||
|
||||
export interface BaseComponentProps {
|
||||
className?: string
|
||||
children?: ReactNode
|
||||
style?: CSSProperties
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
"noImplicitAny": false,
|
||||
"noUnusedLocals": true,
|
||||
"module": "commonjs",
|
||||
|
Loading…
x
Reference in New Issue
Block a user