@khanacademy/wonder-blocks-button 7.0.3 → 7.0.5

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 CHANGED
@@ -1,5 +1,31 @@
1
1
  # @khanacademy/wonder-blocks-button
2
2
 
3
+ ## 7.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - 0cffa81f: Use pseudo-classes for styling states (:hover, :focus-visible). Keep some clickable states for programmatic focus and preserve active/pressed overrides.
8
+ - Updated dependencies [7516b239]
9
+ - @khanacademy/wonder-blocks-core@11.1.0
10
+ - @khanacademy/wonder-blocks-clickable@5.0.5
11
+ - @khanacademy/wonder-blocks-icon@5.0.5
12
+ - @khanacademy/wonder-blocks-progress-spinner@3.0.5
13
+ - @khanacademy/wonder-blocks-typography@3.0.5
14
+
15
+ ## 7.0.4
16
+
17
+ ### Patch Changes
18
+
19
+ - 11a0f5c6: No functional changes. Adding prepublishOnly script.
20
+ - Updated dependencies [11a0f5c6]
21
+ - @khanacademy/wonder-blocks-progress-spinner@3.0.4
22
+ - @khanacademy/wonder-blocks-typography@3.0.4
23
+ - @khanacademy/wonder-blocks-clickable@5.0.4
24
+ - @khanacademy/wonder-blocks-theming@3.0.1
25
+ - @khanacademy/wonder-blocks-tokens@3.0.1
26
+ - @khanacademy/wonder-blocks-core@11.0.1
27
+ - @khanacademy/wonder-blocks-icon@5.0.4
28
+
3
29
  ## 7.0.3
4
30
 
5
31
  ### Patch Changes
package/dist/es/index.js CHANGED
@@ -12,6 +12,7 @@ import { mergeTheme, createThemeContext, ThemeSwitcherContext, useScopedTheme, u
12
12
  import * as tokens from '@khanacademy/wonder-blocks-tokens';
13
13
  import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
14
14
 
15
+ const textUnderlineOffset = tokens.spacing.xxxSmall_4;
15
16
  const theme$1 = {
16
17
  color: {
17
18
  bg: {
@@ -27,8 +28,7 @@ const theme$1 = {
27
28
  },
28
29
  primary: {
29
30
  default: tokens.color.white,
30
- disabled: tokens.color.offBlack32,
31
- inverse: tokens.color.darkBlue
31
+ disabled: tokens.color.offBlack32
32
32
  },
33
33
  secondary: {
34
34
  default: "none",
@@ -39,9 +39,6 @@ const theme$1 = {
39
39
  critical: tokens.color.fadedRed
40
40
  }
41
41
  },
42
- tertiary: {
43
- hover: tokens.color.white
44
- },
45
42
  icon: {
46
43
  secondaryHover: "transparent"
47
44
  }
@@ -80,9 +77,11 @@ const theme$1 = {
80
77
  focused: tokens.border.width.thin,
81
78
  disabled: tokens.border.width.thin
82
79
  },
80
+ offset: {
81
+ primary: tokens.spacing.xxxxSmall_2
82
+ },
83
83
  radius: {
84
84
  default: tokens.border.radius.medium_4,
85
- tertiary: tokens.border.radius.xSmall_2,
86
85
  small: tokens.border.radius.medium_4,
87
86
  large: tokens.border.radius.large_6,
88
87
  icon: tokens.border.radius.full
@@ -90,10 +89,13 @@ const theme$1 = {
90
89
  },
91
90
  size: {
92
91
  height: {
93
- tertiaryHover: tokens.spacing.xxxxSmall_2,
94
92
  small: tokens.spacing.xLarge_32,
95
93
  medium: 40,
96
94
  large: 56
95
+ },
96
+ underline: {
97
+ hover: tokens.spacing.xxxxSmall_2,
98
+ active: 1
97
99
  }
98
100
  },
99
101
  margin: {
@@ -113,10 +115,15 @@ const theme$1 = {
113
115
  large: 18
114
116
  },
115
117
  lineHeight: {
116
- large: tokens.font.lineHeight.medium
118
+ small: tokens.font.lineHeight.small + textUnderlineOffset,
119
+ default: tokens.font.lineHeight.medium + textUnderlineOffset,
120
+ large: tokens.font.lineHeight.medium + 2 + textUnderlineOffset
117
121
  },
118
122
  weight: {
119
123
  default: tokens.font.weight.bold
124
+ },
125
+ offset: {
126
+ default: textUnderlineOffset
120
127
  }
121
128
  }
122
129
  };
@@ -245,7 +252,7 @@ const ButtonCore = React.forwardRef(function ButtonCore(props, ref) {
245
252
  restProps = _objectWithoutPropertiesLoose(props, _excluded$1);
246
253
  const buttonStyles = _generateStyles(color, kind, light, size, theme, themeName);
247
254
  const disabled = spinner || disabledProp;
248
- const defaultStyle = [sharedStyles.shared, disabled && sharedStyles.disabled, startIcon && sharedStyles.withStartIcon, endIcon && sharedStyles.withEndIcon, buttonStyles.default, disabled && buttonStyles.disabled, kind !== "tertiary" && !disabled && (pressed ? buttonStyles.active : (hovered || focused) && buttonStyles.focus), kind === "tertiary" && !pressed && focused && [buttonStyles.focus, disabled && buttonStyles.disabledFocus], size === "small" && sharedStyles.small, size === "large" && sharedStyles.large];
255
+ const defaultStyle = [sharedStyles.shared, disabled && sharedStyles.disabled, startIcon && sharedStyles.withStartIcon, endIcon && sharedStyles.withEndIcon, buttonStyles.default, disabled && buttonStyles.disabled, kind !== "tertiary" && !disabled && (pressed ? buttonStyles.pressed : focused && buttonStyles.focused), kind === "tertiary" && !pressed && focused && [buttonStyles.focused, disabled && buttonStyles.disabledFocus], size === "small" && sharedStyles.small, size === "large" && sharedStyles.large];
249
256
  const commonProps = _extends({
250
257
  "data-testid": testId,
251
258
  id: id,
@@ -254,7 +261,7 @@ const ButtonCore = React.forwardRef(function ButtonCore(props, ref) {
254
261
  }, restProps);
255
262
  const Label = size === "small" ? LabelSmall : LabelLarge;
256
263
  const label = React.createElement(Label, {
257
- style: [sharedStyles.text, size === "large" && sharedStyles.largeText, labelStyle, spinner && sharedStyles.hiddenText, kind === "tertiary" && sharedStyles.textWithFocus, kind === "tertiary" && !disabled && (pressed ? [buttonStyles.hover, buttonStyles.active] : hovered && buttonStyles.hover)],
264
+ style: [sharedStyles.text, size === "small" && sharedStyles.smallText, size === "large" && sharedStyles.largeText, labelStyle, spinner && sharedStyles.hiddenText, kind === "tertiary" && sharedStyles.textWithFocus, kind === "tertiary" && !disabled && (pressed ? [buttonStyles.hover, buttonStyles.active] : hovered && buttonStyles.hover)],
258
265
  testId: testId ? `${testId}-inner-label` : undefined
259
266
  }, children);
260
267
  const sizeMapping = {
@@ -341,10 +348,14 @@ const themedSharedStyles = theme => ({
341
348
  fontWeight: theme.font.weight.default,
342
349
  whiteSpace: "nowrap",
343
350
  overflow: "hidden",
351
+ lineHeight: `${theme.font.lineHeight.default}px`,
344
352
  textOverflow: "ellipsis",
345
353
  display: "inline-block",
346
354
  pointerEvents: "none"
347
355
  },
356
+ smallText: {
357
+ lineHeight: `${theme.font.lineHeight.small}px`
358
+ },
348
359
  largeText: {
349
360
  fontSize: theme.font.size.large,
350
361
  lineHeight: `${theme.font.lineHeight.large}px`
@@ -397,34 +408,55 @@ const _generateStyles = (buttonColor = "default", kind, light, size, theme, them
397
408
  const padding = size === "large" ? theme.padding.xLarge : theme.padding.large;
398
409
  let newStyles = {};
399
410
  if (kind === "primary") {
400
- const boxShadowInnerColor = light ? theme.color.bg.primary.inverse : theme.color.bg.primary.default;
411
+ const focusStyling = {
412
+ outlineColor: light ? theme.color.bg.primary.default : color,
413
+ outlineOffset: theme.border.offset.primary,
414
+ outlineStyle: "solid",
415
+ outlineWidth: theme.border.width.focused
416
+ };
417
+ const activePressedStyling = {
418
+ background: light ? fadedColor : activeColor,
419
+ outlineColor: light ? fadedColor : activeColor
420
+ };
401
421
  newStyles = {
402
422
  default: {
403
423
  background: light ? theme.color.bg.primary.default : color,
404
424
  color: light ? color : theme.color.text.inverse,
405
425
  paddingLeft: padding,
406
- paddingRight: padding
407
- },
408
- focus: {
409
- boxShadow: `0 0 0 1px ${boxShadowInnerColor}, 0 0 0 3px ${light ? theme.color.bg.primary.default : color}`
410
- },
411
- active: {
412
- boxShadow: `0 0 0 1px ${boxShadowInnerColor}, 0 0 0 3px ${light ? fadedColor : activeColor}`,
413
- background: light ? fadedColor : activeColor,
414
- color: light ? activeColor : fadedColor
426
+ paddingRight: padding,
427
+ [":hover:not([aria-disabled=true])"]: focusStyling,
428
+ [":focus-visible:not([aria-disabled=true])"]: focusStyling,
429
+ [":active:not([aria-disabled=true])"]: activePressedStyling
415
430
  },
431
+ focused: focusStyling,
432
+ pressed: activePressedStyling,
416
433
  disabled: {
417
434
  background: light ? fadedColor : theme.color.bg.primary.disabled,
418
435
  color: light ? color : theme.color.text.primary.disabled,
419
436
  cursor: "default",
420
- ":focus": {
421
- boxShadow: `0 0 0 1px ${light ? theme.color.bg.primary.disabled : theme.color.bg.primary.default}, 0 0 0 3px ${light ? fadedColor : theme.color.bg.primary.disabled}`
422
- }
437
+ ":focus-visible": _extends({}, focusStyling, {
438
+ outlineColor: light ? fadedColor : theme.color.bg.primary.disabled
439
+ })
423
440
  }
424
441
  };
425
442
  } else if (kind === "secondary") {
426
443
  const secondaryBorderColor = buttonColor === "destructive" ? theme.color.border.secondary.critical : theme.color.border.secondary.action;
427
444
  const secondaryActiveColor = buttonColor === "destructive" ? theme.color.bg.secondary.active.critical : theme.color.bg.secondary.active.action;
445
+ const focusStyling = {
446
+ background: light ? theme.color.bg.secondary.inverse : theme.color.bg.secondary.focus,
447
+ borderColor: "transparent",
448
+ outlineColor: light ? theme.color.border.primary.inverse : color,
449
+ outlineStyle: "solid",
450
+ outlineWidth: theme.border.width.focused
451
+ };
452
+ const activePressedStyling = {
453
+ background: light ? activeColor : secondaryActiveColor,
454
+ color: light ? fadedColor : activeColor,
455
+ borderColor: "transparent",
456
+ outlineColor: light ? fadedColor : activeColor,
457
+ outlineStyle: "solid",
458
+ outlineWidth: theme.border.width.focused
459
+ };
428
460
  newStyles = {
429
461
  default: {
430
462
  background: light ? theme.color.bg.secondary.inverse : theme.color.bg.secondary.default,
@@ -433,28 +465,18 @@ const _generateStyles = (buttonColor = "default", kind, light, size, theme, them
433
465
  borderStyle: "solid",
434
466
  borderWidth: theme.border.width.secondary,
435
467
  paddingLeft: padding,
436
- paddingRight: padding
437
- },
438
- focus: {
439
- background: light ? theme.color.bg.secondary.inverse : theme.color.bg.secondary.focus,
440
- borderColor: "transparent",
441
- outlineColor: light ? theme.color.border.primary.inverse : color,
442
- outlineStyle: "solid",
443
- outlineWidth: theme.border.width.focused
444
- },
445
- active: {
446
- background: light ? activeColor : secondaryActiveColor,
447
- color: light ? fadedColor : activeColor,
448
- borderColor: "transparent",
449
- outlineColor: light ? fadedColor : activeColor,
450
- outlineStyle: "solid",
451
- outlineWidth: theme.border.width.focused
468
+ paddingRight: padding,
469
+ [":hover:not([aria-disabled=true])"]: focusStyling,
470
+ [":focus-visible:not([aria-disabled=true])"]: focusStyling,
471
+ [":active:not([aria-disabled=true])"]: activePressedStyling
452
472
  },
473
+ focused: focusStyling,
474
+ pressed: activePressedStyling,
453
475
  disabled: {
454
476
  color: light ? theme.color.text.secondary.inverse : theme.color.text.disabled,
455
477
  outlineColor: light ? fadedColor : theme.color.border.disabled,
456
478
  cursor: "default",
457
- ":focus": {
479
+ ":focus-visible": {
458
480
  outlineColor: light ? theme.color.border.secondary.inverse : theme.color.border.disabled,
459
481
  outlineStyle: "solid",
460
482
  outlineWidth: theme.border.width.disabled
@@ -462,38 +484,34 @@ const _generateStyles = (buttonColor = "default", kind, light, size, theme, them
462
484
  }
463
485
  };
464
486
  } else if (kind === "tertiary") {
487
+ const focusStyling = {
488
+ outlineStyle: "solid",
489
+ outlineColor: light ? theme.color.border.tertiary.inverse : color,
490
+ outlineWidth: theme.border.width.focused,
491
+ borderRadius: theme.border.radius.default
492
+ };
493
+ const activePressedStyling = {
494
+ color: light ? fadedColor : activeColor,
495
+ textDecoration: "underline",
496
+ textDecorationThickness: theme.size.underline.active,
497
+ textUnderlineOffset: theme.font.offset.default
498
+ };
465
499
  newStyles = {
466
500
  default: {
467
501
  background: "none",
468
502
  color: light ? theme.color.text.inverse : color,
469
503
  paddingLeft: 0,
470
- paddingRight: 0
471
- },
472
- hover: {
473
- ":after": {
474
- content: "''",
475
- position: "absolute",
476
- height: theme.size.height.tertiaryHover,
477
- width: "100%",
478
- right: 0,
479
- bottom: 0,
480
- background: light ? theme.color.bg.tertiary.hover : color,
481
- borderRadius: theme.border.radius.tertiary
482
- }
483
- },
484
- focus: {
485
- outlineStyle: "solid",
486
- outlineColor: light ? theme.color.border.tertiary.inverse : color,
487
- outlineWidth: theme.border.width.focused,
488
- borderRadius: theme.border.radius.default
489
- },
490
- active: {
491
- color: light ? fadedColor : activeColor,
492
- ":after": {
493
- height: theme.size.height.tertiaryHover,
494
- background: light ? fadedColor : activeColor
495
- }
504
+ paddingRight: 0,
505
+ [":hover:not([aria-disabled=true])"]: {
506
+ textUnderlineOffset: theme.font.offset.default,
507
+ textDecoration: "underline",
508
+ textDecorationThickness: theme.size.underline.hover
509
+ },
510
+ [":focus-visible:not([aria-disabled=true])"]: focusStyling,
511
+ [":active:not([aria-disabled=true])"]: activePressedStyling
496
512
  },
513
+ focused: focusStyling,
514
+ pressed: activePressedStyling,
497
515
  disabled: {
498
516
  color: light ? fadedColor : theme.color.text.disabled,
499
517
  cursor: "default"
package/dist/index.js CHANGED
@@ -39,6 +39,7 @@ var _objectWithoutPropertiesLoose__default = /*#__PURE__*/_interopDefaultLegacy(
39
39
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
40
40
  var tokens__namespace = /*#__PURE__*/_interopNamespace(tokens);
41
41
 
42
+ const textUnderlineOffset = tokens__namespace.spacing.xxxSmall_4;
42
43
  const theme$1 = {
43
44
  color: {
44
45
  bg: {
@@ -54,8 +55,7 @@ const theme$1 = {
54
55
  },
55
56
  primary: {
56
57
  default: tokens__namespace.color.white,
57
- disabled: tokens__namespace.color.offBlack32,
58
- inverse: tokens__namespace.color.darkBlue
58
+ disabled: tokens__namespace.color.offBlack32
59
59
  },
60
60
  secondary: {
61
61
  default: "none",
@@ -66,9 +66,6 @@ const theme$1 = {
66
66
  critical: tokens__namespace.color.fadedRed
67
67
  }
68
68
  },
69
- tertiary: {
70
- hover: tokens__namespace.color.white
71
- },
72
69
  icon: {
73
70
  secondaryHover: "transparent"
74
71
  }
@@ -107,9 +104,11 @@ const theme$1 = {
107
104
  focused: tokens__namespace.border.width.thin,
108
105
  disabled: tokens__namespace.border.width.thin
109
106
  },
107
+ offset: {
108
+ primary: tokens__namespace.spacing.xxxxSmall_2
109
+ },
110
110
  radius: {
111
111
  default: tokens__namespace.border.radius.medium_4,
112
- tertiary: tokens__namespace.border.radius.xSmall_2,
113
112
  small: tokens__namespace.border.radius.medium_4,
114
113
  large: tokens__namespace.border.radius.large_6,
115
114
  icon: tokens__namespace.border.radius.full
@@ -117,10 +116,13 @@ const theme$1 = {
117
116
  },
118
117
  size: {
119
118
  height: {
120
- tertiaryHover: tokens__namespace.spacing.xxxxSmall_2,
121
119
  small: tokens__namespace.spacing.xLarge_32,
122
120
  medium: 40,
123
121
  large: 56
122
+ },
123
+ underline: {
124
+ hover: tokens__namespace.spacing.xxxxSmall_2,
125
+ active: 1
124
126
  }
125
127
  },
126
128
  margin: {
@@ -140,10 +142,15 @@ const theme$1 = {
140
142
  large: 18
141
143
  },
142
144
  lineHeight: {
143
- large: tokens__namespace.font.lineHeight.medium
145
+ small: tokens__namespace.font.lineHeight.small + textUnderlineOffset,
146
+ default: tokens__namespace.font.lineHeight.medium + textUnderlineOffset,
147
+ large: tokens__namespace.font.lineHeight.medium + 2 + textUnderlineOffset
144
148
  },
145
149
  weight: {
146
150
  default: tokens__namespace.font.weight.bold
151
+ },
152
+ offset: {
153
+ default: textUnderlineOffset
147
154
  }
148
155
  }
149
156
  };
@@ -272,7 +279,7 @@ const ButtonCore = React__namespace.forwardRef(function ButtonCore(props, ref) {
272
279
  restProps = _objectWithoutPropertiesLoose__default["default"](props, _excluded$1);
273
280
  const buttonStyles = _generateStyles(color, kind, light, size, theme, themeName);
274
281
  const disabled = spinner || disabledProp;
275
- const defaultStyle = [sharedStyles.shared, disabled && sharedStyles.disabled, startIcon && sharedStyles.withStartIcon, endIcon && sharedStyles.withEndIcon, buttonStyles.default, disabled && buttonStyles.disabled, kind !== "tertiary" && !disabled && (pressed ? buttonStyles.active : (hovered || focused) && buttonStyles.focus), kind === "tertiary" && !pressed && focused && [buttonStyles.focus, disabled && buttonStyles.disabledFocus], size === "small" && sharedStyles.small, size === "large" && sharedStyles.large];
282
+ const defaultStyle = [sharedStyles.shared, disabled && sharedStyles.disabled, startIcon && sharedStyles.withStartIcon, endIcon && sharedStyles.withEndIcon, buttonStyles.default, disabled && buttonStyles.disabled, kind !== "tertiary" && !disabled && (pressed ? buttonStyles.pressed : focused && buttonStyles.focused), kind === "tertiary" && !pressed && focused && [buttonStyles.focused, disabled && buttonStyles.disabledFocus], size === "small" && sharedStyles.small, size === "large" && sharedStyles.large];
276
283
  const commonProps = _extends__default["default"]({
277
284
  "data-testid": testId,
278
285
  id: id,
@@ -281,7 +288,7 @@ const ButtonCore = React__namespace.forwardRef(function ButtonCore(props, ref) {
281
288
  }, restProps);
282
289
  const Label = size === "small" ? wonderBlocksTypography.LabelSmall : wonderBlocksTypography.LabelLarge;
283
290
  const label = React__namespace.createElement(Label, {
284
- style: [sharedStyles.text, size === "large" && sharedStyles.largeText, labelStyle, spinner && sharedStyles.hiddenText, kind === "tertiary" && sharedStyles.textWithFocus, kind === "tertiary" && !disabled && (pressed ? [buttonStyles.hover, buttonStyles.active] : hovered && buttonStyles.hover)],
291
+ style: [sharedStyles.text, size === "small" && sharedStyles.smallText, size === "large" && sharedStyles.largeText, labelStyle, spinner && sharedStyles.hiddenText, kind === "tertiary" && sharedStyles.textWithFocus, kind === "tertiary" && !disabled && (pressed ? [buttonStyles.hover, buttonStyles.active] : hovered && buttonStyles.hover)],
285
292
  testId: testId ? `${testId}-inner-label` : undefined
286
293
  }, children);
287
294
  const sizeMapping = {
@@ -368,10 +375,14 @@ const themedSharedStyles = theme => ({
368
375
  fontWeight: theme.font.weight.default,
369
376
  whiteSpace: "nowrap",
370
377
  overflow: "hidden",
378
+ lineHeight: `${theme.font.lineHeight.default}px`,
371
379
  textOverflow: "ellipsis",
372
380
  display: "inline-block",
373
381
  pointerEvents: "none"
374
382
  },
383
+ smallText: {
384
+ lineHeight: `${theme.font.lineHeight.small}px`
385
+ },
375
386
  largeText: {
376
387
  fontSize: theme.font.size.large,
377
388
  lineHeight: `${theme.font.lineHeight.large}px`
@@ -424,34 +435,55 @@ const _generateStyles = (buttonColor = "default", kind, light, size, theme, them
424
435
  const padding = size === "large" ? theme.padding.xLarge : theme.padding.large;
425
436
  let newStyles = {};
426
437
  if (kind === "primary") {
427
- const boxShadowInnerColor = light ? theme.color.bg.primary.inverse : theme.color.bg.primary.default;
438
+ const focusStyling = {
439
+ outlineColor: light ? theme.color.bg.primary.default : color,
440
+ outlineOffset: theme.border.offset.primary,
441
+ outlineStyle: "solid",
442
+ outlineWidth: theme.border.width.focused
443
+ };
444
+ const activePressedStyling = {
445
+ background: light ? fadedColor : activeColor,
446
+ outlineColor: light ? fadedColor : activeColor
447
+ };
428
448
  newStyles = {
429
449
  default: {
430
450
  background: light ? theme.color.bg.primary.default : color,
431
451
  color: light ? color : theme.color.text.inverse,
432
452
  paddingLeft: padding,
433
- paddingRight: padding
434
- },
435
- focus: {
436
- boxShadow: `0 0 0 1px ${boxShadowInnerColor}, 0 0 0 3px ${light ? theme.color.bg.primary.default : color}`
437
- },
438
- active: {
439
- boxShadow: `0 0 0 1px ${boxShadowInnerColor}, 0 0 0 3px ${light ? fadedColor : activeColor}`,
440
- background: light ? fadedColor : activeColor,
441
- color: light ? activeColor : fadedColor
453
+ paddingRight: padding,
454
+ [":hover:not([aria-disabled=true])"]: focusStyling,
455
+ [":focus-visible:not([aria-disabled=true])"]: focusStyling,
456
+ [":active:not([aria-disabled=true])"]: activePressedStyling
442
457
  },
458
+ focused: focusStyling,
459
+ pressed: activePressedStyling,
443
460
  disabled: {
444
461
  background: light ? fadedColor : theme.color.bg.primary.disabled,
445
462
  color: light ? color : theme.color.text.primary.disabled,
446
463
  cursor: "default",
447
- ":focus": {
448
- boxShadow: `0 0 0 1px ${light ? theme.color.bg.primary.disabled : theme.color.bg.primary.default}, 0 0 0 3px ${light ? fadedColor : theme.color.bg.primary.disabled}`
449
- }
464
+ ":focus-visible": _extends__default["default"]({}, focusStyling, {
465
+ outlineColor: light ? fadedColor : theme.color.bg.primary.disabled
466
+ })
450
467
  }
451
468
  };
452
469
  } else if (kind === "secondary") {
453
470
  const secondaryBorderColor = buttonColor === "destructive" ? theme.color.border.secondary.critical : theme.color.border.secondary.action;
454
471
  const secondaryActiveColor = buttonColor === "destructive" ? theme.color.bg.secondary.active.critical : theme.color.bg.secondary.active.action;
472
+ const focusStyling = {
473
+ background: light ? theme.color.bg.secondary.inverse : theme.color.bg.secondary.focus,
474
+ borderColor: "transparent",
475
+ outlineColor: light ? theme.color.border.primary.inverse : color,
476
+ outlineStyle: "solid",
477
+ outlineWidth: theme.border.width.focused
478
+ };
479
+ const activePressedStyling = {
480
+ background: light ? activeColor : secondaryActiveColor,
481
+ color: light ? fadedColor : activeColor,
482
+ borderColor: "transparent",
483
+ outlineColor: light ? fadedColor : activeColor,
484
+ outlineStyle: "solid",
485
+ outlineWidth: theme.border.width.focused
486
+ };
455
487
  newStyles = {
456
488
  default: {
457
489
  background: light ? theme.color.bg.secondary.inverse : theme.color.bg.secondary.default,
@@ -460,28 +492,18 @@ const _generateStyles = (buttonColor = "default", kind, light, size, theme, them
460
492
  borderStyle: "solid",
461
493
  borderWidth: theme.border.width.secondary,
462
494
  paddingLeft: padding,
463
- paddingRight: padding
464
- },
465
- focus: {
466
- background: light ? theme.color.bg.secondary.inverse : theme.color.bg.secondary.focus,
467
- borderColor: "transparent",
468
- outlineColor: light ? theme.color.border.primary.inverse : color,
469
- outlineStyle: "solid",
470
- outlineWidth: theme.border.width.focused
471
- },
472
- active: {
473
- background: light ? activeColor : secondaryActiveColor,
474
- color: light ? fadedColor : activeColor,
475
- borderColor: "transparent",
476
- outlineColor: light ? fadedColor : activeColor,
477
- outlineStyle: "solid",
478
- outlineWidth: theme.border.width.focused
495
+ paddingRight: padding,
496
+ [":hover:not([aria-disabled=true])"]: focusStyling,
497
+ [":focus-visible:not([aria-disabled=true])"]: focusStyling,
498
+ [":active:not([aria-disabled=true])"]: activePressedStyling
479
499
  },
500
+ focused: focusStyling,
501
+ pressed: activePressedStyling,
480
502
  disabled: {
481
503
  color: light ? theme.color.text.secondary.inverse : theme.color.text.disabled,
482
504
  outlineColor: light ? fadedColor : theme.color.border.disabled,
483
505
  cursor: "default",
484
- ":focus": {
506
+ ":focus-visible": {
485
507
  outlineColor: light ? theme.color.border.secondary.inverse : theme.color.border.disabled,
486
508
  outlineStyle: "solid",
487
509
  outlineWidth: theme.border.width.disabled
@@ -489,38 +511,34 @@ const _generateStyles = (buttonColor = "default", kind, light, size, theme, them
489
511
  }
490
512
  };
491
513
  } else if (kind === "tertiary") {
514
+ const focusStyling = {
515
+ outlineStyle: "solid",
516
+ outlineColor: light ? theme.color.border.tertiary.inverse : color,
517
+ outlineWidth: theme.border.width.focused,
518
+ borderRadius: theme.border.radius.default
519
+ };
520
+ const activePressedStyling = {
521
+ color: light ? fadedColor : activeColor,
522
+ textDecoration: "underline",
523
+ textDecorationThickness: theme.size.underline.active,
524
+ textUnderlineOffset: theme.font.offset.default
525
+ };
492
526
  newStyles = {
493
527
  default: {
494
528
  background: "none",
495
529
  color: light ? theme.color.text.inverse : color,
496
530
  paddingLeft: 0,
497
- paddingRight: 0
498
- },
499
- hover: {
500
- ":after": {
501
- content: "''",
502
- position: "absolute",
503
- height: theme.size.height.tertiaryHover,
504
- width: "100%",
505
- right: 0,
506
- bottom: 0,
507
- background: light ? theme.color.bg.tertiary.hover : color,
508
- borderRadius: theme.border.radius.tertiary
509
- }
510
- },
511
- focus: {
512
- outlineStyle: "solid",
513
- outlineColor: light ? theme.color.border.tertiary.inverse : color,
514
- outlineWidth: theme.border.width.focused,
515
- borderRadius: theme.border.radius.default
516
- },
517
- active: {
518
- color: light ? fadedColor : activeColor,
519
- ":after": {
520
- height: theme.size.height.tertiaryHover,
521
- background: light ? fadedColor : activeColor
522
- }
531
+ paddingRight: 0,
532
+ [":hover:not([aria-disabled=true])"]: {
533
+ textUnderlineOffset: theme.font.offset.default,
534
+ textDecoration: "underline",
535
+ textDecorationThickness: theme.size.underline.hover
536
+ },
537
+ [":focus-visible:not([aria-disabled=true])"]: focusStyling,
538
+ [":active:not([aria-disabled=true])"]: activePressedStyling
523
539
  },
540
+ focused: focusStyling,
541
+ pressed: activePressedStyling,
524
542
  disabled: {
525
543
  color: light ? fadedColor : theme.color.text.disabled,
526
544
  cursor: "default"
@@ -20,7 +20,6 @@ declare const theme: {
20
20
  primary: {
21
21
  default: string;
22
22
  disabled: string;
23
- inverse: string;
24
23
  };
25
24
  secondary: {
26
25
  default: string;
@@ -31,9 +30,6 @@ declare const theme: {
31
30
  critical: string;
32
31
  };
33
32
  };
34
- tertiary: {
35
- hover: string;
36
- };
37
33
  /**
38
34
  * Icons
39
35
  */
@@ -90,9 +86,11 @@ declare const theme: {
90
86
  focused: number;
91
87
  disabled: number;
92
88
  };
89
+ offset: {
90
+ primary: 2;
91
+ };
93
92
  radius: {
94
93
  default: number;
95
- tertiary: number;
96
94
  small: number;
97
95
  large: number;
98
96
  /**
@@ -103,11 +101,14 @@ declare const theme: {
103
101
  };
104
102
  size: {
105
103
  height: {
106
- tertiaryHover: 2;
107
104
  small: 32;
108
105
  medium: number;
109
106
  large: number;
110
107
  };
108
+ underline: {
109
+ hover: 2;
110
+ active: number;
111
+ };
111
112
  };
112
113
  margin: {
113
114
  icon: {
@@ -126,11 +127,16 @@ declare const theme: {
126
127
  large: number;
127
128
  };
128
129
  lineHeight: {
130
+ small: number;
131
+ default: number;
129
132
  large: number;
130
133
  };
131
134
  weight: {
132
135
  default: number;
133
136
  };
137
+ offset: {
138
+ default: 4;
139
+ };
134
140
  };
135
141
  };
136
142
  export default theme;
@@ -17,7 +17,6 @@ declare const theme: {
17
17
  primary: {
18
18
  default: string;
19
19
  disabled: string;
20
- inverse: string;
21
20
  };
22
21
  secondary: {
23
22
  default: string;
@@ -28,9 +27,6 @@ declare const theme: {
28
27
  critical: string;
29
28
  };
30
29
  };
31
- tertiary: {
32
- hover: string;
33
- };
34
30
  icon: {
35
31
  secondaryHover: string;
36
32
  };
@@ -69,9 +65,11 @@ declare const theme: {
69
65
  focused: number;
70
66
  disabled: number;
71
67
  };
68
+ offset: {
69
+ primary: 2;
70
+ };
72
71
  radius: {
73
72
  default: number;
74
- tertiary: number;
75
73
  small: number;
76
74
  large: number;
77
75
  icon: string;
@@ -79,11 +77,14 @@ declare const theme: {
79
77
  };
80
78
  size: {
81
79
  height: {
82
- tertiaryHover: 2;
83
80
  small: 32;
84
81
  medium: number;
85
82
  large: number;
86
83
  };
84
+ underline: {
85
+ hover: 2;
86
+ active: number;
87
+ };
87
88
  };
88
89
  margin: {
89
90
  icon: {
@@ -102,11 +103,16 @@ declare const theme: {
102
103
  large: number;
103
104
  };
104
105
  lineHeight: {
106
+ small: number;
107
+ default: number;
105
108
  large: number;
106
109
  };
107
110
  weight: {
108
111
  default: number;
109
112
  };
113
+ offset: {
114
+ default: 4;
115
+ };
110
116
  };
111
117
  };
112
118
  export default theme;
@@ -24,7 +24,6 @@ export declare const ButtonThemeContext: React.Context<{
24
24
  primary: {
25
25
  default: string;
26
26
  disabled: string;
27
- inverse: string;
28
27
  };
29
28
  secondary: {
30
29
  default: string;
@@ -35,9 +34,6 @@ export declare const ButtonThemeContext: React.Context<{
35
34
  critical: string;
36
35
  };
37
36
  };
38
- tertiary: {
39
- hover: string;
40
- };
41
37
  icon: {
42
38
  secondaryHover: string;
43
39
  };
@@ -76,9 +72,11 @@ export declare const ButtonThemeContext: React.Context<{
76
72
  focused: number;
77
73
  disabled: number;
78
74
  };
75
+ offset: {
76
+ primary: 2;
77
+ };
79
78
  radius: {
80
79
  default: number;
81
- tertiary: number;
82
80
  small: number;
83
81
  large: number;
84
82
  icon: string;
@@ -86,11 +84,14 @@ export declare const ButtonThemeContext: React.Context<{
86
84
  };
87
85
  size: {
88
86
  height: {
89
- tertiaryHover: 2;
90
87
  small: 32;
91
88
  medium: number;
92
89
  large: number;
93
90
  };
91
+ underline: {
92
+ hover: 2;
93
+ active: number;
94
+ };
94
95
  };
95
96
  margin: {
96
97
  icon: {
@@ -109,11 +110,16 @@ export declare const ButtonThemeContext: React.Context<{
109
110
  large: number;
110
111
  };
111
112
  lineHeight: {
113
+ small: number;
114
+ default: number;
112
115
  large: number;
113
116
  };
114
117
  weight: {
115
118
  default: number;
116
119
  };
120
+ offset: {
121
+ default: 4;
122
+ };
117
123
  };
118
124
  }>;
119
125
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-button",
3
- "version": "7.0.3",
3
+ "version": "7.0.5",
4
4
  "design": "v1",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -10,19 +10,20 @@
10
10
  "module": "dist/es/index.js",
11
11
  "types": "dist/index.d.ts",
12
12
  "scripts": {
13
- "test": "echo \"Error: no test specified\" && exit 1"
13
+ "test": "echo \"Error: no test specified\" && exit 1",
14
+ "prepublishOnly": "../../utils/publish/package-pre-publish-check.sh"
14
15
  },
15
16
  "author": "",
16
17
  "license": "MIT",
17
18
  "dependencies": {
18
19
  "@babel/runtime": "^7.18.6",
19
- "@khanacademy/wonder-blocks-clickable": "^5.0.3",
20
- "@khanacademy/wonder-blocks-core": "^11.0.0",
21
- "@khanacademy/wonder-blocks-icon": "^5.0.3",
22
- "@khanacademy/wonder-blocks-progress-spinner": "^3.0.3",
23
- "@khanacademy/wonder-blocks-theming": "^3.0.0",
24
- "@khanacademy/wonder-blocks-tokens": "^3.0.0",
25
- "@khanacademy/wonder-blocks-typography": "^3.0.3"
20
+ "@khanacademy/wonder-blocks-clickable": "^5.0.5",
21
+ "@khanacademy/wonder-blocks-core": "^11.1.0",
22
+ "@khanacademy/wonder-blocks-icon": "^5.0.5",
23
+ "@khanacademy/wonder-blocks-progress-spinner": "^3.0.5",
24
+ "@khanacademy/wonder-blocks-theming": "^3.0.1",
25
+ "@khanacademy/wonder-blocks-tokens": "^3.0.1",
26
+ "@khanacademy/wonder-blocks-typography": "^3.0.5"
26
27
  },
27
28
  "peerDependencies": {
28
29
  "aphrodite": "^1.2.5",