@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
@@ -1,5 +1,11 @@
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
+
3
9
  ## 1.1.1
4
10
 
5
11
  ### Patch 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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-banner",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "design": "v1",
5
5
  "description": "Banner components for Wonder Blocks.",
6
6
  "main": "dist/index.js",
@@ -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
- {title: "button 3", onClick: () => {}},
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
  );
@@ -29,7 +29,15 @@ type ActionTriggerWithLink = {|
29
29
  onClick?: () => void,
30
30
  |};
31
31
 
32
- type ActionTrigger = ActionTriggerWithButton | ActionTriggerWithLink;
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}>