Skip to content

Commit 062a7ec

Browse files
committed
activate section after SPACE was released
1 parent d17b673 commit 062a7ec

2 files changed

Lines changed: 29 additions & 5 deletions

File tree

cypress/support/utils.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,16 +196,21 @@ export function testPieSectorFocus(Component, props, { only }: { only?: boolean
196196

197197
cy.realPress('ArrowRight');
198198
cy.focused().should('have.attr', 'data-sector-index', '5');
199-
cy.realPress('Space');
199+
200+
// Space activates on keyup — hold Space, arrow to next sector, then release
201+
cy.focused().then(($el) => $el[0].dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true })));
202+
cy.realPress('ArrowRight');
203+
cy.focused().should('have.attr', 'data-sector-index', '6');
204+
cy.focused().then(($el) => $el[0].dispatchEvent(new KeyboardEvent('keyup', { key: ' ', bubbles: true })));
200205
cy.get('@onDataPointClick').should(
201206
'have.been.calledWith',
202207
Cypress.sinon.match({
203208
detail: Cypress.sinon.match({
204-
dataIndex: 5,
209+
dataIndex: 6,
205210
}),
206211
}),
207212
);
208-
cy.focused().should('have.attr', 'data-sector-index', '5');
213+
cy.focused().should('have.attr', 'data-sector-index', '6');
209214
});
210215

211216
test('sector focus - activeSegment out of bounds is clamped', () => {

packages/charts/src/components/PieChart/usePieSectorFocus.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export function usePieSectorFocus({
3232
}: UsePieSectorFocusOptions) {
3333
const sectorFocusRef = useRef(-1);
3434
const lastSectorRef = useRef(-1);
35+
const spaceHeldRef = useRef(false);
3536
const [inSectorMode, setInSectorMode] = useState(false);
3637
const getSectorLabelRef = useRef(getSectorLabel);
3738
// Keep ref in sync so focusSector always uses the latest callback without re-creating the memoized function.
@@ -154,14 +155,19 @@ export function usePieSectorFocus({
154155
focusSector((sectorFocusRef.current - 1 + dataLength) % dataLength);
155156
break;
156157
}
157-
case 'Enter':
158-
case ' ': {
158+
case 'Enter': {
159159
e.preventDefault();
160160
if (sectorFocusRef.current >= 0) {
161161
onSelect?.(sectorFocusRef.current, e);
162162
}
163163
break;
164164
}
165+
case ' ': {
166+
// Space activates on keyup so users can hold it, arrow to another sector, then release.
167+
e.preventDefault();
168+
spaceHeldRef.current = true;
169+
break;
170+
}
165171
}
166172
},
167173
[dataLength, chartRef, activeSegment, exitSectorMode, focusSector, onSelect],
@@ -211,6 +217,18 @@ export function usePieSectorFocus({
211217
[handleKeyDown, consumerOnKeyDownCapture],
212218
);
213219

220+
const handleKeyUp = useCallback(
221+
(e: KeyboardEvent<HTMLDivElement>) => {
222+
if (e.key === ' ' && spaceHeldRef.current) {
223+
spaceHeldRef.current = false;
224+
if (sectorFocusRef.current >= 0) {
225+
onSelect?.(sectorFocusRef.current, e);
226+
}
227+
}
228+
},
229+
[onSelect],
230+
);
231+
214232
const handleSectorClick = useCallback(
215233
(dataIndex: number) => {
216234
if (!enabled) {
@@ -249,6 +267,7 @@ export function usePieSectorFocus({
249267
role: 'application' as const,
250268
'aria-roledescription': 'chart',
251269
onKeyDownCapture: handleKeyDownCapture,
270+
onKeyUp: handleKeyUp,
252271
onBlur: handleBlur,
253272
onFocus: handleFocus,
254273
},

0 commit comments

Comments
 (0)