@khanacademy/wonder-blocks-button 4.0.13 → 4.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/dist/index.js CHANGED
@@ -69,10 +69,9 @@ const _excluded$1 = ["children", "skipClientNav", "color", "disabled", "focused"
69
69
  const StyledAnchor = wonderBlocksCore.addStyle("a");
70
70
  const StyledButton = wonderBlocksCore.addStyle("button");
71
71
  const StyledLink = wonderBlocksCore.addStyle(reactRouterDom.Link);
72
- class ButtonCore extends React__namespace.Component {
73
- renderInner(router) {
74
- const _this$props = this.props,
75
- {
72
+ const ButtonCore = React__namespace.forwardRef((props, ref) => {
73
+ const renderInner = router => {
74
+ const {
76
75
  children,
77
76
  skipClientNav,
78
77
  color,
@@ -80,23 +79,23 @@ class ButtonCore extends React__namespace.Component {
80
79
  focused,
81
80
  hovered,
82
81
  href = undefined,
83
- kind,
84
- light,
82
+ kind = "primary",
83
+ light = false,
85
84
  pressed,
86
- size,
85
+ size = "medium",
87
86
  style,
88
87
  testId,
89
88
  type = undefined,
90
89
  spinner,
91
90
  icon,
92
91
  id
93
- } = _this$props,
94
- restProps = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
92
+ } = props,
93
+ restProps = _objectWithoutPropertiesLoose(props, _excluded$1);
95
94
  const buttonColor = color === "destructive" ? Color.SemanticColor.controlDestructive : Color.SemanticColor.controlDefault;
96
95
  const iconWidth = icon ? (size === "small" ? 16 : 24) + 8 : 0;
97
96
  const buttonStyles = _generateStyles(buttonColor, kind, light, iconWidth, size);
98
97
  const disabled = spinner || disabledProp;
99
- const defaultStyle = [sharedStyles.shared, disabled && sharedStyles.disabled, icon && sharedStyles.withIcon, buttonStyles.default, disabled && buttonStyles.disabled, kind !== "tertiary" && !disabled && (pressed ? buttonStyles.active : (hovered || focused) && buttonStyles.focus), size === "small" && sharedStyles.small, size === "large" && sharedStyles.large];
98
+ const defaultStyle = [sharedStyles.shared, disabled && sharedStyles.disabled, icon && sharedStyles.withIcon, 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];
100
99
  const commonProps = _extends({
101
100
  "data-test-id": testId,
102
101
  id: id,
@@ -106,19 +105,22 @@ class ButtonCore extends React__namespace.Component {
106
105
  const Label = size === "small" ? wonderBlocksTypography.LabelSmall : wonderBlocksTypography.LabelLarge;
107
106
  const iconSize = size === "small" ? "small" : "medium";
108
107
  const label = React__namespace.createElement(Label, {
109
- style: [sharedStyles.text, size === "large" && sharedStyles.largeText, icon && sharedStyles.textWithIcon, spinner && sharedStyles.hiddenText, kind === "tertiary" && sharedStyles.textWithFocus, kind === "tertiary" && !disabled && (pressed ? buttonStyles.active : (hovered || focused) && buttonStyles.focus), kind === "tertiary" && disabled && focused && [buttonStyles.focus, buttonStyles.disabledFocus]]
110
- }, icon && React__namespace.createElement(Icon__default["default"], {
111
- size: iconSize,
112
- color: "currentColor",
113
- icon: icon,
114
- style: sharedStyles.icon
115
- }), children);
108
+ style: [sharedStyles.text, size === "large" && sharedStyles.largeText, spinner && sharedStyles.hiddenText, kind === "tertiary" && sharedStyles.textWithFocus, kind === "tertiary" && !disabled && (pressed ? [buttonStyles.hover, buttonStyles.active] : hovered && buttonStyles.hover)],
109
+ testId: testId ? `${testId}-inner-label` : undefined
110
+ }, children);
116
111
  const sizeMapping = {
117
112
  medium: "small",
118
113
  small: "xsmall",
119
114
  large: "medium"
120
115
  };
121
- const contents = React__namespace.createElement(React__namespace.Fragment, null, label, spinner && React__namespace.createElement(wonderBlocksProgressSpinner.CircularSpinner, {
116
+ const contents = React__namespace.createElement(React__namespace.Fragment, null, icon && React__namespace.createElement(Icon__default["default"], {
117
+ size: iconSize,
118
+ color: "currentColor",
119
+ icon: icon,
120
+ style: sharedStyles.icon,
121
+ "aria-hidden": "true",
122
+ testId: testId ? `${testId}-icon` : undefined
123
+ }), label, spinner && React__namespace.createElement(wonderBlocksProgressSpinner.CircularSpinner, {
122
124
  style: sharedStyles.spinner,
123
125
  size: sizeMapping[size],
124
126
  light: kind === "primary",
@@ -126,22 +128,23 @@ class ButtonCore extends React__namespace.Component {
126
128
  }));
127
129
  if (href && !disabled) {
128
130
  return router && !skipClientNav && wonderBlocksClickable.isClientSideUrl(href) ? React__namespace.createElement(StyledLink, _extends({}, commonProps, {
129
- to: href
131
+ to: href,
132
+ ref: ref
130
133
  }), contents) : React__namespace.createElement(StyledAnchor, _extends({}, commonProps, {
131
- href: href
134
+ href: href,
135
+ ref: ref
132
136
  }), contents);
133
137
  } else {
134
138
  return React__namespace.createElement(StyledButton, _extends({
135
139
  type: type || "button"
136
140
  }, commonProps, {
137
- "aria-disabled": disabled
141
+ "aria-disabled": disabled,
142
+ ref: ref
138
143
  }), contents);
139
144
  }
140
- }
141
- render() {
142
- return React__namespace.createElement(reactRouter.__RouterContext.Consumer, null, router => this.renderInner(router));
143
- }
144
- }
145
+ };
146
+ return React__namespace.createElement(reactRouter.__RouterContext.Consumer, null, router => renderInner(router));
147
+ });
145
148
  const sharedStyles = aphrodite.StyleSheet.create({
146
149
  shared: {
147
150
  position: "relative",
@@ -191,9 +194,6 @@ const sharedStyles = aphrodite.StyleSheet.create({
191
194
  fontSize: 18,
192
195
  lineHeight: "20px"
193
196
  },
194
- textWithIcon: {
195
- display: "flex"
196
- },
197
197
  textWithFocus: {
198
198
  position: "relative"
199
199
  },
@@ -258,14 +258,14 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
258
258
  borderColor: light ? white50 : offBlack50,
259
259
  borderStyle: "solid",
260
260
  borderWidth: 1,
261
- paddingLeft: iconWidth ? padding - 4 : padding,
261
+ paddingLeft: padding,
262
262
  paddingRight: padding
263
263
  },
264
264
  focus: {
265
265
  background: light ? "transparent" : white,
266
266
  borderColor: light ? white : color,
267
267
  borderWidth: 2,
268
- paddingLeft: iconWidth ? padding - 5 : padding - 1,
268
+ paddingLeft: padding - 1,
269
269
  paddingRight: padding - 1
270
270
  },
271
271
  active: {
@@ -273,7 +273,7 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
273
273
  color: light ? fadedColor : activeColor,
274
274
  borderColor: light ? fadedColor : activeColor,
275
275
  borderWidth: 2,
276
- paddingLeft: iconWidth ? padding - 5 : padding - 1,
276
+ paddingLeft: padding - 1,
277
277
  paddingRight: padding - 1
278
278
  },
279
279
  disabled: {
@@ -283,7 +283,7 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
283
283
  ":focus": {
284
284
  borderColor: light ? white50 : offBlack32,
285
285
  borderWidth: 2,
286
- paddingLeft: iconWidth ? padding - 5 : padding - 1,
286
+ paddingLeft: padding - 1,
287
287
  paddingRight: padding - 1
288
288
  }
289
289
  }
@@ -296,29 +296,35 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
296
296
  paddingLeft: 0,
297
297
  paddingRight: 0
298
298
  },
299
- focus: {
299
+ hover: {
300
300
  ":after": {
301
301
  content: "''",
302
302
  position: "absolute",
303
303
  height: 2,
304
- width: `calc(100% - ${iconWidth}px)`,
304
+ width: "100%",
305
305
  right: 0,
306
306
  bottom: 0,
307
307
  background: light ? white : color,
308
308
  borderRadius: 2
309
309
  }
310
310
  },
311
- active: {
312
- color: light ? fadedColor : activeColor,
311
+ focus: {
313
312
  ":after": {
314
313
  content: "''",
315
314
  position: "absolute",
316
- height: 2,
317
- width: `calc(100% - ${iconWidth}px)`,
318
- right: 0,
319
- bottom: -1,
320
- background: light ? fadedColor : activeColor,
321
- borderRadius: 2
315
+ width: `calc(100% + ${Spacing__default["default"].xxxSmall_4}px)`,
316
+ height: `calc(100% - ${Spacing__default["default"].xxxSmall_4}px)`,
317
+ borderStyle: "solid",
318
+ borderColor: light ? white : color,
319
+ borderWidth: Spacing__default["default"].xxxxSmall_2,
320
+ borderRadius: Spacing__default["default"].xxxSmall_4
321
+ }
322
+ },
323
+ active: {
324
+ color: light ? fadedColor : activeColor,
325
+ ":after": {
326
+ height: 1,
327
+ background: light ? fadedColor : activeColor
322
328
  }
323
329
  },
324
330
  disabled: {
@@ -327,7 +333,7 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
327
333
  },
328
334
  disabledFocus: {
329
335
  ":after": {
330
- background: light ? white : offBlack32
336
+ borderColor: light ? white50 : offBlack32
331
337
  }
332
338
  }
333
339
  };
@@ -338,35 +344,43 @@ const _generateStyles = (color, kind, light, iconWidth, size) => {
338
344
  return styles[buttonType];
339
345
  };
340
346
 
341
- const _excluded = ["href", "type", "children", "skipClientNav", "spinner", "disabled", "onClick", "beforeNav", "safeWithNav", "tabIndex", "target", "rel"];
342
- class Button extends React__namespace.Component {
343
- renderClickableBehavior(router) {
344
- const _this$props = this.props,
345
- {
346
- href = undefined,
347
- type = undefined,
348
- children,
349
- skipClientNav,
350
- spinner,
351
- disabled,
352
- onClick,
353
- beforeNav = undefined,
354
- safeWithNav = undefined,
355
- tabIndex,
356
- target,
357
- rel
358
- } = _this$props,
359
- sharedButtonCoreProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
347
+ const _excluded = ["href", "type", "children", "skipClientNav", "onClick", "beforeNav", "safeWithNav", "tabIndex", "target", "rel", "color", "kind", "light", "size", "disabled", "spinner"];
348
+ const Button = React__namespace.forwardRef((props, ref) => {
349
+ const {
350
+ href = undefined,
351
+ type = undefined,
352
+ children,
353
+ skipClientNav,
354
+ onClick,
355
+ beforeNav = undefined,
356
+ safeWithNav = undefined,
357
+ tabIndex,
358
+ target,
359
+ rel,
360
+ color = "default",
361
+ kind = "primary",
362
+ light = false,
363
+ size = "medium",
364
+ disabled = false,
365
+ spinner = false
366
+ } = props,
367
+ sharedButtonCoreProps = _objectWithoutPropertiesLoose(props, _excluded);
368
+ const renderClickableBehavior = router => {
360
369
  const ClickableBehavior = wonderBlocksClickable.getClickableBehavior(href, skipClientNav, router);
361
370
  const renderProp = (state, restChildProps) => {
362
371
  return React__namespace.createElement(ButtonCore, _extends({}, sharedButtonCoreProps, state, restChildProps, {
363
372
  disabled: disabled,
364
373
  spinner: spinner || state.waiting,
374
+ color: color,
375
+ kind: kind,
376
+ light: light,
377
+ size: size,
365
378
  skipClientNav: skipClientNav,
366
379
  href: href,
367
380
  target: target,
368
381
  type: type,
369
- tabIndex: tabIndex
382
+ tabIndex: tabIndex,
383
+ ref: ref
370
384
  }), children);
371
385
  };
372
386
  if (beforeNav) {
@@ -392,18 +406,8 @@ class Button extends React__namespace.Component {
392
406
  rel: rel
393
407
  }, renderProp);
394
408
  }
395
- }
396
- render() {
397
- return React__namespace.createElement(reactRouter.__RouterContext.Consumer, null, router => this.renderClickableBehavior(router));
398
- }
399
- }
400
- Button.defaultProps = {
401
- color: "default",
402
- kind: "primary",
403
- light: false,
404
- size: "medium",
405
- disabled: false,
406
- spinner: false
407
- };
409
+ };
410
+ return React__namespace.createElement(reactRouter.__RouterContext.Consumer, null, router => renderClickableBehavior(router));
411
+ });
408
412
 
409
413
  module.exports = Button;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-button",
3
- "version": "4.0.13",
3
+ "version": "4.1.0",
4
4
  "design": "v1",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -16,13 +16,13 @@
16
16
  "license": "MIT",
17
17
  "dependencies": {
18
18
  "@babel/runtime": "^7.18.6",
19
- "@khanacademy/wonder-blocks-clickable": "^3.0.13",
19
+ "@khanacademy/wonder-blocks-clickable": "^3.1.1",
20
20
  "@khanacademy/wonder-blocks-color": "^2.0.1",
21
- "@khanacademy/wonder-blocks-core": "^5.2.3",
22
- "@khanacademy/wonder-blocks-icon": "^2.0.13",
23
- "@khanacademy/wonder-blocks-progress-spinner": "^2.0.13",
21
+ "@khanacademy/wonder-blocks-core": "^5.3.0",
22
+ "@khanacademy/wonder-blocks-icon": "^2.0.14",
23
+ "@khanacademy/wonder-blocks-progress-spinner": "^2.0.14",
24
24
  "@khanacademy/wonder-blocks-spacing": "^4.0.1",
25
- "@khanacademy/wonder-blocks-typography": "^2.0.13"
25
+ "@khanacademy/wonder-blocks-typography": "^2.1.0"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "aphrodite": "^1.2.5",