Skip to content

Commit 7dbe462

Browse files
RI-7189: Add SelectionBox component (#4702)
Co-authored-by: pd-redis <[email protected]>
1 parent 0664a81 commit 7dbe462

File tree

4 files changed

+141
-0
lines changed

4 files changed

+141
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import React from 'react'
2+
import { BoxSelectionGroup } from '@redis-ui/components'
3+
4+
import { cleanup, render, screen, fireEvent } from 'uiSrc/utils/test-utils'
5+
6+
import SelectionBox from './SelectionBox'
7+
8+
const mockBox = {
9+
value: 'rqe',
10+
label: 'Test Label',
11+
text: 'Test Description',
12+
}
13+
14+
const renderWithBoxSelectionGroup = (ui: React.ReactElement) =>
15+
render(<BoxSelectionGroup.Compose>{ui}</BoxSelectionGroup.Compose>)
16+
17+
describe('SelectionBox', () => {
18+
beforeEach(() => {
19+
cleanup()
20+
})
21+
22+
it('should render label and text', () => {
23+
renderWithBoxSelectionGroup(<SelectionBox box={mockBox} />)
24+
25+
expect(screen.getByText('Test Label')).toBeInTheDocument()
26+
expect(screen.getByText('Test Description')).toBeInTheDocument()
27+
})
28+
29+
it('should render label without text when text is not provided', () => {
30+
renderWithBoxSelectionGroup(
31+
<SelectionBox box={{ ...mockBox, text: undefined }} />,
32+
)
33+
34+
expect(screen.getByText(mockBox.label)).toBeInTheDocument()
35+
expect(screen.queryByText(mockBox.text)).not.toBeInTheDocument()
36+
})
37+
38+
it('should show disabled bar when disabled is true', () => {
39+
renderWithBoxSelectionGroup(
40+
<SelectionBox box={{ ...mockBox, disabled: true }} />,
41+
)
42+
43+
expect(screen.getByText(/coming soon/i)).toBeInTheDocument()
44+
})
45+
46+
it('should not show disabled bar when disabled is false', () => {
47+
renderWithBoxSelectionGroup(
48+
<SelectionBox box={{ ...mockBox, disabled: false }} />,
49+
)
50+
51+
expect(screen.queryByText(/coming soon/i)).not.toBeInTheDocument()
52+
})
53+
54+
it('should call onClick handler when clicked', () => {
55+
const onClick = jest.fn()
56+
57+
renderWithBoxSelectionGroup(
58+
<SelectionBox box={mockBox} onClick={onClick} />,
59+
)
60+
61+
fireEvent.click(screen.getByText(mockBox.label))
62+
63+
expect(onClick).toHaveBeenCalled()
64+
})
65+
})
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from 'react'
2+
import styled from 'styled-components'
3+
import { Text, Title } from 'uiSrc/components/base/text'
4+
5+
export const StyledBoxContent = styled.div`
6+
padding: ${({ theme }) => theme.core.space.space200};
7+
text-align: left;
8+
`
9+
10+
export const StyledTitle = styled(Title)`
11+
margin-top: ${({ theme }) => theme.core.space.space050};
12+
`
13+
14+
export const StyledText = styled(Text)`
15+
margin-top: ${({ theme }) => theme.core.space.space050};
16+
white-space: normal;
17+
overflow-wrap: break-word;
18+
`
19+
20+
export const StyledDisabledBar = styled.div`
21+
padding: ${({ theme }) => theme.core.space.space025} 0;
22+
background: ${({ theme }) => theme.color.dusk100};
23+
color: ${({ theme }) => theme.color.dusk400};
24+
/* Theme adjustments TODO: add radii scale */
25+
border-radius: ${({ theme }) => theme.core.space.space025};
26+
/* Theme adjustments TODO: border width scale */
27+
border-bottom: 1px solid ${({ theme }) => theme.color.gray500};
28+
border-bottom-left-radius: 0;
29+
border-bottom-right-radius: 0;
30+
`
31+
32+
export const DisabledBar = () => (
33+
<StyledDisabledBar>
34+
<Text size="xs">Coming soon</Text>
35+
</StyledDisabledBar>
36+
)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, { HTMLAttributes } from 'react'
2+
import { BoxSelectionGroup, BoxSelectionGroupBox } from '@redis-ui/components'
3+
import {
4+
DisabledBar,
5+
StyledBoxContent,
6+
StyledText,
7+
StyledTitle,
8+
} from './SelectionBox.styles'
9+
10+
export interface BoxSelectionOption<T extends string = string>
11+
extends BoxSelectionGroupBox<T> {
12+
text?: string
13+
}
14+
15+
type SelectionBoxProps<T extends string = string> = {
16+
box: BoxSelectionOption<T>
17+
} & HTMLAttributes<HTMLButtonElement>
18+
19+
const SelectionBox = <T extends string = string>({
20+
box,
21+
...rest
22+
}: SelectionBoxProps<T>) => {
23+
const { label, text, disabled } = box
24+
25+
return (
26+
<BoxSelectionGroup.Item.Compose box={box} {...rest}>
27+
{disabled && <DisabledBar />}
28+
29+
<StyledBoxContent>
30+
<BoxSelectionGroup.Item.Icon color="neutral700" customSize="32px" />
31+
32+
<StyledTitle size="S">{label}</StyledTitle>
33+
{text && <StyledText size="M">{text}</StyledText>}
34+
</StyledBoxContent>
35+
</BoxSelectionGroup.Item.Compose>
36+
)
37+
}
38+
39+
export default SelectionBox
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as SelectionBox } from './SelectionBox'

0 commit comments

Comments
 (0)