-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(app): labware and modules setup hifi designs (#12582)
* Add deck map icon [RCORE-733] * Apply hifi designs to labware setup page [RCORE-733] * Code formatting fixes [RCORE-733] * Fix small button text color [RCORE-734] * Create shared back button component [RCORE-734] * Use new back button in setup headers and remove continue button [RCORE-734] * Create FloatingActionButton component and use it for Map View button [RCORE-734] * Add connection-status icon [RCORE-734] * Fix chip component styling [RCORE-734] * Create new InlineNotification component [RCORE-734] * Apply hifi styling to module setup page [RCORE-734] * Add back info icon [RCORE-734] * Remove onClick parameter for inline notification [RCORE-734] * Move ODDBackButton to molecules and add stories and tests [RCORE-734] * Fix imports, formatting, and general code style improvements [RCORE-734] * Use new typography [RCORE-734] * Fix mangled directory names [NOTICKET]
- Loading branch information
Showing
30 changed files
with
750 additions
and
399 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
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
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
39 changes: 39 additions & 0 deletions
39
app/src/atoms/InlineNotification/InlineNotification.stories.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,39 @@ | ||
import * as React from 'react' | ||
import { InlineNotification } from '.' | ||
import type { Story, Meta } from '@storybook/react' | ||
|
||
export default { | ||
title: 'ODD/Atoms/InlineNotification', | ||
argTypes: { | ||
hug: { | ||
control: { | ||
type: 'boolean', | ||
}, | ||
defaultValue: false, | ||
}, | ||
type: { | ||
control: { | ||
type: 'select', | ||
options: ['alert', 'error', 'neutral', 'success'], | ||
}, | ||
defaultValue: 'success', | ||
}, | ||
onCloseClick: { | ||
control: { | ||
type: 'boolean', | ||
}, | ||
defaultValue: true, | ||
}, | ||
}, | ||
} as Meta | ||
|
||
const Template: Story< | ||
React.ComponentProps<typeof InlineNotification> | ||
> = args => <InlineNotification {...args} /> | ||
|
||
export const InlineNotificationComponent = Template.bind({}) | ||
InlineNotificationComponent.args = { | ||
heading: 'awesome', | ||
message: 'you did it', | ||
type: 'success', | ||
} |
66 changes: 66 additions & 0 deletions
66
app/src/atoms/InlineNotification/__tests__/InlineNotification.test.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,66 @@ | ||
import * as React from 'react' | ||
import { fireEvent } from '@testing-library/react' | ||
import { renderWithProviders } from '@opentrons/components' | ||
import { i18n } from '../../../i18n' | ||
import { InlineNotification } from '..' | ||
|
||
const render = (props: React.ComponentProps<typeof InlineNotification>) => { | ||
return renderWithProviders(<InlineNotification {...props} />, { | ||
i18nInstance: i18n, | ||
})[0] | ||
} | ||
|
||
describe('InlineNotification', () => { | ||
let props: React.ComponentProps<typeof InlineNotification> | ||
|
||
beforeEach(() => { | ||
props = { | ||
type: 'success', | ||
heading: 'TITLE', | ||
} | ||
}) | ||
it('renders success inline notification', () => { | ||
const { getByText, getByLabelText } = render(props) | ||
getByLabelText('icon_success') | ||
getByText('TITLE') | ||
}) | ||
it('renders success inline notification with exit button and when click dismisses inline notification', () => { | ||
props = { | ||
type: 'success', | ||
heading: 'TITLE', | ||
onCloseClick: jest.fn(), | ||
} | ||
const { getByText, getByLabelText } = render(props) | ||
getByText('TITLE') | ||
const btn = getByLabelText('close_icon') | ||
fireEvent.click(btn) | ||
expect(props.onCloseClick).toHaveBeenCalled() | ||
}) | ||
it('renders alert inline notification', () => { | ||
props = { | ||
type: 'alert', | ||
heading: 'TITLE', | ||
} | ||
const { getByText, getByLabelText } = render(props) | ||
getByLabelText('icon_alert') | ||
getByText('TITLE') | ||
}) | ||
it('renders error inline notification', () => { | ||
props = { | ||
type: 'error', | ||
heading: 'TITLE', | ||
} | ||
const { getByText, getByLabelText } = render(props) | ||
getByLabelText('icon_error') | ||
getByText('TITLE') | ||
}) | ||
it('renders neutral inline notification', () => { | ||
props = { | ||
type: 'neutral', | ||
heading: 'TITLE', | ||
} | ||
const { getByText, getByLabelText } = render(props) | ||
getByLabelText('icon_neutral') | ||
getByText('TITLE') | ||
}) | ||
}) |
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,110 @@ | ||
import * as React from 'react' | ||
import { | ||
Icon, | ||
JUSTIFY_SPACE_BETWEEN, | ||
IconProps, | ||
Flex, | ||
DIRECTION_ROW, | ||
ALIGN_CENTER, | ||
COLORS, | ||
SPACING, | ||
TYPOGRAPHY, | ||
BORDERS, | ||
Btn, | ||
} from '@opentrons/components' | ||
import { StyledText } from '../text' | ||
|
||
import type { StyleProps } from '@opentrons/components' | ||
|
||
type InlineNotificationType = 'alert' | 'error' | 'neutral' | 'success' | ||
|
||
export interface InlineNotificationProps extends StyleProps { | ||
/** name constant of the icon to display */ | ||
type: InlineNotificationType | ||
/** InlineNotification contents */ | ||
heading: string | ||
message?: string | ||
/** Optional dynamic width based on contents */ | ||
hug?: boolean | ||
/** optional handler to show close button/clear alert */ | ||
onCloseClick?: (() => void) | React.MouseEventHandler<HTMLButtonElement> | ||
} | ||
|
||
const INLINE_NOTIFICATION_PROPS_BY_TYPE: Record< | ||
InlineNotificationType, | ||
{ icon: IconProps; backgroundColor: string; color: string } | ||
> = { | ||
alert: { | ||
icon: { name: 'ot-alert' }, | ||
backgroundColor: COLORS.yellow_three, | ||
color: COLORS.yellow_two, | ||
}, | ||
error: { | ||
icon: { name: 'ot-alert' }, | ||
backgroundColor: COLORS.red_three, | ||
color: COLORS.red_two, | ||
}, | ||
neutral: { | ||
icon: { name: 'information' }, | ||
backgroundColor: COLORS.darkBlack_twenty, | ||
color: COLORS.darkBlackEnabled, | ||
}, | ||
success: { | ||
icon: { name: 'ot-check' }, | ||
backgroundColor: COLORS.green_three, | ||
color: COLORS.green_two, | ||
}, | ||
} | ||
|
||
export function InlineNotification( | ||
props: InlineNotificationProps | ||
): JSX.Element { | ||
const { heading, hug = false, onCloseClick, message, type } = props | ||
const fullHeading = `${heading}${message ? '. ' : ''}` | ||
const fullmessage = `${message}.` | ||
const inlineNotificationProps = INLINE_NOTIFICATION_PROPS_BY_TYPE[type] | ||
const iconProps = { | ||
...inlineNotificationProps.icon, | ||
size: '1.75rem', | ||
color: INLINE_NOTIFICATION_PROPS_BY_TYPE[type].color, | ||
} | ||
return ( | ||
<Flex | ||
alignItems={ALIGN_CENTER} | ||
backgroundColor={INLINE_NOTIFICATION_PROPS_BY_TYPE[type].backgroundColor} | ||
borderRadius={BORDERS.size_three} | ||
data-testid={`InlineNotification_${type}`} | ||
flexDirection={DIRECTION_ROW} | ||
gridGap="0.75rem" | ||
justifyContent={JUSTIFY_SPACE_BETWEEN} | ||
padding={`0.75rem ${SPACING.spacing4}`} | ||
width={hug ? 'max-content' : '100%'} | ||
> | ||
<Icon {...iconProps} aria-label={`icon_${type}`} /> | ||
<Flex flex="1" alignItems={ALIGN_CENTER}> | ||
<StyledText | ||
fontSize={TYPOGRAPHY.fontSize22} | ||
fontWeight={TYPOGRAPHY.fontWeightRegular} | ||
lineHeight={TYPOGRAPHY.lineHeight28} | ||
> | ||
<span | ||
css={` | ||
font-weight: ${TYPOGRAPHY.fontWeightSemiBold}; | ||
`} | ||
> | ||
{fullHeading} | ||
</span> | ||
{message && fullmessage} | ||
</StyledText> | ||
</Flex> | ||
{onCloseClick && ( | ||
<Btn | ||
data-testid="InlineNotification_close-button" | ||
onClick={onCloseClick} | ||
> | ||
<Icon aria-label="close_icon" name="close" size="3rem" /> | ||
</Btn> | ||
)} | ||
</Flex> | ||
) | ||
} |
29 changes: 29 additions & 0 deletions
29
app/src/atoms/buttons/OnDeviceDisplay/FloatingActionButton.stories.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,29 @@ | ||
import * as React from 'react' | ||
import { FloatingActionButton } from '.' | ||
import type { Story, Meta } from '@storybook/react' | ||
import { ICON_DATA_BY_NAME } from '@opentrons/components/src/icons/icon-data' | ||
|
||
export default { | ||
title: 'ODD/Atoms/Buttons/FloatingActionButton', | ||
argTypes: { | ||
iconName: { | ||
control: { | ||
type: 'select', | ||
options: Object.keys(ICON_DATA_BY_NAME), | ||
}, | ||
defaultValue: undefined, | ||
}, | ||
onClick: { action: 'clicked' }, | ||
}, | ||
} as Meta | ||
|
||
const FloatingActionButtonTemplate: Story< | ||
React.ComponentProps<typeof FloatingActionButton> | ||
> = args => <FloatingActionButton {...args} /> | ||
export const FloatingActionButtonComponent = FloatingActionButtonTemplate.bind( | ||
{} | ||
) | ||
FloatingActionButtonComponent.args = { | ||
buttonText: 'Button text', | ||
disabled: false, | ||
} |
91 changes: 91 additions & 0 deletions
91
app/src/atoms/buttons/OnDeviceDisplay/FloatingActionButton.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,91 @@ | ||
import * as React from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
import { css } from 'styled-components' | ||
|
||
import { | ||
Btn, | ||
Flex, | ||
Icon, | ||
ALIGN_CENTER, | ||
BORDERS, | ||
COLORS, | ||
DIRECTION_ROW, | ||
POSITION_FIXED, | ||
SPACING, | ||
TYPOGRAPHY, | ||
} from '@opentrons/components' | ||
import { StyledText } from '../../text' | ||
|
||
import type { IconName, StyleProps } from '@opentrons/components' | ||
|
||
interface FloatingActionButtonProps extends StyleProps { | ||
buttonText?: React.ReactNode | ||
disabled?: boolean | ||
iconName?: IconName | ||
onClick: React.MouseEventHandler | ||
} | ||
|
||
export function FloatingActionButton( | ||
props: FloatingActionButtonProps | ||
): JSX.Element { | ||
const { t } = useTranslation('protocol_setup') | ||
const { | ||
buttonText = t('map_view'), | ||
disabled = false, | ||
iconName = 'deck-map', | ||
...buttonProps | ||
} = props | ||
|
||
const contentColor = disabled ? COLORS.darkBlack_sixty : COLORS.white | ||
const FLOATING_ACTION_BUTTON_STYLE = css` | ||
background-color: ${COLORS.highlightPurple_one}; | ||
border-radius: ${BORDERS.size_five}; | ||
box-shadow: ${BORDERS.shadowBig}; | ||
color: ${contentColor}; | ||
cursor: default; | ||
&:active { | ||
background-color: ${COLORS.highlightPurple_one_pressed}; | ||
} | ||
&:focus-visible { | ||
border-color: ${COLORS.fundamentalsFocus}; | ||
border-width: ${SPACING.spacing2}; | ||
box-shadow: ${BORDERS.shadowBig}; | ||
} | ||
&:disabled { | ||
background-color: ${COLORS.darkBlack_twenty}; | ||
color: ${contentColor}; | ||
} | ||
` | ||
|
||
return ( | ||
<Btn | ||
bottom={SPACING.spacing5} | ||
css={FLOATING_ACTION_BUTTON_STYLE} | ||
disabled={disabled} | ||
fontSize={TYPOGRAPHY.fontSize28} | ||
fontWeight={TYPOGRAPHY.fontWeightSemiBold} | ||
lineHeight={TYPOGRAPHY.lineHeight36} | ||
padding={`0.75rem ${SPACING.spacing5}`} | ||
position={POSITION_FIXED} | ||
right={SPACING.spacing5} | ||
{...buttonProps} | ||
> | ||
<Flex | ||
alignItems={ALIGN_CENTER} | ||
flexDirection={DIRECTION_ROW} | ||
gridGap={SPACING.spacing3} | ||
> | ||
<Icon | ||
color={contentColor} | ||
height="3rem" | ||
name={iconName} | ||
width="3.75rem" | ||
/> | ||
<StyledText>{buttonText}</StyledText> | ||
</Flex> | ||
</Btn> | ||
) | ||
} |
Oops, something went wrong.