@khanacademy/wonder-blocks-banner 1.1.1 → 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
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) {
|
package/package.json
CHANGED
|
@@ -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}>
|