aboutsummaryrefslogtreecommitdiffstats
path: root/packages/forms/src/toggle/index.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/forms/src/toggle/index.tsx')
-rw-r--r--packages/forms/src/toggle/index.tsx117
1 files changed, 117 insertions, 0 deletions
diff --git a/packages/forms/src/toggle/index.tsx b/packages/forms/src/toggle/index.tsx
new file mode 100644
index 000000000..6487f1d07
--- /dev/null
+++ b/packages/forms/src/toggle/index.tsx
@@ -0,0 +1,117 @@
1import { Theme } from '@meetfranz/theme';
2import classnames from 'classnames';
3import CSS from 'csstype';
4import React, { Component, createRef } from 'react';
5import injectStyle from 'react-jss';
6
7import { IFormField, IWithStyle, Omit } from '../typings/generic';
8
9import { Error } from '../error';
10import { Label } from '../label';
11import { Wrapper } from '../wrapper';
12
13interface IProps extends React.InputHTMLAttributes<HTMLInputElement>, IFormField, IWithStyle {
14 className?: string;
15}
16
17const styles = (theme: Theme) => ({
18 toggle: {
19 background: theme.toggleBackground,
20 borderRadius: theme.borderRadius,
21 height: theme.toggleHeight,
22 position: 'relative' as CSS.PositionProperty,
23 width: theme.toggleWidth,
24 },
25 button: {
26 background: theme.toggleButton,
27 borderRadius: '100%',
28 boxShadow: '0 1px 4px rgba(0, 0, 0, .3)',
29 width: theme.toggleHeight - 2,
30 height: theme.toggleHeight - 2,
31 left: 1,
32 top: 1,
33 position: 'absolute' as CSS.PositionProperty,
34 transition: 'all .5s',
35 },
36 buttonActive: {
37 background: theme.toggleButtonActive,
38 left: (theme.toggleWidth - theme.toggleHeight) + 1,
39 },
40 input: {
41 visibility: 'hidden' as any,
42 },
43 disabled: {
44 opacity: theme.inputDisabledOpacity,
45 },
46 toggleLabel: {
47 display: 'flex',
48
49 '& > span': {
50 order: 1,
51 marginLeft: 15,
52 marginTop: 2,
53 },
54 },
55});
56
57class ToggleComponent extends Component<IProps> {
58 public static defaultProps = {
59 onChange: () => {},
60 showLabel: true,
61 disabled: false,
62 error: '',
63 };
64
65 render() {
66 const {
67 classes,
68 className,
69 disabled,
70 error,
71 id,
72 label,
73 showLabel,
74 checked,
75 value,
76 onChange,
77 } = this.props;
78
79 return (
80 <Wrapper
81 className={className}
82 identifier="franz-toggle"
83 >
84 <Label
85 title={label}
86 showLabel={showLabel}
87 htmlFor={id}
88 className={classes.toggleLabel}
89 >
90 <div className={classnames({
91 [`${classes.toggle}`]: true,
92 [`${classes.disabled}`]: disabled,
93 })}>
94 <div className={classnames({
95 [`${classes.button}`]: true,
96 [`${classes.buttonActive}`]: checked,
97 })} />
98 <input
99 className={classes.input}
100 id={id || name}
101 type="checkbox"
102 checked={checked}
103 value={value}
104 onChange={onChange}
105 disabled={disabled}
106 />
107 </div>
108 </Label>
109 {error && (
110 <Error message={error} />
111 )}
112 </Wrapper>
113 );
114 }
115}
116
117export const Toggle = injectStyle(styles)(ToggleComponent);