@khanacademy/wonder-blocks-switch 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/components/switch.d.ts +1 -1
- package/dist/es/index.js +176 -81
- package/dist/index.js +175 -84
- package/dist/themes/default.d.ts +62 -0
- package/dist/themes/khanmigo.d.ts +65 -0
- package/dist/themes/themed-switch.d.ts +80 -0
- package/package.json +4 -5
- package/src/components/__tests__/switch.test.tsx +33 -14
- package/src/components/switch.tsx +123 -99
- package/src/themes/default.ts +73 -0
- package/src/themes/khanmigo.ts +28 -0
- package/src/themes/themed-switch.tsx +42 -0
- package/tsconfig-build.json +1 -0
- package/tsconfig-build.tsbuildinfo +1 -1
package/dist/index.js
CHANGED
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
var React = require('react');
|
|
4
4
|
var aphrodite = require('aphrodite');
|
|
5
5
|
var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
|
|
6
|
-
var
|
|
7
|
-
var Spacing = require('@khanacademy/wonder-blocks-spacing');
|
|
8
|
-
|
|
9
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
6
|
+
var wonderBlocksTheming = require('@khanacademy/wonder-blocks-theming');
|
|
10
7
|
|
|
11
8
|
function _interopNamespace(e) {
|
|
12
9
|
if (e && e.__esModule) return e;
|
|
@@ -27,8 +24,6 @@ function _interopNamespace(e) {
|
|
|
27
24
|
}
|
|
28
25
|
|
|
29
26
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
30
|
-
var Color__default = /*#__PURE__*/_interopDefaultLegacy(Color);
|
|
31
|
-
var Spacing__default = /*#__PURE__*/_interopDefaultLegacy(Spacing);
|
|
32
27
|
|
|
33
28
|
function _extends() {
|
|
34
29
|
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
@@ -45,9 +40,105 @@ function _extends() {
|
|
|
45
40
|
return _extends.apply(this, arguments);
|
|
46
41
|
}
|
|
47
42
|
|
|
43
|
+
const theme$1 = {
|
|
44
|
+
color: {
|
|
45
|
+
bg: {
|
|
46
|
+
switch: {
|
|
47
|
+
off: wonderBlocksTheming.tokens.color.offBlack50,
|
|
48
|
+
disabledOff: wonderBlocksTheming.tokens.color.offBlack32,
|
|
49
|
+
activeOff: wonderBlocksTheming.tokens.color.offBlack64,
|
|
50
|
+
on: wonderBlocksTheming.tokens.color.blue,
|
|
51
|
+
disabledOn: wonderBlocksTheming.tokens.color.fadedBlue,
|
|
52
|
+
activeOn: wonderBlocksTheming.tokens.color.activeBlue
|
|
53
|
+
},
|
|
54
|
+
slider: {
|
|
55
|
+
on: wonderBlocksTheming.tokens.color.white,
|
|
56
|
+
off: wonderBlocksTheming.tokens.color.white
|
|
57
|
+
},
|
|
58
|
+
icon: {
|
|
59
|
+
on: wonderBlocksTheming.tokens.color.blue,
|
|
60
|
+
disabledOn: wonderBlocksTheming.tokens.color.fadedBlue,
|
|
61
|
+
off: wonderBlocksTheming.tokens.color.offBlack50,
|
|
62
|
+
disabledOff: wonderBlocksTheming.tokens.color.offBlack32
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
outline: {
|
|
66
|
+
default: wonderBlocksTheming.tokens.color.blue
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
border: {
|
|
70
|
+
radius: {
|
|
71
|
+
small: wonderBlocksTheming.tokens.spacing.small_12,
|
|
72
|
+
full: wonderBlocksTheming.tokens.border.radius.full
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
size: {
|
|
76
|
+
height: {
|
|
77
|
+
none: 0,
|
|
78
|
+
medium: 20,
|
|
79
|
+
large: wonderBlocksTheming.tokens.spacing.large_24
|
|
80
|
+
},
|
|
81
|
+
width: {
|
|
82
|
+
none: 0,
|
|
83
|
+
small: wonderBlocksTheming.tokens.spacing.xxxxSmall_2,
|
|
84
|
+
medium: 20,
|
|
85
|
+
large: 40
|
|
86
|
+
},
|
|
87
|
+
offset: {
|
|
88
|
+
default: 1
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
spacing: {
|
|
92
|
+
slider: {
|
|
93
|
+
position: wonderBlocksTheming.tokens.spacing.xxxxSmall_2
|
|
94
|
+
},
|
|
95
|
+
icon: {
|
|
96
|
+
position: wonderBlocksTheming.tokens.spacing.xxxSmall_4
|
|
97
|
+
},
|
|
98
|
+
transform: {
|
|
99
|
+
default: `translateX(${wonderBlocksTheming.tokens.spacing.medium_16}px)`,
|
|
100
|
+
transition: "transform 0.15s ease-in-out"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const theme = wonderBlocksTheming.mergeTheme(theme$1, {
|
|
106
|
+
color: {
|
|
107
|
+
bg: {
|
|
108
|
+
switch: {
|
|
109
|
+
off: wonderBlocksTheming.tokens.color.white50,
|
|
110
|
+
disabledOff: wonderBlocksTheming.tokens.color.white32,
|
|
111
|
+
activeOff: wonderBlocksTheming.tokens.color.white50,
|
|
112
|
+
disabledOn: wonderBlocksTheming.tokens.color.activeBlue
|
|
113
|
+
},
|
|
114
|
+
slider: {
|
|
115
|
+
off: wonderBlocksTheming.tokens.color.eggplant
|
|
116
|
+
},
|
|
117
|
+
icon: {
|
|
118
|
+
off: wonderBlocksTheming.tokens.color.white,
|
|
119
|
+
disabledOff: wonderBlocksTheming.tokens.color.white50,
|
|
120
|
+
disabledOn: wonderBlocksTheming.tokens.color.activeBlue
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const themes = {
|
|
127
|
+
default: theme$1,
|
|
128
|
+
khanmigo: theme
|
|
129
|
+
};
|
|
130
|
+
const SwitchThemeContext = wonderBlocksTheming.createThemeContext(theme$1);
|
|
131
|
+
function ThemedSwitch(props) {
|
|
132
|
+
const currentTheme = React__namespace.useContext(wonderBlocksTheming.ThemeSwitcherContext);
|
|
133
|
+
const theme = themes[currentTheme] || theme$1;
|
|
134
|
+
return React__namespace.createElement(SwitchThemeContext.Provider, {
|
|
135
|
+
value: theme
|
|
136
|
+
}, props.children);
|
|
137
|
+
}
|
|
138
|
+
|
|
48
139
|
const StyledSpan = wonderBlocksCore.addStyle("span");
|
|
49
140
|
const StyledInput = wonderBlocksCore.addStyle("input");
|
|
50
|
-
const
|
|
141
|
+
const SwitchCore = React__namespace.forwardRef(function SwitchCore(props, ref) {
|
|
51
142
|
const {
|
|
52
143
|
"aria-label": ariaLabel,
|
|
53
144
|
"aria-labelledby": ariaLabelledBy,
|
|
@@ -59,64 +150,67 @@ const Switch = React__namespace.forwardRef(function Switch(props, ref) {
|
|
|
59
150
|
onChange,
|
|
60
151
|
testId
|
|
61
152
|
} = props;
|
|
153
|
+
const ids = wonderBlocksCore.useUniqueIdWithMock("labeled-field");
|
|
154
|
+
const uniqueId = id != null ? id : ids.get("labeled-field-id");
|
|
155
|
+
const {
|
|
156
|
+
theme,
|
|
157
|
+
themeName
|
|
158
|
+
} = wonderBlocksTheming.useScopedTheme(SwitchThemeContext);
|
|
159
|
+
const sharedStyles = wonderBlocksTheming.useStyles(themedSharedStyles, theme);
|
|
62
160
|
const handleClick = () => {
|
|
63
161
|
if (!disabled && onChange) {
|
|
64
162
|
onChange(!checked);
|
|
65
163
|
}
|
|
66
164
|
};
|
|
67
165
|
const handleChange = () => {};
|
|
68
|
-
const stateStyles = _generateStyles(checked,
|
|
166
|
+
const stateStyles = _generateStyles(checked, onChange !== undefined, disabled, theme, themeName);
|
|
69
167
|
let styledIcon;
|
|
70
168
|
if (icon) {
|
|
71
|
-
styledIcon = React__namespace.cloneElement(icon,
|
|
169
|
+
styledIcon = React__namespace.cloneElement(icon, {
|
|
72
170
|
size: "small",
|
|
73
171
|
style: [sharedStyles.icon, stateStyles.icon],
|
|
74
172
|
"aria-hidden": true
|
|
75
|
-
}
|
|
173
|
+
});
|
|
76
174
|
}
|
|
77
|
-
return React__namespace.createElement(wonderBlocksCore.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
style: sharedStyles.hidden,
|
|
97
|
-
type: "checkbox"
|
|
98
|
-
}), icon && styledIcon, React__namespace.createElement(StyledSpan, {
|
|
99
|
-
style: [sharedStyles.slider, stateStyles.slider]
|
|
100
|
-
}));
|
|
101
|
-
});
|
|
175
|
+
return React__namespace.createElement(wonderBlocksCore.View, {
|
|
176
|
+
onClick: handleClick,
|
|
177
|
+
style: [sharedStyles.switch, stateStyles.switch, disabled && sharedStyles.disabled],
|
|
178
|
+
testId: testId
|
|
179
|
+
}, React__namespace.createElement(StyledInput, {
|
|
180
|
+
"aria-describedby": ariaDescribedBy,
|
|
181
|
+
"aria-label": ariaLabel,
|
|
182
|
+
"aria-labelledby": ariaLabelledBy,
|
|
183
|
+
checked: checked,
|
|
184
|
+
disabled: disabled,
|
|
185
|
+
id: uniqueId,
|
|
186
|
+
onChange: handleChange,
|
|
187
|
+
ref: ref,
|
|
188
|
+
role: "switch",
|
|
189
|
+
style: sharedStyles.hidden,
|
|
190
|
+
type: "checkbox"
|
|
191
|
+
}), icon && styledIcon, React__namespace.createElement(StyledSpan, {
|
|
192
|
+
style: [sharedStyles.slider, stateStyles.slider]
|
|
193
|
+
}));
|
|
102
194
|
});
|
|
103
|
-
const
|
|
195
|
+
const themedSharedStyles = theme => ({
|
|
104
196
|
hidden: {
|
|
105
197
|
opacity: 0,
|
|
106
|
-
height:
|
|
107
|
-
width:
|
|
198
|
+
height: theme.size.height.none,
|
|
199
|
+
width: theme.size.width.none
|
|
108
200
|
},
|
|
109
201
|
switch: {
|
|
110
202
|
display: "inline-flex",
|
|
111
|
-
height:
|
|
112
|
-
width:
|
|
113
|
-
borderRadius:
|
|
203
|
+
height: theme.size.height.large,
|
|
204
|
+
width: theme.size.width.large,
|
|
205
|
+
borderRadius: theme.border.radius.small,
|
|
114
206
|
flexShrink: 0,
|
|
115
|
-
cursor: "pointer",
|
|
116
207
|
":hover": {
|
|
117
|
-
outlineOffset:
|
|
208
|
+
outlineOffset: theme.size.offset.default
|
|
118
209
|
},
|
|
119
|
-
|
|
210
|
+
":focus-within": {
|
|
211
|
+
outline: `solid ${theme.size.width.small}px ${theme.color.outline.default}`,
|
|
212
|
+
outlineOffset: theme.size.offset.default
|
|
213
|
+
}
|
|
120
214
|
},
|
|
121
215
|
disabled: {
|
|
122
216
|
cursor: "auto",
|
|
@@ -126,78 +220,75 @@ const sharedStyles = aphrodite.StyleSheet.create({
|
|
|
126
220
|
},
|
|
127
221
|
slider: {
|
|
128
222
|
position: "absolute",
|
|
129
|
-
top:
|
|
130
|
-
left:
|
|
131
|
-
height:
|
|
132
|
-
width:
|
|
133
|
-
borderRadius:
|
|
134
|
-
backgroundColor:
|
|
135
|
-
transition:
|
|
223
|
+
top: theme.spacing.slider.position,
|
|
224
|
+
left: theme.spacing.slider.position,
|
|
225
|
+
height: theme.size.height.medium,
|
|
226
|
+
width: theme.size.width.medium,
|
|
227
|
+
borderRadius: theme.border.radius.full,
|
|
228
|
+
backgroundColor: theme.color.bg.slider.on,
|
|
229
|
+
transition: theme.spacing.transform.transition
|
|
136
230
|
},
|
|
137
231
|
icon: {
|
|
138
232
|
position: "absolute",
|
|
139
|
-
top:
|
|
140
|
-
left:
|
|
233
|
+
top: theme.spacing.icon.position,
|
|
234
|
+
left: theme.spacing.icon.position,
|
|
141
235
|
zIndex: 1,
|
|
142
|
-
transition:
|
|
143
|
-
transitionProperty: "transform, color"
|
|
236
|
+
transition: theme.spacing.transform.transition
|
|
144
237
|
}
|
|
145
238
|
});
|
|
146
239
|
const styles = {};
|
|
147
|
-
const _generateStyles = (checked, disabled,
|
|
148
|
-
const checkedStyle = `${checked}-${disabled}-${
|
|
240
|
+
const _generateStyles = (checked, clickable, disabled, theme, themeName) => {
|
|
241
|
+
const checkedStyle = `${checked}-${clickable}-${disabled}-${themeName}`;
|
|
149
242
|
if (styles[checkedStyle]) {
|
|
150
243
|
return styles[checkedStyle];
|
|
151
244
|
}
|
|
152
245
|
let newStyles = {};
|
|
153
|
-
const
|
|
154
|
-
|
|
246
|
+
const sharedSwitchStyles = {
|
|
247
|
+
cursor: clickable ? "pointer" : "auto",
|
|
248
|
+
":hover": {
|
|
249
|
+
outline: clickable ? `solid ${theme.size.width.small}px ${theme.color.outline.default}` : "none"
|
|
250
|
+
}
|
|
251
|
+
};
|
|
155
252
|
if (checked) {
|
|
156
253
|
newStyles = {
|
|
157
|
-
switch: {
|
|
158
|
-
backgroundColor: disabled ?
|
|
254
|
+
switch: _extends({
|
|
255
|
+
backgroundColor: disabled ? theme.color.bg.switch.disabledOn : theme.color.bg.switch.on,
|
|
159
256
|
":active": {
|
|
160
|
-
backgroundColor: !disabled && clickable
|
|
161
|
-
},
|
|
162
|
-
":focus-within": {
|
|
163
|
-
outline: `solid ${Spacing__default["default"].xxxxSmall_2}px ${Color__default["default"].blue}`,
|
|
164
|
-
outlineOffset: 1
|
|
165
|
-
},
|
|
166
|
-
":hover": {
|
|
167
|
-
outline: clickable ? `solid ${Spacing__default["default"].xxxxSmall_2}px ${Color__default["default"].blue}` : "none"
|
|
257
|
+
backgroundColor: !disabled && clickable ? theme.color.bg.switch.activeOn : undefined
|
|
168
258
|
}
|
|
169
|
-
},
|
|
259
|
+
}, sharedSwitchStyles),
|
|
170
260
|
slider: {
|
|
171
|
-
transform:
|
|
261
|
+
transform: theme.spacing.transform.default
|
|
172
262
|
},
|
|
173
263
|
icon: {
|
|
174
|
-
color: disabled ?
|
|
175
|
-
transform:
|
|
264
|
+
color: disabled ? theme.color.bg.icon.disabledOn : theme.color.bg.icon.on,
|
|
265
|
+
transform: theme.spacing.transform.default
|
|
176
266
|
}
|
|
177
267
|
};
|
|
178
268
|
} else {
|
|
179
269
|
newStyles = {
|
|
180
|
-
switch: {
|
|
181
|
-
backgroundColor: disabled ?
|
|
270
|
+
switch: _extends({
|
|
271
|
+
backgroundColor: disabled ? theme.color.bg.switch.disabledOff : theme.color.bg.switch.off,
|
|
182
272
|
":active": {
|
|
183
|
-
backgroundColor: !disabled && clickable
|
|
184
|
-
},
|
|
185
|
-
":focus-within": {
|
|
186
|
-
outline: `solid ${Spacing__default["default"].xxxxSmall_2}px ${Color__default["default"].blue}`,
|
|
187
|
-
outlineOffset: 1
|
|
188
|
-
},
|
|
189
|
-
":hover": {
|
|
190
|
-
outline: clickable ? `solid ${Spacing__default["default"].xxxxSmall_2}px ${Color__default["default"].blue}` : "none"
|
|
273
|
+
backgroundColor: !disabled && clickable ? theme.color.bg.switch.activeOff : undefined
|
|
191
274
|
}
|
|
275
|
+
}, sharedSwitchStyles),
|
|
276
|
+
slider: {
|
|
277
|
+
backgroundColor: theme.color.bg.slider.off
|
|
192
278
|
},
|
|
193
279
|
icon: {
|
|
194
|
-
color: disabled ?
|
|
280
|
+
color: disabled ? theme.color.bg.icon.disabledOff : theme.color.bg.icon.off
|
|
195
281
|
}
|
|
196
282
|
};
|
|
197
283
|
}
|
|
198
284
|
styles[checkedStyle] = aphrodite.StyleSheet.create(newStyles);
|
|
199
285
|
return styles[checkedStyle];
|
|
200
286
|
};
|
|
287
|
+
const Switch = React__namespace.forwardRef(function Switch(props, ref) {
|
|
288
|
+
return React__namespace.createElement(ThemedSwitch, null, React__namespace.createElement(SwitchCore, _extends({}, props, {
|
|
289
|
+
ref: ref
|
|
290
|
+
})));
|
|
291
|
+
});
|
|
201
292
|
Switch.displayName = "Switch";
|
|
202
293
|
|
|
203
294
|
module.exports = Switch;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
declare const theme: {
|
|
2
|
+
color: {
|
|
3
|
+
bg: {
|
|
4
|
+
switch: {
|
|
5
|
+
off: string;
|
|
6
|
+
disabledOff: string;
|
|
7
|
+
activeOff: string;
|
|
8
|
+
on: string;
|
|
9
|
+
disabledOn: string;
|
|
10
|
+
activeOn: string;
|
|
11
|
+
};
|
|
12
|
+
slider: {
|
|
13
|
+
on: string;
|
|
14
|
+
off: string;
|
|
15
|
+
};
|
|
16
|
+
icon: {
|
|
17
|
+
on: string;
|
|
18
|
+
disabledOn: string;
|
|
19
|
+
off: string;
|
|
20
|
+
disabledOff: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
outline: {
|
|
24
|
+
default: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
border: {
|
|
28
|
+
radius: {
|
|
29
|
+
small: 12;
|
|
30
|
+
full: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
size: {
|
|
34
|
+
height: {
|
|
35
|
+
none: number;
|
|
36
|
+
medium: number;
|
|
37
|
+
large: 24;
|
|
38
|
+
};
|
|
39
|
+
width: {
|
|
40
|
+
none: number;
|
|
41
|
+
small: 2;
|
|
42
|
+
medium: number;
|
|
43
|
+
large: number;
|
|
44
|
+
};
|
|
45
|
+
offset: {
|
|
46
|
+
default: number;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
spacing: {
|
|
50
|
+
slider: {
|
|
51
|
+
position: 2;
|
|
52
|
+
};
|
|
53
|
+
icon: {
|
|
54
|
+
position: 4;
|
|
55
|
+
};
|
|
56
|
+
transform: {
|
|
57
|
+
default: string;
|
|
58
|
+
transition: string;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
export default theme;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The overrides for khanmigo theme for a switch.
|
|
3
|
+
*/
|
|
4
|
+
declare const theme: {
|
|
5
|
+
color: {
|
|
6
|
+
bg: {
|
|
7
|
+
switch: {
|
|
8
|
+
off: string;
|
|
9
|
+
disabledOff: string;
|
|
10
|
+
activeOff: string;
|
|
11
|
+
on: string;
|
|
12
|
+
disabledOn: string;
|
|
13
|
+
activeOn: string;
|
|
14
|
+
};
|
|
15
|
+
slider: {
|
|
16
|
+
on: string;
|
|
17
|
+
off: string;
|
|
18
|
+
};
|
|
19
|
+
icon: {
|
|
20
|
+
on: string;
|
|
21
|
+
disabledOn: string;
|
|
22
|
+
off: string;
|
|
23
|
+
disabledOff: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
outline: {
|
|
27
|
+
default: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
border: {
|
|
31
|
+
radius: {
|
|
32
|
+
small: 12;
|
|
33
|
+
full: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
size: {
|
|
37
|
+
height: {
|
|
38
|
+
none: number;
|
|
39
|
+
medium: number;
|
|
40
|
+
large: 24;
|
|
41
|
+
};
|
|
42
|
+
width: {
|
|
43
|
+
none: number;
|
|
44
|
+
small: 2;
|
|
45
|
+
medium: number;
|
|
46
|
+
large: number;
|
|
47
|
+
};
|
|
48
|
+
offset: {
|
|
49
|
+
default: number;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
spacing: {
|
|
53
|
+
slider: {
|
|
54
|
+
position: 2;
|
|
55
|
+
};
|
|
56
|
+
icon: {
|
|
57
|
+
position: 4;
|
|
58
|
+
};
|
|
59
|
+
transform: {
|
|
60
|
+
default: string;
|
|
61
|
+
transition: string;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
export default theme;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import defaultTheme from "./default";
|
|
3
|
+
type Props = {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
};
|
|
6
|
+
export type SwitchThemeContract = typeof defaultTheme;
|
|
7
|
+
/**
|
|
8
|
+
* The context that provides the theme to the Switch component.
|
|
9
|
+
* This is generally consumed via the `useScopedTheme` hook.
|
|
10
|
+
*/
|
|
11
|
+
export declare const SwitchThemeContext: React.Context<{
|
|
12
|
+
color: {
|
|
13
|
+
bg: {
|
|
14
|
+
switch: {
|
|
15
|
+
off: string;
|
|
16
|
+
disabledOff: string;
|
|
17
|
+
activeOff: string;
|
|
18
|
+
on: string;
|
|
19
|
+
disabledOn: string;
|
|
20
|
+
activeOn: string;
|
|
21
|
+
};
|
|
22
|
+
slider: {
|
|
23
|
+
/**
|
|
24
|
+
* The context that provides the theme to the Switch component.
|
|
25
|
+
* This is generally consumed via the `useScopedTheme` hook.
|
|
26
|
+
*/
|
|
27
|
+
on: string;
|
|
28
|
+
off: string;
|
|
29
|
+
};
|
|
30
|
+
icon: {
|
|
31
|
+
on: string;
|
|
32
|
+
disabledOn: string;
|
|
33
|
+
off: string;
|
|
34
|
+
disabledOff: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
outline: {
|
|
38
|
+
default: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
border: {
|
|
42
|
+
radius: {
|
|
43
|
+
small: 12;
|
|
44
|
+
full: string;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
size: {
|
|
48
|
+
height: {
|
|
49
|
+
none: number;
|
|
50
|
+
medium: number;
|
|
51
|
+
large: 24;
|
|
52
|
+
};
|
|
53
|
+
width: {
|
|
54
|
+
none: number;
|
|
55
|
+
small: 2;
|
|
56
|
+
medium: number;
|
|
57
|
+
large: number;
|
|
58
|
+
};
|
|
59
|
+
offset: {
|
|
60
|
+
default: number;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
spacing: {
|
|
64
|
+
slider: {
|
|
65
|
+
position: 2;
|
|
66
|
+
};
|
|
67
|
+
icon: {
|
|
68
|
+
position: 4;
|
|
69
|
+
};
|
|
70
|
+
transform: {
|
|
71
|
+
default: string;
|
|
72
|
+
transition: string;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* ThemedSwitch is a component that provides a theme to the <Switch/> component.
|
|
78
|
+
*/
|
|
79
|
+
export default function ThemedSwitch(props: Props): JSX.Element;
|
|
80
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-switch",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"description": "Switch components for Wonder Blocks.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,10 +16,9 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@babel/runtime": "^7.18.6",
|
|
19
|
-
"@khanacademy/wonder-blocks-
|
|
20
|
-
"@khanacademy/wonder-blocks-
|
|
21
|
-
"@khanacademy/wonder-blocks-
|
|
22
|
-
"@khanacademy/wonder-blocks-spacing": "^4.0.1"
|
|
19
|
+
"@khanacademy/wonder-blocks-core": "^6.2.0",
|
|
20
|
+
"@khanacademy/wonder-blocks-icon": "^2.1.6",
|
|
21
|
+
"@khanacademy/wonder-blocks-theming": "^1.1.0"
|
|
23
22
|
},
|
|
24
23
|
"peerDependencies": {
|
|
25
24
|
"aphrodite": "^1.2.5",
|
|
@@ -3,6 +3,7 @@ import {render, screen} from "@testing-library/react";
|
|
|
3
3
|
|
|
4
4
|
import userEvent from "@testing-library/user-event";
|
|
5
5
|
import Icon, {icons} from "@khanacademy/wonder-blocks-icon";
|
|
6
|
+
import {RenderStateRoot} from "@khanacademy/wonder-blocks-core";
|
|
6
7
|
import Switch from "../switch";
|
|
7
8
|
|
|
8
9
|
describe("Switch", () => {
|
|
@@ -10,7 +11,11 @@ describe("Switch", () => {
|
|
|
10
11
|
test("clicking the switch should call onChange", () => {
|
|
11
12
|
// Arrange
|
|
12
13
|
const onChangeSpy = jest.fn();
|
|
13
|
-
render(
|
|
14
|
+
render(
|
|
15
|
+
<RenderStateRoot>
|
|
16
|
+
<Switch checked={false} onChange={onChangeSpy} />
|
|
17
|
+
</RenderStateRoot>,
|
|
18
|
+
);
|
|
14
19
|
|
|
15
20
|
// Act
|
|
16
21
|
const switchComponent = screen.getByRole("switch");
|
|
@@ -24,11 +29,13 @@ describe("Switch", () => {
|
|
|
24
29
|
// Arrange
|
|
25
30
|
const onChangeSpy = jest.fn();
|
|
26
31
|
render(
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
<RenderStateRoot>
|
|
33
|
+
<Switch
|
|
34
|
+
checked={false}
|
|
35
|
+
onChange={onChangeSpy}
|
|
36
|
+
disabled={true}
|
|
37
|
+
/>
|
|
38
|
+
</RenderStateRoot>,
|
|
32
39
|
);
|
|
33
40
|
|
|
34
41
|
// Act
|
|
@@ -42,7 +49,11 @@ describe("Switch", () => {
|
|
|
42
49
|
test("pressing the space key should call onChange", () => {
|
|
43
50
|
// Arrange
|
|
44
51
|
const onChangeSpy = jest.fn();
|
|
45
|
-
render(
|
|
52
|
+
render(
|
|
53
|
+
<RenderStateRoot>
|
|
54
|
+
<Switch checked={false} onChange={onChangeSpy} />
|
|
55
|
+
</RenderStateRoot>,
|
|
56
|
+
);
|
|
46
57
|
|
|
47
58
|
// Act
|
|
48
59
|
const switchComponent = screen.getByRole("switch");
|
|
@@ -57,14 +68,14 @@ describe("Switch", () => {
|
|
|
57
68
|
// Arrange
|
|
58
69
|
const onChangeSpy = jest.fn();
|
|
59
70
|
render(
|
|
60
|
-
|
|
71
|
+
<RenderStateRoot>
|
|
61
72
|
<Switch
|
|
62
73
|
id="switch-id"
|
|
63
74
|
checked={false}
|
|
64
75
|
onChange={onChangeSpy}
|
|
65
76
|
/>
|
|
66
77
|
<label htmlFor="switch-id">Switch</label>
|
|
67
|
-
|
|
78
|
+
</RenderStateRoot>,
|
|
68
79
|
);
|
|
69
80
|
|
|
70
81
|
// Act
|
|
@@ -80,7 +91,13 @@ describe("Switch", () => {
|
|
|
80
91
|
it("should set the accessibility attributes accordingly", () => {
|
|
81
92
|
// Arrange
|
|
82
93
|
render(
|
|
83
|
-
<
|
|
94
|
+
<RenderStateRoot>
|
|
95
|
+
<Switch
|
|
96
|
+
aria-label="Gravity"
|
|
97
|
+
checked={true}
|
|
98
|
+
disabled={true}
|
|
99
|
+
/>
|
|
100
|
+
</RenderStateRoot>,
|
|
84
101
|
);
|
|
85
102
|
|
|
86
103
|
// Act
|
|
@@ -94,10 +111,12 @@ describe("Switch", () => {
|
|
|
94
111
|
it("should render an icon if one is provided", () => {
|
|
95
112
|
// Arrange
|
|
96
113
|
render(
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
114
|
+
<RenderStateRoot>
|
|
115
|
+
<Switch
|
|
116
|
+
checked={false}
|
|
117
|
+
icon={<Icon icon={icons.add} testId="test-icon" />}
|
|
118
|
+
/>
|
|
119
|
+
</RenderStateRoot>,
|
|
101
120
|
);
|
|
102
121
|
|
|
103
122
|
// Act
|