Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/react-core/src/components/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,13 @@ const DatePickerBase = (
const [popoverOpen, setPopoverOpen] = React.useState(false);
const [selectOpen, setSelectOpen] = React.useState(false);
const [pristine, setPristine] = React.useState(true);
const [textInputFocused, setTextInputFocused] = React.useState(false);
const widthChars = React.useMemo(() => Math.max(dateFormat(new Date()).length, placeholder.length), [dateFormat]);
const style = { '--pf-v5-c-date-picker__input--c-form-control--width-chars': widthChars, ...styleProps };
const buttonRef = React.useRef<HTMLButtonElement>();
const datePickerWrapperRef = React.useRef<HTMLDivElement>();
const triggerRef = React.useRef<HTMLDivElement>();
const dateIsRequired = requiredDateOptions?.isRequired || false;
const emptyDateText = requiredDateOptions?.emptyDateText || 'Date cannot be blank';

React.useEffect(() => {
Expand All @@ -146,6 +148,9 @@ const DatePickerBase = (
if (errorText && isValidDate(newValueDate)) {
setError(newValueDate);
}
if (value === '' && !pristine && !textInputFocused) {
dateIsRequired ? setErrorText(emptyDateText) : setErrorText('');
}
}, [value]);

const setError = (date: Date) => {
Expand All @@ -165,6 +170,7 @@ const DatePickerBase = (
};

const onInputBlur = (event: any) => {
setTextInputFocused(false);
const newValueDate = dateParse(value);
const dateIsValid = isValidDate(newValueDate);
const onBlurDateArg = dateIsValid ? new Date(newValueDate) : undefined;
Expand Down Expand Up @@ -282,6 +288,7 @@ const DatePickerBase = (
value={value}
onChange={onTextInput}
onBlur={onInputBlur}
onFocus={() => setTextInputFocused(true)}
onKeyPress={onKeyPress}
{...inputProps}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ The error message can be customized via the `requiredDateOptions.emptyDateText`

```

### Controlled required

```ts file="./DatePickerControlledRequired.tsx"

```

### Controlling the date picker calendar state

```ts file="./DatePickerControlledCalendar.tsx"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Button, DatePicker } from '@patternfly/react-core';
import { Button, DatePicker, Flex, FlexItem } from '@patternfly/react-core';

export const DatePickerControlled: React.FunctionComponent = () => {
const initialValue = '2020-03-17';
Expand All @@ -9,7 +9,14 @@ export const DatePickerControlled: React.FunctionComponent = () => {
<DatePicker value={value} onChange={(_event, value) => setValue(value)} />
<br />
<br />
<Button onClick={() => setValue(initialValue)}>Reset date</Button>
<Flex>
<FlexItem>
<Button onClick={() => setValue(initialValue)}>Reset date</Button>
</FlexItem>
<FlexItem>
<Button onClick={() => setValue('')}>Clear date</Button>
</FlexItem>
</Flex>
</React.Fragment>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { Button, DatePicker, Flex, FlexItem } from '@patternfly/react-core';

export const DatePickerControlled: React.FunctionComponent = () => {
const initialValue = '2020-03-17';
const [value, setValue] = React.useState(initialValue);
return (
<React.Fragment>
<DatePicker
requiredDateOptions={{ isRequired: true, emptyDateText: 'Date is required' }}
value={value}
onChange={(_event, value) => setValue(value)}
/>
<br />
<br />
<Flex>
<FlexItem>
<Button onClick={() => setValue(initialValue)}>Reset date</Button>
</FlexItem>
<FlexItem>
<Button onClick={() => setValue('')}>Clear date</Button>
</FlexItem>
</Flex>
</React.Fragment>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ xit('Verify validation error can be cleared from outside', () => {
cy.get('div.pf-m-error').should('not.exist');
});

it('Verify error can be cleared when resetting the date from outside', () => {
cy.get('#date-picker-clear .pf-v5-c-form-control input').click();
cy.focused().clear().type('something invalid');
cy.focused().blur();
cy.get('div.pf-m-error').should('exist');
cy.get('button').contains('Clear date').click();
cy.get('div.pf-m-error').should('not.exist');
});

it('Verify calendar state can be controlled', () => {
cy.get('#date-picker-controlled .pf-v5-c-popover').should('not.exist');
cy.get('button').contains('Toggle').click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ export const DatePickerDemo = () => {

return (
<>
<div id="date-picker-clear">
<DatePicker value={value} />
<div>
<button onClick={() => setValue('')}>Clear date</button>
</div>
</div>
<div id="date-picker-validator">
<DatePicker value={value} onChange={(event, value) => setValue(value)} validators={[rangeValidator]} />
<div>
Expand Down