Skip to content

Commit 7698504

Browse files
authored
Merge pull request #111 from swarajgolu/feature_toggleSwitch
Feature toggle switch
2 parents 49a327f + fb34c4c commit 7698504

3 files changed

Lines changed: 248 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ __build-es
88

99
**/index.js
1010

11+
!__application/**/index.js
12+
1113
CHANGELOG.md
1214

1315
themePrepare_bck.js
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/* eslint-disable jsx-a11y/label-has-associated-control */
2+
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
3+
import React from 'react';
4+
import styled, { css } from 'styled-components';
5+
import PropTypes from 'prop-types';
6+
7+
/*
8+
Toggle Switch Component
9+
Note: id, checked and onChange are required for ToggleSwitch component to function.
10+
The props name, small, disabled
11+
and optionLabels are optional.
12+
Usage: <ToggleSwitch id="id" checked={value} onChange={checked => setValue(checked)}} />
13+
*/
14+
15+
const ToggleWrapper = styled.div`
16+
position: relative;
17+
margin-right: 10px;
18+
width: ${(props) => props.small ? '40px' : '75px'};
19+
display: inline-block;
20+
vertical-align: middle;
21+
-webkit-user-select: none;
22+
-moz-user-select: none;
23+
-ms-user-select: none;
24+
text-align: left;
25+
26+
${(props) => props.small && css`
27+
28+
& .toggle-switch-inner:after {
29+
content: "";
30+
height: 20px;
31+
line-height: 20px;
32+
}
33+
34+
& .toggle-switch-inner:before {
35+
content: "";
36+
height: 20px;
37+
line-height: 20px;
38+
}
39+
40+
& .toggle-switch-switch {
41+
width: 16px;
42+
right: 20px;
43+
margin: 2px;
44+
}
45+
`}
46+
47+
// @media screen and (max-width: 991px) {
48+
// .toggle-switch {
49+
// transform: scale(0.9);
50+
// }
51+
// }
52+
// @media screen and (max-width: 767px) {
53+
// .toggle-switch {
54+
// transform: scale(0.825);
55+
// }
56+
// }
57+
// @media screen and (max-width: 575px) {
58+
// .toggle-switch {
59+
// transform: scale(0.75);
60+
// }
61+
// }
62+
`;
63+
64+
const StyledCheckBox = styled.input.attrs({ type: 'checkbox' })`
65+
display: none;
66+
&:checked {
67+
+ {
68+
.toggle-switch-label {
69+
.toggle-switch-inner {
70+
margin-left: 0;
71+
}
72+
.toggle-switch-switch {
73+
right: 0px;
74+
}
75+
}
76+
}
77+
}
78+
`;
79+
80+
const StyledLabel = styled.label`
81+
display: block;
82+
overflow: hidden;
83+
cursor: pointer;
84+
border: 0 solid #bbb;
85+
border-radius: 20px;
86+
margin: 0;
87+
88+
&:focus {
89+
outline: none;
90+
> span {
91+
box-shadow: 0 0 2px 5px red;
92+
}
93+
}
94+
> span {
95+
&:focus {
96+
outline: none;
97+
}
98+
}
99+
`;
100+
101+
const StyledSwitchInner = styled.span`
102+
display: block;
103+
width: 200%;
104+
margin-left: -100%;
105+
transition: margin 0.3s ease-in 0s;
106+
107+
&:before {
108+
display: block;
109+
float: left;
110+
width: 50%;
111+
height: 34px;
112+
padding: 0;
113+
line-height: 34px;
114+
font-size: 12px;
115+
color: white;
116+
font-weight: bold;
117+
box-sizing: border-box;
118+
content: attr(data-yes);
119+
text-transform: uppercase;
120+
padding-left: 10px;
121+
background-color: #2f855a;
122+
color: #fff;
123+
}
124+
125+
&:after {
126+
display: block;
127+
float: left;
128+
width: 50%;
129+
height: 34px;
130+
padding: 0;
131+
line-height: 34px;
132+
font-size: 12px;
133+
color: white;
134+
font-weight: bold;
135+
box-sizing: border-box;
136+
content: attr(data-no);
137+
text-transform: uppercase;
138+
padding-right: 10px;
139+
background-color: #bbb;
140+
color: #fff;
141+
text-align: right;
142+
}
143+
${(props) => props.disabled && css`
144+
background-color: #ddd;
145+
cursor: not-allowed;
146+
&:before {
147+
background-color: #ddd;
148+
cursor: not-allowed;
149+
}
150+
`}
151+
`;
152+
153+
const StyledSwitchOuter = styled.span`
154+
display: block;
155+
width: 24px;
156+
margin: 5px;
157+
background: #fff;
158+
position: absolute;
159+
top: 0;
160+
bottom: 0;
161+
right: 40px;
162+
border: 0 solid #bbb;
163+
border-radius: 20px;
164+
transition: all 0.3s ease-in 0s;
165+
${(props) => props.disabled && css`
166+
background-color: #ddd;
167+
cursor: not-allowed;
168+
&:before {
169+
background-color: #ddd;
170+
cursor: not-allowed;
171+
}
172+
`}
173+
`;
174+
175+
function ToggleSwitch({
176+
id,
177+
name,
178+
checked,
179+
onChange,
180+
optionLabels,
181+
small,
182+
disabled,
183+
}) {
184+
function handleKeyPress(e) {
185+
if (e.keyCode !== 32) return;
186+
187+
e.preventDefault();
188+
onChange(!checked);
189+
}
190+
191+
return (
192+
<ToggleWrapper small={small}>
193+
<StyledCheckBox
194+
name={name}
195+
id={id}
196+
checked={checked}
197+
onChange={(e) => onChange(e.target.checked)}
198+
disabled={disabled}
199+
/>
200+
{id ? (
201+
<StyledLabel
202+
tabIndex={disabled ? -1 : 1}
203+
onKeyDown={(e) => handleKeyPress(e)}
204+
htmlFor={id}
205+
className="toggle-switch-label"
206+
>
207+
<StyledSwitchInner
208+
disabled={disabled}
209+
data-yes={optionLabels[0]}
210+
data-no={optionLabels[1]}
211+
tabIndex={-1}
212+
className="toggle-switch-inner"
213+
/>
214+
<StyledSwitchOuter
215+
tabIndex={-1}
216+
disabled={disabled}
217+
className="toggle-switch-switch"
218+
/>
219+
</StyledLabel>
220+
) : null}
221+
</ToggleWrapper>
222+
);
223+
}
224+
225+
// Set optionLabels for rendering.
226+
ToggleSwitch.defaultProps = {
227+
optionLabels: ['Yes', 'No'],
228+
name: 'switch',
229+
small: false,
230+
disabled: false,
231+
};
232+
233+
ToggleSwitch.propTypes = {
234+
id: PropTypes.string.isRequired,
235+
checked: PropTypes.bool.isRequired,
236+
onChange: PropTypes.func.isRequired,
237+
name: PropTypes.string,
238+
optionLabels: PropTypes.array,
239+
small: PropTypes.bool,
240+
disabled: PropTypes.bool,
241+
};
242+
243+
export default ToggleSwitch;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import ToggleSwitch from './ToggleSwitch/ToggleSwitch';
2+
3+
export default ToggleSwitch;

0 commit comments

Comments
 (0)