@wojtekmaj/react-datetimerange-picker
Advanced tools
Comparing version 4.1.0 to 4.1.1
@@ -61,11 +61,13 @@ "use strict"; | ||
_defineProperty(_assertThisInitialized(_this), "wrapper", /*#__PURE__*/(0, _react.createRef)()); | ||
_defineProperty(_assertThisInitialized(_this), "widgetWrapper", /*#__PURE__*/(0, _react.createRef)()); | ||
_defineProperty(_assertThisInitialized(_this), "calendarWrapper", /*#__PURE__*/(0, _react.createRef)()); | ||
_defineProperty(_assertThisInitialized(_this), "clockWrapper", /*#__PURE__*/(0, _react.createRef)()); | ||
_defineProperty(_assertThisInitialized(_this), "onOutsideAction", function (event) { | ||
var _assertThisInitialize = _assertThisInitialized(_this), | ||
wrapper = _assertThisInitialize.wrapper, | ||
widgetWrapper = _assertThisInitialize.widgetWrapper; | ||
calendarWrapper = _assertThisInitialize.calendarWrapper, | ||
clockWrapper = _assertThisInitialize.clockWrapper; | ||
// Try event.composedPath first to handle clicks inside a Shadow DOM. | ||
var target = 'composedPath' in event ? event.composedPath()[0] : event.target; | ||
if (wrapper.current && !wrapper.current.contains(target) && (!widgetWrapper.current || !widgetWrapper.current.contains(target))) { | ||
if (wrapper.current && !wrapper.current.contains(target) && (!calendarWrapper.current || !calendarWrapper.current.contains(target)) && (!clockWrapper.current || !clockWrapper.current.contains(target))) { | ||
_this.closeWidgets(); | ||
@@ -165,11 +167,21 @@ } | ||
_defineProperty(_assertThisInitialized(_this), "openClock", function () { | ||
_this.setState({ | ||
isCalendarOpen: false, | ||
isClockOpen: true | ||
_this.setState(function (prevState) { | ||
var nextState = { | ||
isClockOpen: true | ||
}; | ||
if (prevState.isCalendarOpen) { | ||
nextState.isCalendarOpen = false; | ||
} | ||
return nextState; | ||
}); | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "openCalendar", function () { | ||
_this.setState({ | ||
isCalendarOpen: true, | ||
isClockOpen: false | ||
_this.setState(function (prevState) { | ||
var nextState = { | ||
isCalendarOpen: true | ||
}; | ||
if (prevState.isClockOpen) { | ||
nextState.isClockOpen = false; | ||
} | ||
return nextState; | ||
}); | ||
@@ -179,6 +191,9 @@ }); | ||
_this.setState(function (prevState) { | ||
return { | ||
isCalendarOpen: !prevState.isCalendarOpen, | ||
isClockOpen: false | ||
var nextState = { | ||
isCalendarOpen: !prevState.isCalendarOpen | ||
}; | ||
if (prevState.isClockOpen) { | ||
nextState.isClockOpen = false; | ||
} | ||
return nextState; | ||
}); | ||
@@ -188,9 +203,10 @@ }); | ||
_this.setState(function (prevState) { | ||
if (!prevState.isCalendarOpen && !prevState.isClockOpen) { | ||
return null; | ||
var nextState = {}; | ||
if (prevState.isCalendarOpen) { | ||
nextState.isCalendarOpen = false; | ||
} | ||
return { | ||
isCalendarOpen: false, | ||
isClockOpen: false | ||
}; | ||
if (prevState.isClockOpen) { | ||
nextState.isClockOpen = false; | ||
} | ||
return nextState; | ||
}); | ||
@@ -394,3 +410,3 @@ }); | ||
return portalContainer ? /*#__PURE__*/(0, _reactDom.createPortal)( /*#__PURE__*/_react["default"].createElement("div", { | ||
ref: this.widgetWrapper, | ||
ref: this.calendarWrapper, | ||
className: classNames | ||
@@ -435,3 +451,3 @@ }, calendar), portalContainer) : /*#__PURE__*/_react["default"].createElement(_reactFit["default"], null, /*#__PURE__*/_react["default"].createElement("div", { | ||
return portalContainer ? /*#__PURE__*/(0, _reactDom.createPortal)( /*#__PURE__*/_react["default"].createElement("div", { | ||
ref: this.widgetWrapper, | ||
ref: this.clockWrapper, | ||
className: classNames | ||
@@ -438,0 +454,0 @@ }, clock), portalContainer) : /*#__PURE__*/_react["default"].createElement(_reactFit["default"], null, /*#__PURE__*/_react["default"].createElement("div", { |
{ | ||
"name": "@wojtekmaj/react-datetimerange-picker", | ||
"version": "4.1.0", | ||
"version": "4.1.1", | ||
"description": "A datetime range picker for your React app.", | ||
@@ -54,2 +54,3 @@ "main": "dist/entry.js", | ||
"@testing-library/react": "^13.4.0", | ||
"@testing-library/user-event": "^14.4.0", | ||
"eslint": "^8.26.0", | ||
@@ -56,0 +57,0 @@ "eslint-config-wojtekmaj": "^0.7.1", |
@@ -39,4 +39,6 @@ import React, { createRef, PureComponent } from 'react'; | ||
widgetWrapper = createRef(); | ||
calendarWrapper = createRef(); | ||
clockWrapper = createRef(); | ||
componentDidMount() { | ||
@@ -77,3 +79,3 @@ this.handleOutsideActionListeners(); | ||
onOutsideAction = (event) => { | ||
const { wrapper, widgetWrapper } = this; | ||
const { wrapper, calendarWrapper, clockWrapper } = this; | ||
@@ -86,3 +88,4 @@ // Try event.composedPath first to handle clicks inside a Shadow DOM. | ||
!wrapper.current.contains(target) && | ||
(!widgetWrapper.current || !widgetWrapper.current.contains(target)) | ||
(!calendarWrapper.current || !calendarWrapper.current.contains(target)) && | ||
(!clockWrapper.current || !clockWrapper.current.contains(target)) | ||
) { | ||
@@ -197,5 +200,10 @@ this.closeWidgets(); | ||
openClock = () => { | ||
this.setState({ | ||
isCalendarOpen: false, | ||
isClockOpen: true, | ||
this.setState((prevState) => { | ||
const nextState = { isClockOpen: true }; | ||
if (prevState.isCalendarOpen) { | ||
nextState.isCalendarOpen = false; | ||
} | ||
return nextState; | ||
}); | ||
@@ -205,5 +213,10 @@ }; | ||
openCalendar = () => { | ||
this.setState({ | ||
isCalendarOpen: true, | ||
isClockOpen: false, | ||
this.setState((prevState) => { | ||
const nextState = { isCalendarOpen: true }; | ||
if (prevState.isClockOpen) { | ||
nextState.isClockOpen = false; | ||
} | ||
return nextState; | ||
}); | ||
@@ -213,6 +226,11 @@ }; | ||
toggleCalendar = () => { | ||
this.setState((prevState) => ({ | ||
isCalendarOpen: !prevState.isCalendarOpen, | ||
isClockOpen: false, | ||
})); | ||
this.setState((prevState) => { | ||
const nextState = { isCalendarOpen: !prevState.isCalendarOpen }; | ||
if (prevState.isClockOpen) { | ||
nextState.isClockOpen = false; | ||
} | ||
return nextState; | ||
}); | ||
}; | ||
@@ -222,10 +240,13 @@ | ||
this.setState((prevState) => { | ||
if (!prevState.isCalendarOpen && !prevState.isClockOpen) { | ||
return null; | ||
const nextState = {}; | ||
if (prevState.isCalendarOpen) { | ||
nextState.isCalendarOpen = false; | ||
} | ||
return { | ||
isCalendarOpen: false, | ||
isClockOpen: false, | ||
}; | ||
if (prevState.isClockOpen) { | ||
nextState.isClockOpen = false; | ||
} | ||
return nextState; | ||
}); | ||
@@ -404,3 +425,3 @@ }; | ||
createPortal( | ||
<div ref={this.widgetWrapper} className={classNames}> | ||
<div ref={this.calendarWrapper} className={classNames}> | ||
{calendar} | ||
@@ -463,3 +484,3 @@ </div>, | ||
createPortal( | ||
<div ref={this.widgetWrapper} className={classNames}> | ||
<div ref={this.clockWrapper} className={classNames}> | ||
{clock} | ||
@@ -466,0 +487,0 @@ </div>, |
import React, { createRef } from 'react'; | ||
import { fireEvent, render, waitForElementToBeRemoved } from '@testing-library/react'; | ||
import { act, fireEvent, render, waitFor, waitForElementToBeRemoved } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import DateTimeRangePicker from './DateTimeRangePicker'; | ||
async function waitForElementToBeRemovedOrHidden(callback) { | ||
const element = callback(); | ||
if (element) { | ||
try { | ||
await waitFor(() => | ||
expect(element).toHaveAttribute('class', expect.stringContaining('--closed')), | ||
); | ||
} catch (error) { | ||
await waitForElementToBeRemoved(element); | ||
} | ||
} | ||
} | ||
describe('DateTimeRangePicker', () => { | ||
@@ -479,3 +494,3 @@ it('passes default name to DateTimeInput components', () => { | ||
it('closes Calendar component when clicked outside', () => { | ||
it('closes Calendar component when clicked outside', async () => { | ||
const root = document.createElement('div'); | ||
@@ -486,8 +501,10 @@ document.body.appendChild(root); | ||
fireEvent.mouseDown(document.body); | ||
userEvent.click(document.body); | ||
waitForElementToBeRemoved(() => container.querySelector('.react-calendar')); | ||
await waitForElementToBeRemovedOrHidden(() => | ||
container.querySelector('.react-datetime-picker__calendar'), | ||
); | ||
}); | ||
it('closes Calendar component when focused outside', () => { | ||
it('closes Calendar component when focused outside', async () => { | ||
const root = document.createElement('div'); | ||
@@ -500,6 +517,8 @@ document.body.appendChild(root); | ||
waitForElementToBeRemoved(() => container.querySelector('.react-calendar')); | ||
await waitForElementToBeRemovedOrHidden(() => | ||
container.querySelector('.react-datetimerange-picker__calendar'), | ||
); | ||
}); | ||
it('closes Calendar component when tapped outside', () => { | ||
it('closes Calendar component when tapped outside', async () => { | ||
const root = document.createElement('div'); | ||
@@ -512,6 +531,8 @@ document.body.appendChild(root); | ||
waitForElementToBeRemoved(() => container.querySelector('.react-calendar')); | ||
await waitForElementToBeRemovedOrHidden(() => | ||
container.querySelector('.react-datetimerange-picker__calendar'), | ||
); | ||
}); | ||
it('closes Clock component when clicked outside', () => { | ||
it('closes Clock component when clicked outside', async () => { | ||
const root = document.createElement('div'); | ||
@@ -522,8 +543,10 @@ document.body.appendChild(root); | ||
fireEvent.mouseDown(document.body); | ||
userEvent.click(document.body); | ||
waitForElementToBeRemoved(() => container.querySelector('.react-clock')); | ||
await waitForElementToBeRemovedOrHidden(() => | ||
container.querySelector('.react-datetimerange-picker__clock'), | ||
); | ||
}); | ||
it('closes Clock component when focused outside', () => { | ||
it('closes Clock component when focused outside', async () => { | ||
const root = document.createElement('div'); | ||
@@ -536,6 +559,8 @@ document.body.appendChild(root); | ||
waitForElementToBeRemoved(() => container.querySelector('.react-clock')); | ||
await waitForElementToBeRemovedOrHidden(() => | ||
container.querySelector('.react-datetimerange-picker__clock'), | ||
); | ||
}); | ||
it('closes Clock component when tapped outside', () => { | ||
it('closes Clock component when tapped outside', async () => { | ||
const root = document.createElement('div'); | ||
@@ -548,3 +573,5 @@ document.body.appendChild(root); | ||
waitForElementToBeRemoved(() => container.querySelector('.react-clock')); | ||
await waitForElementToBeRemovedOrHidden(() => | ||
container.querySelector('.react-datetimerange-picker__clock'), | ||
); | ||
}); | ||
@@ -567,3 +594,3 @@ | ||
it('does not close Clock component when focused within time inputs', () => { | ||
it('does not close Clock component when focused within time inputs', async () => { | ||
const { container } = render(<DateTimeRangePicker isClockOpen />); | ||
@@ -578,3 +605,5 @@ | ||
waitForElementToBeRemoved(() => container.querySelector('.react-calendar')); | ||
await waitForElementToBeRemovedOrHidden(() => | ||
container.querySelector('.react-datetimerange-picker__calendar'), | ||
); | ||
@@ -586,3 +615,3 @@ const clock = container.querySelector('.react-clock'); | ||
it('closes Clock when Calendar is opened by a click on the calendar icon', () => { | ||
it('closes Clock when Calendar is opened by a click on the calendar icon', async () => { | ||
const { container } = render(<DateTimeRangePicker isClockOpen />); | ||
@@ -597,6 +626,8 @@ | ||
waitForElementToBeRemoved(() => container.querySelector('.react-clock')); | ||
await waitForElementToBeRemovedOrHidden(() => | ||
container.querySelector('.react-datetimerange-picker__clock'), | ||
); | ||
}); | ||
it('closes Calendar when calling internal onChange by default', () => { | ||
it('closes Calendar when calling internal onChange by default', async () => { | ||
const instance = createRef(); | ||
@@ -606,7 +637,11 @@ | ||
const { onChange } = instance.current; | ||
const { onChange: onChangeInternal } = instance.current; | ||
onChange(new Date()); | ||
act(() => { | ||
onChangeInternal(new Date()); | ||
}); | ||
waitForElementToBeRemoved(() => container.querySelector('.react-calendar')); | ||
await waitForElementToBeRemovedOrHidden(() => | ||
container.querySelector('.react-datetimerange-picker__calendar'), | ||
); | ||
}); | ||
@@ -621,5 +656,7 @@ | ||
const { onChange } = instance.current; | ||
const { onChange: onChangeInternal } = instance.current; | ||
onChange(new Date()); | ||
act(() => { | ||
onChangeInternal(new Date()); | ||
}); | ||
@@ -636,5 +673,7 @@ const calendar = container.querySelector('.react-calendar'); | ||
const { onChange } = instance.current; | ||
const { onChange: onChangeInternal } = instance.current; | ||
onChange(new Date(), false); | ||
act(() => { | ||
onChangeInternal(new Date(), false); | ||
}); | ||
@@ -646,3 +685,3 @@ const calendar = container.querySelector('.react-calendar'); | ||
it('closes Clock when calling internal onChange by default', () => { | ||
it('closes Clock when calling internal onChange by default', async () => { | ||
const instance = createRef(); | ||
@@ -652,7 +691,11 @@ | ||
const { onChange } = instance.current; | ||
const { onChange: onChangeInternal } = instance.current; | ||
onChange(new Date()); | ||
act(() => { | ||
onChangeInternal(new Date()); | ||
}); | ||
waitForElementToBeRemoved(() => container.querySelector('.react-clock')); | ||
await waitForElementToBeRemovedOrHidden(() => | ||
container.querySelector('.react-datetimerange-picker__clock'), | ||
); | ||
}); | ||
@@ -667,5 +710,7 @@ | ||
const { onChange } = instance.current; | ||
const { onChange: onChangeInternal } = instance.current; | ||
onChange(new Date()); | ||
act(() => { | ||
onChangeInternal(new Date()); | ||
}); | ||
@@ -682,5 +727,7 @@ const clock = container.querySelector('.react-clock'); | ||
const { onChange } = instance.current; | ||
const { onChange: onChangeInternal } = instance.current; | ||
onChange(new Date(), false); | ||
act(() => { | ||
onChangeInternal(new Date(), false); | ||
}); | ||
@@ -701,3 +748,5 @@ const clock = container.querySelector('.react-clock'); | ||
onChangeInternal(nextValue); | ||
act(() => { | ||
onChangeInternal(nextValue); | ||
}); | ||
@@ -721,5 +770,7 @@ expect(onChange).toHaveBeenCalledWith(nextValue); | ||
const { onDateChange } = instance.current; | ||
const { onDateChange: onDateChangeInternal } = instance.current; | ||
onDateChange([nextValueFrom, valueTo]); | ||
act(() => { | ||
onDateChangeInternal([nextValueFrom, valueTo]); | ||
}); | ||
@@ -746,5 +797,7 @@ expect(onChange).toHaveBeenCalledWith([ | ||
const { onDateChange } = instance.current; | ||
const { onDateChange: onDateChangeInternal } = instance.current; | ||
onDateChange([valueFrom, nextValueTo]); | ||
act(() => { | ||
onDateChangeInternal([valueFrom, nextValueTo]); | ||
}); | ||
@@ -768,3 +821,5 @@ expect(onChange).toHaveBeenCalledWith([ | ||
onChangeInternal(nextValue); | ||
act(() => { | ||
onChangeInternal(nextValue); | ||
}); | ||
@@ -796,2 +851,3 @@ expect(onChange).toHaveBeenCalledWith(nextValue); | ||
const componentInstance = instance.current; | ||
const { onChangeFrom: onChangeFromInternal } = componentInstance; | ||
@@ -801,4 +857,7 @@ const onChangeSpy = jest.spyOn(componentInstance, 'onChange'); | ||
const nextValueFrom = new Date(); | ||
componentInstance.onChangeFrom(nextValueFrom); | ||
act(() => { | ||
onChangeFromInternal(nextValueFrom); | ||
}); | ||
expect(onChangeSpy).toHaveBeenCalled(); | ||
@@ -815,2 +874,3 @@ expect(onChangeSpy).toHaveBeenCalledWith([nextValueFrom, undefined], undefined); | ||
const componentInstance = instance.current; | ||
const { onChangeFrom: onChangeFromInternal } = componentInstance; | ||
@@ -820,4 +880,7 @@ const onChangeSpy = jest.spyOn(componentInstance, 'onChange'); | ||
const nextValueFrom = new Date(); | ||
componentInstance.onChangeFrom(nextValueFrom); | ||
act(() => { | ||
onChangeFromInternal(nextValueFrom); | ||
}); | ||
expect(onChangeSpy).toHaveBeenCalled(); | ||
@@ -836,2 +899,3 @@ expect(onChangeSpy).toHaveBeenCalledWith([nextValueFrom, undefined], undefined); | ||
const componentInstance = instance.current; | ||
const { onChangeFrom: onChangeFromInternal } = componentInstance; | ||
@@ -841,4 +905,7 @@ const onChangeSpy = jest.spyOn(componentInstance, 'onChange'); | ||
const nextValueFrom = new Date(); | ||
componentInstance.onChangeFrom(nextValueFrom); | ||
act(() => { | ||
onChangeFromInternal(nextValueFrom); | ||
}); | ||
expect(onChangeSpy).toHaveBeenCalled(); | ||
@@ -856,2 +923,3 @@ expect(onChangeSpy).toHaveBeenCalledWith([nextValueFrom, valueTo], undefined); | ||
const componentInstance = instance.current; | ||
const { onChangeTo: onChangeToInternal } = componentInstance; | ||
@@ -861,4 +929,7 @@ const onChangeSpy = jest.spyOn(componentInstance, 'onChange'); | ||
const nextValueTo = new Date(); | ||
componentInstance.onChangeTo(nextValueTo); | ||
act(() => { | ||
onChangeToInternal(nextValueTo); | ||
}); | ||
expect(onChangeSpy).toHaveBeenCalled(); | ||
@@ -875,2 +946,3 @@ expect(onChangeSpy).toHaveBeenCalledWith([undefined, nextValueTo], undefined); | ||
const componentInstance = instance.current; | ||
const { onChangeTo: onChangeToInternal } = componentInstance; | ||
@@ -880,4 +952,7 @@ const onChangeSpy = jest.spyOn(componentInstance, 'onChange'); | ||
const nextValueTo = new Date(); | ||
componentInstance.onChangeTo(nextValueTo); | ||
act(() => { | ||
onChangeToInternal(nextValueTo); | ||
}); | ||
expect(onChangeSpy).toHaveBeenCalled(); | ||
@@ -896,2 +971,3 @@ expect(onChangeSpy).toHaveBeenCalledWith([value, nextValueTo], undefined); | ||
const componentInstance = instance.current; | ||
const { onChangeTo: onChangeToInternal } = componentInstance; | ||
@@ -901,4 +977,7 @@ const onChangeSpy = jest.spyOn(componentInstance, 'onChange'); | ||
const nextValueTo = new Date(); | ||
componentInstance.onChangeTo(nextValueTo); | ||
act(() => { | ||
onChangeToInternal(nextValueTo); | ||
}); | ||
expect(onChangeSpy).toHaveBeenCalled(); | ||
@@ -905,0 +984,0 @@ expect(onChangeSpy).toHaveBeenCalledWith([valueFrom, nextValueTo], undefined); |
122305
1988
18