-
Notifications
You must be signed in to change notification settings - Fork 148
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Alert component, unstyled Signed-off-by: Marcos Iglesias <miglesiasvalle@lyft.com> * Using SVG icon and styling Signed-off-by: Marcos Iglesias <miglesiasvalle@lyft.com> * Knowl adjustments Supporting an action link Signed-off-by: Marcos Iglesias <miglesiasvalle@lyft.com> * Extracts SVGIcons, adds story, adds link and custom action element to Alert Signed-off-by: Marcos Iglesias <miglesiasvalle@lyft.com> * Fixing null check Signed-off-by: Marcos Iglesias <miglesiasvalle@lyft.com>
- Loading branch information
Showing
9 changed files
with
336 additions
and
6 deletions.
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