@spark-web/button 1.1.2 → 1.2.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/README.md +14 -22
- package/dist/declarations/src/BaseButton.d.ts +10 -0
- package/dist/declarations/src/Button.d.ts +1 -7
- package/dist/declarations/src/index.d.ts +2 -0
- package/dist/spark-web-button.cjs.dev.js +64 -36
- package/dist/spark-web-button.cjs.prod.js +64 -36
- package/dist/spark-web-button.esm.js +64 -37
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -196,25 +196,17 @@ with the exception of `href` vs `onClick` props.
|
|
|
196
196
|
</Text>
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
-
##
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
| onClick? | Function | | Function to be fired following a click event of the button. Only applicable for `Button`. |
|
|
214
|
-
| prominence? | 'high' \| 'low' | 'high' | Sets the visual prominence of the button. |
|
|
215
|
-
| size? | 'medium' \| 'large' | 'medium' | Sets the size of the button. |
|
|
216
|
-
| tone? | 'primary' \| 'secondary' \| 'neutral' \| 'positive' \| 'caution' \| 'critical' \| 'info' | 'primary' | Sets the tone of the button. |
|
|
217
|
-
| type? | 'button' \| 'submit' \| 'reset' | 'button' | Sets the button type. Only applicable for `Button`. |
|
|
218
|
-
|
|
219
|
-
[data-attribute-map]:
|
|
220
|
-
https://github.com/brighte-labs/spark-web/blob/e7f6f4285b4cfd876312cc89fbdd094039aa239a/packages/utils/src/internal/buildDataAttributes.ts#L1
|
|
199
|
+
## BaseButton
|
|
200
|
+
|
|
201
|
+
Unstyled button primitive that:
|
|
202
|
+
|
|
203
|
+
- Forwards the button ref
|
|
204
|
+
- Provides a default type of `button` (so it doesn't accidently submit forms if
|
|
205
|
+
left off)
|
|
206
|
+
- Prevents `onClick` from firing when disabled without disabling the button
|
|
207
|
+
- Forces focus of the underlying button when clicked (to address a bug in
|
|
208
|
+
Safari)
|
|
209
|
+
|
|
210
|
+
## Button Props
|
|
211
|
+
|
|
212
|
+
<PropsTable displayName="Button" />
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BoxProps } from '@spark-web/box';
|
|
2
|
+
import type { MouseEvent as ReactMouseEvent } from 'react';
|
|
3
|
+
import type { NativeButtonProps } from './types';
|
|
4
|
+
export declare type BaseButtonProps = NativeButtonProps & Partial<BoxProps>;
|
|
5
|
+
export declare const BaseButton: import("react").ForwardRefExoticComponent<NativeButtonProps & Partial<BoxProps> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
6
|
+
/**
|
|
7
|
+
* handle "disabled" behaviour w/o disabling buttons
|
|
8
|
+
* @see https://axesslab.com/disabled-buttons-suck/
|
|
9
|
+
*/
|
|
10
|
+
export declare function getPreventableClickHandler(onClick: BaseButtonProps['onClick'], disabled: boolean): (event: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
2
|
import type { CommonButtonProps, NativeButtonProps } from './types';
|
|
3
3
|
export declare type ButtonProps = CommonButtonProps & {
|
|
4
4
|
/**
|
|
@@ -26,9 +26,3 @@ export declare type ButtonProps = CommonButtonProps & {
|
|
|
26
26
|
* action will occur when the user interacts with it.
|
|
27
27
|
*/
|
|
28
28
|
export declare const Button: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
29
|
-
/**
|
|
30
|
-
* Prevent click events when the component is "disabled".
|
|
31
|
-
* Note: we don't want to actually disable a button element for several reasons.
|
|
32
|
-
* One being because that would prohibit the use of tooltips.
|
|
33
|
-
*/
|
|
34
|
-
export declare function getPreventableClickHandler(onClick: NativeButtonProps['onClick'], disabled: boolean): (event: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export { BaseButton } from './BaseButton';
|
|
1
2
|
export { Button } from './Button';
|
|
2
3
|
export { ButtonLink } from './ButtonLink';
|
|
4
|
+
export type { BaseButtonProps } from './BaseButton';
|
|
3
5
|
export type { ButtonProps } from './Button';
|
|
4
6
|
export type { ButtonLinkProps } from './ButtonLink';
|
|
@@ -4,18 +4,68 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
6
6
|
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
|
|
7
|
-
var a11y = require('@spark-web/a11y');
|
|
8
7
|
var box = require('@spark-web/box');
|
|
9
|
-
var
|
|
10
|
-
var internal = require('@spark-web/utils/internal');
|
|
8
|
+
var utils = require('@spark-web/utils');
|
|
11
9
|
var react = require('react');
|
|
12
|
-
var text = require('@spark-web/text');
|
|
13
10
|
var jsxRuntime = require('react/jsx-runtime');
|
|
11
|
+
var a11y = require('@spark-web/a11y');
|
|
12
|
+
var spinner = require('@spark-web/spinner');
|
|
13
|
+
var text = require('@spark-web/text');
|
|
14
14
|
var css = require('@emotion/css');
|
|
15
15
|
var theme = require('@spark-web/theme');
|
|
16
16
|
var link = require('@spark-web/link');
|
|
17
|
+
var internal = require('@spark-web/utils/internal');
|
|
17
18
|
var ts = require('@spark-web/utils/ts');
|
|
18
19
|
|
|
20
|
+
var _excluded$2 = ["onClick", "disabled", "type"];
|
|
21
|
+
var BaseButton = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
|
|
22
|
+
var onClickProp = _ref.onClick,
|
|
23
|
+
_ref$disabled = _ref.disabled,
|
|
24
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
25
|
+
_ref$type = _ref.type,
|
|
26
|
+
type = _ref$type === void 0 ? 'button' : _ref$type,
|
|
27
|
+
rest = _objectWithoutProperties(_ref, _excluded$2);
|
|
28
|
+
|
|
29
|
+
var internalRef = react.useRef(null);
|
|
30
|
+
var composedRef = utils.useComposedRefs(internalRef, forwardedRef);
|
|
31
|
+
/**
|
|
32
|
+
* In Safari buttons are not focused automatically by the browser once
|
|
33
|
+
* pressed, the default behaviour is to focus the nearest focusable ancestor.
|
|
34
|
+
* To fix this we need to manually focus the button element after the user
|
|
35
|
+
* presses the element.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
var onClick = react.useCallback(function (event) {
|
|
39
|
+
var _internalRef$current;
|
|
40
|
+
|
|
41
|
+
(_internalRef$current = internalRef.current) === null || _internalRef$current === void 0 ? void 0 : _internalRef$current.focus();
|
|
42
|
+
var preventableClickHandler = getPreventableClickHandler(onClickProp, disabled);
|
|
43
|
+
preventableClickHandler(event);
|
|
44
|
+
}, [disabled, onClickProp]);
|
|
45
|
+
return /*#__PURE__*/jsxRuntime.jsx(box.Box, _objectSpread(_objectSpread({
|
|
46
|
+
as: "button"
|
|
47
|
+
}, rest), {}, {
|
|
48
|
+
onClick: onClick,
|
|
49
|
+
ref: composedRef,
|
|
50
|
+
type: type
|
|
51
|
+
}));
|
|
52
|
+
});
|
|
53
|
+
BaseButton.displayName = 'BaseButton';
|
|
54
|
+
/**
|
|
55
|
+
* handle "disabled" behaviour w/o disabling buttons
|
|
56
|
+
* @see https://axesslab.com/disabled-buttons-suck/
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
function getPreventableClickHandler(onClick, disabled) {
|
|
60
|
+
return function handleClick(event) {
|
|
61
|
+
if (disabled) {
|
|
62
|
+
event.preventDefault();
|
|
63
|
+
} else {
|
|
64
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
19
69
|
var variants = {
|
|
20
70
|
high: {
|
|
21
71
|
primary: {
|
|
@@ -276,13 +326,12 @@ var _excluded$1 = ["aria-controls", "aria-describedby", "aria-expanded", "data",
|
|
|
276
326
|
* Buttons are used to initialize an action, their label should express what
|
|
277
327
|
* action will occur when the user interacts with it.
|
|
278
328
|
*/
|
|
279
|
-
var Button = /*#__PURE__*/react.forwardRef(function (_ref,
|
|
329
|
+
var Button = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
|
|
280
330
|
var ariaControls = _ref['aria-controls'],
|
|
281
331
|
ariaDescribedBy = _ref['aria-describedby'],
|
|
282
332
|
ariaExpanded = _ref['aria-expanded'],
|
|
283
333
|
data = _ref.data,
|
|
284
|
-
|
|
285
|
-
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
334
|
+
disabled = _ref.disabled,
|
|
286
335
|
id = _ref.id,
|
|
287
336
|
_ref$loading = _ref.loading,
|
|
288
337
|
loading = _ref$loading === void 0 ? false : _ref$loading,
|
|
@@ -293,8 +342,7 @@ var Button = /*#__PURE__*/react.forwardRef(function (_ref, ref) {
|
|
|
293
342
|
size = _ref$size === void 0 ? 'medium' : _ref$size,
|
|
294
343
|
_ref$tone = _ref.tone,
|
|
295
344
|
tone = _ref$tone === void 0 ? 'primary' : _ref$tone,
|
|
296
|
-
|
|
297
|
-
type = _ref$type === void 0 ? 'button' : _ref$type,
|
|
345
|
+
type = _ref.type,
|
|
298
346
|
props = _objectWithoutProperties(_ref, _excluded$1);
|
|
299
347
|
|
|
300
348
|
var iconOnly = Boolean(props.label);
|
|
@@ -307,24 +355,18 @@ var Button = /*#__PURE__*/react.forwardRef(function (_ref, ref) {
|
|
|
307
355
|
var isDisabled = disabled || loading;
|
|
308
356
|
var isLoading = loading && !disabled;
|
|
309
357
|
var variant = variants[prominence][tone];
|
|
310
|
-
|
|
311
|
-
* handle "disabled" behaviour w/o disabling buttons
|
|
312
|
-
* @see https://axesslab.com/disabled-buttons-suck/
|
|
313
|
-
*/
|
|
314
|
-
|
|
315
|
-
var handleClick = getPreventableClickHandler(onClick, isDisabled);
|
|
316
|
-
return /*#__PURE__*/jsxRuntime.jsxs(box.Box, _objectSpread(_objectSpread(_objectSpread({
|
|
358
|
+
return /*#__PURE__*/jsxRuntime.jsxs(BaseButton, _objectSpread(_objectSpread({}, buttonStyleProps), {}, {
|
|
317
359
|
"aria-controls": ariaControls,
|
|
318
360
|
"aria-describedby": ariaDescribedBy,
|
|
319
361
|
"aria-disabled": isDisabled,
|
|
320
362
|
"aria-expanded": ariaExpanded,
|
|
321
363
|
"aria-label": props.label,
|
|
322
|
-
|
|
364
|
+
data: data,
|
|
365
|
+
disabled: isDisabled,
|
|
323
366
|
id: id,
|
|
324
|
-
onClick:
|
|
325
|
-
ref:
|
|
326
|
-
type: type
|
|
327
|
-
}, buttonStyleProps), data ? internal.buildDataAttributes(data) : undefined), {}, {
|
|
367
|
+
onClick: onClick,
|
|
368
|
+
ref: forwardedRef,
|
|
369
|
+
type: type,
|
|
328
370
|
children: [resolveButtonChildren(_objectSpread(_objectSpread({}, props), {}, {
|
|
329
371
|
isLoading: isLoading,
|
|
330
372
|
prominence: prominence,
|
|
@@ -336,21 +378,6 @@ var Button = /*#__PURE__*/react.forwardRef(function (_ref, ref) {
|
|
|
336
378
|
}));
|
|
337
379
|
});
|
|
338
380
|
Button.displayName = 'Button';
|
|
339
|
-
/**
|
|
340
|
-
* Prevent click events when the component is "disabled".
|
|
341
|
-
* Note: we don't want to actually disable a button element for several reasons.
|
|
342
|
-
* One being because that would prohibit the use of tooltips.
|
|
343
|
-
*/
|
|
344
|
-
|
|
345
|
-
function getPreventableClickHandler(onClick, disabled) {
|
|
346
|
-
return function handleClick(event) {
|
|
347
|
-
if (disabled) {
|
|
348
|
-
event.preventDefault();
|
|
349
|
-
} else {
|
|
350
|
-
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
381
|
|
|
355
382
|
function Loading(_ref2) {
|
|
356
383
|
var tone = _ref2.tone;
|
|
@@ -413,5 +440,6 @@ var ButtonLink = ts.forwardRefWithAs(function (_ref, ref) {
|
|
|
413
440
|
}));
|
|
414
441
|
});
|
|
415
442
|
|
|
443
|
+
exports.BaseButton = BaseButton;
|
|
416
444
|
exports.Button = Button;
|
|
417
445
|
exports.ButtonLink = ButtonLink;
|
|
@@ -4,18 +4,68 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
6
6
|
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
|
|
7
|
-
var a11y = require('@spark-web/a11y');
|
|
8
7
|
var box = require('@spark-web/box');
|
|
9
|
-
var
|
|
10
|
-
var internal = require('@spark-web/utils/internal');
|
|
8
|
+
var utils = require('@spark-web/utils');
|
|
11
9
|
var react = require('react');
|
|
12
|
-
var text = require('@spark-web/text');
|
|
13
10
|
var jsxRuntime = require('react/jsx-runtime');
|
|
11
|
+
var a11y = require('@spark-web/a11y');
|
|
12
|
+
var spinner = require('@spark-web/spinner');
|
|
13
|
+
var text = require('@spark-web/text');
|
|
14
14
|
var css = require('@emotion/css');
|
|
15
15
|
var theme = require('@spark-web/theme');
|
|
16
16
|
var link = require('@spark-web/link');
|
|
17
|
+
var internal = require('@spark-web/utils/internal');
|
|
17
18
|
var ts = require('@spark-web/utils/ts');
|
|
18
19
|
|
|
20
|
+
var _excluded$2 = ["onClick", "disabled", "type"];
|
|
21
|
+
var BaseButton = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
|
|
22
|
+
var onClickProp = _ref.onClick,
|
|
23
|
+
_ref$disabled = _ref.disabled,
|
|
24
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
25
|
+
_ref$type = _ref.type,
|
|
26
|
+
type = _ref$type === void 0 ? 'button' : _ref$type,
|
|
27
|
+
rest = _objectWithoutProperties(_ref, _excluded$2);
|
|
28
|
+
|
|
29
|
+
var internalRef = react.useRef(null);
|
|
30
|
+
var composedRef = utils.useComposedRefs(internalRef, forwardedRef);
|
|
31
|
+
/**
|
|
32
|
+
* In Safari buttons are not focused automatically by the browser once
|
|
33
|
+
* pressed, the default behaviour is to focus the nearest focusable ancestor.
|
|
34
|
+
* To fix this we need to manually focus the button element after the user
|
|
35
|
+
* presses the element.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
var onClick = react.useCallback(function (event) {
|
|
39
|
+
var _internalRef$current;
|
|
40
|
+
|
|
41
|
+
(_internalRef$current = internalRef.current) === null || _internalRef$current === void 0 ? void 0 : _internalRef$current.focus();
|
|
42
|
+
var preventableClickHandler = getPreventableClickHandler(onClickProp, disabled);
|
|
43
|
+
preventableClickHandler(event);
|
|
44
|
+
}, [disabled, onClickProp]);
|
|
45
|
+
return /*#__PURE__*/jsxRuntime.jsx(box.Box, _objectSpread(_objectSpread({
|
|
46
|
+
as: "button"
|
|
47
|
+
}, rest), {}, {
|
|
48
|
+
onClick: onClick,
|
|
49
|
+
ref: composedRef,
|
|
50
|
+
type: type
|
|
51
|
+
}));
|
|
52
|
+
});
|
|
53
|
+
BaseButton.displayName = 'BaseButton';
|
|
54
|
+
/**
|
|
55
|
+
* handle "disabled" behaviour w/o disabling buttons
|
|
56
|
+
* @see https://axesslab.com/disabled-buttons-suck/
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
function getPreventableClickHandler(onClick, disabled) {
|
|
60
|
+
return function handleClick(event) {
|
|
61
|
+
if (disabled) {
|
|
62
|
+
event.preventDefault();
|
|
63
|
+
} else {
|
|
64
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
19
69
|
var variants = {
|
|
20
70
|
high: {
|
|
21
71
|
primary: {
|
|
@@ -276,13 +326,12 @@ var _excluded$1 = ["aria-controls", "aria-describedby", "aria-expanded", "data",
|
|
|
276
326
|
* Buttons are used to initialize an action, their label should express what
|
|
277
327
|
* action will occur when the user interacts with it.
|
|
278
328
|
*/
|
|
279
|
-
var Button = /*#__PURE__*/react.forwardRef(function (_ref,
|
|
329
|
+
var Button = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
|
|
280
330
|
var ariaControls = _ref['aria-controls'],
|
|
281
331
|
ariaDescribedBy = _ref['aria-describedby'],
|
|
282
332
|
ariaExpanded = _ref['aria-expanded'],
|
|
283
333
|
data = _ref.data,
|
|
284
|
-
|
|
285
|
-
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
334
|
+
disabled = _ref.disabled,
|
|
286
335
|
id = _ref.id,
|
|
287
336
|
_ref$loading = _ref.loading,
|
|
288
337
|
loading = _ref$loading === void 0 ? false : _ref$loading,
|
|
@@ -293,8 +342,7 @@ var Button = /*#__PURE__*/react.forwardRef(function (_ref, ref) {
|
|
|
293
342
|
size = _ref$size === void 0 ? 'medium' : _ref$size,
|
|
294
343
|
_ref$tone = _ref.tone,
|
|
295
344
|
tone = _ref$tone === void 0 ? 'primary' : _ref$tone,
|
|
296
|
-
|
|
297
|
-
type = _ref$type === void 0 ? 'button' : _ref$type,
|
|
345
|
+
type = _ref.type,
|
|
298
346
|
props = _objectWithoutProperties(_ref, _excluded$1);
|
|
299
347
|
|
|
300
348
|
var iconOnly = Boolean(props.label);
|
|
@@ -307,24 +355,18 @@ var Button = /*#__PURE__*/react.forwardRef(function (_ref, ref) {
|
|
|
307
355
|
var isDisabled = disabled || loading;
|
|
308
356
|
var isLoading = loading && !disabled;
|
|
309
357
|
var variant = variants[prominence][tone];
|
|
310
|
-
|
|
311
|
-
* handle "disabled" behaviour w/o disabling buttons
|
|
312
|
-
* @see https://axesslab.com/disabled-buttons-suck/
|
|
313
|
-
*/
|
|
314
|
-
|
|
315
|
-
var handleClick = getPreventableClickHandler(onClick, isDisabled);
|
|
316
|
-
return /*#__PURE__*/jsxRuntime.jsxs(box.Box, _objectSpread(_objectSpread(_objectSpread({
|
|
358
|
+
return /*#__PURE__*/jsxRuntime.jsxs(BaseButton, _objectSpread(_objectSpread({}, buttonStyleProps), {}, {
|
|
317
359
|
"aria-controls": ariaControls,
|
|
318
360
|
"aria-describedby": ariaDescribedBy,
|
|
319
361
|
"aria-disabled": isDisabled,
|
|
320
362
|
"aria-expanded": ariaExpanded,
|
|
321
363
|
"aria-label": props.label,
|
|
322
|
-
|
|
364
|
+
data: data,
|
|
365
|
+
disabled: isDisabled,
|
|
323
366
|
id: id,
|
|
324
|
-
onClick:
|
|
325
|
-
ref:
|
|
326
|
-
type: type
|
|
327
|
-
}, buttonStyleProps), data ? internal.buildDataAttributes(data) : undefined), {}, {
|
|
367
|
+
onClick: onClick,
|
|
368
|
+
ref: forwardedRef,
|
|
369
|
+
type: type,
|
|
328
370
|
children: [resolveButtonChildren(_objectSpread(_objectSpread({}, props), {}, {
|
|
329
371
|
isLoading: isLoading,
|
|
330
372
|
prominence: prominence,
|
|
@@ -336,21 +378,6 @@ var Button = /*#__PURE__*/react.forwardRef(function (_ref, ref) {
|
|
|
336
378
|
}));
|
|
337
379
|
});
|
|
338
380
|
Button.displayName = 'Button';
|
|
339
|
-
/**
|
|
340
|
-
* Prevent click events when the component is "disabled".
|
|
341
|
-
* Note: we don't want to actually disable a button element for several reasons.
|
|
342
|
-
* One being because that would prohibit the use of tooltips.
|
|
343
|
-
*/
|
|
344
|
-
|
|
345
|
-
function getPreventableClickHandler(onClick, disabled) {
|
|
346
|
-
return function handleClick(event) {
|
|
347
|
-
if (disabled) {
|
|
348
|
-
event.preventDefault();
|
|
349
|
-
} else {
|
|
350
|
-
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
381
|
|
|
355
382
|
function Loading(_ref2) {
|
|
356
383
|
var tone = _ref2.tone;
|
|
@@ -413,5 +440,6 @@ var ButtonLink = ts.forwardRefWithAs(function (_ref, ref) {
|
|
|
413
440
|
}));
|
|
414
441
|
});
|
|
415
442
|
|
|
443
|
+
exports.BaseButton = BaseButton;
|
|
416
444
|
exports.Button = Button;
|
|
417
445
|
exports.ButtonLink = ButtonLink;
|
|
@@ -1,17 +1,67 @@
|
|
|
1
1
|
import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
|
|
2
2
|
import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
|
|
3
|
-
import { useFocusRing, VisuallyHidden } from '@spark-web/a11y';
|
|
4
3
|
import { Box } from '@spark-web/box';
|
|
4
|
+
import { useComposedRefs } from '@spark-web/utils';
|
|
5
|
+
import { forwardRef, useRef, useCallback, Children, isValidElement, cloneElement } from 'react';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
import { useFocusRing, VisuallyHidden } from '@spark-web/a11y';
|
|
5
8
|
import { Spinner } from '@spark-web/spinner';
|
|
6
|
-
import { buildDataAttributes } from '@spark-web/utils/internal';
|
|
7
|
-
import { Children, isValidElement, cloneElement, forwardRef } from 'react';
|
|
8
9
|
import { Text } from '@spark-web/text';
|
|
9
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
10
10
|
import { css } from '@emotion/css';
|
|
11
11
|
import { useTheme } from '@spark-web/theme';
|
|
12
12
|
import { useLinkComponent } from '@spark-web/link';
|
|
13
|
+
import { buildDataAttributes } from '@spark-web/utils/internal';
|
|
13
14
|
import { forwardRefWithAs } from '@spark-web/utils/ts';
|
|
14
15
|
|
|
16
|
+
var _excluded$2 = ["onClick", "disabled", "type"];
|
|
17
|
+
var BaseButton = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
|
|
18
|
+
var onClickProp = _ref.onClick,
|
|
19
|
+
_ref$disabled = _ref.disabled,
|
|
20
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
21
|
+
_ref$type = _ref.type,
|
|
22
|
+
type = _ref$type === void 0 ? 'button' : _ref$type,
|
|
23
|
+
rest = _objectWithoutProperties(_ref, _excluded$2);
|
|
24
|
+
|
|
25
|
+
var internalRef = useRef(null);
|
|
26
|
+
var composedRef = useComposedRefs(internalRef, forwardedRef);
|
|
27
|
+
/**
|
|
28
|
+
* In Safari buttons are not focused automatically by the browser once
|
|
29
|
+
* pressed, the default behaviour is to focus the nearest focusable ancestor.
|
|
30
|
+
* To fix this we need to manually focus the button element after the user
|
|
31
|
+
* presses the element.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
var onClick = useCallback(function (event) {
|
|
35
|
+
var _internalRef$current;
|
|
36
|
+
|
|
37
|
+
(_internalRef$current = internalRef.current) === null || _internalRef$current === void 0 ? void 0 : _internalRef$current.focus();
|
|
38
|
+
var preventableClickHandler = getPreventableClickHandler(onClickProp, disabled);
|
|
39
|
+
preventableClickHandler(event);
|
|
40
|
+
}, [disabled, onClickProp]);
|
|
41
|
+
return /*#__PURE__*/jsx(Box, _objectSpread(_objectSpread({
|
|
42
|
+
as: "button"
|
|
43
|
+
}, rest), {}, {
|
|
44
|
+
onClick: onClick,
|
|
45
|
+
ref: composedRef,
|
|
46
|
+
type: type
|
|
47
|
+
}));
|
|
48
|
+
});
|
|
49
|
+
BaseButton.displayName = 'BaseButton';
|
|
50
|
+
/**
|
|
51
|
+
* handle "disabled" behaviour w/o disabling buttons
|
|
52
|
+
* @see https://axesslab.com/disabled-buttons-suck/
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
function getPreventableClickHandler(onClick, disabled) {
|
|
56
|
+
return function handleClick(event) {
|
|
57
|
+
if (disabled) {
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
} else {
|
|
60
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
15
65
|
var variants = {
|
|
16
66
|
high: {
|
|
17
67
|
primary: {
|
|
@@ -272,13 +322,12 @@ var _excluded$1 = ["aria-controls", "aria-describedby", "aria-expanded", "data",
|
|
|
272
322
|
* Buttons are used to initialize an action, their label should express what
|
|
273
323
|
* action will occur when the user interacts with it.
|
|
274
324
|
*/
|
|
275
|
-
var Button = /*#__PURE__*/forwardRef(function (_ref,
|
|
325
|
+
var Button = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
|
|
276
326
|
var ariaControls = _ref['aria-controls'],
|
|
277
327
|
ariaDescribedBy = _ref['aria-describedby'],
|
|
278
328
|
ariaExpanded = _ref['aria-expanded'],
|
|
279
329
|
data = _ref.data,
|
|
280
|
-
|
|
281
|
-
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
330
|
+
disabled = _ref.disabled,
|
|
282
331
|
id = _ref.id,
|
|
283
332
|
_ref$loading = _ref.loading,
|
|
284
333
|
loading = _ref$loading === void 0 ? false : _ref$loading,
|
|
@@ -289,8 +338,7 @@ var Button = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
289
338
|
size = _ref$size === void 0 ? 'medium' : _ref$size,
|
|
290
339
|
_ref$tone = _ref.tone,
|
|
291
340
|
tone = _ref$tone === void 0 ? 'primary' : _ref$tone,
|
|
292
|
-
|
|
293
|
-
type = _ref$type === void 0 ? 'button' : _ref$type,
|
|
341
|
+
type = _ref.type,
|
|
294
342
|
props = _objectWithoutProperties(_ref, _excluded$1);
|
|
295
343
|
|
|
296
344
|
var iconOnly = Boolean(props.label);
|
|
@@ -303,24 +351,18 @@ var Button = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
303
351
|
var isDisabled = disabled || loading;
|
|
304
352
|
var isLoading = loading && !disabled;
|
|
305
353
|
var variant = variants[prominence][tone];
|
|
306
|
-
|
|
307
|
-
* handle "disabled" behaviour w/o disabling buttons
|
|
308
|
-
* @see https://axesslab.com/disabled-buttons-suck/
|
|
309
|
-
*/
|
|
310
|
-
|
|
311
|
-
var handleClick = getPreventableClickHandler(onClick, isDisabled);
|
|
312
|
-
return /*#__PURE__*/jsxs(Box, _objectSpread(_objectSpread(_objectSpread({
|
|
354
|
+
return /*#__PURE__*/jsxs(BaseButton, _objectSpread(_objectSpread({}, buttonStyleProps), {}, {
|
|
313
355
|
"aria-controls": ariaControls,
|
|
314
356
|
"aria-describedby": ariaDescribedBy,
|
|
315
357
|
"aria-disabled": isDisabled,
|
|
316
358
|
"aria-expanded": ariaExpanded,
|
|
317
359
|
"aria-label": props.label,
|
|
318
|
-
|
|
360
|
+
data: data,
|
|
361
|
+
disabled: isDisabled,
|
|
319
362
|
id: id,
|
|
320
|
-
onClick:
|
|
321
|
-
ref:
|
|
322
|
-
type: type
|
|
323
|
-
}, buttonStyleProps), data ? buildDataAttributes(data) : undefined), {}, {
|
|
363
|
+
onClick: onClick,
|
|
364
|
+
ref: forwardedRef,
|
|
365
|
+
type: type,
|
|
324
366
|
children: [resolveButtonChildren(_objectSpread(_objectSpread({}, props), {}, {
|
|
325
367
|
isLoading: isLoading,
|
|
326
368
|
prominence: prominence,
|
|
@@ -332,21 +374,6 @@ var Button = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
332
374
|
}));
|
|
333
375
|
});
|
|
334
376
|
Button.displayName = 'Button';
|
|
335
|
-
/**
|
|
336
|
-
* Prevent click events when the component is "disabled".
|
|
337
|
-
* Note: we don't want to actually disable a button element for several reasons.
|
|
338
|
-
* One being because that would prohibit the use of tooltips.
|
|
339
|
-
*/
|
|
340
|
-
|
|
341
|
-
function getPreventableClickHandler(onClick, disabled) {
|
|
342
|
-
return function handleClick(event) {
|
|
343
|
-
if (disabled) {
|
|
344
|
-
event.preventDefault();
|
|
345
|
-
} else {
|
|
346
|
-
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
377
|
|
|
351
378
|
function Loading(_ref2) {
|
|
352
379
|
var tone = _ref2.tone;
|
|
@@ -409,4 +436,4 @@ var ButtonLink = forwardRefWithAs(function (_ref, ref) {
|
|
|
409
436
|
}));
|
|
410
437
|
});
|
|
411
438
|
|
|
412
|
-
export { Button, ButtonLink };
|
|
439
|
+
export { BaseButton, Button, ButtonLink };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spark-web/button",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/spark-web-button.cjs.js",
|
|
6
6
|
"module": "dist/spark-web-button.esm.js",
|
|
@@ -8,16 +8,16 @@
|
|
|
8
8
|
"dist"
|
|
9
9
|
],
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@babel/runtime": "^7.18.
|
|
11
|
+
"@babel/runtime": "^7.18.3",
|
|
12
12
|
"@emotion/css": "^11.9.0",
|
|
13
|
-
"@spark-web/a11y": "^1.0
|
|
14
|
-
"@spark-web/box": "^1.0.
|
|
15
|
-
"@spark-web/icon": "^1.1.
|
|
16
|
-
"@spark-web/link": "^1.0.
|
|
17
|
-
"@spark-web/spinner": "^1.0.
|
|
18
|
-
"@spark-web/text": "^1.0.
|
|
19
|
-
"@spark-web/theme": "^3.0.
|
|
20
|
-
"@spark-web/utils": "^1.1.
|
|
13
|
+
"@spark-web/a11y": "^1.1.0",
|
|
14
|
+
"@spark-web/box": "^1.0.6",
|
|
15
|
+
"@spark-web/icon": "^1.1.4",
|
|
16
|
+
"@spark-web/link": "^1.0.6",
|
|
17
|
+
"@spark-web/spinner": "^1.0.4",
|
|
18
|
+
"@spark-web/text": "^1.0.6",
|
|
19
|
+
"@spark-web/theme": "^3.0.2",
|
|
20
|
+
"@spark-web/utils": "^1.1.5"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/react": "^17.0.12",
|