diff --git a/packages/react/src/components/lozenge/lozenge.test.tsx b/packages/react/src/components/lozenge/lozenge.test.tsx index 119412876f..f4e6ffe983 100644 --- a/packages/react/src/components/lozenge/lozenge.test.tsx +++ b/packages/react/src/components/lozenge/lozenge.test.tsx @@ -15,4 +15,28 @@ describe('Lozenge', () => { expect(tree).toMatchSnapshot(); }); + + test('success matches the snapshot', () => { + const tree = renderWithTheme(success); + + expect(tree).toMatchSnapshot(); + }); + + test('warning matches the snapshot', () => { + const tree = renderWithTheme(warning); + + expect(tree).toMatchSnapshot(); + }); + + test('info matches the snapshot', () => { + const tree = renderWithTheme(info); + + expect(tree).toMatchSnapshot(); + }); + + test('alert matches the snapshot', () => { + const tree = renderWithTheme(alert); + + expect(tree).toMatchSnapshot(); + }); }); diff --git a/packages/react/src/components/lozenge/lozenge.test.tsx.snap b/packages/react/src/components/lozenge/lozenge.test.tsx.snap index c170146bdf..62290beefe 100644 --- a/packages/react/src/components/lozenge/lozenge.test.tsx.snap +++ b/packages/react/src/components/lozenge/lozenge.test.tsx.snap @@ -1,5 +1,77 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Lozenge alert matches the snapshot 1`] = ` +.c0 { + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: #FFFAFB; + border: 1px solid #CD2C23; + border-radius: var(--border-radius-half); + box-sizing: border-box; + color: #CD2C23; + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + font-size: 0.75rem; + font-weight: var(--font-semi-bold); + line-height: 0.875rem; + max-width: 312px; + overflow: hidden; + padding: 0 var(--spacing-half); + text-overflow: ellipsis; + text-transform: uppercase; + white-space: nowrap; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; +} + + + alert + +`; + +exports[`Lozenge info matches the snapshot 1`] = ` +.c0 { + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: #f9f7fb; + border: 1px solid #602FA0; + border-radius: var(--border-radius-half); + box-sizing: border-box; + color: #602FA0; + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + font-size: 0.75rem; + font-weight: var(--font-semi-bold); + line-height: 0.875rem; + max-width: 312px; + overflow: hidden; + padding: 0 var(--spacing-half); + text-overflow: ellipsis; + text-transform: uppercase; + white-space: nowrap; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; +} + + + info + +`; + exports[`Lozenge matches the snapshot 1`] = ` .c0 { -webkit-align-items: center; @@ -16,6 +88,7 @@ exports[`Lozenge matches the snapshot 1`] = ` display: -ms-inline-flexbox; display: inline-flex; font-size: 0.75rem; + font-weight: var(--font-semi-bold); line-height: 0.875rem; max-width: 312px; overflow: hidden; @@ -34,3 +107,75 @@ exports[`Lozenge matches the snapshot 1`] = ` Hello World `; + +exports[`Lozenge success matches the snapshot 1`] = ` +.c0 { + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: #F6FCF8; + border: 1px solid #008533; + border-radius: var(--border-radius-half); + box-sizing: border-box; + color: #008533; + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + font-size: 0.75rem; + font-weight: var(--font-semi-bold); + line-height: 0.875rem; + max-width: 312px; + overflow: hidden; + padding: 0 var(--spacing-half); + text-overflow: ellipsis; + text-transform: uppercase; + white-space: nowrap; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; +} + + + success + +`; + +exports[`Lozenge warning matches the snapshot 1`] = ` +.c0 { + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: #FFF9F5; + border: 1px solid #F5A200; + border-radius: var(--border-radius-half); + box-sizing: border-box; + color: #F5A200; + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + font-size: 0.75rem; + font-weight: var(--font-semi-bold); + line-height: 0.875rem; + max-width: 312px; + overflow: hidden; + padding: 0 var(--spacing-half); + text-overflow: ellipsis; + text-transform: uppercase; + white-space: nowrap; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; +} + + + warning + +`; diff --git a/packages/react/src/components/lozenge/lozenge.tsx b/packages/react/src/components/lozenge/lozenge.tsx index 8b169d22a0..8efe03f076 100644 --- a/packages/react/src/components/lozenge/lozenge.tsx +++ b/packages/react/src/components/lozenge/lozenge.tsx @@ -1,20 +1,82 @@ import { FunctionComponent } from 'react'; import styled from 'styled-components'; +import { Theme } from '../../themes'; import { useDeviceContext } from '../device-context-provider/device-context-provider'; import { Icon, IconName } from '../icon/icon'; const MAXIMUM_LENGTH = '312px'; -const StyledLozenge = styled.span<{ isMobile: boolean }>` +export type LozengeType = 'success' | 'alert' | 'warning' | 'info' | 'disabled'; + +interface StyledLozengeProps { + $isMobile: boolean; + $type?: LozengeType; + theme: Theme; +} + +function getLozengeBackgroundColor({ $type, theme }: StyledLozengeProps): string { + switch ($type) { + case 'success': + return theme.notifications['success-1.2']; + case 'disabled': + return theme.greys['light-grey']; + case 'alert': + return theme.notifications['alert-2.2']; + case 'warning': + return theme.notifications['warning-3.2']; + case 'info': + // TODO: add this color in default themes + return '#f9f7fb'; + default: + return theme.greys['light-grey']; + } +} + +function getLozengeBorderColor({ $type, theme }: StyledLozengeProps): string { + switch ($type) { + case 'success': + return theme.notifications['success-1.1']; + case 'disabled': + return theme.greys['mid-grey']; + case 'alert': + return theme.notifications['alert-2.1']; + case 'warning': + return theme.notifications['warning-3.1']; + case 'info': + return theme.notifications['info-1.1']; + default: + return theme.greys['dark-grey']; + } +} + +function getLozengeColor({ $type, theme }: StyledLozengeProps): string { + switch ($type) { + case 'success': + return theme.notifications['success-1.1']; + case 'disabled': + return theme.greys['mid-grey']; + case 'alert': + return theme.notifications['alert-2.1']; + case 'warning': + return theme.notifications['warning-3.1']; + case 'info': + return theme.notifications['info-1.1']; + default: + return theme.greys['dark-grey']; + } +} + +const StyledLozenge = styled.span` align-items: center; - background-color: ${({ theme }) => theme.greys['light-grey']}; - border: 1px solid ${({ theme }) => theme.greys['dark-grey']}; - border-radius: ${({ isMobile }) => (isMobile ? 'var(--border-radius)' : 'var(--border-radius-half)')}; + background-color: ${getLozengeBackgroundColor}; + border: 1px solid ${getLozengeBorderColor}; + border-radius: ${({ $isMobile }) => ($isMobile ? 'var(--border-radius)' : 'var(--border-radius-half)')}; box-sizing: border-box; - color: ${({ theme }) => theme.greys['dark-grey']}; + color: ${getLozengeColor}; display: inline-flex; - font-size: ${({ isMobile }) => (isMobile ? '0.875rem' : '0.75rem')}; - line-height: ${({ isMobile }) => (isMobile ? '1.375rem' : '0.875rem')}; + font-size: ${({ $isMobile }) => ($isMobile ? '0.875rem' : '0.75rem')}; + font-weight: var(--font-semi-bold); + line-height: ${({ $isMobile }) => ($isMobile ? '1.375rem' : '0.875rem')}; max-width: ${MAXIMUM_LENGTH}; overflow: hidden; padding: 0 var(--spacing-half); @@ -24,12 +86,13 @@ const StyledLozenge = styled.span<{ isMobile: boolean }>` width: fit-content; `; -const StyledIcon = styled(Icon)<{ isMobile: boolean }>` - margin-right: ${({ isMobile }) => (isMobile ? 'var(--spacing-1x)' : 'var(--spacing-half)')}; +const StyledIcon = styled(Icon)<{ $isMobile: boolean }>` + margin-right: ${({ $isMobile }) => ($isMobile ? 'var(--spacing-1x)' : 'var(--spacing-half)')}; `; interface Props { className?: string; + type?: LozengeType; icon?: IconName; } @@ -37,16 +100,21 @@ export const Lozenge: FunctionComponent = ({ children, className, icon, + type, }) => { const { isMobile } = useDeviceContext(); return ( - + {icon && ( )} {children} diff --git a/packages/storybook/stories/lozenge.stories.tsx b/packages/storybook/stories/lozenge.stories.tsx index 73a3bd2751..cb606acdb9 100644 --- a/packages/storybook/stories/lozenge.stories.tsx +++ b/packages/storybook/stories/lozenge.stories.tsx @@ -1,5 +1,7 @@ import { Lozenge } from '@equisoft/design-elements-react'; import { Story } from '@storybook/react'; +import styled from 'styled-components'; +import { decorateWith } from './utils/decorator'; import { MobileDecorator } from './utils/device-context-decorator'; export default { @@ -16,6 +18,25 @@ export const Mobile: Story = () => ( ); Mobile.decorators = [MobileDecorator]; +const TypeDecorator = styled.div` + > :not(:first-child) { + margin-left: 1rem; + } +`; + +export const Type: Story = () => ( + <> + default + success + alert + warning + info + disabled + +); + +Type.decorators = [decorateWith(TypeDecorator)]; + export const WithIcon: Story = () => ( With icon );