Skip to content

RI-7189: Add SelectionBox component #4702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: feature/RI-6855/vector-search
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from 'react'
import { BoxSelectionGroup } from '@redis-ui/components'

import { cleanup, render, screen, fireEvent } from 'uiSrc/utils/test-utils'

import SelectionBox from './SelectionBox'

const mockBox = {
value: 'rqe',
label: 'Test Label',
text: 'Test Description',
}

const renderWithBoxSelectionGroup = (ui: React.ReactElement) =>
render(<BoxSelectionGroup.Compose>{ui}</BoxSelectionGroup.Compose>)

describe('SelectionBox', () => {
beforeEach(() => {
cleanup()
})

it('should render label and text', () => {
renderWithBoxSelectionGroup(<SelectionBox box={mockBox} />)

expect(screen.getByText('Test Label')).toBeInTheDocument()
expect(screen.getByText('Test Description')).toBeInTheDocument()
})

it('should render label without text when text is not provided', () => {
renderWithBoxSelectionGroup(
<SelectionBox box={{ ...mockBox, text: undefined }} />,
)

expect(screen.getByText(mockBox.label)).toBeInTheDocument()
expect(screen.queryByText(mockBox.text)).not.toBeInTheDocument()
})

it('should show disabled bar when disabled is true', () => {
renderWithBoxSelectionGroup(
<SelectionBox box={{ ...mockBox, disabled: true }} />,
)

expect(screen.getByText(/coming soon/i)).toBeInTheDocument()
})

it('should not show disabled bar when disabled is false', () => {
renderWithBoxSelectionGroup(
<SelectionBox box={{ ...mockBox, disabled: false }} />,
)

expect(screen.queryByText(/coming soon/i)).not.toBeInTheDocument()
})

it('should call onClick handler when clicked', () => {
const onClick = jest.fn()

renderWithBoxSelectionGroup(
<SelectionBox box={mockBox} onClick={onClick} />,
)

fireEvent.click(screen.getByText(mockBox.label))

expect(onClick).toHaveBeenCalled()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react'
import styled from 'styled-components'
import { Text, Title } from 'uiSrc/components/base/text'

export const StyledBoxContent = styled.div`
padding: ${({ theme }) => theme.core.space.space200};
text-align: left;
`

export const StyledTitle = styled(Title)`
margin-top: ${({ theme }) => theme.core.space.space050};
`

export const StyledText = styled(Text)`
margin-top: ${({ theme }) => theme.core.space.space050};
white-space: normal;
overflow-wrap: break-word;
`

export const StyledDisabledBar = styled.div`
padding: ${({ theme }) => theme.core.space.space025} 0;
background: ${({ theme }) => theme.color.dusk100};
color: ${({ theme }) => theme.color.dusk400};
/* Theme adjustments TODO: add radii scale */
border-radius: ${({ theme }) => theme.core.space.space025};
/* Theme adjustments TODO: border width scale */
border-bottom: 1px solid ${({ theme }) => theme.color.gray500};
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
`

export const DisabledBar = () => (
<StyledDisabledBar>
<Text size="xs">Coming soon</Text>
</StyledDisabledBar>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { HTMLAttributes } from 'react'
import { BoxSelectionGroup, BoxSelectionGroupBox } from '@redis-ui/components'
import {
DisabledBar,
StyledBoxContent,
StyledText,
StyledTitle,
} from './SelectionBox.styles'

export interface BoxSelectionOption<T extends string = string>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't that already exported above?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I understand the question properly, but this is an extension to BoxSelectionGroupBox as we want to support text as well. So I'm exporting the type for the consumers of this component.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing something, but these look identical - BoxSelectionOption interface
image
image

extends BoxSelectionGroupBox<T> {
text?: string
}

type SelectionBoxProps<T extends string = string> = {
box: BoxSelectionOption<T>
} & HTMLAttributes<HTMLButtonElement>

const SelectionBox = <T extends string = string>({
box,
...rest
}: SelectionBoxProps<T>) => {
const { label, text, disabled } = box

return (
<BoxSelectionGroup.Item.Compose box={box} {...rest}>
{disabled && <DisabledBar />}

<StyledBoxContent>
<BoxSelectionGroup.Item.Icon color="neutral700" customSize="32px" />

<StyledTitle size="S">{label}</StyledTitle>
{text && <StyledText size="M">{text}</StyledText>}
</StyledBoxContent>
</BoxSelectionGroup.Item.Compose>
)
}

export default SelectionBox
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as SelectionBox } './SelectionBox'
Loading