Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

Commit

Permalink
Add error state to a DropList's SelectTag toggler
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubjanczyk committed May 10, 2021
1 parent de28823 commit 108eff1
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
23 changes: 23 additions & 0 deletions src/components/DropList/DropList.stories.mdx
Expand Up @@ -711,6 +711,29 @@ The `toggler` prop accepts any React component, so you can provide your own cust
/>
</div>
</Story>
<Story name="Toggler: SelectTag with error">
<div
style={{
width: '400px',
margin: '50px 100px 0 150px',
border: '1px dashed silver',
borderRadius: '5px',
padding: '20px',
}}
>
<DropList
items={regularItems}
toggler={
<SelectTag
onClick={() => {
console.log('Clicked from story')
}}
error={'Some error'}
/>
}
/>
</div>
</Story>
<Story name="Toggler: SplittedButton">
<div
style={{
Expand Down
27 changes: 26 additions & 1 deletion src/components/DropList/DropList.test.js
@@ -1,5 +1,5 @@
import React from 'react'
import { render, waitFor } from '@testing-library/react'
import { getByLabelText, render, waitFor } from '@testing-library/react'
import user from '@testing-library/user-event'
import { css } from 'styled-components'
import DropList from './DropList'
Expand Down Expand Up @@ -577,6 +577,31 @@ describe('Togglers', () => {
})
})

describe('SelectTag error state', () => {
test('Should show error when error provided to toggler', async () => {
const error = 'Some error'
const { getByLabelText, getByTitle } = render(
<DropList items={beatles} toggler={<SelectTag error={error} />} />
)

await waitFor(() => {
expect(getByTitle('alert')).toBeInTheDocument()
})
expect(getByLabelText('toggle menu')).toHaveClass('is-error')
})

test('Should not show error when none', async () => {
const { getByLabelText, queryByTitle } = render(
<DropList items={beatles} toggler={<SelectTag />} />
)

await waitFor(() => {
expect(getByLabelText('toggle menu')).not.toHaveClass('is-error')
})
expect(queryByTitle('alert')).not.toBeInTheDocument()
})
})

test('Should run action click callback on a SplittedButton', async () => {
const onActionClick = jest.fn()
const { getByText } = render(
Expand Down
41 changes: 39 additions & 2 deletions src/components/DropList/DropList.togglers.jsx
Expand Up @@ -6,6 +6,8 @@ import { noop } from '../../utilities/other'
import ControlGroup from '../ControlGroup'
import HSDSButton from '../Button'
import Icon from '../Icon'
import { STATES } from '../../constants'
import Tooltip from '../Tooltip'

export const SimpleButton = forwardRef(
(
Expand Down Expand Up @@ -196,14 +198,33 @@ const SplitButtonTogglerUI = styled(HSDSButton)`
}
`

const ErrorTooltipIcon = ({ error }) => {
return (
<Tooltip
animationDelay={0}
animationDuration={0}
closeOnContentClick={true}
display="block"
placement="top-end"
title={error}
>
<Icon name={'alert'} size={24} state={STATES.error} tabIndex={-1} />
</Tooltip>
)
}

export const SelectTag = forwardRef(
({ isActive = false, text = '', onClick = noop, ...rest }, ref) => {
({ isActive = false, text = '', onClick = noop, error, ...rest }, ref) => {
const className = classNames(
'DropListToggler SelectTagToggler',
error && 'is-error'
)
return (
<SelectUI
aria-label="toggle menu"
aria-haspopup="true"
aria-expanded={isActive}
className="DropListToggler SelectTagToggler"
className={className}
data-cy="DropList.SelectTagToggler"
data-testid="DropList.SelectTagToggler"
onClick={onClick}
Expand All @@ -213,6 +234,12 @@ export const SelectTag = forwardRef(
>
<span>{text}</span>
<SelectArrowsUI />
{error && (
// avoid list open/close when clicked on error icon
<SelectErrorTooltipIconUI onClick={e => e.stopPropagation()}>
<ErrorTooltipIcon error={error} />
</SelectErrorTooltipIconUI>
)}
</SelectUI>
)
}
Expand All @@ -235,13 +262,19 @@ const SelectUI = styled('button')`
font-size: 13px;
color: ${getColor('charcoal.600')};
&.is-error {
box-shadow: inset 0 0 0 2px ${getColor('red.500')};
padding-right: 10px;
}
&:focus {
outline: 0;
box-shadow: inset 0 0 0 2px ${getColor('blue.500')};
}
`

const SelectArrowsUI = styled('div')`
margin-left: auto;
width: 7px;
height: 14px;
position: relative;
Expand All @@ -266,6 +299,10 @@ const SelectArrowsUI = styled('div')`
}
`

const SelectErrorTooltipIconUI = styled('div')`
margin-left: 8px;
`

const KebabUI = styled('button')`
width: 24px;
height: 24px;
Expand Down

0 comments on commit 108eff1

Please sign in to comment.