@khanacademy/wonder-blocks-button 2.10.0 → 2.11.1
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 +14 -0
- package/dist/es/index.js +44 -25
- package/dist/index.js +25 -6
- package/package.json +11 -12
- package/src/__tests__/__snapshots__/custom-snapshot.test.js.snap +155 -125
- package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +307 -72
- package/src/__tests__/generated-snapshot.test.js +74 -12
- package/src/components/__docs__/accessibility.stories.mdx +92 -0
- package/src/components/__docs__/best-practices.stories.mdx +107 -0
- package/src/components/__docs__/button.argtypes.js +231 -0
- package/src/components/__docs__/navigation-callbacks.stories.mdx +68 -0
- package/src/components/__tests__/button.test.js +52 -0
- package/src/components/button-core.js +19 -1
- package/src/components/button.js +10 -8
- package/src/components/button.md +134 -23
- package/src/components/button.stories.js +392 -50
- package/LICENSE +0 -21
package/CHANGELOG.md
ADDED
package/dist/es/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _extends from '@babel/runtime/helpers/extends';
|
|
2
2
|
import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/objectWithoutPropertiesLoose';
|
|
3
|
-
import
|
|
3
|
+
import * as React from 'react';
|
|
4
4
|
import { __RouterContext } from 'react-router';
|
|
5
5
|
import { isClientSideUrl, getClickableBehavior } from '@khanacademy/wonder-blocks-clickable';
|
|
6
6
|
import { StyleSheet } from 'aphrodite';
|
|
@@ -12,11 +12,11 @@ import { CircularSpinner } from '@khanacademy/wonder-blocks-progress-spinner';
|
|
|
12
12
|
import Icon from '@khanacademy/wonder-blocks-icon';
|
|
13
13
|
import Spacing from '@khanacademy/wonder-blocks-spacing';
|
|
14
14
|
|
|
15
|
-
const _excluded = ["children", "skipClientNav", "color", "disabled", "focused", "hovered", "href", "kind", "light", "pressed", "size", "style", "testId", "type", "spinner", "icon", "id", "waiting"];
|
|
15
|
+
const _excluded$1 = ["children", "skipClientNav", "color", "disabled", "focused", "hovered", "href", "kind", "light", "pressed", "size", "style", "testId", "type", "spinner", "icon", "id", "waiting"];
|
|
16
16
|
const StyledAnchor = addStyle("a");
|
|
17
17
|
const StyledButton = addStyle("button");
|
|
18
18
|
const StyledLink = addStyle(Link);
|
|
19
|
-
class ButtonCore extends Component {
|
|
19
|
+
class ButtonCore extends React.Component {
|
|
20
20
|
renderInner(router) {
|
|
21
21
|
const _this$props = this.props,
|
|
22
22
|
{
|
|
@@ -38,7 +38,7 @@ class ButtonCore extends Component {
|
|
|
38
38
|
icon,
|
|
39
39
|
id
|
|
40
40
|
} = _this$props,
|
|
41
|
-
restProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
|
|
41
|
+
restProps = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
|
|
42
42
|
|
|
43
43
|
const buttonColor = color === "destructive" ? SemanticColor.controlDestructive : SemanticColor.controlDefault;
|
|
44
44
|
const iconWidth = icon ? (size === "small" ? 16 : 24) + 8 : 0;
|
|
@@ -57,16 +57,16 @@ class ButtonCore extends Component {
|
|
|
57
57
|
}, restProps);
|
|
58
58
|
|
|
59
59
|
const Label = size === "small" ? LabelSmall : LabelLarge;
|
|
60
|
-
const label = /*#__PURE__*/createElement(Label, {
|
|
60
|
+
const label = /*#__PURE__*/React.createElement(Label, {
|
|
61
61
|
style: [sharedStyles.text, size === "xlarge" && sharedStyles.xlargeText, icon && sharedStyles.textWithIcon, spinner && sharedStyles.hiddenText, kind === "tertiary" && sharedStyles.textWithFocus, // apply focus effect on the label instead
|
|
62
62
|
kind === "tertiary" && !disabled && (pressed ? buttonStyles.active : (hovered || focused) && buttonStyles.focus)]
|
|
63
|
-
}, icon && /*#__PURE__*/createElement(Icon, {
|
|
63
|
+
}, icon && /*#__PURE__*/React.createElement(Icon, {
|
|
64
64
|
size: size,
|
|
65
65
|
color: "currentColor",
|
|
66
66
|
icon: icon,
|
|
67
67
|
style: sharedStyles.icon
|
|
68
68
|
}), children);
|
|
69
|
-
const contents = /*#__PURE__*/createElement(Fragment, null, label, spinner && /*#__PURE__*/createElement(CircularSpinner, {
|
|
69
|
+
const contents = /*#__PURE__*/React.createElement(React.Fragment, null, label, spinner && /*#__PURE__*/React.createElement(CircularSpinner, {
|
|
70
70
|
style: sharedStyles.spinner,
|
|
71
71
|
size: {
|
|
72
72
|
medium: "small",
|
|
@@ -77,22 +77,22 @@ class ButtonCore extends Component {
|
|
|
77
77
|
}));
|
|
78
78
|
|
|
79
79
|
if (href && !disabled) {
|
|
80
|
-
return router && !skipClientNav && isClientSideUrl(href) ? /*#__PURE__*/createElement(StyledLink, _extends({}, commonProps, {
|
|
80
|
+
return router && !skipClientNav && isClientSideUrl(href) ? /*#__PURE__*/React.createElement(StyledLink, _extends({}, commonProps, {
|
|
81
81
|
to: href
|
|
82
|
-
}), contents) : /*#__PURE__*/createElement(StyledAnchor, _extends({}, commonProps, {
|
|
82
|
+
}), contents) : /*#__PURE__*/React.createElement(StyledAnchor, _extends({}, commonProps, {
|
|
83
83
|
href: href
|
|
84
84
|
}), contents);
|
|
85
85
|
} else {
|
|
86
|
-
return /*#__PURE__*/createElement(StyledButton, _extends({
|
|
86
|
+
return /*#__PURE__*/React.createElement(StyledButton, _extends({
|
|
87
87
|
type: type || "button"
|
|
88
88
|
}, commonProps, {
|
|
89
|
-
disabled: disabled
|
|
89
|
+
"aria-disabled": disabled
|
|
90
90
|
}), contents);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
render() {
|
|
95
|
-
return /*#__PURE__*/createElement(__RouterContext.Consumer, null, router => this.renderInner(router));
|
|
95
|
+
return /*#__PURE__*/React.createElement(__RouterContext.Consumer, null, router => this.renderInner(router));
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
}
|
|
@@ -213,7 +213,10 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
|
|
|
213
213
|
disabled: {
|
|
214
214
|
background: light ? fadedColor : offBlack32,
|
|
215
215
|
color: light ? color : white64,
|
|
216
|
-
cursor: "default"
|
|
216
|
+
cursor: "default",
|
|
217
|
+
":focus": {
|
|
218
|
+
boxShadow: `0 0 0 1px ${light ? offBlack32 : white}, 0 0 0 3px ${light ? fadedColor : offBlack32}`
|
|
219
|
+
}
|
|
217
220
|
}
|
|
218
221
|
};
|
|
219
222
|
} else if (kind === "secondary") {
|
|
@@ -241,6 +244,8 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
|
|
|
241
244
|
color: light ? fadedColor : activeColor,
|
|
242
245
|
borderColor: light ? fadedColor : activeColor,
|
|
243
246
|
borderWidth: 2,
|
|
247
|
+
// We need to reduce padding to offset the difference
|
|
248
|
+
// caused by the border becoming thicker on focus.
|
|
244
249
|
// The left padding for the button with icon should have 4px
|
|
245
250
|
// less padding
|
|
246
251
|
paddingLeft: iconWidth ? padding - 5 : padding - 1,
|
|
@@ -249,10 +254,21 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
|
|
|
249
254
|
disabled: {
|
|
250
255
|
color: light ? white50 : offBlack32,
|
|
251
256
|
borderColor: light ? fadedColor : offBlack32,
|
|
252
|
-
cursor: "default"
|
|
257
|
+
cursor: "default",
|
|
258
|
+
":focus": {
|
|
259
|
+
borderColor: light ? white50 : offBlack32,
|
|
260
|
+
borderWidth: 2,
|
|
261
|
+
// We need to reduce padding to offset the difference
|
|
262
|
+
// caused by the border becoming thicker on focus.
|
|
263
|
+
// The left padding for the button with icon should have 4px
|
|
264
|
+
// less padding
|
|
265
|
+
paddingLeft: iconWidth ? padding - 5 : padding - 1,
|
|
266
|
+
paddingRight: padding - 1
|
|
267
|
+
}
|
|
253
268
|
}
|
|
254
269
|
};
|
|
255
270
|
} else if (kind === "tertiary") {
|
|
271
|
+
// TODO(FEI-4229): Make tertiary buttons focusable
|
|
256
272
|
newStyles = {
|
|
257
273
|
default: {
|
|
258
274
|
background: "none",
|
|
@@ -298,7 +314,7 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
|
|
|
298
314
|
return styles[buttonType];
|
|
299
315
|
};
|
|
300
316
|
|
|
301
|
-
const _excluded
|
|
317
|
+
const _excluded = ["href", "type", "children", "skipClientNav", "spinner", "disabled", "onClick", "beforeNav", "safeWithNav", "tabIndex", "target", "rel"],
|
|
302
318
|
_excluded2 = ["tabIndex"];
|
|
303
319
|
|
|
304
320
|
/**
|
|
@@ -309,16 +325,19 @@ const _excluded$1 = ["href", "type", "children", "skipClientNav", "spinner", "di
|
|
|
309
325
|
* `ButtonCore` is a stateless component which displays the different states
|
|
310
326
|
* the `Button` can take.
|
|
311
327
|
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
328
|
+
* ### Usage
|
|
329
|
+
*
|
|
330
|
+
* ```jsx
|
|
331
|
+
* import Button from "@khanacademy/wonder-blocks-button";
|
|
332
|
+
*
|
|
314
333
|
* <Button
|
|
315
334
|
* onClick={(e) => console.log("Hello, world!")}
|
|
316
335
|
* >
|
|
317
|
-
*
|
|
336
|
+
* Hello, world!
|
|
318
337
|
* </Button>
|
|
319
338
|
* ```
|
|
320
339
|
*/
|
|
321
|
-
class Button extends Component {
|
|
340
|
+
class Button extends React.Component {
|
|
322
341
|
renderClickableBehavior(router) {
|
|
323
342
|
const _this$props = this.props,
|
|
324
343
|
{
|
|
@@ -335,7 +354,7 @@ class Button extends Component {
|
|
|
335
354
|
target,
|
|
336
355
|
rel
|
|
337
356
|
} = _this$props,
|
|
338
|
-
sharedButtonCoreProps = _objectWithoutPropertiesLoose(_this$props, _excluded
|
|
357
|
+
sharedButtonCoreProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
|
|
339
358
|
|
|
340
359
|
const ClickableBehavior = getClickableBehavior(href, skipClientNav, router);
|
|
341
360
|
|
|
@@ -345,7 +364,7 @@ class Button extends Component {
|
|
|
345
364
|
} = _ref,
|
|
346
365
|
restChildProps = _objectWithoutPropertiesLoose(_ref, _excluded2);
|
|
347
366
|
|
|
348
|
-
return /*#__PURE__*/createElement(ButtonCore, _extends({}, sharedButtonCoreProps, state, restChildProps, {
|
|
367
|
+
return /*#__PURE__*/React.createElement(ButtonCore, _extends({}, sharedButtonCoreProps, state, restChildProps, {
|
|
349
368
|
disabled: disabled,
|
|
350
369
|
spinner: spinner || state.waiting,
|
|
351
370
|
skipClientNav: skipClientNav,
|
|
@@ -360,7 +379,7 @@ class Button extends Component {
|
|
|
360
379
|
};
|
|
361
380
|
|
|
362
381
|
if (beforeNav) {
|
|
363
|
-
return /*#__PURE__*/createElement(ClickableBehavior, {
|
|
382
|
+
return /*#__PURE__*/React.createElement(ClickableBehavior, {
|
|
364
383
|
disabled: spinner || disabled,
|
|
365
384
|
href: href,
|
|
366
385
|
role: "button",
|
|
@@ -371,7 +390,7 @@ class Button extends Component {
|
|
|
371
390
|
rel: rel
|
|
372
391
|
}, renderProp);
|
|
373
392
|
} else {
|
|
374
|
-
return /*#__PURE__*/createElement(ClickableBehavior, {
|
|
393
|
+
return /*#__PURE__*/React.createElement(ClickableBehavior, {
|
|
375
394
|
disabled: spinner || disabled,
|
|
376
395
|
href: href,
|
|
377
396
|
role: "button",
|
|
@@ -385,7 +404,7 @@ class Button extends Component {
|
|
|
385
404
|
}
|
|
386
405
|
|
|
387
406
|
render() {
|
|
388
|
-
return /*#__PURE__*/createElement(__RouterContext.Consumer, null, router => this.renderClickableBehavior(router));
|
|
407
|
+
return /*#__PURE__*/React.createElement(__RouterContext.Consumer, null, router => this.renderClickableBehavior(router));
|
|
389
408
|
}
|
|
390
409
|
|
|
391
410
|
}
|
|
@@ -398,4 +417,4 @@ Button.defaultProps = {
|
|
|
398
417
|
spinner: false
|
|
399
418
|
};
|
|
400
419
|
|
|
401
|
-
export default
|
|
420
|
+
export { Button as default };
|
package/dist/index.js
CHANGED
|
@@ -161,12 +161,15 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
|
|
|
161
161
|
* `ButtonCore` is a stateless component which displays the different states
|
|
162
162
|
* the `Button` can take.
|
|
163
163
|
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
164
|
+
* ### Usage
|
|
165
|
+
*
|
|
166
|
+
* ```jsx
|
|
167
|
+
* import Button from "@khanacademy/wonder-blocks-button";
|
|
168
|
+
*
|
|
166
169
|
* <Button
|
|
167
170
|
* onClick={(e) => console.log("Hello, world!")}
|
|
168
171
|
* >
|
|
169
|
-
*
|
|
172
|
+
* Hello, world!
|
|
170
173
|
* </Button>
|
|
171
174
|
* ```
|
|
172
175
|
*/
|
|
@@ -358,7 +361,7 @@ class ButtonCore extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
358
361
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](StyledButton, _extends({
|
|
359
362
|
type: type || "button"
|
|
360
363
|
}, commonProps, {
|
|
361
|
-
disabled: disabled
|
|
364
|
+
"aria-disabled": disabled
|
|
362
365
|
}), contents);
|
|
363
366
|
}
|
|
364
367
|
}
|
|
@@ -485,7 +488,10 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
|
|
|
485
488
|
disabled: {
|
|
486
489
|
background: light ? fadedColor : offBlack32,
|
|
487
490
|
color: light ? color : white64,
|
|
488
|
-
cursor: "default"
|
|
491
|
+
cursor: "default",
|
|
492
|
+
":focus": {
|
|
493
|
+
boxShadow: `0 0 0 1px ${light ? offBlack32 : white}, 0 0 0 3px ${light ? fadedColor : offBlack32}`
|
|
494
|
+
}
|
|
489
495
|
}
|
|
490
496
|
};
|
|
491
497
|
} else if (kind === "secondary") {
|
|
@@ -513,6 +519,8 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
|
|
|
513
519
|
color: light ? fadedColor : activeColor,
|
|
514
520
|
borderColor: light ? fadedColor : activeColor,
|
|
515
521
|
borderWidth: 2,
|
|
522
|
+
// We need to reduce padding to offset the difference
|
|
523
|
+
// caused by the border becoming thicker on focus.
|
|
516
524
|
// The left padding for the button with icon should have 4px
|
|
517
525
|
// less padding
|
|
518
526
|
paddingLeft: iconWidth ? padding - 5 : padding - 1,
|
|
@@ -521,10 +529,21 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
|
|
|
521
529
|
disabled: {
|
|
522
530
|
color: light ? white50 : offBlack32,
|
|
523
531
|
borderColor: light ? fadedColor : offBlack32,
|
|
524
|
-
cursor: "default"
|
|
532
|
+
cursor: "default",
|
|
533
|
+
":focus": {
|
|
534
|
+
borderColor: light ? white50 : offBlack32,
|
|
535
|
+
borderWidth: 2,
|
|
536
|
+
// We need to reduce padding to offset the difference
|
|
537
|
+
// caused by the border becoming thicker on focus.
|
|
538
|
+
// The left padding for the button with icon should have 4px
|
|
539
|
+
// less padding
|
|
540
|
+
paddingLeft: iconWidth ? padding - 5 : padding - 1,
|
|
541
|
+
paddingRight: padding - 1
|
|
542
|
+
}
|
|
525
543
|
}
|
|
526
544
|
};
|
|
527
545
|
} else if (kind === "tertiary") {
|
|
546
|
+
// TODO(FEI-4229): Make tertiary buttons focusable
|
|
528
547
|
newStyles = {
|
|
529
548
|
default: {
|
|
530
549
|
background: "none",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-button",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.1",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
"author": "",
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@babel/runtime": "^7.
|
|
19
|
-
"@khanacademy/wonder-blocks-clickable": "^2.2.
|
|
20
|
-
"@khanacademy/wonder-blocks-color": "^1.1.
|
|
21
|
-
"@khanacademy/wonder-blocks-core": "^
|
|
22
|
-
"@khanacademy/wonder-blocks-icon": "^1.2.
|
|
23
|
-
"@khanacademy/wonder-blocks-progress-spinner": "^1.1.
|
|
24
|
-
"@khanacademy/wonder-blocks-spacing": "^3.0.
|
|
25
|
-
"@khanacademy/wonder-blocks-typography": "^1.1.
|
|
18
|
+
"@babel/runtime": "^7.16.3",
|
|
19
|
+
"@khanacademy/wonder-blocks-clickable": "^2.2.2",
|
|
20
|
+
"@khanacademy/wonder-blocks-color": "^1.1.20",
|
|
21
|
+
"@khanacademy/wonder-blocks-core": "^4.0.0",
|
|
22
|
+
"@khanacademy/wonder-blocks-icon": "^1.2.24",
|
|
23
|
+
"@khanacademy/wonder-blocks-progress-spinner": "^1.1.28",
|
|
24
|
+
"@khanacademy/wonder-blocks-spacing": "^3.0.5",
|
|
25
|
+
"@khanacademy/wonder-blocks-typography": "^1.1.28"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"aphrodite": "^1.2.5",
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
"react-router-dom": "5.3.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"wb-dev-build-settings": "^0.
|
|
35
|
-
}
|
|
36
|
-
"gitHead": "b6193f70c73e70fbaf76bc688dc69a47fb1d0ef3"
|
|
34
|
+
"wb-dev-build-settings": "^0.2.0"
|
|
35
|
+
}
|
|
37
36
|
}
|