@khanacademy/wonder-blocks-banner 1.1.0 → 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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-banner
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b9b24953: Allow for custom actions in Banner
|
|
8
|
+
|
|
9
|
+
## 1.1.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [ceb111df]
|
|
14
|
+
- @khanacademy/wonder-blocks-button@3.0.7
|
|
15
|
+
- @khanacademy/wonder-blocks-icon-button@3.4.15
|
|
16
|
+
- @khanacademy/wonder-blocks-link@3.8.13
|
|
17
|
+
|
|
3
18
|
## 1.1.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
package/dist/es/index.js
CHANGED
|
@@ -72,7 +72,14 @@ const Banner = props => {
|
|
|
72
72
|
} = props;
|
|
73
73
|
|
|
74
74
|
const renderActions = () => {
|
|
75
|
-
return actions == null ? void 0 : actions.filter(Boolean).map(action => {
|
|
75
|
+
return actions == null ? void 0 : actions.filter(Boolean).map((action, i) => {
|
|
76
|
+
if (action.type === "custom") {
|
|
77
|
+
return React.createElement(View, {
|
|
78
|
+
style: styles.action,
|
|
79
|
+
key: `custom-action-${i}`
|
|
80
|
+
}, action.node);
|
|
81
|
+
}
|
|
82
|
+
|
|
76
83
|
const handleClick = action.onClick;
|
|
77
84
|
|
|
78
85
|
if (action.href) {
|
package/dist/index.js
CHANGED
|
@@ -225,7 +225,14 @@ const Banner = props => {
|
|
|
225
225
|
} = props;
|
|
226
226
|
|
|
227
227
|
const renderActions = () => {
|
|
228
|
-
return actions == null ? void 0 : actions.filter(Boolean).map(action => {
|
|
228
|
+
return actions == null ? void 0 : actions.filter(Boolean).map((action, i) => {
|
|
229
|
+
if (action.type === "custom") {
|
|
230
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4__["View"], {
|
|
231
|
+
style: styles.action,
|
|
232
|
+
key: `custom-action-${i}`
|
|
233
|
+
}, action.node);
|
|
234
|
+
}
|
|
235
|
+
|
|
229
236
|
const handleClick = action.onClick;
|
|
230
237
|
|
|
231
238
|
if (action.href) {
|
|
@@ -374,6 +381,8 @@ const styles = aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
|
374
381
|
},
|
|
375
382
|
floatingBorder: {
|
|
376
383
|
borderRadius: 4,
|
|
384
|
+
// Stop the square corners of the inner container from
|
|
385
|
+
// flowing out of the rounded corners of the outer container.
|
|
377
386
|
overflow: "hidden"
|
|
378
387
|
}
|
|
379
388
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-banner",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"description": "Banner components for Wonder Blocks.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@babel/runtime": "^7.18.6",
|
|
19
|
-
"@khanacademy/wonder-blocks-button": "^3.0.
|
|
19
|
+
"@khanacademy/wonder-blocks-button": "^3.0.7",
|
|
20
20
|
"@khanacademy/wonder-blocks-color": "^1.2.0",
|
|
21
21
|
"@khanacademy/wonder-blocks-core": "^4.5.0",
|
|
22
22
|
"@khanacademy/wonder-blocks-icon": "^1.2.32",
|
|
23
|
-
"@khanacademy/wonder-blocks-icon-button": "^3.4.
|
|
24
|
-
"@khanacademy/wonder-blocks-link": "^3.8.
|
|
23
|
+
"@khanacademy/wonder-blocks-icon-button": "^3.4.15",
|
|
24
|
+
"@khanacademy/wonder-blocks-link": "^3.8.13",
|
|
25
25
|
"@khanacademy/wonder-blocks-spacing": "^3.0.5",
|
|
26
26
|
"@khanacademy/wonder-blocks-typography": "^1.1.34"
|
|
27
27
|
},
|
|
@@ -393,6 +393,85 @@ WithDismissal.parameters = {
|
|
|
393
393
|
},
|
|
394
394
|
};
|
|
395
395
|
|
|
396
|
+
export const WithCustomAction: StoryComponentType = () => (
|
|
397
|
+
<Banner
|
|
398
|
+
text="some text"
|
|
399
|
+
layout="floating"
|
|
400
|
+
actions={[
|
|
401
|
+
{
|
|
402
|
+
type: "custom",
|
|
403
|
+
node: (
|
|
404
|
+
<Button
|
|
405
|
+
kind="tertiary"
|
|
406
|
+
size="small"
|
|
407
|
+
onClick={() => {}}
|
|
408
|
+
spinner={true}
|
|
409
|
+
>
|
|
410
|
+
Spinner Button
|
|
411
|
+
</Button>
|
|
412
|
+
),
|
|
413
|
+
},
|
|
414
|
+
]}
|
|
415
|
+
/>
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
WithCustomAction.parameters = {
|
|
419
|
+
docs: {
|
|
420
|
+
storyDescription: `**NOTE: Custom actions are discouraged**
|
|
421
|
+
**and should only be used as a last resort!**\n\nThere are a
|
|
422
|
+
number of other props that Buttons and Links may have that are
|
|
423
|
+
not currently supported by the \`actions\` prop in Banner.
|
|
424
|
+
These would require the use of custom actions. If it absolutely
|
|
425
|
+
necessary to have a custom action, it can be done by passing
|
|
426
|
+
in an object into the \`actions\` prop array that has
|
|
427
|
+
\`type:"custom"\`, and your desired element in the \`node\`
|
|
428
|
+
field. Here is an example of a case where the built in actions
|
|
429
|
+
may not be enough - a button with a \`spinner\` prop would need
|
|
430
|
+
a custom implementation here.`,
|
|
431
|
+
},
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
export const WithMixedActions: StoryComponentType = () => (
|
|
435
|
+
<Banner
|
|
436
|
+
text="some text"
|
|
437
|
+
layout="floating"
|
|
438
|
+
actions={[
|
|
439
|
+
{
|
|
440
|
+
title: "Normal button",
|
|
441
|
+
onClick: () => {},
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
type: "custom",
|
|
445
|
+
node: (
|
|
446
|
+
<Button kind="tertiary" size="small" onClick={() => {}}>
|
|
447
|
+
Custom button
|
|
448
|
+
</Button>
|
|
449
|
+
),
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
type: "custom",
|
|
453
|
+
node: (
|
|
454
|
+
<Button
|
|
455
|
+
kind="tertiary"
|
|
456
|
+
size="small"
|
|
457
|
+
onClick={() => {}}
|
|
458
|
+
spinner={true}
|
|
459
|
+
>
|
|
460
|
+
Spinner Button
|
|
461
|
+
</Button>
|
|
462
|
+
),
|
|
463
|
+
},
|
|
464
|
+
]}
|
|
465
|
+
/>
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
WithMixedActions.parameters = {
|
|
469
|
+
docs: {
|
|
470
|
+
storyDescription: `Here is an example that includes both a
|
|
471
|
+
normal action and a custom action.`,
|
|
472
|
+
},
|
|
473
|
+
};
|
|
474
|
+
|
|
396
475
|
export const RightToLeft: StoryComponentType = () => (
|
|
397
476
|
<View style={styles.rightToLeft}>
|
|
398
477
|
<Banner
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import {render, screen} from "@testing-library/react";
|
|
4
4
|
|
|
5
|
+
import Button from "@khanacademy/wonder-blocks-button";
|
|
6
|
+
|
|
5
7
|
import Banner from "../banner.js";
|
|
6
8
|
|
|
7
9
|
describe("Banner", () => {
|
|
@@ -82,6 +84,38 @@ describe("Banner", () => {
|
|
|
82
84
|
expect(link).toBeInTheDocument();
|
|
83
85
|
});
|
|
84
86
|
|
|
87
|
+
test("passing a custom action causes the action to appear", async () => {
|
|
88
|
+
// Arrange
|
|
89
|
+
|
|
90
|
+
// Act
|
|
91
|
+
render(
|
|
92
|
+
<Banner
|
|
93
|
+
text="some text"
|
|
94
|
+
layout="floating"
|
|
95
|
+
actions={[
|
|
96
|
+
{
|
|
97
|
+
type: "custom",
|
|
98
|
+
node: (
|
|
99
|
+
<Button
|
|
100
|
+
kind="tertiary"
|
|
101
|
+
size="small"
|
|
102
|
+
onClick={() => {}}
|
|
103
|
+
spinner={true}
|
|
104
|
+
testId="custom-button-in-banner"
|
|
105
|
+
>
|
|
106
|
+
Spinner Button
|
|
107
|
+
</Button>
|
|
108
|
+
),
|
|
109
|
+
},
|
|
110
|
+
]}
|
|
111
|
+
/>,
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
// Assert
|
|
115
|
+
const button = await screen.findByTestId("custom-button-in-banner");
|
|
116
|
+
expect(button).toBeInTheDocument();
|
|
117
|
+
});
|
|
118
|
+
|
|
85
119
|
test("passing multiple actions causes multiple actions to appear", async () => {
|
|
86
120
|
// Arrange
|
|
87
121
|
|
|
@@ -93,7 +127,19 @@ describe("Banner", () => {
|
|
|
93
127
|
actions={[
|
|
94
128
|
{title: "button 1", onClick: () => {}},
|
|
95
129
|
{title: "button 2", onClick: () => {}},
|
|
96
|
-
{
|
|
130
|
+
{
|
|
131
|
+
type: "custom",
|
|
132
|
+
node: (
|
|
133
|
+
<Button
|
|
134
|
+
kind="tertiary"
|
|
135
|
+
size="small"
|
|
136
|
+
onClick={() => {}}
|
|
137
|
+
spinner={true}
|
|
138
|
+
>
|
|
139
|
+
Spinner Button
|
|
140
|
+
</Button>
|
|
141
|
+
),
|
|
142
|
+
},
|
|
97
143
|
]}
|
|
98
144
|
/>,
|
|
99
145
|
);
|
package/src/components/banner.js
CHANGED
|
@@ -29,7 +29,15 @@ type ActionTriggerWithLink = {|
|
|
|
29
29
|
onClick?: () => void,
|
|
30
30
|
|};
|
|
31
31
|
|
|
32
|
-
type
|
|
32
|
+
type ActionTriggerCustom = {|
|
|
33
|
+
type: "custom",
|
|
34
|
+
node: React.Node,
|
|
35
|
+
|};
|
|
36
|
+
|
|
37
|
+
type ActionTrigger =
|
|
38
|
+
| ActionTriggerWithButton
|
|
39
|
+
| ActionTriggerWithLink
|
|
40
|
+
| ActionTriggerCustom;
|
|
33
41
|
|
|
34
42
|
type BannerKind =
|
|
35
43
|
/**
|
|
@@ -181,8 +189,17 @@ const Banner = (props: Props): React.Node => {
|
|
|
181
189
|
} = props;
|
|
182
190
|
|
|
183
191
|
const renderActions = () => {
|
|
184
|
-
return actions?.filter(Boolean).map((action) => {
|
|
192
|
+
return actions?.filter(Boolean).map((action, i) => {
|
|
193
|
+
if (action.type === "custom") {
|
|
194
|
+
return (
|
|
195
|
+
<View style={styles.action} key={`custom-action-${i}`}>
|
|
196
|
+
{action.node}
|
|
197
|
+
</View>
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
185
201
|
const handleClick = action.onClick;
|
|
202
|
+
|
|
186
203
|
if (action.href) {
|
|
187
204
|
return (
|
|
188
205
|
<View style={styles.action} key={action.title}>
|
|
@@ -352,6 +369,8 @@ const styles = StyleSheet.create({
|
|
|
352
369
|
},
|
|
353
370
|
floatingBorder: {
|
|
354
371
|
borderRadius: 4,
|
|
372
|
+
// Stop the square corners of the inner container from
|
|
373
|
+
// flowing out of the rounded corners of the outer container.
|
|
355
374
|
overflow: "hidden",
|
|
356
375
|
},
|
|
357
376
|
});
|