Skip to content

Commit ce1565c

Browse files
[LENS-911] MessageBar custom actions (#1188)
1 parent d1a1f7c commit ce1565c

File tree

16 files changed

+456
-140
lines changed

16 files changed

+456
-140
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3434
- `Tooltip` now renders in a `Portal`
3535
- `TabList` now supports distribute prop
3636
- `MessageBar`
37-
- Sets `canDismiss` to true by default
37+
- MessageBar is dismissable by default. Use prop `noActions` in place of `canDismiss={false}` to hide dismiss button.
3838
- Adds new `visible` prop to toggle display externally
39+
- Accepts primary and secondary action overrides and callbacks
3940

4041
### Fixed
4142

packages/components/src/MessageBar/MessageBar.test.tsx

Lines changed: 120 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,45 @@ import {
3434
import { MessageBar } from './MessageBar'
3535

3636
describe('MessageBar', () => {
37-
describe('clear button functionality', () => {
38-
test('clearable by default', () => {
37+
test('controlled component', () => {
38+
const handleDismiss = jest.fn()
39+
40+
const { getByText, queryByText, rerender } = renderWithTheme(
41+
<MessageBar onPrimaryClick={handleDismiss} visible>
42+
Message text
43+
</MessageBar>
44+
)
45+
46+
// visible message bar
47+
expect(getByText('Message text')).toBeInTheDocument()
48+
49+
// dismiss callback
50+
expect(handleDismiss).not.toHaveBeenCalled()
51+
52+
const dismissButton =
53+
getByText('Dismiss Inform').closest('button') ||
54+
document.createElement('button') // suppress typescript warning about possible null button
55+
56+
fireEvent.click(dismissButton)
57+
58+
expect(handleDismiss).toHaveBeenCalledTimes(1)
59+
60+
// message bar remains visible until `visible` prop is toggled
61+
expect(getByText('Message text')).toBeInTheDocument()
62+
63+
// dismiss message bar through `visible` prop change
64+
rerender(
65+
withThemeProvider(
66+
<MessageBar onPrimaryClick={handleDismiss} visible={false}>
67+
Message text
68+
</MessageBar>
69+
)
70+
)
71+
expect(queryByText('Message text')).not.toBeInTheDocument()
72+
})
73+
74+
describe('action buttons', () => {
75+
test('renders standard Dismiss button by default', () => {
3976
const { getByText, queryByText } = renderWithTheme(
4077
<MessageBar>Message text</MessageBar>
4178
)
@@ -54,61 +91,107 @@ describe('MessageBar', () => {
5491
expect(queryByText('Message text')).not.toBeInTheDocument()
5592
})
5693

57-
test('controlled component', () => {
58-
const handleDismiss = jest.fn()
59-
94+
test('hides the dismiss button', () => {
6095
const { getByText, queryByText, rerender } = renderWithTheme(
61-
<MessageBar onDismiss={handleDismiss} visible>
62-
Message text
63-
</MessageBar>
96+
<MessageBar>Message text</MessageBar>
6497
)
6598

66-
// visible message bar
67-
expect(getByText('Message text')).toBeInTheDocument()
99+
expect(getByText('Dismiss Inform')).toBeInTheDocument()
68100

69-
// dismiss callback
70-
expect(handleDismiss).not.toHaveBeenCalled()
101+
rerender(
102+
withThemeProvider(<MessageBar noActions>Message text</MessageBar>)
103+
)
71104

72-
const dismissButton =
73-
getByText('Dismiss Inform').closest('button') ||
74-
document.createElement('button') // suppress typescript warning about possible null button
105+
expect(queryByText('Dismiss Inform')).not.toBeInTheDocument()
106+
})
75107

76-
fireEvent.click(dismissButton)
108+
test('accepts a text label to customize primaryAction', () => {
109+
const handlePrimaryClick = jest.fn()
110+
const { getByText, queryByText } = renderWithTheme(
111+
<MessageBar
112+
primaryAction="Take the red pill"
113+
onPrimaryClick={handlePrimaryClick}
114+
>
115+
Do you want to know what the matrix is?
116+
</MessageBar>
117+
)
77118

78-
expect(handleDismiss).toHaveBeenCalledTimes(1)
119+
const primaryButton = getByText('Take the red pill')
79120

80-
// message bar remains visible until `visible` prop is toggled
81-
expect(getByText('Message text')).toBeInTheDocument()
121+
expect(primaryButton).toBeInTheDocument()
122+
expect(
123+
getByText('Do you want to know what the matrix is?')
124+
).toBeInTheDocument()
125+
expect(queryByText('Dismiss Inform')).not.toBeInTheDocument()
82126

83-
// dismiss message bar through `visible` prop change
84-
rerender(
85-
withThemeProvider(
86-
<MessageBar onDismiss={handleDismiss} visible={false}>
87-
Message text
88-
</MessageBar>
89-
)
90-
)
91-
expect(queryByText('Message text')).not.toBeInTheDocument()
127+
fireEvent.click(primaryButton)
128+
129+
expect(handlePrimaryClick).toBeCalledTimes(1)
130+
// clears messageBar on primary action click
131+
expect(
132+
queryByText('Do you want to know what the matrix is?')
133+
).not.toBeInTheDocument()
92134
})
93135

94-
test('`canDismiss` toggles the clear button', () => {
95-
const { getByText, queryByText, rerender } = renderWithTheme(
96-
<MessageBar>Message text</MessageBar>
136+
test('accepts a text label to customize secondaryAction', () => {
137+
const handleSecondaryClick = jest.fn()
138+
const { getByText, queryByText } = renderWithTheme(
139+
<MessageBar
140+
secondaryAction="Take the blue pill"
141+
onSecondaryClick={handleSecondaryClick}
142+
>
143+
Do you want to know what the matrix is?
144+
</MessageBar>
97145
)
98146

99-
expect(getByText('Dismiss Inform')).toBeInTheDocument()
147+
const secondaryButton = getByText('Take the blue pill')
100148

101-
rerender(
102-
withThemeProvider(
103-
<MessageBar canDismiss={false}>Message text</MessageBar>
104-
)
149+
expect(secondaryButton).toBeInTheDocument()
150+
expect(
151+
getByText('Do you want to know what the matrix is?')
152+
).toBeInTheDocument()
153+
154+
fireEvent.click(secondaryButton)
155+
156+
expect(handleSecondaryClick).toBeCalledTimes(1)
157+
// clears messageBar on secondary action click
158+
expect(
159+
queryByText('Do you want to know what the matrix is?')
160+
).not.toBeInTheDocument()
161+
})
162+
163+
test('renders custom JSX Button elements for primary and secondary actions', () => {
164+
const { getByText, queryByText } = renderWithTheme(
165+
<MessageBar
166+
intent="inform"
167+
primaryAction={<button>Take the red pill</button>}
168+
secondaryAction={<button>Take the blue pill</button>}
169+
>
170+
Message text
171+
</MessageBar>
105172
)
106173

174+
expect(getByText('Take the red pill')).toBeInTheDocument()
175+
expect(getByText('Take the blue pill')).toBeInTheDocument()
107176
expect(queryByText('Dismiss Inform')).not.toBeInTheDocument()
108177
})
178+
179+
test('renders secondaryButton next to default Dismiss button', () => {
180+
const { getByText } = renderWithTheme(
181+
<MessageBar
182+
intent="inform"
183+
secondaryAction={<button>secondary action</button>}
184+
>
185+
Message text
186+
</MessageBar>
187+
)
188+
189+
expect(getByText('secondary action')).toBeInTheDocument()
190+
expect(getByText('Dismiss Inform')).toBeInTheDocument()
191+
})
109192
})
110193

111-
describe('MessageBar intents', () => {
194+
describe('intent styling', () => {
112195
test('Warn MessageBar', () => {
113196
const { getByText, getByTitle } = renderWithTheme(
114197
<MessageBar intent="warn">Warn</MessageBar>

0 commit comments

Comments
 (0)