mirror of
https://github.com/woodchen-ink/clash-and-dashboard.git
synced 2025-07-18 22:11:56 +08:00
Add: component <Switch>
This commit is contained in:
parent
0988ca8131
commit
d193373419
36
src/components/Switch/index.tsx
Normal file
36
src/components/Switch/index.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import * as React from 'react'
|
||||||
|
import { BaseComponentProps } from '@models/BaseProps'
|
||||||
|
import { Icon } from '@components'
|
||||||
|
import classnames from 'classnames'
|
||||||
|
import './style.scss'
|
||||||
|
|
||||||
|
interface SwitchProps extends BaseComponentProps {
|
||||||
|
checked: boolean
|
||||||
|
disabled?: boolean
|
||||||
|
onChange?: (checked: boolean) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Switch extends React.Component<SwitchProps, {}> {
|
||||||
|
static defaultProps: SwitchProps = {
|
||||||
|
checked: false,
|
||||||
|
disabled: false,
|
||||||
|
onChange: () => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick = (e: React.MouseEvent<HTMLElement>) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
if (!this.props.disabled) {
|
||||||
|
this.props.onChange(!this.props.checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { className, checked, disabled } = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classnames('switch', { checked, disabled }, className)} onClick={this.handleClick}>
|
||||||
|
<Icon className="switch-icon" type="check" size={8} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
57
src/components/Switch/style.scss
Normal file
57
src/components/Switch/style.scss
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
@import '~@styles/variables';
|
||||||
|
|
||||||
|
$height: 14px;
|
||||||
|
$switch-radius: 16px;
|
||||||
|
$switch-offset: 2px;
|
||||||
|
$width: 28px;
|
||||||
|
|
||||||
|
.switch {
|
||||||
|
display: inline-block;
|
||||||
|
width: $width;
|
||||||
|
height: $height;
|
||||||
|
border-radius: $height / 2;
|
||||||
|
background-color: $color-gray;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.checked {
|
||||||
|
background-color: $color-primary;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
transform: translateX(-$switch-offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
background-color: $color-gray-dark;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.checked.disabled {
|
||||||
|
background-color: $color-primary-lightly;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: ($switch-radius - $height) / -2;
|
||||||
|
height: $switch-radius;
|
||||||
|
width: $switch-radius;
|
||||||
|
border-radius: $switch-radius / 2;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 0 8px rgba($color-primary-dark, 0.25);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
transform: translateX($width - $switch-radius + $switch-offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-icon {
|
||||||
|
position: absolute;
|
||||||
|
right: $switch-offset * 2;
|
||||||
|
color: #fff;
|
||||||
|
line-height: $height;
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
export * from './Header'
|
export * from './Header'
|
||||||
export * from './Icon'
|
export * from './Icon'
|
||||||
export * from './Proxy'
|
export * from './Proxy'
|
||||||
|
export * from './Switch'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user