Skip to content
Merged
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
31 changes: 31 additions & 0 deletions packages/module/src/BulkSelect/BulkSelect.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,35 @@ describe('BulkSelect component', () => {
expect(toggleWrapper).toBeInTheDocument();
expect(toggleWrapper).toHaveClass('custom-menu-toggle');
});

test('should render with custom i18n labels', async () => {
const user = userEvent.setup();
render(
<BulkSelect
canSelectAll
pageCount={5}
totalCount={10}
selectedCount={2}
pageSelected={false}
pagePartiallySelected={true}
onSelect={() => null}
selectNoneLabel="Aucune sélection (0)"
selectPageLabel={(pageCount) => `Sélectionner la page${pageCount ? ` (${pageCount})` : ''}`}
selectAllLabel={(totalCount) => `Tout sélectionner${totalCount ? ` (${totalCount})` : ''}`}
selectedLabel={(selectedCount) => `${selectedCount} sélectionné${selectedCount > 1 ? 's' : ''}`}
/>
);

// Check custom selected label
expect(screen.getByText('2 sélectionnés')).toBeInTheDocument();

// Open the dropdown to check option labels
const toggleButton = screen.getByLabelText('Bulk select toggle');
await user.click(toggleButton);

// Check custom dropdown labels
expect(screen.getByText('Aucune sélection (0)')).toBeInTheDocument();
expect(screen.getByText('Sélectionner la page (5)')).toBeInTheDocument();
expect(screen.getByText('Tout sélectionner (10)')).toBeInTheDocument();
});
});
28 changes: 23 additions & 5 deletions packages/module/src/BulkSelect/BulkSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export const BulkSelectValue = {

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

const defaultSelectPageLabel = (pageCount?: number) => `Select page${pageCount ? ` (${pageCount})` : ''}`;
const defaultSelectAllLabel = (totalCount?: number) => `Select all${totalCount ? ` (${totalCount})` : ''}`;
const defaultSelectedLabel = (selectedCount: number) => `${selectedCount} selected`;

/** extends DropdownProps */
export interface BulkSelectProps extends Omit<DropdownProps, 'toggle' | 'onSelect'> {
/** BulkSelect className */
Expand Down Expand Up @@ -50,6 +54,14 @@ export interface BulkSelectProps extends Omit<DropdownProps, 'toggle' | 'onSelec
dropdownListProps?: Omit<DropdownListProps, 'children'>;
/** Additional props for MenuToggleProps */
menuToggleProps?: Omit<MenuToggleProps, 'children' | 'splitButtonItems' | 'ref' | 'isExpanded' | 'onClick'>;
/** Custom label for "Select none" option. Defaults to "Select none (0)" */
selectNoneLabel?: string;
/** Custom label for "Select page" option. Receives pageCount as parameter. Defaults to "Select page (N)" */
selectPageLabel?: (pageCount?: number) => string;
/** Custom label for "Select all" option. Receives totalCount as parameter. Defaults to "Select all (N)" */
selectAllLabel?: (totalCount?: number) => string;
/** Custom label formatter for selected count. Receives selectedCount as parameter. Defaults to "N selected" */
selectedLabel?: (selectedCount: number) => string;
}

export const BulkSelect: FC<BulkSelectProps> = ({
Expand All @@ -65,6 +77,10 @@ export const BulkSelect: FC<BulkSelectProps> = ({
menuToggleCheckboxProps,
dropdownListProps,
menuToggleProps,
selectNoneLabel = 'Select none (0)',
selectPageLabel = defaultSelectPageLabel,
selectAllLabel = defaultSelectAllLabel,
selectedLabel = defaultSelectedLabel,
...props
}: BulkSelectProps) => {
const [ isOpen, setOpen ] = useState(false);
Expand All @@ -73,23 +89,25 @@ export const BulkSelect: FC<BulkSelectProps> = ({
() => (
<>
<DropdownItem ouiaId={`${ouiaId}-select-none`} value={BulkSelectValue.none} key={BulkSelectValue.none}>
Select none (0)
{selectNoneLabel}
</DropdownItem>
{isDataPaginated && (
<DropdownItem ouiaId={`${ouiaId}-select-page`} value={BulkSelectValue.page} key={BulkSelectValue.page}>
{`Select page${pageCount ? ` (${pageCount})` : ''}`}
{selectPageLabel(pageCount)}
</DropdownItem>
)}
{canSelectAll && (
<DropdownItem ouiaId={`${ouiaId}-select-all`} value={BulkSelectValue.all} key={BulkSelectValue.all}>
{`Select all${totalCount ? ` (${totalCount})` : ''}`}
{selectAllLabel(totalCount)}
</DropdownItem>
)}
</>
),
[ isDataPaginated, canSelectAll, ouiaId, pageCount, totalCount ]
[ isDataPaginated, canSelectAll, ouiaId, selectNoneLabel, selectPageLabel, selectAllLabel, pageCount, totalCount ]
);

const selectedLabelText = selectedLabel(selectedCount);

const allOption = isDataPaginated ? BulkSelectValue.page : BulkSelectValue.all;
const noneOption = isDataPaginated ? BulkSelectValue.nonePage : BulkSelectValue.none;

Expand Down Expand Up @@ -129,7 +147,7 @@ export const BulkSelect: FC<BulkSelectProps> = ({
>
{selectedCount > 0 ? (
<span data-ouia-component-id={`${ouiaId}-text`}>
{`${selectedCount} selected`}
{selectedLabelText}
</span>
) : null}
</MenuToggleCheckbox>
Expand Down
Loading