From fcb7e6ab5e83be30560d5f7335127bcc2aa61e1f Mon Sep 17 00:00:00 2001 From: Juwon Jeong Date: Thu, 29 Aug 2024 12:52:21 +0900 Subject: [PATCH] WRQ-31515: Fixed Scroller, VirtualList, and VirtualGridList to set prop value to default when undefined is passed for the prop value (#3268) * WRQ-31515: Fixed Scroller and VirtualList to set prop value to default value when undefined is passed for the prop value Enact-DCO-1.0-Signed-off-by: Juwon Jeong (juwon.jeong@lge.com) * Added unit test Enact-DCO-1.0-Signed-off-by: Juwon Jeong (juwon.jeong@lge.com) * Apply review Enact-DCO-1.0-Signed-off-by: Juwon Jeong (juwon.jeong@lge.com) --- packages/core/CHANGELOG.md | 6 ++++++ packages/core/util/tests/util-specs.js | 28 +++++++++++++++++++++++++- packages/core/util/util.js | 25 +++++++++++++++++++++++ packages/ui/CHANGELOG.md | 1 + packages/ui/Scroller/Scroller.js | 3 ++- packages/ui/VirtualList/VirtualList.js | 5 +++-- 6 files changed, 64 insertions(+), 4 deletions(-) diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index c14744238f..18b6553a9e 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -2,6 +2,12 @@ The following is a curated list of changes in the Enact core module, newest changes on the top. +## [unreleased] + +### Added + +- `core/util` function `setDefaultProps` to set props that are missing or `undefined` to default values + ## [4.9.0] - 2024-07-17 No significant changes. diff --git a/packages/core/util/tests/util-specs.js b/packages/core/util/tests/util-specs.js index 7155610df8..81f871af65 100644 --- a/packages/core/util/tests/util-specs.js +++ b/packages/core/util/tests/util-specs.js @@ -1,6 +1,6 @@ import {forwardRef, memo, lazy} from 'react'; -import {cap, clamp, coerceArray, coerceFunction, extractAriaProps, isRenderable, memoize, mergeClassNameMaps, mapAndFilterChildren, shallowEqual} from '../util'; +import {cap, clamp, coerceArray, coerceFunction, extractAriaProps, isRenderable, memoize, mergeClassNameMaps, mapAndFilterChildren, setDefaultProps, shallowEqual} from '../util'; describe('util', () => { describe('cap', () => { @@ -255,6 +255,32 @@ describe('util', () => { }); }); + describe('setDefaultProps', () => { + const props = { + // eslint-disable-next-line no-undefined + direction: undefined, + index: 0, + size: 'small' + }; + const defaultProps = { + direction: 'below', + selected: true, + size: 'large' + }; + + test('should set props that are missing or `undefined` to default values', () => { + const expected = { + direction: 'below', + index: 0, + selected: true, + size: 'small' + }; + const actual = setDefaultProps(props, defaultProps); + + expect(expected).toEqual(actual); + }); + }); + describe('shallowEqual', () => { const child = { name: 'child' diff --git a/packages/core/util/util.js b/packages/core/util/util.js index e6b6e40276..05840c7a1f 100644 --- a/packages/core/util/util.js +++ b/packages/core/util/util.js @@ -266,6 +266,30 @@ const mapAndFilterChildren = (children, callback, filter) => { } }; +/** + * Sets props that are missing or `undefined` to default values + * + * @function + * @param {Obejct} props Props object + * @param {Obejct} defaultProps Default value object + * + * @returns {Object} Props with default values + * @memberof core/util + * @public + */ +const setDefaultProps = (props, defaultProps = {}) => { + const result = Object.assign({}, props); + + for (const prop in defaultProps) { + // eslint-disable-next-line no-undefined + if (props[prop] === undefined) { + result[prop] = defaultProps[prop]; + } + } + + return result; +}; + /** * Performs shallow comparison for given objects. * @@ -317,5 +341,6 @@ export { mergeClassNameMaps, perfNow, mapAndFilterChildren, + setDefaultProps, shallowEqual }; diff --git a/packages/ui/CHANGELOG.md b/packages/ui/CHANGELOG.md index 11f598fc53..65edaeb2ce 100644 --- a/packages/ui/CHANGELOG.md +++ b/packages/ui/CHANGELOG.md @@ -11,6 +11,7 @@ The following is a curated list of changes in the Enact ui module, newest change ### Fixed - `ui/Marquee.MarqueeController` to start animation properly when `marqueeOnFocus` is set to `true` and text changed +- `ui/Scroller` and `ui/VirtualList` to have default prop when `undefined` prop is passed ## [4.9.0] - 2024-07-17 diff --git a/packages/ui/Scroller/Scroller.js b/packages/ui/Scroller/Scroller.js index 12d901f030..e901d82017 100644 --- a/packages/ui/Scroller/Scroller.js +++ b/packages/ui/Scroller/Scroller.js @@ -6,6 +6,7 @@ * @exports ScrollerBasic */ +import {setDefaultProps} from '@enact/core/util'; import PropTypes from 'prop-types'; import {ResizeContext} from '../Resizable'; @@ -51,7 +52,7 @@ const scrollerDefaultProps = { const Scroller = (props) => { // Hooks - const scrollerProps = Object.assign({}, scrollerDefaultProps, props); + const scrollerProps = setDefaultProps(props, scrollerDefaultProps); const { scrollContentHandle, diff --git a/packages/ui/VirtualList/VirtualList.js b/packages/ui/VirtualList/VirtualList.js index 1127dbc0cd..f95f2d8879 100644 --- a/packages/ui/VirtualList/VirtualList.js +++ b/packages/ui/VirtualList/VirtualList.js @@ -9,6 +9,7 @@ * @exports VirtualListBasic */ +import {setDefaultProps} from '@enact/core/util'; import PropTypes from 'prop-types'; import {ResizeContext} from '../Resizable'; @@ -50,7 +51,7 @@ const virtualListDefaultProps = { const VirtualList = (props) => { // Hooks - const virtualListProps = Object.assign({}, virtualListDefaultProps, props); + const virtualListProps = setDefaultProps(props, virtualListDefaultProps); const { scrollContentHandle, @@ -326,7 +327,7 @@ const virtualGridListDefaultProps = { * @public */ const VirtualGridList = (props) => { - const virtualGridListProps = Object.assign({}, virtualGridListDefaultProps, props); + const virtualGridListProps = setDefaultProps(props, virtualGridListDefaultProps); const { scrollContentHandle,