diff --git a/src/components/Switch/index.tsx b/src/components/Switch/index.tsx new file mode 100644 index 0000000..a0be627 --- /dev/null +++ b/src/components/Switch/index.tsx @@ -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 { + static defaultProps: SwitchProps = { + checked: false, + disabled: false, + onChange: () => {} + } + + handleClick = (e: React.MouseEvent) => { + e.stopPropagation() + if (!this.props.disabled) { + this.props.onChange(!this.props.checked) + } + } + + render () { + const { className, checked, disabled } = this.props + + return ( +
+ +
+ ) + } +} diff --git a/src/components/Switch/style.scss b/src/components/Switch/style.scss new file mode 100644 index 0000000..0d75a19 --- /dev/null +++ b/src/components/Switch/style.scss @@ -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; +} diff --git a/src/components/index.ts b/src/components/index.ts index a6d28f8..6f8fc28 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,3 +1,4 @@ export * from './Header' export * from './Icon' export * from './Proxy' +export * from './Switch'