-
Notifications
You must be signed in to change notification settings - Fork 148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Alerts component #621
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
08aef9b
Alert component, unstyled
Golodhros 9c6b706
Using SVG icon and styling
Golodhros 156317e
Knowl adjustments
Golodhros 0a0fe32
Extracts SVGIcons, adds story, adds link and custom action element to…
Golodhros 6966f45
Fixing null check
Golodhros File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
amundsen_application/static/js/components/common/Alert/alert.story.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import React from 'react'; | ||
import { storiesOf } from '@storybook/react'; | ||
|
||
import StorySection from '../StorySection'; | ||
import Alert from '.'; | ||
|
||
const stories = storiesOf('Components/Alert', module); | ||
|
||
stories.add('Alert', () => ( | ||
<> | ||
<StorySection title="Alert"> | ||
<Alert | ||
message="Alert text that can be short" | ||
onAction={() => { | ||
alert('action executed!'); | ||
}} | ||
/> | ||
</StorySection> | ||
<StorySection title="Alert with text link"> | ||
<Alert | ||
message={ | ||
<span> | ||
Alert text that has a <a href="https://lyft.com">link</a> | ||
</span> | ||
} | ||
/> | ||
</StorySection> | ||
<StorySection title="Alert with Action as button"> | ||
<Alert | ||
message="Alert text that can be short" | ||
actionText="Action Text" | ||
onAction={() => { | ||
alert('action executed!'); | ||
}} | ||
/> | ||
</StorySection> | ||
<StorySection title="Alert with Action as link"> | ||
<Alert | ||
message="Alert text that can be short" | ||
actionText="Action Text" | ||
actionHref="http://www.lyft.com" | ||
/> | ||
</StorySection> | ||
<StorySection title="Alert with Action as custom link"> | ||
<Alert | ||
message="Alert text that can be short" | ||
actionLink={ | ||
<a className="test-action-link" href="http://testSite.com"> | ||
Custom Link | ||
</a> | ||
} | ||
/> | ||
</StorySection> | ||
<StorySection title="Alert with long text"> | ||
<Alert message="Lorem ipsum dolor sit amet consectetur adipisicing elit. Laboriosam perspiciatis non ipsa officia expedita magnam mollitia, excepturi iste eveniet qui nisi eum illum, quas voluptas, reprehenderit quam molestias cum quisquam!" /> | ||
</StorySection> | ||
<StorySection title="Alert with long text and action"> | ||
<Alert | ||
actionText="Action Text" | ||
onAction={() => { | ||
alert('action executed!'); | ||
}} | ||
message="Lorem ipsum dolor sit amet consectetur adipisicing elit. Laboriosam perspiciatis non ipsa officia expedita magnam mollitia, excepturi iste eveniet qui nisi eum illum, quas voluptas, reprehenderit quam molestias cum quisquam!" | ||
/> | ||
</StorySection> | ||
</> | ||
)); |
115 changes: 115 additions & 0 deletions
115
amundsen_application/static/js/components/common/Alert/index.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// Copyright Contributors to the Amundsen project. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import * as React from 'react'; | ||
import { mount } from 'enzyme'; | ||
|
||
import Alert, { AlertProps } from '.'; | ||
|
||
const setup = (propOverrides?: Partial<AlertProps>) => { | ||
const props: AlertProps = { | ||
message: 'Test Message', | ||
onAction: jest.fn(), | ||
...propOverrides, | ||
}; | ||
const wrapper = mount(<Alert {...props} />); | ||
|
||
return { props, wrapper }; | ||
}; | ||
|
||
describe('Alert', () => { | ||
describe('render', () => { | ||
it('should render an alert icon', () => { | ||
const { wrapper } = setup(); | ||
const expected = 1; | ||
const actual = wrapper.find('.alert-triangle-svg-icon').length; | ||
|
||
expect(actual).toEqual(expected); | ||
}); | ||
|
||
it('should render the alert message text', () => { | ||
const { props, wrapper } = setup(); | ||
const expected = props.message; | ||
const actual = wrapper.find('.alert-message').text(); | ||
|
||
expect(actual).toEqual(expected); | ||
}); | ||
|
||
describe('when passing an action text and action handler', () => { | ||
it('should render the action button', () => { | ||
const { wrapper } = setup({ actionText: 'Action Text' }); | ||
const expected = 1; | ||
const actual = wrapper.find('.btn-link').length; | ||
|
||
expect(actual).toEqual(expected); | ||
}); | ||
|
||
it('should render the action text', () => { | ||
const { props, wrapper } = setup({ actionText: 'Action Text' }); | ||
const expected = props.actionText; | ||
const actual = wrapper.find('.btn-link').text(); | ||
|
||
expect(actual).toEqual(expected); | ||
}); | ||
}); | ||
|
||
describe('when passing an action text and action href', () => { | ||
it('should render the action link', () => { | ||
const { wrapper } = setup({ | ||
actionHref: 'http://testSite.com', | ||
actionText: 'Action Text', | ||
}); | ||
const expected = 1; | ||
const actual = wrapper.find('.action-link').length; | ||
|
||
expect(actual).toEqual(expected); | ||
}); | ||
|
||
it('should render the action text', () => { | ||
const { props, wrapper } = setup({ | ||
actionHref: 'http://testSite.com', | ||
actionText: 'Action Text', | ||
}); | ||
const expected = props.actionText; | ||
const actual = wrapper.find('.action-link').text(); | ||
|
||
expect(actual).toEqual(expected); | ||
}); | ||
}); | ||
|
||
describe('when passing a custom action link', () => { | ||
it('should render the custom action link', () => { | ||
const { wrapper } = setup({ | ||
actionLink: ( | ||
<a className="test-action-link" href="http://testSite.com"> | ||
Custom Link | ||
</a> | ||
), | ||
}); | ||
const expected = 1; | ||
const actual = wrapper.find('.test-action-link').length; | ||
|
||
expect(actual).toEqual(expected); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('lifetime', () => { | ||
describe('when clicking on the action button', () => { | ||
it('should call the handler', () => { | ||
const handlerSpy = jest.fn(); | ||
const { wrapper } = setup({ | ||
actionText: 'Action Text', | ||
onAction: handlerSpy, | ||
}); | ||
const expected = 1; | ||
|
||
wrapper.find('button.btn-link').simulate('click'); | ||
|
||
const actual = handlerSpy.mock.calls.length; | ||
|
||
expect(actual).toEqual(expected); | ||
}); | ||
}); | ||
}); | ||
}); |
62 changes: 62 additions & 0 deletions
62
amundsen_application/static/js/components/common/Alert/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright Contributors to the Amundsen project. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import * as React from 'react'; | ||
|
||
import { AlertIcon, IconSizes } from '../SVGIcons'; | ||
|
||
import './styles.scss'; | ||
|
||
const STROKE_COLOR = '#b8072c'; // $red70 | ||
|
||
export interface AlertProps { | ||
message: string | React.ReactNode; | ||
actionLink?: React.ReactNode; | ||
actionText?: string; | ||
actionHref?: string; | ||
onAction?: (event: React.MouseEvent<HTMLButtonElement>) => void; | ||
} | ||
|
||
const Alert: React.FC<AlertProps> = ({ | ||
message, | ||
onAction, | ||
actionText, | ||
actionHref, | ||
actionLink, | ||
}: AlertProps) => { | ||
let action: null | React.ReactNode = null; | ||
|
||
if (actionText && onAction) { | ||
action = ( | ||
<span className="alert-action"> | ||
<button type="button" className="btn btn-link" onClick={onAction}> | ||
{actionText} | ||
</button> | ||
</span> | ||
); | ||
} | ||
|
||
if (actionText && actionHref) { | ||
action = ( | ||
<span className="alert-action"> | ||
<a className="action-link" href={actionHref}> | ||
{actionText} | ||
</a> | ||
</span> | ||
); | ||
} | ||
|
||
if (actionLink) { | ||
action = <span className="alert-action">{actionLink}</span>; | ||
} | ||
|
||
return ( | ||
<div className="alert"> | ||
<AlertIcon stroke={STROKE_COLOR} size={IconSizes.SMALL} /> | ||
<p className="alert-message">{message}</p> | ||
{action} | ||
</div> | ||
); | ||
}; | ||
|
||
export default Alert; |
34 changes: 34 additions & 0 deletions
34
amundsen_application/static/js/components/common/Alert/styles.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright Contributors to the Amundsen project. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
@import 'variables'; | ||
@import 'typography'; | ||
|
||
$alert-border-radius: 4px; | ||
$alert-message-line-height: 24px; | ||
|
||
.alert { | ||
background-color: $body-bg; | ||
border-radius: $alert-border-radius; | ||
display: flex; | ||
padding: $spacer-1 $spacer-1 * 1.5 $spacer-1 $spacer-2; | ||
justify-content: flex-start; | ||
box-shadow: $elevation-level2; | ||
|
||
.alert-message { | ||
@extend %text-body-w2; | ||
|
||
margin: 0; | ||
display: inline; | ||
} | ||
|
||
.alert-triangle-svg-icon { | ||
flex-shrink: 0; | ||
align-self: center; | ||
margin-right: $spacer-1; | ||
} | ||
|
||
.alert-action { | ||
margin: auto 0 auto auto; | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
amundsen_application/static/js/components/common/SVGIcons/AlertIcon.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import * as React from 'react'; | ||
|
||
import { IconSizes } from '.'; | ||
|
||
const DEFAULT_STROKE_COLOR = 'currentColor'; | ||
|
||
export interface IconProps { | ||
stroke?: string; | ||
size?: number; | ||
} | ||
|
||
export const AlertIcon: React.FC<IconProps> = ({ | ||
stroke = DEFAULT_STROKE_COLOR, | ||
size = IconSizes.REGULAR, | ||
}: IconProps) => { | ||
return ( | ||
<svg | ||
width={size} | ||
height={size} | ||
viewBox="0 0 24 24" | ||
fill="none" | ||
stroke={stroke} | ||
strokeWidth={2} | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
className="alert-triangle-svg-icon" | ||
> | ||
<path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0zM12 9v4M12 17h0" /> | ||
</svg> | ||
); | ||
}; |
6 changes: 6 additions & 0 deletions
6
amundsen_application/static/js/components/common/SVGIcons/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export * from './AlertIcon'; | ||
|
||
export enum IconSizes { | ||
REGULAR = 24, | ||
SMALL = 16, | ||
} |
15 changes: 15 additions & 0 deletions
15
amundsen_application/static/js/components/common/SVGIcons/svgIcons.story.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import React from 'react'; | ||
import { storiesOf } from '@storybook/react'; | ||
|
||
import StorySection from '../StorySection'; | ||
import { AlertIcon } from '.'; | ||
|
||
const stories = storiesOf('Attributes/Icons', module); | ||
|
||
stories.add('SVG Icons', () => ( | ||
<> | ||
<StorySection title="Alert"> | ||
<AlertIcon /> | ||
</StorySection> | ||
</> | ||
)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For our internal use case, the text will end up being a link to another Amundsen page. Given our desire to use the correct components for specific actions, do you think we should still support a button with onClick vs and anchor with an href...or both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see.
I could make it support both easily. I will add an optional actionHref prop, if that has a value, I will render a router Link instead