@khanacademy/wonder-blocks-button 2.11.7 → 3.0.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/CHANGELOG.md +6 -0
- package/dist/es/index.js +12 -9
- package/dist/index.js +25 -20
- package/package.json +1 -1
- package/src/__tests__/__snapshots__/custom-snapshot.test.js.snap +4646 -780
- package/src/__tests__/custom-snapshot.test.js +1 -1
- package/src/components/__docs__/accessibility.stories.mdx +1 -1
- package/src/components/__docs__/best-practices.stories.mdx +1 -1
- package/src/components/__docs__/button.argtypes.js +3 -3
- package/src/components/{button.stories.js → __docs__/button.stories.js} +195 -275
- package/src/components/__docs__/navigation-callbacks.stories.mdx +121 -2
- package/src/components/__tests__/button.test.js +138 -191
- package/src/components/button-core.js +14 -8
- package/src/components/button.js +2 -2
- package/src/components/button.md +4 -920
- package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +0 -5009
- package/src/__tests__/generated-snapshot.test.js +0 -789
|
@@ -38,7 +38,7 @@ describe("Button", () => {
|
|
|
38
38
|
describe("ButtonCore", () => {
|
|
39
39
|
for (const kind of ["primary", "secondary", "tertiary"]) {
|
|
40
40
|
for (const color of ["default", "destructive"]) {
|
|
41
|
-
for (const size of ["medium", "small"]) {
|
|
41
|
+
for (const size of ["medium", "small", "large"]) {
|
|
42
42
|
for (const light of [true, false]) {
|
|
43
43
|
for (const state of [
|
|
44
44
|
"disabled",
|
|
@@ -66,15 +66,15 @@ export default {
|
|
|
66
66
|
},
|
|
67
67
|
size: {
|
|
68
68
|
description: "The size of the button.",
|
|
69
|
-
options: ["small", "medium", "
|
|
69
|
+
options: ["small", "medium", "large"],
|
|
70
70
|
control: {type: "select"},
|
|
71
71
|
table: {
|
|
72
72
|
category: "Layout",
|
|
73
73
|
defaultValue: {
|
|
74
|
-
detail: `"medium" = height: 40; "small" = height: 32; "
|
|
74
|
+
detail: `"medium" = height: 40; "small" = height: 32; "large" = height: 56;`,
|
|
75
75
|
},
|
|
76
76
|
type: {
|
|
77
|
-
summary: `"medium" | "small" | "
|
|
77
|
+
summary: `"medium" | "small" | "large"`,
|
|
78
78
|
},
|
|
79
79
|
},
|
|
80
80
|
},
|
|
@@ -11,15 +11,18 @@ import {View} from "@khanacademy/wonder-blocks-core";
|
|
|
11
11
|
import {icons} from "@khanacademy/wonder-blocks-icon";
|
|
12
12
|
import {Strut} from "@khanacademy/wonder-blocks-layout";
|
|
13
13
|
import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
14
|
+
import {LabelMedium} from "@khanacademy/wonder-blocks-typography";
|
|
14
15
|
import type {StoryComponentType} from "@storybook/react";
|
|
15
|
-
import
|
|
16
|
+
import type {StyleDeclaration} from "aphrodite";
|
|
16
17
|
|
|
17
|
-
import
|
|
18
|
-
|
|
19
|
-
import
|
|
18
|
+
import Button from "../button.js";
|
|
19
|
+
|
|
20
|
+
import ComponentInfo from "../../../../../.storybook/components/component-info.js";
|
|
21
|
+
import ButtonArgTypes from "./button.argtypes.js";
|
|
22
|
+
import {name, version} from "../../../package.json";
|
|
20
23
|
|
|
21
24
|
export default {
|
|
22
|
-
title: "
|
|
25
|
+
title: "Button",
|
|
23
26
|
component: Button,
|
|
24
27
|
parameters: {
|
|
25
28
|
componentSubtitle: ((
|
|
@@ -28,13 +31,14 @@ export default {
|
|
|
28
31
|
},
|
|
29
32
|
decorators: [withDesign],
|
|
30
33
|
argTypes: ButtonArgTypes,
|
|
34
|
+
excludeStories: ["styles"],
|
|
31
35
|
};
|
|
32
36
|
|
|
33
37
|
const Template = (args) => <Button {...args} />;
|
|
34
38
|
|
|
35
|
-
export const
|
|
39
|
+
export const Default: StoryComponentType = Template.bind({});
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
Default.args = {
|
|
38
42
|
children: "Hello, world!",
|
|
39
43
|
kind: "primary",
|
|
40
44
|
color: "default",
|
|
@@ -45,7 +49,7 @@ DefaultButton.args = {
|
|
|
45
49
|
onClick: () => {},
|
|
46
50
|
};
|
|
47
51
|
|
|
48
|
-
|
|
52
|
+
Default.parameters = {
|
|
49
53
|
design: {
|
|
50
54
|
type: "figma",
|
|
51
55
|
url: "https://www.figma.com/file/VbVu3h2BpBhH80niq101MHHE/Wonder-Blocks-(Web)?node-id=401%3A307",
|
|
@@ -56,7 +60,25 @@ DefaultButton.parameters = {
|
|
|
56
60
|
},
|
|
57
61
|
};
|
|
58
62
|
|
|
59
|
-
export const
|
|
63
|
+
export const styles: StyleDeclaration = StyleSheet.create({
|
|
64
|
+
row: {
|
|
65
|
+
flexDirection: "row",
|
|
66
|
+
alignItems: "center",
|
|
67
|
+
marginBottom: Spacing.xSmall_8,
|
|
68
|
+
},
|
|
69
|
+
button: {
|
|
70
|
+
marginRight: Spacing.xSmall_8,
|
|
71
|
+
},
|
|
72
|
+
fillSpace: {
|
|
73
|
+
minWidth: 140,
|
|
74
|
+
},
|
|
75
|
+
example: {
|
|
76
|
+
background: Color.offWhite,
|
|
77
|
+
padding: Spacing.medium_16,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
export const Variants: StoryComponentType = () => (
|
|
60
82
|
<View>
|
|
61
83
|
<View style={{flexDirection: "row"}}>
|
|
62
84
|
<Button onClick={() => {}}>Hello, world!</Button>
|
|
@@ -100,14 +122,14 @@ export const BasicButtons: StoryComponentType = () => (
|
|
|
100
122
|
</View>
|
|
101
123
|
);
|
|
102
124
|
|
|
103
|
-
|
|
125
|
+
Variants.parameters = {
|
|
104
126
|
docs: {
|
|
105
127
|
storyDescription:
|
|
106
128
|
"There are three kinds of buttons: `primary` (default), `secondary`, and `tertiary`.",
|
|
107
129
|
},
|
|
108
130
|
};
|
|
109
131
|
|
|
110
|
-
export const
|
|
132
|
+
export const WithColor: StoryComponentType = () => (
|
|
111
133
|
<View style={styles.row}>
|
|
112
134
|
<Button style={styles.button} onClick={() => {}} color="destructive">
|
|
113
135
|
Primary
|
|
@@ -131,14 +153,16 @@ export const ButtonsWithColors: StoryComponentType = () => (
|
|
|
131
153
|
</View>
|
|
132
154
|
);
|
|
133
155
|
|
|
134
|
-
|
|
156
|
+
WithColor.storyName = "Color";
|
|
157
|
+
|
|
158
|
+
WithColor.parameters = {
|
|
135
159
|
docs: {
|
|
136
160
|
storyDescription:
|
|
137
161
|
"Buttons have a `color` that is either `default` (the default, as shown above) or `destructive` (as can seen below):",
|
|
138
162
|
},
|
|
139
163
|
};
|
|
140
164
|
|
|
141
|
-
export const
|
|
165
|
+
export const Dark: StoryComponentType = () => (
|
|
142
166
|
<View style={{backgroundColor: Color.darkBlue}}>
|
|
143
167
|
<View style={{flexDirection: "row"}}>
|
|
144
168
|
<Button onClick={() => {}} light={true}>
|
|
@@ -204,7 +228,7 @@ export const DarkBackgroundButtons: StoryComponentType = () => (
|
|
|
204
228
|
</View>
|
|
205
229
|
);
|
|
206
230
|
|
|
207
|
-
|
|
231
|
+
Dark.parameters = {
|
|
208
232
|
backgrounds: {
|
|
209
233
|
default: "darkBlue",
|
|
210
234
|
},
|
|
@@ -214,87 +238,135 @@ DarkBackgroundButtons.parameters = {
|
|
|
214
238
|
},
|
|
215
239
|
};
|
|
216
240
|
|
|
217
|
-
|
|
241
|
+
const kinds = ["primary", "secondary", "tertiary"];
|
|
242
|
+
|
|
243
|
+
export const Icon: StoryComponentType = () => (
|
|
218
244
|
<View>
|
|
219
245
|
<View style={styles.row}>
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
</Button>
|
|
231
|
-
<Button
|
|
232
|
-
style={styles.button}
|
|
233
|
-
onClick={() => {}}
|
|
234
|
-
kind="tertiary"
|
|
235
|
-
size="small"
|
|
236
|
-
>
|
|
237
|
-
Label
|
|
238
|
-
</Button>
|
|
246
|
+
{kinds.map((kind, idx) => (
|
|
247
|
+
<Button
|
|
248
|
+
kind={kind}
|
|
249
|
+
icon={icons.contentExercise}
|
|
250
|
+
style={styles.button}
|
|
251
|
+
key={idx}
|
|
252
|
+
>
|
|
253
|
+
{kind}
|
|
254
|
+
</Button>
|
|
255
|
+
))}
|
|
239
256
|
</View>
|
|
240
257
|
<View style={styles.row}>
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
<Button
|
|
253
|
-
style={styles.button}
|
|
254
|
-
onClick={() => {}}
|
|
255
|
-
kind="tertiary"
|
|
256
|
-
size="medium"
|
|
257
|
-
>
|
|
258
|
-
Label
|
|
259
|
-
</Button>
|
|
258
|
+
{kinds.map((kind, idx) => (
|
|
259
|
+
<Button
|
|
260
|
+
kind={kind}
|
|
261
|
+
icon={icons.contentExercise}
|
|
262
|
+
style={styles.button}
|
|
263
|
+
key={idx}
|
|
264
|
+
size="small"
|
|
265
|
+
>
|
|
266
|
+
{`${kind} small`}
|
|
267
|
+
</Button>
|
|
268
|
+
))}
|
|
260
269
|
</View>
|
|
270
|
+
</View>
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
Icon.parameters = {
|
|
274
|
+
docs: {
|
|
275
|
+
storyDescription: "Buttons can have an icon on it's left side.",
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export const Size: StoryComponentType = () => (
|
|
280
|
+
<View>
|
|
261
281
|
<View style={styles.row}>
|
|
262
|
-
<
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
282
|
+
<LabelMedium style={styles.fillSpace}>small</LabelMedium>
|
|
283
|
+
<View style={[styles.row, styles.example]}>
|
|
284
|
+
<Button style={styles.button} onClick={() => {}} size="small">
|
|
285
|
+
Label
|
|
286
|
+
</Button>
|
|
287
|
+
<Button
|
|
288
|
+
style={styles.button}
|
|
289
|
+
onClick={() => {}}
|
|
290
|
+
kind="secondary"
|
|
291
|
+
size="small"
|
|
292
|
+
>
|
|
293
|
+
Label
|
|
294
|
+
</Button>
|
|
295
|
+
<Button
|
|
296
|
+
style={styles.button}
|
|
297
|
+
onClick={() => {}}
|
|
298
|
+
kind="tertiary"
|
|
299
|
+
size="small"
|
|
300
|
+
>
|
|
301
|
+
Label
|
|
302
|
+
</Button>
|
|
303
|
+
</View>
|
|
304
|
+
</View>
|
|
305
|
+
<View style={styles.row}>
|
|
306
|
+
<LabelMedium style={styles.fillSpace}>medium (default)</LabelMedium>
|
|
307
|
+
|
|
308
|
+
<View style={[styles.row, styles.example]}>
|
|
309
|
+
<Button style={styles.button} onClick={() => {}} size="medium">
|
|
310
|
+
Label
|
|
311
|
+
</Button>
|
|
312
|
+
<Button
|
|
313
|
+
style={styles.button}
|
|
314
|
+
onClick={() => {}}
|
|
315
|
+
kind="secondary"
|
|
316
|
+
size="medium"
|
|
317
|
+
>
|
|
318
|
+
Label
|
|
319
|
+
</Button>
|
|
320
|
+
<Button
|
|
321
|
+
style={styles.button}
|
|
322
|
+
onClick={() => {}}
|
|
323
|
+
kind="tertiary"
|
|
324
|
+
size="medium"
|
|
325
|
+
>
|
|
326
|
+
Label
|
|
327
|
+
</Button>
|
|
328
|
+
</View>
|
|
329
|
+
</View>
|
|
330
|
+
<View style={styles.row}>
|
|
331
|
+
<LabelMedium style={styles.fillSpace}>large</LabelMedium>
|
|
332
|
+
<View style={[styles.row, styles.example]}>
|
|
333
|
+
<Button style={styles.button} onClick={() => {}} size="large">
|
|
334
|
+
Label
|
|
335
|
+
</Button>
|
|
336
|
+
<Button
|
|
337
|
+
style={styles.button}
|
|
338
|
+
onClick={() => {}}
|
|
339
|
+
kind="secondary"
|
|
340
|
+
size="large"
|
|
341
|
+
>
|
|
342
|
+
Label
|
|
343
|
+
</Button>
|
|
344
|
+
<Button
|
|
345
|
+
style={styles.button}
|
|
346
|
+
onClick={() => {}}
|
|
347
|
+
kind="tertiary"
|
|
348
|
+
size="large"
|
|
349
|
+
>
|
|
350
|
+
Label
|
|
351
|
+
</Button>
|
|
352
|
+
</View>
|
|
281
353
|
</View>
|
|
282
354
|
</View>
|
|
283
355
|
);
|
|
284
356
|
|
|
285
|
-
|
|
357
|
+
Size.parameters = {
|
|
286
358
|
docs: {
|
|
287
359
|
storyDescription:
|
|
288
|
-
"Buttons have a size that's either `medium` (default), `small`, or `
|
|
360
|
+
"Buttons have a size that's either `medium` (default), `small`, or `large`.",
|
|
289
361
|
},
|
|
290
362
|
};
|
|
291
363
|
|
|
292
|
-
export const
|
|
364
|
+
export const Spinner: StoryComponentType = () => (
|
|
293
365
|
<View style={{flexDirection: "row"}}>
|
|
294
366
|
<Button
|
|
295
367
|
onClick={() => {}}
|
|
296
368
|
spinner={true}
|
|
297
|
-
size="
|
|
369
|
+
size="large"
|
|
298
370
|
aria-label={"waiting"}
|
|
299
371
|
>
|
|
300
372
|
Hello, world
|
|
@@ -315,139 +387,71 @@ export const ButtonWithSpinner: StoryComponentType = () => (
|
|
|
315
387
|
</View>
|
|
316
388
|
);
|
|
317
389
|
|
|
318
|
-
|
|
390
|
+
Spinner.parameters = {
|
|
319
391
|
docs: {
|
|
320
392
|
storyDescription:
|
|
321
393
|
"Buttons can show a spinner. This is useful when indicating to a user that their input has been recognized but that the operation will take some time. While the spinner property is set to true the button is disabled.",
|
|
322
394
|
},
|
|
323
395
|
};
|
|
324
396
|
|
|
325
|
-
export const
|
|
326
|
-
<
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
Uses Client-side Nav
|
|
330
|
-
</Button>
|
|
331
|
-
<Button href="/foo" style={styles.button} skipClientNav>
|
|
332
|
-
Avoids Client-side Nav
|
|
333
|
-
</Button>
|
|
334
|
-
<Switch>
|
|
335
|
-
<Route path="/foo">
|
|
336
|
-
<View id="foo">Hello, world!</View>
|
|
337
|
-
</Route>
|
|
338
|
-
</Switch>
|
|
339
|
-
</View>
|
|
340
|
-
</MemoryRouter>
|
|
397
|
+
export const TruncatingLabels: StoryComponentType = () => (
|
|
398
|
+
<Button onClick={() => {}} style={{maxWidth: 200}}>
|
|
399
|
+
label too long for the parent container
|
|
400
|
+
</Button>
|
|
341
401
|
);
|
|
342
402
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
ButtonsWithRouter.parameters = {
|
|
403
|
+
TruncatingLabels.parameters = {
|
|
346
404
|
docs: {
|
|
347
405
|
storyDescription:
|
|
348
|
-
"
|
|
349
|
-
},
|
|
350
|
-
chromatic: {
|
|
351
|
-
disableSnapshot: true,
|
|
406
|
+
"If the label is too long for the button width, the text will be truncated.",
|
|
352
407
|
},
|
|
353
408
|
};
|
|
354
409
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
>
|
|
367
|
-
beforeNav, client-side nav
|
|
368
|
-
</Button>
|
|
369
|
-
<Button
|
|
370
|
-
href="/foo"
|
|
371
|
-
style={styles.button}
|
|
372
|
-
skipClientNav={true}
|
|
373
|
-
beforeNav={() =>
|
|
374
|
-
new Promise((resolve, reject) => {
|
|
375
|
-
setTimeout(resolve, 1000);
|
|
376
|
-
})
|
|
377
|
-
}
|
|
378
|
-
>
|
|
379
|
-
beforeNav, server-side nav
|
|
380
|
-
</Button>
|
|
381
|
-
<Button
|
|
382
|
-
href="https://google.com"
|
|
383
|
-
style={styles.button}
|
|
384
|
-
skipClientNav={true}
|
|
385
|
-
beforeNav={() =>
|
|
386
|
-
new Promise((resolve, reject) => {
|
|
387
|
-
setTimeout(resolve, 1000);
|
|
388
|
-
})
|
|
389
|
-
}
|
|
390
|
-
>
|
|
391
|
-
beforeNav, open URL in new tab
|
|
392
|
-
</Button>
|
|
393
|
-
<Switch>
|
|
394
|
-
<Route path="/foo">
|
|
395
|
-
<View id="foo">Hello, world!</View>
|
|
396
|
-
</Route>
|
|
397
|
-
</Switch>
|
|
410
|
+
TruncatingLabels.storyName = "Truncating labels";
|
|
411
|
+
|
|
412
|
+
export const SubmittingForms: StoryComponentType = () => (
|
|
413
|
+
<form
|
|
414
|
+
onSubmit={(e) => {
|
|
415
|
+
e.preventDefault();
|
|
416
|
+
window.alert("form submitted"); // eslint-disable-line no-alert
|
|
417
|
+
}}
|
|
418
|
+
>
|
|
419
|
+
<View>
|
|
420
|
+
Foo: <input id="foo" value="bar" />
|
|
421
|
+
<Button type="submit">Submit</Button>
|
|
398
422
|
</View>
|
|
399
|
-
</
|
|
423
|
+
</form>
|
|
400
424
|
);
|
|
401
425
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
BeforeNavCallbacks.parameters = {
|
|
426
|
+
SubmittingForms.parameters = {
|
|
405
427
|
docs: {
|
|
406
428
|
storyDescription:
|
|
407
|
-
|
|
429
|
+
'If the button is inside a form, you can use the `type="submit"` variant, so the form will be submitted on click.',
|
|
430
|
+
},
|
|
431
|
+
options: {
|
|
432
|
+
showAddonPanel: true,
|
|
408
433
|
},
|
|
409
434
|
chromatic: {
|
|
435
|
+
// We already have screenshots of other stories that cover more of the
|
|
436
|
+
// button states.
|
|
410
437
|
disableSnapshot: true,
|
|
411
438
|
},
|
|
412
439
|
};
|
|
413
440
|
|
|
414
|
-
|
|
441
|
+
SubmittingForms.storyName = "Submitting forms";
|
|
442
|
+
|
|
443
|
+
export const PreventNavigation: StoryComponentType = () => (
|
|
415
444
|
<MemoryRouter>
|
|
416
445
|
<View style={styles.row}>
|
|
417
446
|
<Button
|
|
418
447
|
href="/foo"
|
|
419
448
|
style={styles.button}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}
|
|
425
|
-
>
|
|
426
|
-
safeWithNav, client-side nav
|
|
427
|
-
</Button>
|
|
428
|
-
<Button
|
|
429
|
-
href="/foo"
|
|
430
|
-
style={styles.button}
|
|
431
|
-
skipClientNav={true}
|
|
432
|
-
safeWithNav={() =>
|
|
433
|
-
new Promise((resolve, reject) => {
|
|
434
|
-
setTimeout(resolve, 1000);
|
|
435
|
-
})
|
|
436
|
-
}
|
|
437
|
-
>
|
|
438
|
-
safeWithNav, server-side nav
|
|
439
|
-
</Button>
|
|
440
|
-
<Button
|
|
441
|
-
href="https://google.com"
|
|
442
|
-
style={styles.button}
|
|
443
|
-
skipClientNav={true}
|
|
444
|
-
safeWithNav={() =>
|
|
445
|
-
new Promise((resolve, reject) => {
|
|
446
|
-
setTimeout(resolve, 1000);
|
|
447
|
-
})
|
|
448
|
-
}
|
|
449
|
+
onClick={(e) => {
|
|
450
|
+
action("clicked")(e);
|
|
451
|
+
e.preventDefault();
|
|
452
|
+
}}
|
|
449
453
|
>
|
|
450
|
-
|
|
454
|
+
This button prevents navigation.
|
|
451
455
|
</Button>
|
|
452
456
|
<Switch>
|
|
453
457
|
<Route path="/foo">
|
|
@@ -458,30 +462,26 @@ export const SafeWithNavCallbacks: StoryComponentType = () => (
|
|
|
458
462
|
</MemoryRouter>
|
|
459
463
|
);
|
|
460
464
|
|
|
461
|
-
|
|
465
|
+
PreventNavigation.storyName = "Preventing navigation";
|
|
462
466
|
|
|
463
|
-
|
|
467
|
+
PreventNavigation.parameters = {
|
|
464
468
|
docs: {
|
|
465
469
|
storyDescription:
|
|
466
|
-
"
|
|
470
|
+
"Sometimes you may need to perform an async action either before or during navigation. This can be accomplished with `beforeNav` and `safeWithNav` respectively.",
|
|
467
471
|
},
|
|
468
472
|
chromatic: {
|
|
469
473
|
disableSnapshot: true,
|
|
470
474
|
},
|
|
471
475
|
};
|
|
472
476
|
|
|
473
|
-
export const
|
|
477
|
+
export const WithRouter: StoryComponentType = () => (
|
|
474
478
|
<MemoryRouter>
|
|
475
479
|
<View style={styles.row}>
|
|
476
|
-
<Button
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
e.preventDefault();
|
|
482
|
-
}}
|
|
483
|
-
>
|
|
484
|
-
This button prevents navigation.
|
|
480
|
+
<Button href="/foo" style={styles.button}>
|
|
481
|
+
Uses Client-side Nav
|
|
482
|
+
</Button>
|
|
483
|
+
<Button href="/foo" style={styles.button} skipClientNav>
|
|
484
|
+
Avoids Client-side Nav
|
|
485
485
|
</Button>
|
|
486
486
|
<Switch>
|
|
487
487
|
<Route path="/foo">
|
|
@@ -492,94 +492,14 @@ export const PreventNavigation: StoryComponentType = () => (
|
|
|
492
492
|
</MemoryRouter>
|
|
493
493
|
);
|
|
494
494
|
|
|
495
|
-
|
|
496
|
-
"Prevent navigation by calling e.preventDefault()";
|
|
495
|
+
WithRouter.storyName = "Navigation with React Router";
|
|
497
496
|
|
|
498
|
-
|
|
497
|
+
WithRouter.parameters = {
|
|
499
498
|
docs: {
|
|
500
499
|
storyDescription:
|
|
501
|
-
"
|
|
502
|
-
},
|
|
503
|
-
chromatic: {
|
|
504
|
-
disableSnapshot: true,
|
|
505
|
-
},
|
|
506
|
-
};
|
|
507
|
-
|
|
508
|
-
const kinds = ["primary", "secondary", "tertiary"];
|
|
509
|
-
|
|
510
|
-
export const ButtonsWithIcons: StoryComponentType = () => (
|
|
511
|
-
<View>
|
|
512
|
-
<View style={styles.row}>
|
|
513
|
-
{kinds.map((kind, idx) => (
|
|
514
|
-
<Button
|
|
515
|
-
kind={kind}
|
|
516
|
-
icon={icons.contentExercise}
|
|
517
|
-
style={styles.button}
|
|
518
|
-
key={idx}
|
|
519
|
-
>
|
|
520
|
-
{kind}
|
|
521
|
-
</Button>
|
|
522
|
-
))}
|
|
523
|
-
</View>
|
|
524
|
-
<View style={styles.row}>
|
|
525
|
-
{kinds.map((kind, idx) => (
|
|
526
|
-
<Button
|
|
527
|
-
kind={kind}
|
|
528
|
-
icon={icons.contentExercise}
|
|
529
|
-
style={styles.button}
|
|
530
|
-
key={idx}
|
|
531
|
-
size="small"
|
|
532
|
-
>
|
|
533
|
-
{`${kind} small`}
|
|
534
|
-
</Button>
|
|
535
|
-
))}
|
|
536
|
-
</View>
|
|
537
|
-
</View>
|
|
538
|
-
);
|
|
539
|
-
|
|
540
|
-
ButtonsWithIcons.parameters = {
|
|
541
|
-
docs: {
|
|
542
|
-
storyDescription: "Buttons can have an icon on it's left side.",
|
|
543
|
-
},
|
|
544
|
-
};
|
|
545
|
-
|
|
546
|
-
export const LongLabelsAreEllipsized: StoryComponentType = () => (
|
|
547
|
-
<Button onClick={() => {}} style={{maxWidth: 200}}>
|
|
548
|
-
label too long for the parent container
|
|
549
|
-
</Button>
|
|
550
|
-
);
|
|
551
|
-
|
|
552
|
-
export const SubmitButtonInForm: StoryComponentType = () => (
|
|
553
|
-
<form
|
|
554
|
-
onSubmit={(e) => {
|
|
555
|
-
e.preventDefault();
|
|
556
|
-
window.alert("form submitted"); // eslint-disable-line no-alert
|
|
557
|
-
}}
|
|
558
|
-
>
|
|
559
|
-
<View>
|
|
560
|
-
Foo: <input id="foo" value="bar" />
|
|
561
|
-
<Button type="submit">Submit</Button>
|
|
562
|
-
</View>
|
|
563
|
-
</form>
|
|
564
|
-
);
|
|
565
|
-
|
|
566
|
-
SubmitButtonInForm.parameters = {
|
|
567
|
-
options: {
|
|
568
|
-
showAddonPanel: true,
|
|
500
|
+
"Buttons do client-side navigation by default, if React Router exists:",
|
|
569
501
|
},
|
|
570
502
|
chromatic: {
|
|
571
|
-
// We already have screenshots of other stories that cover more of the
|
|
572
|
-
// button states.
|
|
573
503
|
disableSnapshot: true,
|
|
574
504
|
},
|
|
575
505
|
};
|
|
576
|
-
|
|
577
|
-
const styles = StyleSheet.create({
|
|
578
|
-
row: {
|
|
579
|
-
flexDirection: "row",
|
|
580
|
-
marginBottom: Spacing.xSmall_8,
|
|
581
|
-
},
|
|
582
|
-
button: {
|
|
583
|
-
marginRight: Spacing.xSmall_8,
|
|
584
|
-
},
|
|
585
|
-
});
|