From e2fa8c75c1ad5bd39b7cc6aaba62cb85cbceaa08 Mon Sep 17 00:00:00 2001 From: alexandru-morariu-lgp Date: Tue, 3 Dec 2024 16:40:31 +0200 Subject: [PATCH 1/5] Changed DateTimeDecorator to a functional component. --- internal/DateTime/DateTimeDecorator.js | 533 +++++++++++++++++-------- 1 file changed, 367 insertions(+), 166 deletions(-) diff --git a/internal/DateTime/DateTimeDecorator.js b/internal/DateTime/DateTimeDecorator.js index a8a5c2dee2..0f53faefcb 100644 --- a/internal/DateTime/DateTimeDecorator.js +++ b/internal/DateTime/DateTimeDecorator.js @@ -13,7 +13,7 @@ import Spotlight from '@enact/spotlight'; import Changeable from '@enact/ui/Changeable'; import DateFactory from 'ilib/lib/DateFactory'; import PropTypes from 'prop-types'; -import {Component} from 'react'; +import {Component, useEffect, useState} from 'react'; /* * Converts a JavaScript Date to unix time @@ -47,104 +47,237 @@ const DateTimeDecorator = hoc((config, Wrapped) => { return null; }); - const Decorator = class extends Component { - static displayName = 'DateTimeDecorator'; - - static propTypes = /** @lends sandstone/internal/DateTimeDecorator.DateTimeDecorator.prototype */ { - /** - * The current locale as a - * {@link https://tools.ietf.org/html/rfc5646|BCP 47 language tag}. - * - * @type {String} - * @public - */ - locale: PropTypes.string, - - /** - * Handler for `onChange` events - * - * @type {Function} - * @public - */ - onChange: PropTypes.func, - - /** - * Handler for `onComplete` event - * - * @type {Function} - * @public - */ - onComplete: PropTypes.func, - - /** - * When `true`, the date picker is expanded to select a new date. - * - * @type {Boolean} - * @public - */ - open: PropTypes.bool, - - /** - * Indicates the content's text direction is right-to-left. - * - * @type {Boolean} - * @private - */ - rtl: PropTypes.bool, - - /** - * The selected date - * - * @type {Date} - * @public - */ - value: PropTypes.instanceOf(Date) + // const Decorator = class extends Component { + // static displayName = 'DateTimeDecorator'; + // + // static propTypes = /** @lends sandstone/internal/DateTimeDecorator.DateTimeDecorator.prototype */ { + // /** + // * The current locale as a + // * {@link https://tools.ietf.org/html/rfc5646|BCP 47 language tag}. + // * + // * @type {String} + // * @public + // */ + // locale: PropTypes.string, + // + // /** + // * Handler for `onChange` events + // * + // * @type {Function} + // * @public + // */ + // onChange: PropTypes.func, + // + // /** + // * Handler for `onComplete` event + // * + // * @type {Function} + // * @public + // */ + // onComplete: PropTypes.func, + // + // /** + // * When `true`, the date picker is expanded to select a new date. + // * + // * @type {Boolean} + // * @public + // */ + // open: PropTypes.bool, + // + // /** + // * Indicates the content's text direction is right-to-left. + // * + // * @type {Boolean} + // * @private + // */ + // rtl: PropTypes.bool, + // + // /** + // * The selected date + // * + // * @type {Date} + // * @public + // */ + // value: PropTypes.instanceOf(Date) + // }; + // + // constructor (props) { + // super(props); + // + // this.state = { + // initialValue: null, + // value: null + // }; + // + // const newValue = toTime(this.props.value); + // const value = newValue || Date.now(); + // + // // if no value was provided, we need to emit the onChange event for the generated value + // if (!newValue) { + // this.emitChange(this.toIDate(value)); + // } + // + // this.handlers = {}; + // if (handlers) { + // Object.keys(handlers).forEach(name => { + // this.handlers[name] = this.handlePickerChange.bind(this, handlers[name]); + // }); + // } + // } + // + // static getDerivedStateFromProps (props, state) { + // let value = toTime(props.value); + // + // if (props.open && !props.disabled && state.initialValue == null && state.value == null) { + // // when the expandable opens, we cache the prop value so it can be restored on + // // cancel and set value to be the current time if unset in order to initialize the + // // pickers + // return { + // initialValue: value, + // value: value || Date.now() + // }; + // } else if (state.value !== value) { + // // always respect a value change from props + // return { + // value + // }; + // } + // + // return null; + // } + // + // /** + // * Converts a Date to an IDate + // * + // * @param {Date} time Date object + // * + // * @returns {IDate} ilib Date object + // */ + // toIDate (time) { + // if (time && this.props.locale) { + // return DateFactory({ + // unixtime: time, + // timezone: 'local' + // }); + // } + // } + // + // /** + // * Updates the internal value in state + // * + // * @param {IDate} value ilib Date object + // * + // * @returns {Number} Updated internal value + // */ + // updateValue = (value) => { + // const {day, month, year} = value; + // const maxDays = value.cal.getMonLength(month, year); + // value.day = (day <= maxDays) ? day : maxDays; + // + // const date = DateFactory(value); + // const newValue = date.getTimeExtended(); + // const changed = this.props.value == null || this.props.value !== newValue; + // + // this.setState({ + // value: newValue + // }); + // + // if (changed) { + // this.emitChange(date); + // } + // + // return newValue; + // }; + // + // emitChange = (date) => { + // forwardCustom('onChange', () => ({value: date ? date.getJSDate() : null}))(null, this.props); + // }; + // + // handlePickerChange = (handler, ev) => { + // const value = this.toIDate(this.state.value); + // handler(ev, value, memoizedI18nConfig(this.props.locale)); + // this.updateValue(value); + // }; + // + // handleCancel = () => { + // const {initialValue, value} = this.state; + // + // // if we're cancelling, reset our state and emit an onChange with the initial value + // this.setState({ + // value: null, + // initialValue: null, + // pickerValue: value + // }); + // + // if (initialValue !== value) { + // this.emitChange(this.toIDate(initialValue)); + // } + // }; + // + // handleEnter = (ev) => { + // if (ev.target && ev.target.dataset.lastElement === 'true') { + // const value = this.state.value ? this.toIDate(this.state.value) : null; + // + // forwardCustom('onComplete', () => ({value: value ? value.getJSDate() : null}))(null, this.props); + // } else { + // Spotlight.move(this.props.rtl ? 'left' : 'right'); + // } + // }; + // + // handleKeyDown = handle( + // forward('onKeyDown'), + // forKey('enter'), + // forProp('disabled', false), + // call('handleEnter') + // ).bindAs(this, 'handleKeyDown'); + // + // render () { + // const value = this.toIDate(this.state.value); + // // pickerValue is only set when cancelling to prevent the unexpected changing of the + // // picker values before closing. + // const pickerValue = this.state.pickerValue ? this.toIDate(this.state.pickerValue) : value; + // + // let label = null; + // let props = null; + // let order = defaultOrder; + // + // const i18nConfig = memoizedI18nConfig(this.props.locale); + // if (i18nConfig) { + // if (value) { + // label = i18nConfig.formatter.format(value); + // } + // props = customProps(i18nConfig, pickerValue, this.props); + // order = i18nConfig.order; + // } + // + // const rest = Object.assign({}, this.props); + // delete rest.onComplete; + // + // return ( + // + // ); + // } + // }; + + const Decorator = (props) => { + const newValue = toTime(props.value); + + const [initialValue, setInitialValue] = useState(null); + const [value, setValue] = useState(newValue || Date.now()); + const [pickerValue, setPickerValue] = useState(null); + + const emitChange = (date) => { + forwardCustom('onChange', () => ({value: date ? date.getJSDate() : null}))(null, props); }; - constructor (props) { - super(props); - - this.state = { - initialValue: null, - value: null - }; - - const newValue = toTime(this.props.value); - const value = newValue || Date.now(); - - // if no value was provided, we need to emit the onChange event for the generated value - if (!newValue) { - this.emitChange(this.toIDate(value)); - } - - this.handlers = {}; - if (handlers) { - Object.keys(handlers).forEach(name => { - this.handlers[name] = this.handlePickerChange.bind(this, handlers[name]); - }); - } - } - - static getDerivedStateFromProps (props, state) { - let value = toTime(props.value); - - if (props.open && !props.disabled && state.initialValue == null && state.value == null) { - // when the expandable opens, we cache the prop value so it can be restored on - // cancel and set value to be the current time if unset in order to initialize the - // pickers - return { - initialValue: value, - value: value || Date.now() - }; - } else if (state.value !== value) { - // always respect a value change from props - return { - value - }; - } - - return null; - } /** * Converts a Date to an IDate @@ -153,8 +286,8 @@ const DateTimeDecorator = hoc((config, Wrapped) => { * * @returns {IDate} ilib Date object */ - toIDate (time) { - if (time && this.props.locale) { + const toIDate = (time) => { + if (time && props.locale) { return DateFactory({ unixtime: time, timezone: 'local' @@ -162,6 +295,39 @@ const DateTimeDecorator = hoc((config, Wrapped) => { } } + // if no value was provided, we need to emit the onChange event for the generated value + if (!newValue) { + emitChange(toIDate(value)); + } + + const handlePickerChange = (handler, ev) => { + const newValue = toIDate(value); + handler(ev, newValue, memoizedI18nConfig(props.locale)); + updateValue(newValue); + }; + + const localHandlers = {}; + if (handlers) { + Object.keys(handlers).forEach(name => { + localHandlers[name] = handlePickerChange.bind(this, handlers[name]); + }); + } + + useEffect(() => { + let newValue = toTime(props.value); + + if (props.open && !props.disabled && initialValue == null && value == null) { + // when the expandable opens, we cache the prop value so it can be restored on + // cancel and set value to be the current time if unset in order to initialize the + // pickers + setInitialValue(newValue); + setValue(newValue || Date.now()); + } else if (value !== newValue) { + // always respect a value change from props + setValue(newValue); + } + }, [props]); + /** * Updates the internal value in state * @@ -169,102 +335,137 @@ const DateTimeDecorator = hoc((config, Wrapped) => { * * @returns {Number} Updated internal value */ - updateValue = (value) => { + const updateValue = (value) => { const {day, month, year} = value; const maxDays = value.cal.getMonLength(month, year); value.day = (day <= maxDays) ? day : maxDays; const date = DateFactory(value); const newValue = date.getTimeExtended(); - const changed = this.props.value == null || this.props.value !== newValue; + const changed = props.value == null || props.value !== newValue; - this.setState({ - value: newValue - }); + setValue(newValue); if (changed) { - this.emitChange(date); + emitChange(date); } return newValue; }; - emitChange = (date) => { - forwardCustom('onChange', () => ({value: date ? date.getJSDate() : null}))(null, this.props); - }; - - handlePickerChange = (handler, ev) => { - const value = this.toIDate(this.state.value); - handler(ev, value, memoizedI18nConfig(this.props.locale)); - this.updateValue(value); - }; - - handleCancel = () => { - const {initialValue, value} = this.state; + const handleCancel = () => { // if we're cancelling, reset our state and emit an onChange with the initial value - this.setState({ - value: null, - initialValue: null, - pickerValue: value - }); + setValue(null); + setInitialValue(null); + setPickerValue(value); if (initialValue !== value) { - this.emitChange(this.toIDate(initialValue)); + emitChange(toIDate(initialValue)); } }; - handleEnter = (ev) => { + const handleEnter = (ev) => { if (ev.target && ev.target.dataset.lastElement === 'true') { - const value = this.state.value ? this.toIDate(this.state.value) : null; + const newValue = value ? toIDate(value) : null; - forwardCustom('onComplete', () => ({value: value ? value.getJSDate() : null}))(null, this.props); + forwardCustom('onComplete', () => ({value: newValue ? newValue.getJSDate() : null}))(null, props); } else { - Spotlight.move(this.props.rtl ? 'left' : 'right'); + Spotlight.move(props.rtl ? 'left' : 'right'); } }; - handleKeyDown = handle( - forward('onKeyDown'), - forKey('enter'), - forProp('disabled', false), - call('handleEnter') - ).bindAs(this, 'handleKeyDown'); - - render () { - const value = this.toIDate(this.state.value); - // pickerValue is only set when cancelling to prevent the unexpected changing of the - // picker values before closing. - const pickerValue = this.state.pickerValue ? this.toIDate(this.state.pickerValue) : value; - - let label = null; - let props = null; - let order = defaultOrder; - - const i18nConfig = memoizedI18nConfig(this.props.locale); - if (i18nConfig) { - if (value) { - label = i18nConfig.formatter.format(value); - } - props = customProps(i18nConfig, pickerValue, this.props); - order = i18nConfig.order; - } + const handleKeyDown = (ev) => { + forward('onKeyDown'); + forKey('enter'); + forProp('disabled', false); + handleEnter(ev); + }; - const rest = Object.assign({}, this.props); - delete rest.onComplete; - - return ( - - ); + const finalValue = toIDate(value); + // pickerValue is only set when cancelling to prevent the unexpected changing of the + // picker values before closing. + const finalPickerValue = pickerValue ? toIDate(pickerValue) : finalValue; + + let label = null; + let finalProps = null; + let order = defaultOrder; + + const i18nConfig = memoizedI18nConfig(props.locale); + if (i18nConfig) { + if (finalValue) { + label = i18nConfig.formatter.format(finalValue); + } + finalProps = customProps(i18nConfig, finalPickerValue, props); + order = i18nConfig.order; } + + const rest = Object.assign({}, props); + delete rest.onComplete; + + return ( + + ); + }; + + Decorator.displayName = 'DateTimeDecorator'; + Decorator.propTypes = /** @lends sandstone/internal/DateTimeDecorator.DateTimeDecorator.prototype */ { + /** + * The current locale as a + * {@link https://tools.ietf.org/html/rfc5646|BCP 47 language tag}. + * + * @type {String} + * @public + */ + locale: PropTypes.string, + + /** + * Handler for `onChange` events + * + * @type {Function} + * @public + */ + onChange: PropTypes.func, + + /** + * Handler for `onComplete` event + * + * @type {Function} + * @public + */ + onComplete: PropTypes.func, + + /** + * When `true`, the date picker is expanded to select a new date. + * + * @type {Boolean} + * @public + */ + open: PropTypes.bool, + + /** + * Indicates the content's text direction is right-to-left. + * + * @type {Boolean} + * @private + */ + rtl: PropTypes.bool, + + /** + * The selected date + * + * @type {Date} + * @public + */ + value: PropTypes.instanceOf(Date) }; return I18nContextDecorator( From b4ed6ceca5e6637b74271a44f267aed8f7720871 Mon Sep 17 00:00:00 2001 From: alexandru-morariu-lgp Date: Wed, 11 Dec 2024 15:47:23 +0200 Subject: [PATCH 2/5] Migrate internal/DateTime/DateTimeDecorator from class to functional component. --- internal/DateTime/DateTimeDecorator.js | 330 +++++-------------------- 1 file changed, 57 insertions(+), 273 deletions(-) diff --git a/internal/DateTime/DateTimeDecorator.js b/internal/DateTime/DateTimeDecorator.js index 0f53faefcb..e8f248149b 100644 --- a/internal/DateTime/DateTimeDecorator.js +++ b/internal/DateTime/DateTimeDecorator.js @@ -5,15 +5,16 @@ * @private */ -import handle, {call, forKey, forProp, forward, forwardCustom} from '@enact/core/handle'; +import {forKey, forProp, forward, forwardCustom} from '@enact/core/handle'; import hoc from '@enact/core/hoc'; +import {is} from '@enact/core/keymap'; import {memoize} from '@enact/core/util'; import {I18nContextDecorator} from '@enact/i18n/I18nDecorator'; import Spotlight from '@enact/spotlight'; import Changeable from '@enact/ui/Changeable'; import DateFactory from 'ilib/lib/DateFactory'; import PropTypes from 'prop-types'; -import {Component, useEffect, useState} from 'react'; +import {useCallback, useEffect, useState} from 'react'; /* * Converts a JavaScript Date to unix time @@ -26,6 +27,8 @@ const toTime = (date) => { return date && date.getTime(); }; +const isEnter = is('enter'); + /** * {@link sandstone/internal/DateTimeDecorator.DateTimeDecorator} provides common behavior for * {@link sandstone/DatePicker.DatePicker} and {@link sandstone/TimePicker.TimePicker}. @@ -47,226 +50,6 @@ const DateTimeDecorator = hoc((config, Wrapped) => { return null; }); - // const Decorator = class extends Component { - // static displayName = 'DateTimeDecorator'; - // - // static propTypes = /** @lends sandstone/internal/DateTimeDecorator.DateTimeDecorator.prototype */ { - // /** - // * The current locale as a - // * {@link https://tools.ietf.org/html/rfc5646|BCP 47 language tag}. - // * - // * @type {String} - // * @public - // */ - // locale: PropTypes.string, - // - // /** - // * Handler for `onChange` events - // * - // * @type {Function} - // * @public - // */ - // onChange: PropTypes.func, - // - // /** - // * Handler for `onComplete` event - // * - // * @type {Function} - // * @public - // */ - // onComplete: PropTypes.func, - // - // /** - // * When `true`, the date picker is expanded to select a new date. - // * - // * @type {Boolean} - // * @public - // */ - // open: PropTypes.bool, - // - // /** - // * Indicates the content's text direction is right-to-left. - // * - // * @type {Boolean} - // * @private - // */ - // rtl: PropTypes.bool, - // - // /** - // * The selected date - // * - // * @type {Date} - // * @public - // */ - // value: PropTypes.instanceOf(Date) - // }; - // - // constructor (props) { - // super(props); - // - // this.state = { - // initialValue: null, - // value: null - // }; - // - // const newValue = toTime(this.props.value); - // const value = newValue || Date.now(); - // - // // if no value was provided, we need to emit the onChange event for the generated value - // if (!newValue) { - // this.emitChange(this.toIDate(value)); - // } - // - // this.handlers = {}; - // if (handlers) { - // Object.keys(handlers).forEach(name => { - // this.handlers[name] = this.handlePickerChange.bind(this, handlers[name]); - // }); - // } - // } - // - // static getDerivedStateFromProps (props, state) { - // let value = toTime(props.value); - // - // if (props.open && !props.disabled && state.initialValue == null && state.value == null) { - // // when the expandable opens, we cache the prop value so it can be restored on - // // cancel and set value to be the current time if unset in order to initialize the - // // pickers - // return { - // initialValue: value, - // value: value || Date.now() - // }; - // } else if (state.value !== value) { - // // always respect a value change from props - // return { - // value - // }; - // } - // - // return null; - // } - // - // /** - // * Converts a Date to an IDate - // * - // * @param {Date} time Date object - // * - // * @returns {IDate} ilib Date object - // */ - // toIDate (time) { - // if (time && this.props.locale) { - // return DateFactory({ - // unixtime: time, - // timezone: 'local' - // }); - // } - // } - // - // /** - // * Updates the internal value in state - // * - // * @param {IDate} value ilib Date object - // * - // * @returns {Number} Updated internal value - // */ - // updateValue = (value) => { - // const {day, month, year} = value; - // const maxDays = value.cal.getMonLength(month, year); - // value.day = (day <= maxDays) ? day : maxDays; - // - // const date = DateFactory(value); - // const newValue = date.getTimeExtended(); - // const changed = this.props.value == null || this.props.value !== newValue; - // - // this.setState({ - // value: newValue - // }); - // - // if (changed) { - // this.emitChange(date); - // } - // - // return newValue; - // }; - // - // emitChange = (date) => { - // forwardCustom('onChange', () => ({value: date ? date.getJSDate() : null}))(null, this.props); - // }; - // - // handlePickerChange = (handler, ev) => { - // const value = this.toIDate(this.state.value); - // handler(ev, value, memoizedI18nConfig(this.props.locale)); - // this.updateValue(value); - // }; - // - // handleCancel = () => { - // const {initialValue, value} = this.state; - // - // // if we're cancelling, reset our state and emit an onChange with the initial value - // this.setState({ - // value: null, - // initialValue: null, - // pickerValue: value - // }); - // - // if (initialValue !== value) { - // this.emitChange(this.toIDate(initialValue)); - // } - // }; - // - // handleEnter = (ev) => { - // if (ev.target && ev.target.dataset.lastElement === 'true') { - // const value = this.state.value ? this.toIDate(this.state.value) : null; - // - // forwardCustom('onComplete', () => ({value: value ? value.getJSDate() : null}))(null, this.props); - // } else { - // Spotlight.move(this.props.rtl ? 'left' : 'right'); - // } - // }; - // - // handleKeyDown = handle( - // forward('onKeyDown'), - // forKey('enter'), - // forProp('disabled', false), - // call('handleEnter') - // ).bindAs(this, 'handleKeyDown'); - // - // render () { - // const value = this.toIDate(this.state.value); - // // pickerValue is only set when cancelling to prevent the unexpected changing of the - // // picker values before closing. - // const pickerValue = this.state.pickerValue ? this.toIDate(this.state.pickerValue) : value; - // - // let label = null; - // let props = null; - // let order = defaultOrder; - // - // const i18nConfig = memoizedI18nConfig(this.props.locale); - // if (i18nConfig) { - // if (value) { - // label = i18nConfig.formatter.format(value); - // } - // props = customProps(i18nConfig, pickerValue, this.props); - // order = i18nConfig.order; - // } - // - // const rest = Object.assign({}, this.props); - // delete rest.onComplete; - // - // return ( - // - // ); - // } - // }; - const Decorator = (props) => { const newValue = toTime(props.value); @@ -286,24 +69,51 @@ const DateTimeDecorator = hoc((config, Wrapped) => { * * @returns {IDate} ilib Date object */ - const toIDate = (time) => { + const toIDate = useCallback((time) => { if (time && props.locale) { return DateFactory({ unixtime: time, timezone: 'local' }); } - } + }, [props.locale]); // if no value was provided, we need to emit the onChange event for the generated value - if (!newValue) { - emitChange(toIDate(value)); - } + useEffect(() => { + if (!newValue) { + emitChange(toIDate(value)); + } + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + /** + * Updates the internal value in state + * + * @param {IDate} updatedValue ilib Date object + * + * @returns {Number} Updated internal value + */ + const updateValue = (updatedValue) => { + const {day, month, year} = updatedValue; + const maxDays = updatedValue.cal.getMonLength(month, year); + updatedValue.day = (day <= maxDays) ? day : maxDays; + + const date = DateFactory(updatedValue); + const newUpdateValue = date.getTimeExtended(); + const changed = props.value == null || props.value !== newUpdateValue; + + setValue(newUpdateValue); + + if (changed) { + emitChange(date); + } + + return newUpdateValue; + }; const handlePickerChange = (handler, ev) => { - const newValue = toIDate(value); - handler(ev, newValue, memoizedI18nConfig(props.locale)); - updateValue(newValue); + const changedValue = toIDate(value); + handler(ev, changedValue, memoizedI18nConfig(props.locale)); + updateValue(changedValue); }; const localHandlers = {}; @@ -314,73 +124,47 @@ const DateTimeDecorator = hoc((config, Wrapped) => { } useEffect(() => { - let newValue = toTime(props.value); + let newestValue = toTime(props.value); if (props.open && !props.disabled && initialValue == null && value == null) { // when the expandable opens, we cache the prop value so it can be restored on // cancel and set value to be the current time if unset in order to initialize the // pickers - setInitialValue(newValue); - setValue(newValue || Date.now()); - } else if (value !== newValue) { + setInitialValue(newestValue); + setValue(newestValue || Date.now()); + } else if (value !== newestValue) { // always respect a value change from props - setValue(newValue); + setValue(newestValue); } - }, [props]); - - /** - * Updates the internal value in state - * - * @param {IDate} value ilib Date object - * - * @returns {Number} Updated internal value - */ - const updateValue = (value) => { - const {day, month, year} = value; - const maxDays = value.cal.getMonLength(month, year); - value.day = (day <= maxDays) ? day : maxDays; - - const date = DateFactory(value); - const newValue = date.getTimeExtended(); - const changed = props.value == null || props.value !== newValue; - - setValue(newValue); + }, [initialValue, props, value]); - if (changed) { - emitChange(date); - } - - return newValue; - }; - - - const handleCancel = () => { + const handleCancel = () => { // eslint-disable-line no-unused-vars // if we're cancelling, reset our state and emit an onChange with the initial value - setValue(null); - setInitialValue(null); - setPickerValue(value); + setValue(null); + setInitialValue(null); + setPickerValue(value); if (initialValue !== value) { emitChange(toIDate(initialValue)); } }; - const handleEnter = (ev) => { + const handleEnter = useCallback((ev) => { if (ev.target && ev.target.dataset.lastElement === 'true') { - const newValue = value ? toIDate(value) : null; + const newestValue = value ? toIDate(value) : null; - forwardCustom('onComplete', () => ({value: newValue ? newValue.getJSDate() : null}))(null, props); + forwardCustom('onComplete', () => ({value: newestValue ? newestValue.getJSDate() : null}))(null, props); } else { Spotlight.move(props.rtl ? 'left' : 'right'); } - }; + }, [props, toIDate, value]); - const handleKeyDown = (ev) => { + const handleKeyDown = useCallback((ev) => { forward('onKeyDown'); forKey('enter'); forProp('disabled', false); - handleEnter(ev); - }; + if (isEnter(ev.keyCode)) handleEnter(ev); + }, [handleEnter]); const finalValue = toIDate(value); // pickerValue is only set when cancelling to prevent the unexpected changing of the From eadd90ccb2fa5b55c08b82e6f4cf18952e04ba9d Mon Sep 17 00:00:00 2001 From: alexandru-morariu-lgp Date: Wed, 11 Dec 2024 16:01:13 +0200 Subject: [PATCH 3/5] Small fixes. --- internal/DateTime/DateTimeDecorator.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/DateTime/DateTimeDecorator.js b/internal/DateTime/DateTimeDecorator.js index e8f248149b..44b345cad7 100644 --- a/internal/DateTime/DateTimeDecorator.js +++ b/internal/DateTime/DateTimeDecorator.js @@ -52,7 +52,6 @@ const DateTimeDecorator = hoc((config, Wrapped) => { const Decorator = (props) => { const newValue = toTime(props.value); - const [initialValue, setInitialValue] = useState(null); const [value, setValue] = useState(newValue || Date.now()); const [pickerValue, setPickerValue] = useState(null); @@ -61,8 +60,7 @@ const DateTimeDecorator = hoc((config, Wrapped) => { forwardCustom('onChange', () => ({value: date ? date.getJSDate() : null}))(null, props); }; - - /** + /* * Converts a Date to an IDate * * @param {Date} time Date object @@ -85,7 +83,7 @@ const DateTimeDecorator = hoc((config, Wrapped) => { } }, []); // eslint-disable-line react-hooks/exhaustive-deps - /** + /* * Updates the internal value in state * * @param {IDate} updatedValue ilib Date object From 73995b5c2e53c3616ad70a514d14e2c63ef5a288 Mon Sep 17 00:00:00 2001 From: Daniel Stoian <63335068+daniel-stoian-lgp@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:41:23 +0200 Subject: [PATCH 4/5] Update internal/DateTime/DateTimeDecorator.js --- internal/DateTime/DateTimeDecorator.js | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/DateTime/DateTimeDecorator.js b/internal/DateTime/DateTimeDecorator.js index 44b345cad7..97697fdbb8 100644 --- a/internal/DateTime/DateTimeDecorator.js +++ b/internal/DateTime/DateTimeDecorator.js @@ -199,6 +199,7 @@ const DateTimeDecorator = hoc((config, Wrapped) => { }; Decorator.displayName = 'DateTimeDecorator'; + Decorator.propTypes = /** @lends sandstone/internal/DateTimeDecorator.DateTimeDecorator.prototype */ { /** * The current locale as a From be8d93bc21a8cac2e16791565fc478afae55b024 Mon Sep 17 00:00:00 2001 From: Daniel Stoian Date: Thu, 12 Dec 2024 15:07:13 +0200 Subject: [PATCH 5/5] fixed lint warning --- internal/DateTime/DateTimeDecorator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/DateTime/DateTimeDecorator.js b/internal/DateTime/DateTimeDecorator.js index 97697fdbb8..05b772f424 100644 --- a/internal/DateTime/DateTimeDecorator.js +++ b/internal/DateTime/DateTimeDecorator.js @@ -199,7 +199,7 @@ const DateTimeDecorator = hoc((config, Wrapped) => { }; Decorator.displayName = 'DateTimeDecorator'; - + Decorator.propTypes = /** @lends sandstone/internal/DateTimeDecorator.DateTimeDecorator.prototype */ { /** * The current locale as a