From 66bf9abb0940a82a3d44b125db62c74a037191f3 Mon Sep 17 00:00:00 2001 From: Blake Stephens Date: Thu, 20 Feb 2020 12:23:20 -0800 Subject: [PATCH 1/2] Implemented marqueeOn prop support for MarqueeController Enact-DCO-1.0-Signed-off-by: Blake Stephens --- packages/ui/Marquee/MarqueeController.js | 5 +++- packages/ui/Marquee/MarqueeDecorator.js | 31 +++++++++++++++--------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/packages/ui/Marquee/MarqueeController.js b/packages/ui/Marquee/MarqueeController.js index 44283b32ea..6f611e7af5 100644 --- a/packages/ui/Marquee/MarqueeController.js +++ b/packages/ui/Marquee/MarqueeController.js @@ -56,6 +56,7 @@ const MarqueeController = hoc(defaultConfig, (config, Wrapped) => { complete: this.handleComplete, enter: this.handleEnter, leave: this.handleLeave, + marqueeOn: props.marqueeOn, register: this.handleRegister, start: this.handleStart, unregister: this.handleUnregister @@ -284,7 +285,7 @@ const MarqueeController = hoc(defaultConfig, (config, Wrapped) => { } render () { - let props = this.props; + let {...props} = this.props; if (marqueeOnFocus) { props = { @@ -294,6 +295,8 @@ const MarqueeController = hoc(defaultConfig, (config, Wrapped) => { }; } + delete props.marqueeOn; + return ( diff --git a/packages/ui/Marquee/MarqueeDecorator.js b/packages/ui/Marquee/MarqueeDecorator.js index 590f3196a0..581aff3ce5 100644 --- a/packages/ui/Marquee/MarqueeDecorator.js +++ b/packages/ui/Marquee/MarqueeDecorator.js @@ -114,6 +114,10 @@ const didPropChange = (propList, prev, next) => { return hasPropsChanged.indexOf(true) !== -1; }; +const getMarqueeOn = function (props, context, marqueeOnDefault = 'focus') { + return (props.marqueeOn || (context && context.marqueeOn) || marqueeOnDefault); +}; + /* * There's only one timer shared for Marquee so we need to keep track of what we may be using it * for. We may need to clean up certain things as we move among states. @@ -304,15 +308,13 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { static defaultProps = { marqueeDelay: 1000, - marqueeOn: 'focus', + // marqueeOn: 'focus', marqueeOnRenderDelay: 1000, marqueeResetDelay: 1000, marqueeSpacing: '50%', marqueeSpeed: 60 } - static contextType = MarqueeControllerContext - constructor (props) { super(props); this.state = { @@ -338,7 +340,7 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { } this.validateTextDirection(); - if (this.props.marqueeOn === 'render') { + if (getMarqueeOn(this.props, this.context) === 'render') { this.startAnimation(this.props.marqueeOnRenderDelay); } on('keydown', this.handlePointerHide); @@ -352,7 +354,7 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { } componentDidUpdate (prevProps) { - const {children, disabled, forceDirection, locale, marqueeOn, marqueeDisabled, marqueeSpacing, marqueeSpeed, rtl} = this.props; + const {children, disabled, forceDirection, locale, marqueeOn = getMarqueeOn(this.props, this.context), marqueeDisabled, marqueeSpacing, marqueeSpeed, rtl} = this.props; let forceRestartMarquee = false; @@ -371,7 +373,8 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { this.invalidateMetrics(); this.cancelAnimation(); } else if ( - prevProps.marqueeOn !== marqueeOn || + // prevProps.marqueeOn !== marqueeOn || + getMarqueeOn(prevProps, this.context) !== marqueeOn || prevProps.marqueeDisabled !== marqueeDisabled || prevProps.marqueeSpeed !== marqueeSpeed || prevProps.forceDirection !== forceDirection @@ -383,7 +386,7 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { this.validateTextDirection(); if (forceRestartMarquee || this.shouldStartMarquee()) { - this.tryStartingAnimation(this.props.marqueeOn === 'render' ? this.props.marqueeOnRenderDelay : this.props.marqueeDelay); + this.tryStartingAnimation(marqueeOn === 'render' ? this.props.marqueeOnRenderDelay : this.props.marqueeDelay); } } @@ -402,6 +405,8 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { off('keydown', this.handlePointerHide); } + static contextType = MarqueeControllerContext + promoteJob = new Job(() => { if (!this.contentFits) { this.setState(state => state.promoted ? null : {promoted: true}); @@ -462,7 +467,7 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { * @returns {Boolean} - `true` if a possible marquee condition exists */ shouldStartMarquee () { - const {disabled, marqueeDisabled, marqueeOn} = this.props; + const {disabled, marqueeDisabled, marqueeOn = getMarqueeOn(this.props, this.context)} = this.props; return !marqueeDisabled && ( marqueeOn === 'render' || !this.sync && ( @@ -769,7 +774,7 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { forwardBlur(ev, this.props); if (this.isFocused) { this.isFocused = false; - if (!this.sync && !(this.isHovered && this.props.marqueeOn === 'hover')) { + if (!this.sync && !(this.isHovered && getMarqueeOn(this.props, this.context) === 'hover')) { this.cancelAnimation(); } } @@ -777,7 +782,7 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { handleEnter = (ev) => { this.isHovered = true; - if (this.props.marqueeOn === 'hover') { + if (getMarqueeOn(this.props, this.context) === 'hover') { if (this.sync) { this.context.enter(this); } else if (!this.state.animating) { @@ -801,7 +806,7 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { handleUnhover () { this.isHovered = false; - if (this.props.marqueeOn === 'hover') { + if (getMarqueeOn(this.props, this.context) === 'hover') { if (this.sync) { this.context.leave(this); } else { @@ -826,11 +831,13 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { alignment, children, disabled, - marqueeOn, + marqueeOn = getMarqueeOn(this.props, this.context), marqueeSpeed, ...rest } = this.props; + console.log('marqueeOn:', marqueeOn, this.context && this.context.marqueeOn, children); + const marqueeOnFocus = marqueeOn === 'focus'; const marqueeOnHover = marqueeOn === 'hover'; const marqueeOnRender = marqueeOn === 'render'; From 19f8a15e90e9ccfbd728202fca118f3b4b1e8291 Mon Sep 17 00:00:00 2001 From: Blake Stephens Date: Thu, 20 Feb 2020 14:10:17 -0800 Subject: [PATCH 2/2] Added docs and fix linting issues Enact-DCO-1.0-Signed-off-by: Blake Stephens --- packages/ui/Marquee/MarqueeController.js | 15 +++++++++++++++ packages/ui/Marquee/MarqueeDecorator.js | 7 ++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/ui/Marquee/MarqueeController.js b/packages/ui/Marquee/MarqueeController.js index 6f611e7af5..9d4ee4ae18 100644 --- a/packages/ui/Marquee/MarqueeController.js +++ b/packages/ui/Marquee/MarqueeController.js @@ -1,6 +1,7 @@ import {forward} from '@enact/core/handle'; import hoc from '@enact/core/hoc'; import {Job} from '@enact/core/util'; +import PropTypes from 'prop-types'; import React from 'react'; const STATE = { @@ -46,6 +47,20 @@ const MarqueeController = hoc(defaultConfig, (config, Wrapped) => { return class extends React.Component { static displayName = 'MarqueeController' + static propTypes = /** @lends ui/Marquee.MarqueeController.prototype */ { + /** + * Determines what triggers the marquee to start its animation. + * + * This property is passed down to any chirdren Marquee components, and is used there, + * unless `marqueeOn` is specified for them as well. + * + * @type {('focus'|'hover'|'render')} + * @default 'focus' + * @public + */ + marqueeOn: PropTypes.oneOf(['focus', 'hover', 'render']) + } + constructor (props) { super(props); diff --git a/packages/ui/Marquee/MarqueeDecorator.js b/packages/ui/Marquee/MarqueeDecorator.js index 581aff3ce5..f20187e086 100644 --- a/packages/ui/Marquee/MarqueeDecorator.js +++ b/packages/ui/Marquee/MarqueeDecorator.js @@ -308,13 +308,14 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { static defaultProps = { marqueeDelay: 1000, - // marqueeOn: 'focus', marqueeOnRenderDelay: 1000, marqueeResetDelay: 1000, marqueeSpacing: '50%', marqueeSpeed: 60 } + static contextType = MarqueeControllerContext + constructor (props) { super(props); this.state = { @@ -405,8 +406,6 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { off('keydown', this.handlePointerHide); } - static contextType = MarqueeControllerContext - promoteJob = new Job(() => { if (!this.contentFits) { this.setState(state => state.promoted ? null : {promoted: true}); @@ -836,8 +835,6 @@ const MarqueeDecorator = hoc(defaultConfig, (config, Wrapped) => { ...rest } = this.props; - console.log('marqueeOn:', marqueeOn, this.context && this.context.marqueeOn, children); - const marqueeOnFocus = marqueeOn === 'focus'; const marqueeOnHover = marqueeOn === 'hover'; const marqueeOnRender = marqueeOn === 'render';