@spark-web/button 1.0.3 → 1.1.2
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 +93 -90
- package/dist/declarations/src/Button.d.ts +16 -4
- package/dist/declarations/src/ButtonLink.d.ts +1 -1
- package/dist/declarations/src/resolveButtonChildren.d.ts +3 -1
- package/dist/declarations/src/types.d.ts +6 -0
- package/dist/spark-web-button.cjs.dev.js +80 -53
- package/dist/spark-web-button.cjs.prod.js +80 -53
- package/dist/spark-web-button.esm.js +79 -33
- package/package.json +14 -10
- package/CHANGELOG.md +0 -79
- package/src/Button.stories.tsx +0 -34
- package/src/Button.test.tsx +0 -34
- package/src/Button.tsx +0 -110
- package/src/ButtonLink.tsx +0 -56
- package/src/index.ts +0 -7
- package/src/resolveButtonChildren.tsx +0 -57
- package/src/types.ts +0 -42
- package/src/useButtonStyles.ts +0 -96
- package/src/utils.ts +0 -170
package/README.md
CHANGED
|
@@ -45,95 +45,56 @@ options are: `low` and `high`.
|
|
|
45
45
|
Defaults to `high`.
|
|
46
46
|
|
|
47
47
|
```jsx live
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
</Button>
|
|
99
|
-
<Button prominence="low" tone="info">
|
|
100
|
-
<LightBulbIcon />
|
|
101
|
-
Informative
|
|
102
|
-
</Button>
|
|
103
|
-
</Inline>
|
|
104
|
-
<Divider />
|
|
105
|
-
<Text weight="strong">None prominence</Text>
|
|
106
|
-
<Inline gap="small">
|
|
107
|
-
<Button prominence="none" tone="primary">
|
|
108
|
-
<LightBulbIcon />
|
|
109
|
-
Primary
|
|
110
|
-
</Button>
|
|
111
|
-
<Button prominence="none" tone="secondary">
|
|
112
|
-
<LightBulbIcon />
|
|
113
|
-
Secondary
|
|
114
|
-
</Button>
|
|
115
|
-
<Button prominence="none" tone="neutral">
|
|
116
|
-
<LightBulbIcon />
|
|
117
|
-
Neutral
|
|
118
|
-
</Button>
|
|
119
|
-
<Button prominence="none" tone="positive">
|
|
120
|
-
<LightBulbIcon />
|
|
121
|
-
Positive
|
|
122
|
-
</Button>
|
|
123
|
-
<Button prominence="none" tone="critical">
|
|
124
|
-
<LightBulbIcon />
|
|
125
|
-
Critical
|
|
126
|
-
</Button>
|
|
127
|
-
<Button prominence="none" tone="caution">
|
|
128
|
-
<LightBulbIcon />
|
|
129
|
-
Critical
|
|
130
|
-
</Button>
|
|
131
|
-
<Button prominence="none" tone="info">
|
|
132
|
-
<LightBulbIcon />
|
|
133
|
-
Informative
|
|
134
|
-
</Button>
|
|
135
|
-
</Inline>
|
|
136
|
-
</Stack>
|
|
48
|
+
const baseButtonTones = [
|
|
49
|
+
{ label: 'Primary', tone: 'primary' },
|
|
50
|
+
{ label: 'Secondary', tone: 'secondary' },
|
|
51
|
+
{ label: 'Neutral', tone: 'neutral' },
|
|
52
|
+
{ label: 'Positive', tone: 'positive' },
|
|
53
|
+
{ label: 'Critical', tone: 'critical' },
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
const extraButtonTones = [
|
|
57
|
+
{ label: 'Caution', tone: 'caution' },
|
|
58
|
+
{ label: 'Informative', tone: 'info' },
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<Stack gap="large" dividers>
|
|
63
|
+
<Stack gap="large">
|
|
64
|
+
<Text weight="strong">High prominence</Text>
|
|
65
|
+
<Inline gap="small">
|
|
66
|
+
{baseButtonTones.map(({ label, tone }) => (
|
|
67
|
+
<Button key={label} tone={tone} prominence="high">
|
|
68
|
+
<LightBulbIcon />
|
|
69
|
+
{label}
|
|
70
|
+
</Button>
|
|
71
|
+
))}
|
|
72
|
+
</Inline>
|
|
73
|
+
</Stack>
|
|
74
|
+
<Stack gap="large">
|
|
75
|
+
<Text weight="strong">Low prominence</Text>
|
|
76
|
+
<Inline gap="small">
|
|
77
|
+
{baseButtonTones.concat(extraButtonTones).map(({ label, tone }) => (
|
|
78
|
+
<Button key={label} tone={tone} prominence="low">
|
|
79
|
+
<LightBulbIcon />
|
|
80
|
+
{label}
|
|
81
|
+
</Button>
|
|
82
|
+
))}
|
|
83
|
+
</Inline>
|
|
84
|
+
</Stack>
|
|
85
|
+
<Stack gap="large">
|
|
86
|
+
<Text weight="strong">None prominence</Text>
|
|
87
|
+
<Inline gap="small">
|
|
88
|
+
{baseButtonTones.concat(extraButtonTones).map(({ label, tone }) => (
|
|
89
|
+
<Button key={label} tone={tone} prominence="none">
|
|
90
|
+
<LightBulbIcon />
|
|
91
|
+
{label}
|
|
92
|
+
</Button>
|
|
93
|
+
))}
|
|
94
|
+
</Inline>
|
|
95
|
+
</Stack>
|
|
96
|
+
</Stack>
|
|
97
|
+
);
|
|
137
98
|
```
|
|
138
99
|
|
|
139
100
|
## Size
|
|
@@ -186,6 +147,44 @@ users of assistive technology.
|
|
|
186
147
|
</Inline>
|
|
187
148
|
```
|
|
188
149
|
|
|
150
|
+
## Loading
|
|
151
|
+
|
|
152
|
+
Buttons have an optional `loading` prop to indicate that an action is in
|
|
153
|
+
progress. When this is true a spinner will be displayed.
|
|
154
|
+
|
|
155
|
+
Note: buttons will not be interative when `loading` is true.
|
|
156
|
+
|
|
157
|
+
```jsx live
|
|
158
|
+
const [loading, setLoading] = React.useState(false);
|
|
159
|
+
const toggle = event => setLoading(event.target.checked);
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<Stack gap="large">
|
|
163
|
+
<Checkbox size="medium" checked={loading} onChange={toggle}>
|
|
164
|
+
<Text>Toggle loading state</Text>
|
|
165
|
+
</Checkbox>
|
|
166
|
+
<Inline gap="large">
|
|
167
|
+
<Button label="Download" loading={loading}>
|
|
168
|
+
<DownloadIcon />
|
|
169
|
+
</Button>
|
|
170
|
+
<Button loading={loading}>
|
|
171
|
+
<DownloadIcon />
|
|
172
|
+
Download
|
|
173
|
+
</Button>
|
|
174
|
+
</Inline>
|
|
175
|
+
<Inline gap="large">
|
|
176
|
+
<Button label="Download" size="large" loading={loading}>
|
|
177
|
+
<DownloadIcon />
|
|
178
|
+
</Button>
|
|
179
|
+
<Button size="large" loading={loading}>
|
|
180
|
+
<DownloadIcon />
|
|
181
|
+
Download
|
|
182
|
+
</Button>
|
|
183
|
+
</Inline>
|
|
184
|
+
</Stack>
|
|
185
|
+
);
|
|
186
|
+
```
|
|
187
|
+
|
|
189
188
|
## ButtonLink
|
|
190
189
|
|
|
191
190
|
The appearance of a button, with the semantics of a link — shares `Button` API,
|
|
@@ -205,13 +204,17 @@ with the exception of `href` vs `onClick` props.
|
|
|
205
204
|
| aria-describedby? | string | | Identifies the element (or elements) that describes the object. Only applicable for `Button`. |
|
|
206
205
|
| aria-expanded? | string | | Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed. Only applicable for `Button`. |
|
|
207
206
|
| children | string \| React.ReactElement\<IconProps> | | Children element to be rendered inside the button. |
|
|
208
|
-
| data? |
|
|
207
|
+
| data? | [DataAttributeMap][data-attribute-map] | | Allows setting of data attributes on the button. |
|
|
209
208
|
| disabled? | boolean | | When true, prevents `onClick` from firing. Only applicable for `Button`. |
|
|
210
209
|
| href | string | | Specifies the url the button should redirect to upon being clicked. Only applicable for `ButtonLink`. |
|
|
211
210
|
| id? | string | | Unique identifier for the button. |
|
|
212
211
|
| label? | string | | Implicit label for buttons only required for icon-only buttons for accessibility reasons. |
|
|
212
|
+
| loading? | boolean | | When true, the button will display a loading spinner. |
|
|
213
213
|
| onClick? | Function | | Function to be fired following a click event of the button. Only applicable for `Button`. |
|
|
214
214
|
| prominence? | 'high' \| 'low' | 'high' | Sets the visual prominence of the button. |
|
|
215
215
|
| size? | 'medium' \| 'large' | 'medium' | Sets the size of the button. |
|
|
216
216
|
| tone? | 'primary' \| 'secondary' \| 'neutral' \| 'positive' \| 'caution' \| 'critical' \| 'info' | 'primary' | Sets the tone of the button. |
|
|
217
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
|
|
@@ -1,22 +1,34 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { MouseEvent as ReactMouseEvent } from 'react';
|
|
2
2
|
import type { CommonButtonProps, NativeButtonProps } from './types';
|
|
3
3
|
export declare type ButtonProps = CommonButtonProps & {
|
|
4
|
+
/**
|
|
5
|
+
* Identifies the element (or elements) whose contents or presence
|
|
6
|
+
* are controlled by the current element.
|
|
7
|
+
*/
|
|
4
8
|
'aria-controls'?: NativeButtonProps['aria-controls'];
|
|
9
|
+
/** Identifies the element (or elements) that describes the object. */
|
|
5
10
|
'aria-describedby'?: NativeButtonProps['aria-describedby'];
|
|
11
|
+
/** Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed. */
|
|
6
12
|
'aria-expanded'?: NativeButtonProps['aria-expanded'];
|
|
13
|
+
/** When true, prevents onClick from firing. */
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
/** When true, the button will display a loading spinner. */
|
|
16
|
+
loading?: boolean;
|
|
17
|
+
/** Function to be fired following a click event of the button. Only applicable for Button. */
|
|
7
18
|
onClick?: NativeButtonProps['onClick'];
|
|
19
|
+
/** The size of the button. */
|
|
8
20
|
size?: CommonButtonProps['size'];
|
|
21
|
+
/** Provide an alternate type if the button is within a form. */
|
|
9
22
|
type?: 'button' | 'submit' | 'reset';
|
|
10
|
-
disabled?: boolean;
|
|
11
23
|
};
|
|
12
24
|
/**
|
|
13
25
|
* Buttons are used to initialize an action, their label should express what
|
|
14
26
|
* action will occur when the user interacts with it.
|
|
15
27
|
*/
|
|
16
|
-
export declare const Button:
|
|
28
|
+
export declare const Button: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
17
29
|
/**
|
|
18
30
|
* Prevent click events when the component is "disabled".
|
|
19
31
|
* Note: we don't want to actually disable a button element for several reasons.
|
|
20
32
|
* One being because that would prohibit the use of tooltips.
|
|
21
33
|
*/
|
|
22
|
-
export declare function getPreventableClickHandler(onClick: NativeButtonProps['onClick'], disabled: boolean): (event:
|
|
34
|
+
export declare function getPreventableClickHandler(onClick: NativeButtonProps['onClick'], disabled: boolean): (event: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
|
@@ -5,5 +5,5 @@ export declare type ButtonLinkProps = LinkComponentProps & CommonButtonProps;
|
|
|
5
5
|
/** The appearance of a `Button`, with the semantics of a link. */
|
|
6
6
|
export declare const ButtonLink: <Comp extends import("react").ElementType<any> = "a">(props: {
|
|
7
7
|
as?: Comp | undefined;
|
|
8
|
-
ref?: import("react").Ref<Comp extends "symbol" | "clipPath" | "filter" | "mask" | "marker" | "
|
|
8
|
+
ref?: import("react").Ref<Comp extends "symbol" | "clipPath" | "filter" | "mask" | "marker" | "svg" | "animate" | "animateMotion" | "animateTransform" | "circle" | "defs" | "desc" | "ellipse" | "feBlend" | "feColorMatrix" | "feComponentTransfer" | "feComposite" | "feConvolveMatrix" | "feDiffuseLighting" | "feDisplacementMap" | "feDistantLight" | "feDropShadow" | "feFlood" | "feFuncA" | "feFuncB" | "feFuncG" | "feFuncR" | "feGaussianBlur" | "feImage" | "feMerge" | "feMergeNode" | "feMorphology" | "feOffset" | "fePointLight" | "feSpecularLighting" | "feSpotLight" | "feTile" | "feTurbulence" | "foreignObject" | "g" | "image" | "line" | "linearGradient" | "metadata" | "mpath" | "path" | "pattern" | "polygon" | "polyline" | "radialGradient" | "rect" | "stop" | "switch" | "text" | "textPath" | "tspan" | "use" | "view" | keyof HTMLElementTagNameMap | "set" ? (HTMLElementTagNameMap & Pick<SVGElementTagNameMap, "symbol" | "clipPath" | "filter" | "mask" | "marker" | "svg" | "animate" | "animateMotion" | "animateTransform" | "circle" | "defs" | "desc" | "ellipse" | "feBlend" | "feColorMatrix" | "feComponentTransfer" | "feComposite" | "feConvolveMatrix" | "feDiffuseLighting" | "feDisplacementMap" | "feDistantLight" | "feDropShadow" | "feFlood" | "feFuncA" | "feFuncB" | "feFuncG" | "feFuncR" | "feGaussianBlur" | "feImage" | "feMerge" | "feMergeNode" | "feMorphology" | "feOffset" | "fePointLight" | "feSpecularLighting" | "feSpotLight" | "feTile" | "feTurbulence" | "foreignObject" | "g" | "image" | "line" | "linearGradient" | "metadata" | "mpath" | "path" | "pattern" | "polygon" | "polyline" | "radialGradient" | "rect" | "stop" | "switch" | "text" | "textPath" | "tspan" | "use" | "view" | "set">)[Comp] : Comp extends new (...args: any) => any ? InstanceType<Comp> : undefined> | undefined;
|
|
9
9
|
} & Omit<import("react").PropsWithoutRef<import("react").ComponentProps<Comp>>, "as"> & ButtonLinkProps) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
import type { ButtonChildrenProps, ButtonProminence, ButtonSize, ButtonTone } from './types';
|
|
2
3
|
declare type ResolveButtonChildren = ButtonChildrenProps & {
|
|
4
|
+
isLoading: boolean;
|
|
3
5
|
prominence: ButtonProminence;
|
|
4
6
|
size: ButtonSize;
|
|
5
7
|
tone: ButtonTone;
|
|
6
8
|
};
|
|
7
|
-
export declare const resolveButtonChildren: ({ children, prominence, size, tone, }: ResolveButtonChildren) => JSX.Element[];
|
|
9
|
+
export declare const resolveButtonChildren: ({ children, isLoading, prominence, size, tone, }: ResolveButtonChildren) => JSX.Element[];
|
|
8
10
|
export {};
|
|
@@ -11,13 +11,19 @@ declare type ChildrenWithText = {
|
|
|
11
11
|
children: string | [ReactElement<IconProps>, string] | [string, ReactElement<IconProps>];
|
|
12
12
|
};
|
|
13
13
|
declare type IconOnly = {
|
|
14
|
+
/**
|
|
15
|
+
* Implicit label for buttons only required for icon-only buttons
|
|
16
|
+
* for accessibility reasons.
|
|
17
|
+
*/
|
|
14
18
|
label: string;
|
|
15
19
|
children: ReactElement<IconProps>;
|
|
16
20
|
};
|
|
17
21
|
export declare type ButtonChildrenProps = ChildrenWithText | IconOnly;
|
|
18
22
|
export declare type NativeButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
|
19
23
|
export declare type CommonButtonProps = {
|
|
24
|
+
/** Allows setting of data attributes on the underlying element. */
|
|
20
25
|
data?: DataAttributeMap;
|
|
26
|
+
/** Unique identifier for the underlying element. */
|
|
21
27
|
id?: string;
|
|
22
28
|
} & ButtonChildrenProps & ButtonStyleProps;
|
|
23
29
|
export declare type ButtonStyleProps = {
|
|
@@ -4,37 +4,18 @@ 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');
|
|
7
8
|
var box = require('@spark-web/box');
|
|
9
|
+
var spinner = require('@spark-web/spinner');
|
|
8
10
|
var internal = require('@spark-web/utils/internal');
|
|
9
|
-
var
|
|
11
|
+
var react = require('react');
|
|
10
12
|
var text = require('@spark-web/text');
|
|
11
13
|
var jsxRuntime = require('react/jsx-runtime');
|
|
12
14
|
var css = require('@emotion/css');
|
|
13
|
-
var a11y = require('@spark-web/a11y');
|
|
14
15
|
var theme = require('@spark-web/theme');
|
|
15
16
|
var link = require('@spark-web/link');
|
|
16
17
|
var ts = require('@spark-web/utils/ts');
|
|
17
18
|
|
|
18
|
-
function _interopNamespace(e) {
|
|
19
|
-
if (e && e.__esModule) return e;
|
|
20
|
-
var n = Object.create(null);
|
|
21
|
-
if (e) {
|
|
22
|
-
Object.keys(e).forEach(function (k) {
|
|
23
|
-
if (k !== 'default') {
|
|
24
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
25
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
26
|
-
enumerable: true,
|
|
27
|
-
get: function () { return e[k]; }
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
n["default"] = e;
|
|
33
|
-
return Object.freeze(n);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
37
|
-
|
|
38
19
|
var variants = {
|
|
39
20
|
high: {
|
|
40
21
|
primary: {
|
|
@@ -179,32 +160,39 @@ var mapTokens = {
|
|
|
179
160
|
|
|
180
161
|
var resolveButtonChildren = function resolveButtonChildren(_ref) {
|
|
181
162
|
var children = _ref.children,
|
|
163
|
+
isLoading = _ref.isLoading,
|
|
182
164
|
prominence = _ref.prominence,
|
|
183
165
|
size = _ref.size,
|
|
184
166
|
tone = _ref.tone;
|
|
185
167
|
var variant = variants[prominence][tone];
|
|
186
|
-
return
|
|
168
|
+
return react.Children.map(children, function (child) {
|
|
187
169
|
if (typeof child === 'string') {
|
|
188
|
-
return /*#__PURE__*/jsxRuntime.jsx(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
170
|
+
return /*#__PURE__*/jsxRuntime.jsx(HiddenWhenLoading, {
|
|
171
|
+
isLoading: isLoading,
|
|
172
|
+
children: /*#__PURE__*/jsxRuntime.jsx(text.Text, {
|
|
173
|
+
as: "span",
|
|
174
|
+
baseline: false,
|
|
175
|
+
overflowStrategy: "nowrap",
|
|
176
|
+
weight: "semibold",
|
|
177
|
+
size: mapTokens.fontSize[size],
|
|
178
|
+
tone: variant === null || variant === void 0 ? void 0 : variant.textTone,
|
|
179
|
+
children: child
|
|
180
|
+
})
|
|
196
181
|
});
|
|
197
182
|
}
|
|
198
183
|
|
|
199
|
-
if ( /*#__PURE__*/
|
|
200
|
-
return /*#__PURE__*/
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
184
|
+
if ( /*#__PURE__*/react.isValidElement(child)) {
|
|
185
|
+
return /*#__PURE__*/jsxRuntime.jsx(HiddenWhenLoading, {
|
|
186
|
+
isLoading: isLoading,
|
|
187
|
+
children: /*#__PURE__*/react.cloneElement(child, {
|
|
188
|
+
// Dismiss buttons need to be `xxsmall`
|
|
189
|
+
// For everything else, we force them to be `xsmall`
|
|
190
|
+
size: child.props.size === 'xxsmall' ? child.props.size : 'xsmall',
|
|
191
|
+
// If the button is low prominence with a decorative tone we want to force
|
|
192
|
+
// the tone to be the same as the button
|
|
193
|
+
// We also don't want users to override the tone of the icon inside of the button
|
|
194
|
+
tone: variant === null || variant === void 0 ? void 0 : variant.textTone
|
|
195
|
+
})
|
|
208
196
|
});
|
|
209
197
|
}
|
|
210
198
|
|
|
@@ -212,6 +200,19 @@ var resolveButtonChildren = function resolveButtonChildren(_ref) {
|
|
|
212
200
|
});
|
|
213
201
|
};
|
|
214
202
|
|
|
203
|
+
function HiddenWhenLoading(_ref2) {
|
|
204
|
+
var children = _ref2.children,
|
|
205
|
+
isLoading = _ref2.isLoading;
|
|
206
|
+
return /*#__PURE__*/jsxRuntime.jsx(box.Box, {
|
|
207
|
+
as: "span",
|
|
208
|
+
display: "inline-flex",
|
|
209
|
+
alignItems: "center",
|
|
210
|
+
justifyContent: "center",
|
|
211
|
+
opacity: isLoading ? 0 : undefined,
|
|
212
|
+
children: children
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
215
216
|
function useButtonStyles(_ref) {
|
|
216
217
|
var iconOnly = _ref.iconOnly,
|
|
217
218
|
prominence = _ref.prominence,
|
|
@@ -269,13 +270,13 @@ function useButtonStyles(_ref) {
|
|
|
269
270
|
return buttonStyleProps;
|
|
270
271
|
}
|
|
271
272
|
|
|
272
|
-
var _excluded$1 = ["aria-controls", "aria-describedby", "aria-expanded", "data", "disabled", "id", "onClick", "prominence", "size", "tone", "type"];
|
|
273
|
+
var _excluded$1 = ["aria-controls", "aria-describedby", "aria-expanded", "data", "disabled", "id", "loading", "onClick", "prominence", "size", "tone", "type"];
|
|
273
274
|
|
|
274
275
|
/**
|
|
275
276
|
* Buttons are used to initialize an action, their label should express what
|
|
276
277
|
* action will occur when the user interacts with it.
|
|
277
278
|
*/
|
|
278
|
-
var Button = /*#__PURE__*/
|
|
279
|
+
var Button = /*#__PURE__*/react.forwardRef(function (_ref, ref) {
|
|
279
280
|
var ariaControls = _ref['aria-controls'],
|
|
280
281
|
ariaDescribedBy = _ref['aria-describedby'],
|
|
281
282
|
ariaExpanded = _ref['aria-expanded'],
|
|
@@ -283,6 +284,8 @@ var Button = /*#__PURE__*/React__namespace.forwardRef(function (_ref, ref) {
|
|
|
283
284
|
_ref$disabled = _ref.disabled,
|
|
284
285
|
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
285
286
|
id = _ref.id,
|
|
287
|
+
_ref$loading = _ref.loading,
|
|
288
|
+
loading = _ref$loading === void 0 ? false : _ref$loading,
|
|
286
289
|
onClick = _ref.onClick,
|
|
287
290
|
_ref$prominence = _ref.prominence,
|
|
288
291
|
prominence = _ref$prominence === void 0 ? 'high' : _ref$prominence,
|
|
@@ -300,18 +303,17 @@ var Button = /*#__PURE__*/React__namespace.forwardRef(function (_ref, ref) {
|
|
|
300
303
|
size: size,
|
|
301
304
|
tone: tone,
|
|
302
305
|
prominence: prominence
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
var
|
|
306
|
-
|
|
307
|
-
|
|
306
|
+
});
|
|
307
|
+
var isDisabled = disabled || loading;
|
|
308
|
+
var isLoading = loading && !disabled;
|
|
309
|
+
var variant = variants[prominence][tone];
|
|
308
310
|
/**
|
|
309
311
|
* handle "disabled" behaviour w/o disabling buttons
|
|
310
312
|
* @see https://axesslab.com/disabled-buttons-suck/
|
|
311
313
|
*/
|
|
312
314
|
|
|
313
315
|
var handleClick = getPreventableClickHandler(onClick, isDisabled);
|
|
314
|
-
return /*#__PURE__*/jsxRuntime.
|
|
316
|
+
return /*#__PURE__*/jsxRuntime.jsxs(box.Box, _objectSpread(_objectSpread(_objectSpread({
|
|
315
317
|
"aria-controls": ariaControls,
|
|
316
318
|
"aria-describedby": ariaDescribedBy,
|
|
317
319
|
"aria-disabled": isDisabled,
|
|
@@ -323,14 +325,17 @@ var Button = /*#__PURE__*/React__namespace.forwardRef(function (_ref, ref) {
|
|
|
323
325
|
ref: ref,
|
|
324
326
|
type: type
|
|
325
327
|
}, buttonStyleProps), data ? internal.buildDataAttributes(data) : undefined), {}, {
|
|
326
|
-
children: resolveButtonChildren(_objectSpread(_objectSpread({}, props), {}, {
|
|
328
|
+
children: [resolveButtonChildren(_objectSpread(_objectSpread({}, props), {}, {
|
|
329
|
+
isLoading: isLoading,
|
|
327
330
|
prominence: prominence,
|
|
328
331
|
size: size,
|
|
329
332
|
tone: tone
|
|
330
|
-
}))
|
|
333
|
+
})), isLoading && /*#__PURE__*/jsxRuntime.jsx(Loading, {
|
|
334
|
+
tone: variant === null || variant === void 0 ? void 0 : variant.textTone
|
|
335
|
+
})]
|
|
331
336
|
}));
|
|
332
337
|
});
|
|
333
|
-
Button.displayName = '
|
|
338
|
+
Button.displayName = 'Button';
|
|
334
339
|
/**
|
|
335
340
|
* Prevent click events when the component is "disabled".
|
|
336
341
|
* Note: we don't want to actually disable a button element for several reasons.
|
|
@@ -347,6 +352,27 @@ function getPreventableClickHandler(onClick, disabled) {
|
|
|
347
352
|
};
|
|
348
353
|
}
|
|
349
354
|
|
|
355
|
+
function Loading(_ref2) {
|
|
356
|
+
var tone = _ref2.tone;
|
|
357
|
+
return /*#__PURE__*/jsxRuntime.jsxs(box.Box, {
|
|
358
|
+
as: "span",
|
|
359
|
+
position: "absolute",
|
|
360
|
+
top: 0,
|
|
361
|
+
bottom: 0,
|
|
362
|
+
left: 0,
|
|
363
|
+
right: 0,
|
|
364
|
+
display: "flex",
|
|
365
|
+
alignItems: "center",
|
|
366
|
+
justifyContent: "center",
|
|
367
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(a11y.VisuallyHidden, {
|
|
368
|
+
children: "button loading indicator"
|
|
369
|
+
}), /*#__PURE__*/jsxRuntime.jsx(spinner.Spinner, {
|
|
370
|
+
size: "xsmall",
|
|
371
|
+
tone: tone
|
|
372
|
+
})]
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
|
|
350
376
|
var _excluded = ["data", "href", "id", "prominence", "size", "tone"];
|
|
351
377
|
|
|
352
378
|
/** The appearance of a `Button`, with the semantics of a link. */
|
|
@@ -366,9 +392,9 @@ var ButtonLink = ts.forwardRefWithAs(function (_ref, ref) {
|
|
|
366
392
|
var iconOnly = Boolean(props.label);
|
|
367
393
|
var buttonStyleProps = useButtonStyles({
|
|
368
394
|
iconOnly: iconOnly,
|
|
395
|
+
prominence: prominence,
|
|
369
396
|
size: size,
|
|
370
|
-
tone: tone
|
|
371
|
-
prominence: prominence
|
|
397
|
+
tone: tone
|
|
372
398
|
});
|
|
373
399
|
return /*#__PURE__*/jsxRuntime.jsx(box.Box, _objectSpread(_objectSpread(_objectSpread({
|
|
374
400
|
"aria-label": props.label,
|
|
@@ -379,6 +405,7 @@ var ButtonLink = ts.forwardRefWithAs(function (_ref, ref) {
|
|
|
379
405
|
ref: ref
|
|
380
406
|
}, buttonStyleProps), data ? internal.buildDataAttributes(data) : undefined), {}, {
|
|
381
407
|
children: resolveButtonChildren(_objectSpread(_objectSpread({}, props), {}, {
|
|
408
|
+
isLoading: false,
|
|
382
409
|
prominence: prominence,
|
|
383
410
|
size: size,
|
|
384
411
|
tone: tone
|