diff --git a/packages/react-core/src/components/DatePicker/DatePicker.tsx b/packages/react-core/src/components/DatePicker/DatePicker.tsx index 59f810c0ab6..e1a31074ffa 100644 --- a/packages/react-core/src/components/DatePicker/DatePicker.tsx +++ b/packages/react-core/src/components/DatePicker/DatePicker.tsx @@ -72,7 +72,7 @@ export interface DatePickerRef { * If the eventKey parameter is set to 'Escape', that will invoke the date pickers * onEscapePress event to toggle the correct control appropriately. */ - toggleCalendar: (isOpen?: boolean, eventKey?: string) => void; + toggleCalendar: (isOpen?: boolean) => void; } export const yyyyMMddFormat = (date: Date) => @@ -189,10 +189,8 @@ const DatePickerBase = ( ref, () => ({ setCalendarOpen: (isOpen: boolean) => setPopoverOpen(isOpen), - toggleCalendar: (setOpen?: boolean, eventKey?: string) => { - if (eventKey === KeyTypes.Escape && popoverOpen && !selectOpen) { - setPopoverOpen((prev) => (setOpen !== undefined ? setOpen : !prev)); - } + toggleCalendar: (setOpen?: boolean) => { + setPopoverOpen((prev) => (setOpen !== undefined ? setOpen : !prev)); }, isCalendarOpen: popoverOpen }), @@ -222,7 +220,7 @@ const DatePickerBase = ( } showClose={false} isVisible={popoverOpen} - shouldClose={(event, _fn) => { + shouldClose={(event, hideFunction) => { event = event as KeyboardEvent; if (event.key === KeyTypes.Escape && selectOpen) { event.stopPropagation(); @@ -233,7 +231,12 @@ const DatePickerBase = ( if (buttonRef.current && buttonRef.current.contains(event.target as Node)) { return false; } - setPopoverOpen(false); + + if (popoverOpen) { + event.stopPropagation(); + setPopoverOpen(false); + hideFunction(); + } if (event.key === KeyTypes.Escape && popoverOpen) { event.stopPropagation(); } diff --git a/packages/react-core/src/components/DatePicker/examples/DatePickerControlled.tsx b/packages/react-core/src/components/DatePicker/examples/DatePickerControlled.tsx index e64771fbf59..a305b70330f 100644 --- a/packages/react-core/src/components/DatePicker/examples/DatePickerControlled.tsx +++ b/packages/react-core/src/components/DatePicker/examples/DatePickerControlled.tsx @@ -6,8 +6,10 @@ export const DatePickerControlled: React.FunctionComponent = () => { const [value, setValue] = React.useState(initialValue); return ( - setValue(value)} /> +
+
+
); }; diff --git a/packages/react-core/src/components/DatePicker/examples/DatePickerControlledCalendar.tsx b/packages/react-core/src/components/DatePicker/examples/DatePickerControlledCalendar.tsx index 7065c3d8c8f..89291a358c7 100644 --- a/packages/react-core/src/components/DatePicker/examples/DatePickerControlledCalendar.tsx +++ b/packages/react-core/src/components/DatePicker/examples/DatePickerControlledCalendar.tsx @@ -10,8 +10,10 @@ export const DatePickerControlledCalendar: React.FunctionComponent = () => { }; return ( - +
+
+
); }; diff --git a/packages/react-integration/cypress/integration/datepicker.spec.ts b/packages/react-integration/cypress/integration/datepicker.spec.ts index ab0a15c5576..53cecdfb50b 100644 --- a/packages/react-integration/cypress/integration/datepicker.spec.ts +++ b/packages/react-integration/cypress/integration/datepicker.spec.ts @@ -4,7 +4,7 @@ it('Navigate to demo section', () => { // TODO: Reenable with issue #8457 xit('Verify validation error can be cleared from outside', () => { - cy.get('.pf-v5-c-date-picker') + cy.get('#date-picker-validator > .pf-v5-c-date-picker') .children() .within(() => { cy.get('input'); @@ -17,3 +17,11 @@ xit('Verify validation error can be cleared from outside', () => { cy.get('button').contains('Set 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(); + cy.get('#date-picker-controlled .pf-v5-c-popover').should('exist'); + cy.get('button').contains('Toggle').click(); + cy.get('#date-picker-controlled .pf-v5-c-popover').should('not.exist'); +}); diff --git a/packages/react-integration/demo-app-ts/src/components/demos/DatePickerDemo/DatePickerDemo.tsx b/packages/react-integration/demo-app-ts/src/components/demos/DatePickerDemo/DatePickerDemo.tsx index 3dba32c7427..b61f84e7898 100644 --- a/packages/react-integration/demo-app-ts/src/components/demos/DatePickerDemo/DatePickerDemo.tsx +++ b/packages/react-integration/demo-app-ts/src/components/demos/DatePickerDemo/DatePickerDemo.tsx @@ -3,6 +3,7 @@ import React from 'react'; export const DatePickerDemo = () => { const [value, setValue] = React.useState('2020-03-18'); + const controlledDateRef = React.useRef(null); const rangeValidator = (date: Date) => { if (date < new Date('2020-03-17')) { @@ -13,9 +14,25 @@ export const DatePickerDemo = () => { return ( <> - setValue(value)} validators={[rangeValidator]} /> -
- +
+ setValue(value)} validators={[rangeValidator]} /> +
+ +
+
+
+ +
+ +
);