summaryrefslogtreecommitdiffhomepage
path: root/gui/src/renderer/components/Switch.tsx
blob: e5aaec4bb0bb86c92c1c13317af552ee90602523 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import React from 'react';
import styled from 'styled-components';

import { colors } from '../../config.json';

interface IProps {
  id?: string;
  'aria-labelledby'?: string;
  'aria-describedby'?: string;
  isOn: boolean;
  onChange?: (isOn: boolean) => void;
  className?: string;
  disabled?: boolean;
  innerRef?: React.Ref<HTMLDivElement>;
}

const SwitchContainer = styled.div<{ disabled: boolean }>((props) => ({
  position: 'relative',
  width: '48px',
  height: '30px',
  borderColor: props.disabled ? colors.white20 : colors.white80,
  borderWidth: '2px',
  borderStyle: 'solid',
  borderRadius: '16px',
  padding: '2px',
}));

const Knob = styled.div<{ $isOn: boolean; disabled: boolean }>((props) => {
  let backgroundColor = props.$isOn ? colors.green : colors.red;
  if (props.disabled) {
    backgroundColor = props.$isOn ? colors.green40 : colors.red40;
  }

  return {
    position: 'absolute',
    height: '22px',
    borderRadius: '11px',
    transition: 'all 200ms linear',
    width: '22px',
    backgroundColor,
    // When enabled the button should be placed all the way to the right (100%) minus padding (2px)
    // minus it's own width (22px).
    left: props.$isOn ? 'calc(100% - 2px - 22px)' : '2px',
  };
});

export default class Switch extends React.PureComponent<IProps> {
  public render() {
    return (
      <SwitchContainer
        ref={this.props.innerRef}
        id={this.props.id}
        role="checkbox"
        aria-labelledby={this.props['aria-labelledby']}
        aria-describedby={this.props['aria-describedby']}
        aria-checked={this.props.isOn}
        onClick={this.handleClick}
        disabled={this.props.disabled ?? false}
        aria-disabled={this.props.disabled ?? false}
        tabIndex={-1}
        className={this.props.className}>
        <Knob disabled={this.props.disabled ?? false} $isOn={this.props.isOn} />
      </SwitchContainer>
    );
  }

  private handleClick = () => {
    if (!this.props.disabled) {
      this.props.onChange?.(!this.props.isOn);
    }
  };
}