Skip to content

feat(BulkSelect): add internationalization (i18n) support#896

Open
rhamilto wants to merge 1 commit intopatternfly:mainfrom
rhamilto:feat-bulkselect-i18n-support
Open

feat(BulkSelect): add internationalization (i18n) support#896
rhamilto wants to merge 1 commit intopatternfly:mainfrom
rhamilto:feat-bulkselect-i18n-support

Conversation

@rhamilto
Copy link
Copy Markdown
Member

@rhamilto rhamilto commented Mar 27, 2026

Summary

Details

Applications using BulkSelect that need to support non-English languages or custom terminology can now provide custom labels for all user-facing strings.

New Props

All props are optional with English defaults:

  • selectNoneLabel: Custom label for "Select none" option (default: "Select none (0)")
  • selectPageLabel: Function receiving pageCount to format "Select page" label (default: `Select page${pageCount ? ` (${pageCount})` : ''}`)
  • selectAllLabel: Function receiving totalCount to format "Select all" label (default: `Select all${totalCount ? ` (${totalCount})` : ''}`)
  • selectedLabel: Function receiving selectedCount to format the displayed count (default: `${selectedCount} selected`)

Example Usage

import { useTranslation } from 'react-i18next';

const MyComponent = () => {
  const { t } = useTranslation();
  
  return (
    <BulkSelect
      selectedCount={5}
      totalCount={100}
      pageCount={20}
      onSelect={handleSelect}
      selectNoneLabel={t('bulkSelect.selectNone')}
      selectPageLabel={(pageCount) => t('bulkSelect.selectPage', { pageCount })}
      selectAllLabel={(totalCount) => t('bulkSelect.selectAll', { totalCount })}
      selectedLabel={(selectedCount) => t('bulkSelect.selected', { selectedCount })}
    />
  );
};

Note: Parameter names (pageCount, totalCount, selectedCount) are deliberately chosen to avoid conflicts with i18n reserved keywords like count used for pluralization.

Test plan

  • All existing tests pass (backward compatibility maintained)
  • Added new test with French labels to verify i18n functionality
  • Build completes successfully
  • No breaking changes - existing usage works exactly as before
  • Parameter names avoid i18n reserved keyword conflicts

🤖 Generated with Claude Code

@patternfly-build
Copy link
Copy Markdown

patternfly-build commented Mar 27, 2026

menuToggleCheckboxProps,
dropdownListProps,
menuToggleProps,
selectNoneLabel = 'Select none (0)',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One issue: useMemo invalidation on every render.

The default values for selectPageLabel, selectAllLabel, and selectedLabel are inline arrow functions in the destructuring:

  selectPageLabel = (pageCount?: number) => `Select page${pageCount ? ` (${pageCount})` : ''}`,                                
  selectAllLabel = (totalCount?: number) => `Select all${totalCount ? ` (${totalCount})` : ''}`,            

These create new function references on every render, even when the consumer doesn't pass custom labels. Since they're added
to the useMemo dependency array, the memoization of dropdown items is effectively broken — it will recompute every render
instead of only when pageCount/totalCount change.

Fix: Hoist the defaults to module-level constants:

  const defaultSelectPageLabel = (pageCount?: number) => `Select page${pageCount ? ` (${pageCount})` : ''}`;                   
  const defaultSelectAllLabel = (totalCount?: number) => `Select all${totalCount ? ` (${totalCount})` : ''}`;                  
  const defaultSelectedLabel = (count: number) => `${count} selected`;                                                         
                                                                                                                               
  export const BulkSelect: FC<BulkSelectProps> = ({                                                                            
    // ...other props                                                                                                          
    selectNoneLabel = 'Select none (0)',                                                                                       
    selectPageLabel = defaultSelectPageLabel,                                                                                  
    selectAllLabel = defaultSelectAllLabel,                                                                                    
    selectedLabel = defaultSelectedLabel,                                                                                      
    ...props                                                                                                                   
  }: BulkSelectProps) => {                                                                                                     
    // rest of component unchanged    

@rhamilto rhamilto force-pushed the feat-bulkselect-i18n-support branch 4 times, most recently from 28a2b2c to 4511ba3 Compare March 27, 2026 15:18
Adds optional props for customizing all user-facing strings in BulkSelect
to support internationalization and custom terminology. All changes are
backward compatible with sensible English defaults.

New props:
- selectNoneLabel: Custom label for "Select none" option
- selectPageLabel: Function receiving pageCount to format "Select page" label
- selectAllLabel: Function receiving totalCount to format "Select all" label
- selectedLabel: Function receiving selectedCount to format the displayed count

Implementation details:
- Default label functions are hoisted to module level for stable references
- Label functions are called inside useMemo to prevent unnecessary re-renders
- Optimized for performance with expensive operations like pseudolocalization
- Parameter names avoid i18n reserved keywords (e.g., 'count' for pluralization)

Fixes patternfly#895

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@rhamilto rhamilto force-pushed the feat-bulkselect-i18n-support branch from 4511ba3 to 14fd69b Compare March 27, 2026 15:36
rhamilto added a commit to rhamilto/console that referenced this pull request Mar 27, 2026
Implements row selection with checkboxes for the Nodes list page, allowing
users to select multiple nodes and perform bulk actions to mark them as
schedulable or unschedulable.

Changes:
- Add selection column with checkboxes for each node row
- Integrate PatternFly BulkSelect component in ConsoleDataView with i18n support
- Add bulk actions (schedulable/unschedulable) with context-aware visibility
- Implement sticky selection and name columns for better horizontal scroll UX
- Create reusable selection helpers: useDataViewSelection, dataViewSelectionHelpers
- Add configurable actionsBreakpoint prop for responsive toolbar layout
- Fix DropEvent type conflict in droppable-edit-yaml
- Remove isActionCell prop to fix React DOM warning
- Update i18n keys to use itemCount/nodeCount instead of reserved 'count' keyword

Features:
- Filter-aware selection: bulk select respects current filters
- Context-aware actions: only show relevant actions based on selection state
- Robust error handling with Promise.allSettled() and granular feedback
- Full internationalization support for all user-facing strings

TODO:
- Update @patternfly/react-component-groups to published version after
  patternfly/react-component-groups#896 is merged
- Revert temporary local package testing changes in package.json and
  scripts/check-patternfly-modules.ts

Temporary changes for testing:
- Using local react-component-groups package for i18n fixes
- Disabled version check in check-patternfly-modules.ts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
rhamilto added a commit to rhamilto/console that referenced this pull request Mar 27, 2026
Implements row selection with checkboxes for the Nodes list page, allowing
users to select multiple nodes and perform bulk actions to mark them as
schedulable or unschedulable.

Changes:
- Add selection column with checkboxes for each node row
- Integrate PatternFly BulkSelect component in ConsoleDataView with i18n support
- Add bulk actions (schedulable/unschedulable) with context-aware visibility
- Implement sticky selection and name columns for better horizontal scroll UX
- Create reusable selection helpers: useDataViewSelection, dataViewSelectionHelpers
- Add configurable actionsBreakpoint prop for responsive toolbar layout
- Fix DropEvent type conflict in droppable-edit-yaml
- Remove isActionCell prop to fix React DOM warning
- Update i18n keys to use itemCount/nodeCount instead of reserved 'count' keyword

Features:
- Filter-aware selection: bulk select respects current filters
- Filter-aware bulk actions: actions only apply to filtered selected items
- Context-aware actions: only show relevant actions based on selection state
- Robust error handling with Promise.allSettled() and granular feedback
- Full internationalization support for all user-facing strings

Selection behavior:
- BulkSelect counts only show items in current filtered view
- Bulk actions operate only on filtered selected items
- Selection automatically updates when filters change to reflect visible items
- When "select all" is used with filters, only filtered items are selected

Implementation details:
- Added getItemId to selection config for proper ID tracking across filters
- Added onFilteredSelectionChange callback to notify parent of filtered selection
- BulkSelect now receives pageCount for accurate "Select page (N)" labels

TODO:
- Update @patternfly/react-component-groups to published version after
  patternfly/react-component-groups#896 is merged
- Revert temporary local package testing changes in package.json and
  scripts/check-patternfly-modules.ts

Temporary changes for testing:
- Using local react-component-groups package for i18n fixes
- Disabled version check in check-patternfly-modules.ts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
rhamilto added a commit to rhamilto/console that referenced this pull request Mar 27, 2026
Implements row selection with checkboxes for the Nodes list page, allowing
users to select multiple nodes and perform bulk actions to mark them as
schedulable or unschedulable.

Changes:
- Add selection column with checkboxes for each node row
- Integrate PatternFly BulkSelect component in ConsoleDataView with i18n support
- Add bulk actions (schedulable/unschedulable) with context-aware visibility
- Implement sticky selection and name columns for better horizontal scroll UX
- Create reusable selection helpers: useDataViewSelection, dataViewSelectionHelpers
- Add configurable actionsBreakpoint prop for responsive toolbar layout
- Fix DropEvent type conflict in droppable-edit-yaml
- Remove isActionCell prop to fix React DOM warning
- Update i18n keys to use itemCount/nodeCount instead of reserved 'count' keyword

Features:
- Filter-aware selection: bulk select respects current filters
- Filter-aware bulk actions: actions only apply to filtered selected items
- Context-aware actions: only show relevant actions based on selection state
- Robust error handling with Promise.allSettled() and granular feedback
- Full internationalization support for all user-facing strings

Selection behavior:
- BulkSelect counts only show items in current filtered view
- Bulk actions operate only on filtered selected items
- Selection automatically updates when filters change to reflect visible items
- When "select all" is used with filters, only filtered items are selected

Implementation details:
- Added getItemId to selection config for proper ID tracking across filters
- Added onFilteredSelectionChange callback to notify parent of filtered selection
- BulkSelect now receives pageCount for accurate "Select page (N)" labels

TODO:
- Update @patternfly/react-component-groups to published version after
  patternfly/react-component-groups#896 is merged
- Revert temporary local package testing changes in package.json and
  scripts/check-patternfly-modules.ts

Temporary changes for testing:
- Using local react-component-groups package for i18n fixes
- Disabled version check in check-patternfly-modules.ts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BulkSelect: Add internationalization (i18n) support

3 participants