Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IndexTable.Row] Add ability to hide selectable checkbox on a per row basis #11944

Merged
merged 1 commit into from May 2, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sweet-masks-walk.md
@@ -0,0 +1,5 @@
---
'@shopify/polaris': patch
---

Add support for hiding selectable checkbox on a per `IndexTable.Row` basis via `hideSelectable` prop`
25 changes: 16 additions & 9 deletions polaris-react/src/components/IndexTable/components/Row/Row.tsx
Expand Up @@ -6,6 +6,7 @@ import {
SelectionType,
useIndexSelectionChange,
} from '../../../../utilities/index-provider';
import {Cell} from '../Cell';
import {Checkbox} from '../Checkbox';
import {classNames, variationName} from '../../../../utilities/css';
import {RowContext, RowHoveredContext} from '../../../../utilities/index-table';
Expand All @@ -21,6 +22,8 @@ export interface RowProps {
children: React.ReactNode;
/** A unique identifier for the row */
id: string;
/** Whether the row should hide the selectable checkbox while the parent IndexTable is selectable */
hideSelectable?: boolean;
jesstelford marked this conversation as resolved.
Show resolved Hide resolved
/** Whether the row is selected */
selected?: boolean | 'indeterminate';
/** The zero-indexed position of the row. Used for Shift key multi-selection */
Expand All @@ -47,6 +50,7 @@ export interface RowProps {

export const Row = memo(function Row({
children,
hideSelectable,
selected,
id,
position,
Expand All @@ -58,7 +62,8 @@ export const Row = memo(function Row({
onNavigation,
onClick,
}: RowProps) {
const {selectable, selectMode, condensed} = useIndexRow();
const {selectable: tableIsSelectable, selectMode, condensed} = useIndexRow();
const rowIsSelectable = tableIsSelectable && !hideSelectable;
const onSelectionChange = useIndexSelectionChange();
const {
value: hovered,
Expand All @@ -73,7 +78,7 @@ export const Row = memo(function Row({

if (
disabled ||
!selectable ||
!rowIsSelectable ||
('key' in event && event.key !== ' ') ||
!onSelectionChange
)
Expand All @@ -95,7 +100,7 @@ export const Row = memo(function Row({
selectionRange,
position,
disabled,
selectable,
rowIsSelectable,
],
);

Expand Down Expand Up @@ -128,20 +133,20 @@ export const Row = memo(function Row({
styles.TableRow,
rowType === 'subheader' && styles['TableRow-subheader'],
rowType === 'child' && styles['TableRow-child'],
selectable && condensed && styles.condensedRow,
rowIsSelectable && condensed && styles.condensedRow,
selected && styles['TableRow-selected'],
hovered && !condensed && styles['TableRow-hovered'],
disabled && styles['TableRow-disabled'],
tone && styles[variationName('tone', tone)],
!selectable &&
!rowIsSelectable &&
!onClick &&
!primaryLinkElement.current &&
styles['TableRow-unclickable'],
);

let handleRowClick;

if ((!disabled && selectable) || onClick || primaryLinkElement.current) {
if ((!disabled && rowIsSelectable) || onClick || primaryLinkElement.current) {
handleRowClick = (event: React.MouseEvent) => {
if (rowType === 'subheader') return;

Expand Down Expand Up @@ -184,9 +189,11 @@ export const Row = memo(function Row({
}

const RowWrapper = condensed ? 'li' : 'tr';
const checkboxMarkup = selectable ? (
const checkboxMarkup = hideSelectable ? (
<Cell />
) : (
<Checkbox accessibilityLabel={accessibilityLabel} />
) : null;
);

return (
<RowContext.Provider value={contextValue}>
Expand All @@ -200,7 +207,7 @@ export const Row = memo(function Row({
onClick={handleRowClick}
ref={tableRowCallbackRef}
>
{checkboxMarkup}
{tableIsSelectable ? checkboxMarkup : null}
{children}
</RowWrapper>
</RowHoveredContext.Provider>
Expand Down
Expand Up @@ -14,6 +14,7 @@ import {Link} from '../../../../Link';
import {Checkbox as PolarisCheckbox} from '../../../../Checkbox';
import styles from '../../../IndexTable.module.css';
import type {Range} from '../../../../../utilities/index-provider';
import {Cell} from '../../Cell';

const defaultEvent = {
preventDefault: noop,
Expand Down Expand Up @@ -78,6 +79,29 @@ describe('<Row />', () => {
expect(row).not.toContainReactComponent(Checkbox);
});

it('renders checkboxes when hideSelectable is false and selectable set to true in IndexTable', () => {
const row = mountWithTable(
<Row {...defaultProps} hideSelectable={false}>
<th>Child</th>
</Row>,
{indexTableProps: {selectable: true}},
);

expect(row).toContainReactComponent(Checkbox);
});

it('does not render checkboxes when hideSelectable is true and selectable set to true in IndexTable', () => {
const row = mountWithTable(
<Row {...defaultProps} hideSelectable>
<th>Child</th>
</Row>,
{indexTableProps: {selectable: true}},
);

expect(row).not.toContainReactComponent(Checkbox);
expect(row).toContainReactComponent(Cell, {});
});

it('renders a RowHoveredContext provider', () => {
const row = mountWithTable(
<Row id="id" selected position={1}>
Expand Down