Skip to content

feat(Table): add indeterminate checkbox state support for select-all header#12411

Open
rhamilto wants to merge 1 commit intopatternfly:mainfrom
rhamilto:feat/table-indeterminate-checkbox
Open

feat(Table): add indeterminate checkbox state support for select-all header#12411
rhamilto wants to merge 1 commit intopatternfly:mainfrom
rhamilto:feat/table-indeterminate-checkbox

Conversation

@rhamilto
Copy link
Copy Markdown
Member

@rhamilto rhamilto commented May 5, 2026

Summary

Adds support for indeterminate state to the Table component's select-all checkbox in the header, following PatternFly's bulk selection design guidelines.

The select-all checkbox now properly supports three states:

  • Unchecked - no items selected
  • Indeterminate (dash/minus icon) - some items selected
  • Checked - all items selected

Changes

  • Added isIndeterminate?: boolean property to ThSelectType interface
  • Added isIndeterminate?: boolean to IColumn extraParams type
  • Updated Th component to pass isIndeterminate to the selectable decorator
  • Updated selectable decorator to pass indeterminate state to SelectColumn
  • Updated SelectColumn to use PatternFly Checkbox's native indeterminate support (isChecked: null)
  • Added new TableSelectableIndeterminate example showcasing the feature

Technical implementation

The indeterminate state is implemented using the PatternFly Checkbox component's native support by setting isChecked: null when isIndeterminate is true. This leverages PatternFly's built-in indeterminate checkbox handling.

<Checkbox
  isChecked={isIndeterminate ? null : isSelected}
  // ... other props
/>

Usage example

const areSomeReposSelected = selectedRepoNames.length > 0 && selectedRepoNames.length < selectableRepos.length;

<Th
  select={{
    onSelect: (_event, isSelecting) => selectAllRepos(isSelecting),
    isSelected: areAllReposSelected,
    isIndeterminate: areSomeReposSelected  // NEW: shows dash when some selected
  }}
  aria-label="Row select"
/>

Related issues

Test plan

  • Build passes without TypeScript errors
  • Visual testing of TableSelectableIndeterminate example shows indeterminate state when some rows selected
  • Accessibility: Screen readers properly announce the checkbox state
  • Checkbox toggles correctly between all three states

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Tables now support an indeterminate select state, displaying a dash icon in the header checkbox when only some rows are selected. This provides clearer visual feedback on partial selection. Updated documentation and examples demonstrate how to implement this feature, including shift+click range selection support.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bf88a767-7c0b-4505-a606-55335fac4ab6

📥 Commits

Reviewing files that changed from the base of the PR and between 1b9740e and 6308f98.

📒 Files selected for processing (7)
  • packages/react-table/src/components/Table/SelectColumn.tsx
  • packages/react-table/src/components/Table/TableTypes.tsx
  • packages/react-table/src/components/Table/Th.tsx
  • packages/react-table/src/components/Table/base/types.tsx
  • packages/react-table/src/components/Table/examples/Table.md
  • packages/react-table/src/components/Table/examples/TableSelectableIndeterminate.tsx
  • packages/react-table/src/components/Table/utils/decorators/selectable.tsx
✅ Files skipped from review due to trivial changes (1)
  • packages/react-table/src/components/Table/examples/Table.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/react-table/src/components/Table/Th.tsx
  • packages/react-table/src/components/Table/TableTypes.tsx
  • packages/react-table/src/components/Table/base/types.tsx
  • packages/react-table/src/components/Table/utils/decorators/selectable.tsx
  • packages/react-table/src/components/Table/examples/TableSelectableIndeterminate.tsx

Walkthrough

This PR adds indeterminate checkbox state support to the PatternFly React Table component. A new optional isIndeterminate prop flows through the type hierarchy, component layers, and decorator chain to enable the select-all header checkbox to display a dash/minus icon when some (but not all) rows are selected.

Changes

Indeterminate Checkbox State Support

Layer / File(s) Summary
Type Shape
packages/react-table/src/components/Table/base/types.tsx, packages/react-table/src/components/Table/TableTypes.tsx, packages/react-table/src/components/Table/SelectColumn.tsx
ThSelectType adds optional isIndeterminate?: boolean prop. IColumn.extraParams adds matching isIndeterminate?: boolean field. SelectColumnProps declares isIndeterminate?: boolean for checkbox variant support.
Core Checkbox Rendering
packages/react-table/src/components/Table/SelectColumn.tsx
SelectColumn destructures isIndeterminate and builds checkboxProps object for checkbox variant, setting isChecked: null when isIndeterminate is truthy to signal indeterminate state to PatternFly Checkbox.
Integration & Wiring
packages/react-table/src/components/Table/utils/decorators/selectable.tsx, packages/react-table/src/components/Table/Th.tsx
selectable decorator destructures isIndeterminate from extraParams and passes it to SelectColumn only for header rows (rowId === -1). Th passes select?.isIndeterminate into the selectable helper's extraParams when select is provided.
Example & Documentation
packages/react-table/src/components/Table/examples/TableSelectableIndeterminate.tsx, packages/react-table/src/components/Table/examples/Table.md
New TableSelectableIndeterminate example demonstrates indeterminate state with row selection tracking, computed isIndeterminate based on partial selection, and shift\+click range selection support. Documentation section added explaining indeterminate dash/minus behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

Needs design review

Suggested reviewers

  • kmcfaul
  • thatblindgeye
  • mcoker
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding indeterminate checkbox state support for the select-all header in the Table component.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from issue #12404: extends ThSelectType with isIndeterminate, propagates it through selectable decorator and Th component, and implements PatternFly's native indeterminate support in SelectColumn.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing indeterminate checkbox support: type definitions, component logic, decorator updates, example, and documentation modifications are all aligned with the stated objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@patternfly-build
Copy link
Copy Markdown
Collaborator

patternfly-build commented May 5, 2026

@rhamilto rhamilto force-pushed the feat/table-indeterminate-checkbox branch from 3ab7def to 1b9740e Compare May 5, 2026 15:05
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/react-table/src/components/Table/SelectColumn.tsx (1)

47-61: 💤 Low value

checkboxProps duplicates all four fields from commonProps — consider eliminating the separate object.

PatternFly's Checkbox supports isChecked?: boolean | null, where null means the checkbox will be indeterminate (partially checked). The override is correct, but checkboxProps replicates all four fields (...props, id, ref, onChange) already present in commonProps. You can eliminate the duplication by building the conditional override directly at the call-site:

♻️ Proposed refactor
-  // PatternFly Checkbox supports indeterminate via isChecked: null
-  const checkboxProps = {
-    ...props,
-    id,
-    ref: inputRef,
-    onChange: handleChange,
-    ...(isIndeterminate && { isChecked: null })
-  };
-
   const commonProps = {
     ...props,
     id,
     ref: inputRef,
     onChange: handleChange
   };
-        <Checkbox {...checkboxProps} />
+        <Checkbox {...commonProps} {...(isIndeterminate && { isChecked: null })} />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react-table/src/components/Table/SelectColumn.tsx` around lines 47 -
61, Remove the duplicated object by using commonProps as the base and applying
the indeterminate override only where Checkbox is rendered: delete the separate
checkboxProps declaration and, at the Checkbox render site, spread commonProps
and conditionally include isChecked: null when isIndeterminate is true
(preserving ...props, id, ref: inputRef, onChange: handleChange from
commonProps). Keep the identifier names isIndeterminate, commonProps and
checkbox behavior consistent with PatternFly's Checkbox which accepts
isChecked?: boolean | null.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/react-table/src/components/Table/SelectColumn.tsx`:
- Around line 47-61: Remove the duplicated object by using commonProps as the
base and applying the indeterminate override only where Checkbox is rendered:
delete the separate checkboxProps declaration and, at the Checkbox render site,
spread commonProps and conditionally include isChecked: null when
isIndeterminate is true (preserving ...props, id, ref: inputRef, onChange:
handleChange from commonProps). Keep the identifier names isIndeterminate,
commonProps and checkbox behavior consistent with PatternFly's Checkbox which
accepts isChecked?: boolean | null.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 407847d8-4ecd-4bbc-80dc-1d367e75dd63

📥 Commits

Reviewing files that changed from the base of the PR and between 90f963f and 1b9740e.

📒 Files selected for processing (8)
  • packages/react-table/src/components/Table/SelectColumn.tsx
  • packages/react-table/src/components/Table/TableTypes.tsx
  • packages/react-table/src/components/Table/Th.tsx
  • packages/react-table/src/components/Table/base/types.tsx
  • packages/react-table/src/components/Table/examples/Table.md
  • packages/react-table/src/components/Table/examples/TableSelectable.tsx
  • packages/react-table/src/components/Table/examples/TableSelectableIndeterminate.tsx
  • packages/react-table/src/components/Table/utils/decorators/selectable.tsx
✅ Files skipped from review due to trivial changes (2)
  • packages/react-table/src/components/Table/examples/TableSelectable.tsx
  • packages/react-table/src/components/Table/examples/Table.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/react-table/src/components/Table/utils/decorators/selectable.tsx
  • packages/react-table/src/components/Table/Th.tsx

@rhamilto
Copy link
Copy Markdown
Member Author

rhamilto commented May 5, 2026

cc: @nicolethoen, this is needed to complete openshift/console#16203

@rhamilto rhamilto force-pushed the feat/table-indeterminate-checkbox branch from 1b9740e to a99a368 Compare May 5, 2026 20:30
…header

Add support for indeterminate state to the Table component's select-all
checkbox, following PatternFly's bulk selection design guidelines.

The select-all checkbox now supports three states:
- Unchecked: no items selected
- Indeterminate: some items selected (shows dash/minus icon)
- Checked: all items selected

## Changes

- Add `isIndeterminate?: boolean` property to `ThSelectType` interface
- Add `isIndeterminate?: boolean` to `IColumn` extraParams type
- Update `Th` component to pass `isIndeterminate` to the selectable decorator
- Update `selectable` decorator to pass indeterminate state to `SelectColumn`
- Update `SelectColumn` to use PatternFly Checkbox's native indeterminate support (isChecked: null)
- Add new `TableSelectableIndeterminate` example showcasing the feature

## Implementation

The indeterminate state is implemented using the PatternFly Checkbox component's
native support by setting `isChecked: null` when `isIndeterminate` is true.

## Usage

```typescript
const areSomeReposSelected = selectedRepoNames.length > 0 && selectedRepoNames.length < selectableRepos.length;

<Th
  select={{
    onSelect: (_event, isSelecting) => selectAllRepos(isSelecting),
    isSelected: areAllReposSelected,
    isIndeterminate: areSomeReposSelected
  }}
  aria-label="Row select"
/>
```

Fixes patternfly#12404

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@rhamilto rhamilto force-pushed the feat/table-indeterminate-checkbox branch from a99a368 to 6308f98 Compare May 5, 2026 20:31
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.

Table: Add indeterminate checkbox state support for select-all header

2 participants