Skip to content

Commit

Permalink
fix: disable tab for outside days (#1567) (#1576)
Browse files Browse the repository at this point in the history
Co-authored-by: Dan Kelly <dkelly@neat.com>
Co-authored-by: gpbl <io@gpbl.dev>
  • Loading branch information
3 people authored Oct 9, 2022
1 parent 2f50a6d commit 9991023
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import startOfMonth from 'date-fns/startOfMonth';
import { getActiveModifiers } from 'contexts/Modifiers';
import { Modifiers } from 'types/Modifiers';

/** Returns the day that should be the target of the focus when DayPicker is rendered the first time. */
/**
* Returns the day that should be the target of the focus when DayPicker is
* rendered the first time.
*
* TODO: this function doesn't consider if the day is outside the month. We
* implemented this check in `useDayRender` but it should probably go here. See
* https://github.com/gpbl/react-day-picker/pull/1576
*/
export function getInitialFocusTarget(
displayMonths: Date[],
modifiers: Modifiers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,25 @@ describe('when the day is target of focus', () => {
});
});

describe('when the day is target of focus but outside', () => {
const date = today;
const focusContext: FocusContextValue = {
...mockedFocusContext,
focusTarget: date
};
beforeEach(() => {
setup(
date,
date,
{ modifiers: { outside: date } },
{ focus: focusContext }
);
});
test('the button should have tabIndex -1', () => {
expect(result.current.buttonProps.tabIndex).toBe(-1);
});
});

describe('when the day is disabled', () => {
const date = today;
const dayPickerProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,11 @@ export function useDayRender(
'aria-label': ariaLabel
};

const isFocusTarget = Boolean(
focusContext.focusTarget && isSameDay(focusContext.focusTarget, day)
);
const isFocusTarget =
focusContext.focusTarget &&
isSameDay(focusContext.focusTarget, day) &&
!activeModifiers.outside;

const buttonProps = {
...divProps,
disabled: activeModifiers.disabled,
Expand Down
30 changes: 30 additions & 0 deletions website/examples/testcase-1567.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { useState } from 'react';

import { DateRange, DayPicker } from 'react-day-picker';

/**
* Test case for issue #1567
*
* @see https://github.com/gpbl/react-day-picker/issues/1567
*/
export default function App() {
const [selected, setSelected] = useState<DateRange>({
from: new Date(2022, 8, 25),
to: new Date(2022, 9, 1)
});

return (
<div className="App">
<DayPicker
mode="range"
defaultMonth={new Date(2022, 8)}
onSelect={setSelected}
numberOfMonths={2}
showOutsideDays
selected={selected}
fromDate={new Date(2020, 5)}
/>
<button>I should be focusable</button>
</div>
);
}
21 changes: 21 additions & 0 deletions website/test-integration/examples/testcase-1567.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

import { render, screen } from '@testing-library/react';

import { pressTab } from 'react-day-picker/test/actions';

import Example from '@examples/testcase-1567';

beforeEach(() => {
render(<Example />);
pressTab();
pressTab();
pressTab();
pressTab();
});

test('the button should have focus', () => {
expect(
screen.getByRole('button', { name: 'I should be focusable' })
).toHaveFocus();
});

0 comments on commit 9991023

Please sign in to comment.