Skip to content

Commit 4650995

Browse files
committed
fix(AnalyticalTable): allow selecting all rows via keyboard (#6168)
Fixes #6110
1 parent ecb50ce commit 4650995

File tree

4 files changed

+53
-5
lines changed

4 files changed

+53
-5
lines changed

packages/main/src/components/AnalyticalTable/AnalyticalTable.cy.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,8 @@ describe('AnalyticalTable', () => {
617617
cy.findByTestId('payloadRowsById').should('have.text', '{"1":true,"2":true,"3":false}');
618618
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
619619

620+
//select all
621+
//click
620622
cy.get('[data-row-index="0"][data-column-index="0"]').click();
621623
cy.get('@onRowSelectSpy').should('have.callCount', 6);
622624
cy.findByTestId('payload').should(
@@ -629,6 +631,33 @@ describe('AnalyticalTable', () => {
629631
);
630632
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'true');
631633

634+
// enter (keydown)
635+
cy.get('[data-row-index="0"][data-column-index="0"]').realPress('Enter');
636+
cy.get('@onRowSelectSpy').should('have.callCount', 7);
637+
cy.findByTestId('payload').should('have.text', '[]');
638+
cy.findByTestId('payloadRowsById').should('have.text', '{}');
639+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
640+
641+
// Space (keyup) + ArrowDown => 1st row selected
642+
cy.get('[data-row-index="0"][data-column-index="0"]').realPress(['Space', 'ArrowDown']);
643+
cy.get('@onRowSelectSpy').should('have.callCount', 8);
644+
cy.findByTestId('payload').should('have.text', '["0"]');
645+
cy.findByTestId('payloadRowsById').should('have.text', '{"0":true}');
646+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
647+
648+
// Space (keyup) + ArrowUp => all rows selected
649+
cy.get('[data-row-index="0"][data-column-index="0"]').realPress(['Space', 'ArrowUp']);
650+
cy.get('@onRowSelectSpy').should('have.callCount', 9);
651+
cy.findByTestId('payload').should(
652+
'have.text',
653+
'["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"]'
654+
);
655+
cy.findByTestId('payloadRowsById').should(
656+
'have.text',
657+
'{"0":true,"1":true,"2":true,"3":true,"4":true,"5":true,"6":true,"7":true,"8":true,"9":true,"10":true,"11":true,"12":true,"13":true,"14":true,"15":true,"16":true,"17":true,"18":true,"19":true,"20":true}'
658+
);
659+
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'true');
660+
632661
cy.get('[data-row-index="0"][data-column-index="0"]').click();
633662

634663
cy.findByText('Name-0').click();
@@ -641,7 +670,7 @@ describe('AnalyticalTable', () => {
641670
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
642671

643672
cy.get('[data-row-index="0"][data-column-index="0"]').click();
644-
cy.get('@onRowSelectSpy').should('have.callCount', 11);
673+
cy.get('@onRowSelectSpy').should('have.callCount', 14);
645674
cy.findByTestId('payload').should('have.text', '["0","1","5","7","17","20"]');
646675
cy.findByTestId('payloadRowsById').should('have.text', '{"0":true,"1":true,"5":true,"7":true,"17":true,"20":true}');
647676
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'false');
@@ -696,7 +725,7 @@ describe('AnalyticalTable', () => {
696725
'{"0":true,"1":true,"2":true,"3":true,"4":true,"5":true,"6":true,"7":true,"8":true,"9":true,"10":true,"11":true,"12":true,"13":true,"14":true,"15":true,"16":true,"17":true,"18":true,"19":true,"20":true}'
697726
);
698727
cy.findByTestId('payloadAllRowsSelected').should('have.text', 'true');
699-
cy.get('@onRowSelectSpy').should('have.callCount', 16);
728+
cy.get('@onRowSelectSpy').should('have.callCount', 19);
700729
});
701730

702731
it('row & header height', () => {

packages/main/src/components/AnalyticalTable/ColumnHeader/index.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export interface ColumnHeaderProps {
4545
id: string;
4646
onClick: MouseEventHandler<HTMLDivElement> | undefined;
4747
onKeyDown?: KeyboardEventHandler<HTMLDivElement> | undefined;
48+
onKeyUp?: KeyboardEventHandler<HTMLDivElement> | undefined;
4849
className: string;
4950
style: CSSProperties;
5051
column: ColumnType;
@@ -82,6 +83,7 @@ export const ColumnHeader = (props: ColumnHeaderProps) => {
8283
onClick,
8384
onKeyDown,
8485
portalContainer,
86+
onKeyUp,
8587
isFiltered,
8688
title,
8789
'aria-label': ariaLabel,
@@ -130,7 +132,9 @@ export const ColumnHeader = (props: ColumnHeaderProps) => {
130132
const hasPopover = column.canGroupBy || column.canSort || column.canFilter;
131133

132134
const handleHeaderCellClick = (e) => {
133-
onClick?.(e);
135+
if (typeof onClick === 'function') {
136+
onClick(e);
137+
}
134138
if (hasPopover) {
135139
setPopoverOpen(true);
136140
}
@@ -141,7 +145,9 @@ export const ColumnHeader = (props: ColumnHeaderProps) => {
141145
: { left: 0, transform: `translateX(${virtualColumn.start}px)` };
142146

143147
const handleHeaderCellKeyDown = (e) => {
144-
onKeyDown?.(e);
148+
if (typeof onKeyDown === 'function') {
149+
onKeyDown(e);
150+
}
145151
if (hasPopover && e.code === 'Enter') {
146152
setPopoverOpen(true);
147153
}
@@ -151,6 +157,9 @@ export const ColumnHeader = (props: ColumnHeaderProps) => {
151157
};
152158

153159
const handleHeaderCellKeyUp = (e) => {
160+
if (typeof onKeyUp === 'function') {
161+
onKeyUp(e);
162+
}
154163
if (hasPopover && e.code === 'Space' && !e.target.hasAttribute('ui5-li')) {
155164
setPopoverOpen(true);
156165
}

packages/main/src/components/AnalyticalTable/hooks/useKeyboardNavigation.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ function getPayload(e, column) {
349349
const setHeaderProps = (headerProps, { instance: { dispatch }, column }) => {
350350
// resize col with keyboard
351351
const handleKeyDown = (e) => {
352+
if (typeof headerProps.onKeyDown === 'function') {
353+
headerProps.onKeyDown(e);
354+
}
352355
if (e.nativeEvent.shiftKey) {
353356
if (e.key === 'ArrowRight') {
354357
const payload = getPayload(e, column);

packages/main/src/components/AnalyticalTable/hooks/useRowSelectionColumn.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import type { ReactTableHooks } from '../types/index.js';
66

77
const customCheckBoxStyling = {
88
verticalAlign: 'middle',
9-
pointerEvents: 'none'
9+
pointerEvents: 'none',
10+
display: 'block'
1011
} as CSSProperties;
1112

1213
/*
@@ -78,6 +79,9 @@ const headerProps = (props, { instance }) => {
7879
selectionMode === AnalyticalTableSelectionMode.MultiSelect
7980
) {
8081
const onClick = (e) => {
82+
if (typeof props.onClick === 'function') {
83+
props.onClick(e);
84+
}
8185
toggleAllRowsSelected(!isAllRowsSelected);
8286
const isFiltered = filters?.length > 0 || !!globalFilter;
8387
if (typeof onRowSelect === 'function') {
@@ -97,6 +101,9 @@ const headerProps = (props, { instance }) => {
97101
};
98102

99103
const onKeyDown = (e) => {
104+
if (typeof props.onKeyDown === 'function') {
105+
props.onKeyDown(e);
106+
}
100107
if (e.code === 'Space' || e.code === 'Enter') {
101108
e.preventDefault();
102109
onClick(e);

0 commit comments

Comments
 (0)