diff --git a/src/components/forms/ComboBox/ComboBox.stories.tsx b/src/components/forms/ComboBox/ComboBox.stories.tsx index 1cfd8f7598..8375d07843 100644 --- a/src/components/forms/ComboBox/ComboBox.stories.tsx +++ b/src/components/forms/ComboBox/ComboBox.stories.tsx @@ -46,6 +46,54 @@ export const DefaultComboBoxWithPropOptions = (): JSX.Element => { ) } +export const WithCustomOptions = (): JSX.Element => { + const veggieList = Object.entries(veggies).map(([key, value]) => ({ + value: key, + label: value, + render: () => { + return ( +
+
+ {value} +
+
+ Category: Veggies +
+
+ ) + } + })) + + const fruitList = Object.entries(fruits).map(([key, value]) => ({ + value: key, + label: value, + render: () => { + return ( +
+
+ {value} +
+
+ Category: Fruit +
+
+ ) + } + })) + + return ( +
+ + + + ) +} + export const WithDefaultValue = (): JSX.Element => { const fruitList = Object.entries(fruits).map(([value, key]) => ({ value: value, diff --git a/src/components/forms/ComboBox/ComboBox.test.tsx b/src/components/forms/ComboBox/ComboBox.test.tsx index 09d537f63b..86321c0956 100644 --- a/src/components/forms/ComboBox/ComboBox.test.tsx +++ b/src/components/forms/ComboBox/ComboBox.test.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { screen, render, waitFor } from '@testing-library/react' +import { screen, render, waitFor, within } from '@testing-library/react' import { userEvent } from '@testing-library/user-event' import { ComboBox, ComboBoxOption, ComboBoxRef } from './ComboBox' @@ -26,6 +26,25 @@ const veggieOptions: ComboBoxOption[] = Object.entries(veggies).map( }) ) +const veggieCustomOptions: ComboBoxOption[] = Object.entries(veggies).map( + ([value, key]) => ({ + value: value, + label: key, + render: () => { + return ( +
+
+ {value} +
+
+ Category: Veggies +
+
+ ) + } + }) +) + describe('ComboBox component', () => { it('renders the expected markup without errors', () => { render( @@ -282,6 +301,28 @@ describe('ComboBox component', () => { expect(getByTestId('combo-box-option-list')).not.toBeVisible() }) + it('renders custom JSX options', async () => { + const { getByTestId } = render( + + ) + + await userEvent.click(getByTestId('combo-box-toggle')) + expect(screen.getAllByRole('option')).toHaveLength(veggieCustomOptions.length) + + veggieCustomOptions.forEach(item => { + const listEl = screen.getByTestId('combo-box-option-' + item.value) + expect(listEl).toBeInTheDocument() + expect(listEl).toHaveAttribute('value', item.value) + const categoryEl = within(listEl).getByText('Category: Veggies') + expect(categoryEl).toBeInTheDocument() + }) + }) + describe('with custom props', () => { it('renders select with custom props if passed in', () => { const { getByTestId } = render( diff --git a/src/components/forms/ComboBox/ComboBox.tsx b/src/components/forms/ComboBox/ComboBox.tsx index 198a9de9c2..a06475c4f7 100644 --- a/src/components/forms/ComboBox/ComboBox.tsx +++ b/src/components/forms/ComboBox/ComboBox.tsx @@ -23,6 +23,7 @@ const DEFAULT_FILTER = '.*{{query}}.*' export interface ComboBoxOption { value: string label: string + render?: () => JSX.Element } enum Direction { @@ -485,7 +486,7 @@ const ComboBoxForwardRef: React.ForwardRefRenderFunction< onClick={(): void => { dispatch({ type: ActionTypes.SELECT_OPTION, option: option }) }}> - {option.label} + {option.render ? option.render(): option.label} ) })}