Skip to content
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
82 changes: 70 additions & 12 deletions packages/module/src/BulkSelect/BulkSelect.test.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import BulkSelect from './BulkSelect';
import BulkSelect, { BulkSelectSource, BulkSelectValue } from './BulkSelect';

describe('BulkSelect component', () => {
test('should render', () => {
expect(render(
<BulkSelect
canSelectAll
pageCount={5}
totalCount={10}
selectedCount={2}
pageSelected={false}
pagePartiallySelected={true}
onSelect={() => null}
/>)).toMatchSnapshot();
expect(
render(
<BulkSelect
canSelectAll
pageCount={5}
totalCount={10}
selectedCount={2}
pageSelected={false}
pagePartiallySelected={true}
onSelect={() => null}
/>
)
).toMatchSnapshot();
});

test('should render with dropdownListProps', async () => {
Expand Down Expand Up @@ -121,6 +124,7 @@ describe('BulkSelect component', () => {

test('should enable Select none when at least one row is selected', async () => {
const user = userEvent.setup();

render(
<BulkSelect
canSelectAll
Expand All @@ -136,4 +140,58 @@ describe('BulkSelect component', () => {
await user.click(screen.getByLabelText('Bulk select toggle'));
expect(screen.getByRole('menuitem', { name: 'Select none (0)' })).not.toBeDisabled();
});
});

test(`should call onSelect with source ${BulkSelectSource.dropdown} when choosing menu items`, async () => {
const user = userEvent.setup();
const onSelect = jest.fn();

render(
<BulkSelect
canSelectAll
pageCount={5}
totalCount={10}
selectedCount={1}
pageSelected={false}
pagePartiallySelected={true}
onSelect={onSelect}
/>
);

const openMenu = async () => {
await user.click(screen.getByLabelText('Bulk select toggle'));
};

await openMenu();
await user.click(screen.getByRole('menuitem', { name: 'Select none (0)' }));
expect(onSelect).toHaveBeenLastCalledWith(BulkSelectValue.none, BulkSelectSource.dropdown);

onSelect.mockClear();
await openMenu();
await user.click(screen.getByRole('menuitem', { name: 'Select page (5)' }));
expect(onSelect).toHaveBeenLastCalledWith(BulkSelectValue.page, BulkSelectSource.dropdown);

onSelect.mockClear();
await openMenu();
await user.click(screen.getByRole('menuitem', { name: 'Select all (10)' }));
expect(onSelect).toHaveBeenLastCalledWith(BulkSelectValue.all, BulkSelectSource.dropdown);
});

test(`should call onSelect with source ${BulkSelectSource.checkbox} when using split checkbox`, async () => {
const user = userEvent.setup();
const onSelect = jest.fn();
render(
<BulkSelect
canSelectAll
pageCount={5}
totalCount={10}
selectedCount={0}
pageSelected={false}
pagePartiallySelected={false}
onSelect={onSelect}
/>
);

await user.click(screen.getByRole('checkbox', { name: 'Select page' }));
expect(onSelect).toHaveBeenCalledWith(BulkSelectValue.page, BulkSelectSource.checkbox);
});
});
17 changes: 12 additions & 5 deletions packages/module/src/BulkSelect/BulkSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ export const BulkSelectValue = {

export type BulkSelectValue = (typeof BulkSelectValue)[keyof typeof BulkSelectValue];

export const BulkSelectSource = {
dropdown: 'dropdown',
checkbox: 'checkbox'
} as const;

export type BulkSelectSource = (typeof BulkSelectSource)[keyof typeof BulkSelectSource];

const defaultSelectPageLabel = (pageCount?: number) => `Select page${pageCount ? ` (${pageCount})` : ''}`;
const defaultSelectAllLabel = (totalCount?: number) => `Select all${totalCount ? ` (${totalCount})` : ''}`;
const defaultSelectedLabel = (selectedCount: number) => `${selectedCount} selected`;
Expand All @@ -45,7 +52,7 @@ export interface BulkSelectProps extends Omit<DropdownProps, 'toggle' | 'onSelec
/** Indicates if ONLY some current page items are selected */
pagePartiallySelected?: boolean;
/** Callback called on item select */
onSelect: (value: BulkSelectValue) => void;
onSelect: (value: BulkSelectValue, source?: BulkSelectSource) => void;
/** Custom OUIA ID */
ouiaId?: string;
/** Additional props for MenuToggleCheckbox */
Expand Down Expand Up @@ -119,12 +126,12 @@ export const BulkSelect: FC<BulkSelectProps> = ({
const onToggleClick = () => setOpen(!isOpen);

return (
(<Dropdown
<Dropdown
shouldFocusToggleOnSelect
ouiaId={`${ouiaId}-dropdown`}
onSelect={(_e, value) => {
setOpen(!isOpen);
onSelect?.(value as BulkSelectValue);
onSelect?.(value as BulkSelectValue, BulkSelectSource.dropdown);
}}
isOpen={isOpen}
onOpenChange={(isOpen: boolean) => setOpen(isOpen)}
Expand All @@ -147,7 +154,7 @@ export const BulkSelect: FC<BulkSelectProps> = ({
? null
: pageSelected || (selectedCount === totalCount && totalCount > 0)
}
onChange={(checked) => onSelect?.(!checked || checked === null ? noneOption : allOption)}
onChange={(checked) => onSelect?.(!checked || checked === null ? noneOption : allOption, BulkSelectSource.checkbox)}
{...menuToggleCheckboxProps}
>
{selectedCount > 0 ? (
Expand All @@ -163,7 +170,7 @@ export const BulkSelect: FC<BulkSelectProps> = ({
{...props}
>
<DropdownList {...dropdownListProps}>{splitButtonDropdownItems}</DropdownList>
</Dropdown>)
</Dropdown>
);
};

Expand Down
Loading