Migrating to Enact 2.0
Overview
Section titled “Overview”This document lists changes between Enact versions 1.x and 2.0 likely to affect most apps.
General Changes
Section titled “General Changes”React and React DOM
Section titled “React and React DOM”Enact 2.0 updates the react and react-dom dependencies to 16.x. Developers should ensure
their code does not rely on features that are no longer available in these versions.
factory
Section titled “factory”The factory module has been replaced by the css override feature.
Example
Section titled “Example”import factory from '@enact/core/factory';import kind from '@enact/core/kind';
import componentCss from './Button.module.less';
const ButtonFactory = factory({css: componentCss}, ({css}) => { return kind({ name: 'Button',
// Since 'button' will be resolved against the combined `css` map, it can be overridden too styles: { css, className: 'button' },
// Component authors can also prevent overrides by using their css map directly as is done // with the `inner` class below render: ({children, ...rest}) => ( <button {...rest}> <div className={componentCss.inner}> {children} </div> </button> ) });});
// If `buttonCss` includes a `button` class, it will be appended to the `button` class of the// `Button` component.import buttonCss from './CustomButton.less';const CustomizedButton = ButtonFactory({css: buttonCss});... render: ({...rest}) => { return ( <div {...rest} > <CustomizedButton /> </div> ); }......import Button from '@enact/ui/Button';
// If `buttonCss` includes a `button` class, it will be appended to the `button` class of the// `Button` component.import buttonCss from './CustomButton.less';... render: ({...rest}) => { return ( <div {...rest} > <Button css={buttonCss} /> </div> ); }...kind will always return a component regardless of the configuration options. Prior to 2.0,
kind could return either a component or a stateless functional component (SFC). This change
should only impact rare cases such as relying on a reference to a contained component, or
caching the result of calling the SFC directly.
util.childrenEquals
Section titled “util.childrenEquals”childrenEquals has been removed since React components should not be directly compared. Developers
can do shallow compares of String children in shouldComponentUpdate instead.
Example
Section titled “Example”shouldComponentUpdate (nextProps) { return !childrenEquals(this.props.children, nextProps.children);}shouldComponentUpdate (nextProps) { return this.props.children !== nextProps.children;}The API for accessing the context for i18n/I18nDecorator has been removed. It is replaced with i18n/I18nDecorator.I18nContextDecorator.
This change only impacts apps that were using context to determine locale or RTL/LTR settings.
moonstone
Section titled “moonstone”Button
Section titled “Button”The noAnimation prop has been removed. This change only impacts Enact apps that rely
on Enyo UX.
The exports for ButtonFactory and ButtonBaseFactory have been removed. If your code imported
these, you should use ui/Button and ui/ButtonBase instead.
Example
Section titled “Example”import {ButtonFactory} from '@enact/moonstone/Button';import {ButtonBaseFactory} from '@enact/moonstone/Button';import Button from '@enact/ui/Button';import {ButtonBase} from '@enact/ui/Button';Automatic tooltip support has been removed. It can be easily added using moonstone/TooltipDecorator.
Example
Section titled “Example”import Button from '@enact/ui/Button';import BasicButton from '@enact/ui/Button';import TooltipDecorator from '@enact/ui/TooltipDecorator';
const Button = TooltipDecorator(BasicButton);ContextualPopup
Section titled “ContextualPopup”The popupContainerId prop has changed to popupSpotlightId.
Example
Section titled “Example”<ContextualPopup popupContainerId="popupSpotlightContainer" /><ContextualPopup popupSpotlightId="popupSpotlightContainer" />Dialog
Section titled “Dialog”The preserveCase and showDivider props have changed to casing and noDivider, respectively.
Example
Section titled “Example”<Dialog preserveCase showDivider /> // preserve casing and show divider<Dialog preserveCase /> // preserve casing and do not show divider<Dialog casing="preserve" /> // preserve casing and show divider<Dialog casing="preserve" noDivider /> // preserve casing and do not show dividerDivider
Section titled “Divider”The preserveCase prop has changed to casing.
Example
Section titled “Example”<Divider preserveCase /><Divider casing="preserve" />ExpandableInput
Section titled “ExpandableInput”The onInputChange prop has changed to onChange.
Example
Section titled “Example”const handleChange = () => { // do something when the input changes};...<ExpandableInput onInputChange={handleChange} />const handleChange = () => { // do something when the input changes};...<ExpandableInput onChange={handleChange} />ExpandableList
Section titled “ExpandableList”ExpandableList now requires a unique key for Object type data. Read about keys
for more information.
IconButton
Section titled “IconButton”The noAnimation prop has been removed. This change only impacts Enact apps that rely
on Enyo UX.
The exports for IconButtonFactory and IconButtonBaseFactory have been removed. If your code
imported these, you should use ui/IconButton and ui/IconButtonBase instead.
Example
Section titled “Example”import {IconButtonFactory} from '@enact/moonstone/IconButton';import {IconButtonBaseFactory} from '@enact/moonstone/IconButton';import IconButton from '@enact/ui/IconButton';import {IconButtonBase} from '@enact/ui/IconButton';IncrementSlider
Section titled “IncrementSlider”The exports for IncrementSliderFactory and IncrementSliderBaseFactory have been removed. If your
code imported these, you should use moonstone/IncrementSlider and moonstone/IncrementSliderBase
instead.
Example
Section titled “Example”import {IncrementSliderFactory} from '@enact/moonstone/IncrementSlider';import {IncrementSliderBaseFactory} from '@enact/moonstone/IncrementSlider';import IncrementSlider from '@enact/moonstone/IncrementSlider';import {IncrementSliderBase} from '@enact/moonstone/IncrementSlider';The boolean props horizontal and vertical have been replaced by the orientation prop.
Example
Section titled “Example”<IncrementSlider /> // `horizontal` prop is `true` by default.<IncrementSlider vertical /><IncrementSlider /> // `orientation` prop is `"horizontal"` by default.<IncrementSlider orientation="vertical" />The tooltipAsPercent, tooltipSide, and tooltipForceSide props for the built-in tooltip
have been removed. Use a moonstone/IncrementSlider.IncrementSliderTooltip and its percent
and side props instead. side supports both locale-aware and locale-independent values.
Example
Section titled “Example”<IncrementSlider orientation="vertical" tooltip tooltipAsPercent tooltipForceSide tooltipSide="after" />...import {IncrementSlider, IncrementSliderTooltip} from '@enact/moonstone/IncrementSlider';...<IncrementSlider orientation="vertical"> <IncrementSliderTooltip percent side="right" /></IncrementSlider>The onDecrement and onIncrement props have been removed. These callbacks were only available
on IncrementSliderBase and mostly used internally by the framework. If necessary, developers can use
onKeyDown and/or onKeyUp.
The detachedKnob and scrubbing props have been removed with no replacement.
The <input> element’s styles have changed for height, vertical-align, and margins. Some previously used
sizing and positioning CSS may no longer be necessary. Developers should verify their layouts.
Item.OverlayDecorator, Item.Overlay, and Item.ItemOverlay
Section titled “Item.OverlayDecorator, Item.Overlay, and Item.ItemOverlay”These components are all replaced by moonstone/SlotItem.
Marquee.MarqueeText
Section titled “Marquee.MarqueeText”This component is replaced by moonstone/Marquee.
Example
Section titled “Example”import {MarqueeText} from '@enact/moonstone/Marquee';import Marquee from '@enact/moonstone/Marquee';MoonstoneDecorator.TextSizeDecorator
Section titled “MoonstoneDecorator.TextSizeDecorator”This HOC has been replaced by MoonstoneDecorator.AccessibilityDecorator.
Panels.Header
Section titled “Panels.Header”The preserveCase prop has changed to casing.
Example
Section titled “Example”<Header preserveCase /><Header casing="preserve" />Panels.Panel
Section titled “Panels.Panel”The noAutoFocus prop has changed to autoFocus.
Example
Section titled “Example”<Panel /> // automatically focus the Panel<Panel noAutoFocus /> // do not automatically focus the Panel<Panel /> // automatically focus the Panel<Panel autoFocus="none" /> // do not automatically focus the PanelThe containerId prop has changed to spotlightId.
Example
Section titled “Example”<Popup containerId="spotlightContainer" /><Popup spotlightId="spotlightContainer" />ProgressBar
Section titled “ProgressBar”The boolean props horizontal and vertical have been replaced by the orientation prop.
Example
Section titled “Example”<ProgressBar /> // `horizontal` prop is `true` by default.<ProgressBar vertical /><ProgressBar /> // `orientation` prop is `"horizontal"` by default.<ProgressBar orientation="vertical" />Scroller
Section titled “Scroller”The boolean props horizontal and vertical have been replaced by the direction prop.
Example
Section titled “Example”<Scroller /> // `horizontal` prop is `true` by default.<Scroller vertical /><Scroller /> // `direction` prop is `"horizontal"` by default.<Scroller direction="vertical" />The scrollTo method’s indexToFocus option has been removed. Use the focus option and
scroll by index (only applicable for components like VirtualList) or node.
Example
Section titled “Example”...const cbScrollTo = () => { this.scrollTo({indexToFocus: 1});};...<VirtualList cbScrollTo={cbScrollTo} ... />......const cbScrollTo = () => { this.scrollTo({focus: true, index: 1});};...<VirtualList cbScrollTo={cbScrollTo} ... />...Slider
Section titled “Slider”The exports for SliderFactory and SliderBaseFactory have been removed. If your code
imported these, you should use ui/Slider and ui/SliderBase instead.
Example
Section titled “Example”import {SliderFactory} from '@enact/moonstone/Slider';import {SliderBaseFactory} from '@enact/moonstone/Slider';import Slider from '@enact/ui/Slider';import {SliderBase} from '@enact/ui/Slider';The boolean props horizontal and vertical have been replaced by the orientation prop.
Example
Section titled “Example”<Slider /> // `horizontal` prop is `true` by default.<Slider vertical /><Slider /> // `orientation` prop is `"horizontal"` by default.<Slider orientation="vertical" />The tooltipAsPercent, tooltipSide, and tooltipForceSide props for the built-in tooltip
have been removed. Use a moonstone/Slider.SliderTooltip and its percent and side props
instead. side supports both local-aware and locale-independent values.
Example
Section titled “Example”<Slider orientation="vertical" tooltip tooltipAsPercent tooltipForceSide tooltipSide="after" />...import {Slider, SliderTooltip} from '@enact/moonstone/Slider';...<Slider orientation="vertical"> <SliderTooltip percent side="right" /></Slider>The onDecrement and onIncrement props have been removed. These callbacks were only available
on SliderBase and mostly used internally by the framework. If necessary, developers can use
onKeyDown and/or onKeyUp.
The detachedKnob, scrubbing and onKnobMove props have been removed with no replacement.
Slider.SliderTooltip
Section titled “Slider.SliderTooltip”The boolean props horizontal and vertical have been replaced by the orientation prop.
Example
Section titled “Example”<SliderTooltip /> // `horizontal` prop is `true` by default.<SliderTooltip vertical /><SliderTooltip /> // `orientation` prop is `"horizontal"` by default.<SliderTooltip orientation="vertical" />TooltipDecorator
Section titled “TooltipDecorator”The tooltipPreserveCase prop has changed to tooltipCasing.
Example
Section titled “Example”import BasicButton from '@enact/ui/Button';import TooltipDecorator from '@enact/ui/TooltipDecorator';
const Button = TooltipDecorator(BasicButton);
<Button tooltipPreserveCase />import BasicButton from '@enact/ui/Button';import TooltipDecorator from '@enact/ui/TooltipDecorator';
const Button = TooltipDecorator({tooltipCasing: 'preserve'}, BasicButton);
<Button tooltipCasing="preserve" />VideoPlayer
Section titled “VideoPlayer”The containerId prop has changed to spotlightId.
Example
Section titled “Example”<VideoPlayer containerId="spotlightContainer" /><VideoPlayer spotlightId="spotlightContainer" />The tooltipHideDelay prop has been removed with no replacement.
VirtualFlexList
Section titled “VirtualFlexList”This component has been removed with no replacement.
VirtualGridList
Section titled “VirtualGridList”The component and data props are replaced by itemRenderer. itemRenderer should
return the component to render from a set of arbitrary items given an index.
Example
Section titled “Example”...import Item from '@enact/moonstone/Item';const items = [];const ListItem = ({data, index}) => { const {title} = data[index]; return ( <Item> {title} </Item> );};...<VirtualGridList ... component={ListItem} data={items} .../>......import Item from '@enact/moonstone/Item';const items = [];const itemRenderer = ({index}) => { const {title} = items[index]; return ( <Item> {title} </Item> );};...<VirtualGridList ... itemRenderer={itemRenderer} .../>...VirtualGridList.GridListImageItem
Section titled “VirtualGridList.GridListImageItem”This component is replaced by moonstone/GridListImageItem.
VirtualList
Section titled “VirtualList”The scrollTo method’s indexToFocus option has been removed. Use the focus option and
scroll by index or node.
Example
Section titled “Example”...const cbScrollTo = () => { this.scrollTo({indexToFocus: 1});};...<VirtualList cbScrollTo={cbScrollTo} ... />......const cbScrollTo = () => { this.scrollTo({focus: true, index: 1});};...<VirtualList cbScrollTo={cbScrollTo} ... />...The component and data props are replaced by itemRenderer. itemRenderer should return
the component to render from a set of arbitrary items given an index.
Example
Section titled “Example”...import Item from '@enact/moonstone/Item';const items = [];const ListItem = ({data, index}) => { const {title} = data[index]; return ( <Item> {title} </Item> );};...<VirtualList ... component={ListItem} data={items} .../>......import Item from '@enact/moonstone/Item';const items = [];const itemRenderer = ({index}) => { const {title} = items[index]; return ( <Item> {title} </Item> );};...<VirtualList ... itemRenderer={itemRenderer} .../>...spotlight
Section titled “spotlight”Selectors targeting the spotlight container attributes data-container-disabled or data-container-muted
should use data-spotlight-container-disabled or data-spotlight-container-muted instead.
spotlight/Spottable added support for the spotlightId prop which can be used to identify the component
in calls to Spotlight.focus(). In cases where you might have added a custom data attribute to identify a node,
you can now use spotlightId instead.
Example
Section titled “Example”... <MyComponent data-component-id="my-first-component" />... Spotlight.focus('[data-component-id="my-first-component"]]);...... <MyComponent spotlightId="my-first-component" />... Spotlight.focus('my-first-component');...SpotlightContainerDecorator
Section titled “SpotlightContainerDecorator”The containerId prop has changed to spotlightId.
Example
Section titled “Example”const MyComponent = ...;const MyContainer = SpotlightContainerDecorator(MyComponent);<MyContainer containerId="spotlightContainer" />const MyComponent = ...;const MyContainer = SpotlightContainerDecorator(MyComponent);<MyContainer spotlightId="spotlightContainer" />Group now requires a unique key for Object type data. Read about keys
for more information.
Holdable
Section titled “Holdable”This component has been replaced by ui/Touchable.
Pressable
Section titled “Pressable”This component has been replaced by ui/Touchable.
Repeater
Section titled “Repeater”Repeater now requires a unique key for Object type data. Read about keys
for more information.
Toggleable
Section titled “Toggleable”The default prop for the default HOC configuration is changed from 'active' to 'selected'.
Example
Section titled “Example”const MyComponent = ...;const MyToggleComponent = Toggleable(MyComponent); // toggle prop is `active`const MyOtherToggleComponent = Toggleable({prop: 'selected'}, MyComponent); // toggle prop is `selected`const MyComponent = ...;const MyToggleComponent = Toggleable(MyComponent); // toggle prop is `selected`const MyOtherToggleComponent = Toggleable({prop: 'active'}, MyComponent); // toggle prop is `active`Transition
Section titled “Transition”children is now a required prop for this component.
The clipHeight prop has been removed. The base component’s clipHeight is now automatically computed base on the
Transition’s initial height.
VoiceReadout
Section titled “VoiceReadout”This module (which only had exported readAlert) has been replaced by webos/speech/readAlert.
Example
Section titled “Example”import {readAlert} from `@enact/webos/VoiceReadout`;import {readAlert} from `@enact/webos/speech`;