Skip to content

Commit

Permalink
DateInput Calendar Icon Opens Drop when Clicked (#5838)
Browse files Browse the repository at this point in the history
* first pass

* calendar button opens and closes calendar

* remove accidental change

* Added jest test

* Changed Calendar icon to be wrapped with Box

* Changed box back to button for accessibility

* adjust padding

* Changes from review comments & added ref to button to fix blink behavior on calendar when clicking part of button without icon

* Changed call to close and open calendar

* Simplified refs

* simplified close and open calendar calls
  • Loading branch information
jcfilben committed Dec 17, 2021
1 parent 2e12221 commit 19b996a
Show file tree
Hide file tree
Showing 3 changed files with 9,964 additions and 7,192 deletions.
97 changes: 60 additions & 37 deletions src/js/components/DateInput/DateInput.js
@@ -1,4 +1,5 @@
import React, {
useRef,
forwardRef,
useContext,
useEffect,
Expand All @@ -12,6 +13,7 @@ import { defaultProps } from '../../default-props';
import { AnnounceContext } from '../../contexts/AnnounceContext';
import { MessageContext } from '../../contexts/MessageContext';
import { Box } from '../Box';
import { Button } from '../Button';
import { Calendar } from '../Calendar';
import { Drop } from '../Drop';
import { DropButton } from '../DropButton';
Expand Down Expand Up @@ -44,6 +46,7 @@ const DateInput = forwardRef(
name,
onChange,
onFocus,
plain,
value: valueArg,
messages,
...rest
Expand All @@ -57,6 +60,7 @@ const DateInput = forwardRef(
(theme.dateInput.icon && theme.dateInput.icon.size) || 'medium';
const { useFormInput } = useContext(FormContext);
const ref = useForwardedRef(refArg);
const containerRef = useRef();
const [value, setValue] = useFormInput({
name,
value: valueArg,
Expand Down Expand Up @@ -190,42 +194,56 @@ const DateInput = forwardRef(
onEsc={open ? () => closeCalendar() : undefined}
onSpace={openCalendar}
>
<MaskedInput
ref={ref}
id={id}
name={name}
icon={<CalendarIcon size={iconSize} />}
reverse
disabled={disabled}
mask={mask}
{...inputProps}
{...rest}
value={textValue}
onChange={(event) => {
const nextTextValue = event.target.value;
setTextValue(nextTextValue);
const nextValue = textToValue(
nextTextValue,
schema,
range,
timestamp,
);
// update value even when undefined
setValue(nextValue);
if (onChange) {
event.persist(); // extract from React synthetic event pool
const adjustedEvent = event;
adjustedEvent.value = nextValue;
onChange(adjustedEvent);
}
}}
onFocus={(event) => {
announce(
formatMessage({ id: 'dateInput.openCalendar', messages }),
);
if (onFocus) onFocus(event);
}}
/>
<Box
ref={containerRef}
border={!plain}
round="xxsmall"
direction="row"
fill
>
<MaskedInput
ref={ref}
id={id}
name={name}
reverse
disabled={disabled}
mask={mask}
plain
{...inputProps}
{...rest}
value={textValue}
onChange={(event) => {
const nextTextValue = event.target.value;
setTextValue(nextTextValue);
const nextValue = textToValue(
nextTextValue,
schema,
range,
timestamp,
);
// update value even when undefined
setValue(nextValue);
if (onChange) {
event.persist(); // extract from React synthetic event pool
const adjustedEvent = event;
adjustedEvent.value = nextValue;
onChange(adjustedEvent);
}
}}
onFocus={(event) => {
announce(
formatMessage({ id: 'dateInput.openCalendar', messages }),
);
if (onFocus) onFocus(event);
}}
/>
<Button
onClick={open ? closeCalendar : openCalendar}
plain
icon={<CalendarIcon size={iconSize} />}
margin={{ right: 'small' }}
/>
</Box>
</Keyboard>
</FormContext.Provider>
);
Expand All @@ -250,7 +268,12 @@ const DateInput = forwardRef(
align={{ top: 'bottom', left: 'left', ...dropProps }}
onEsc={closeCalendar}
onClickOutside={({ target }) => {
if (target !== ref.current) closeCalendar();
if (
target !== containerRef.current &&
!containerRef.current.contains(target)
) {
closeCalendar();
}
}}
{...dropProps}
>
Expand Down
18 changes: 17 additions & 1 deletion src/js/components/DateInput/__tests__/DateInput-test.tsx
@@ -1,10 +1,11 @@
import React from 'react';
import 'jest-styled-components';
import { fireEvent, render } from '@testing-library/react';
import { fireEvent, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { axe } from 'jest-axe';
import 'jest-axe/extend-expect';
import 'regenerator-runtime/runtime';
import '@testing-library/jest-dom';

import { createPortal, expectPortal } from '../../../utils/portal';
import { Grommet } from '../../Grommet';
Expand Down Expand Up @@ -888,4 +889,19 @@ describe('DateInput', () => {
);
expect(container.children).toMatchSnapshot();
});

test('clicking calendar icon should open drop', () => {
render(
<Grommet>
<DateInput format="m/d/yy" defaultValue="1/1/2021" />
</Grommet>,
);
expect(
screen.queryByRole('heading', { name: /January 2021/i }),
).not.toBeInTheDocument();
userEvent.click(screen.getByRole('button', { name: /Calendar/i }));
expect(
screen.getByRole('heading', { name: /January 2021/i }),
).toBeInTheDocument();
});
});

0 comments on commit 19b996a

Please sign in to comment.