Migrating to Enact 2.0

Overview

This document lists changes between Enact versions 1.x and 2.0 likely to affect most apps.

General Changes

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.

core

factory

The factory module has been replaced by the css override feature.

Example

1.x
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>
		);
	}
...
2.0
...
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

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

childrenEquals has been removed since React components should not be directly compared. Developers can do shallow compares of String children in shouldComponentUpdate instead.

Example

1.x
shouldComponentUpdate (nextProps) {
	return !childrenEquals(this.props.children, nextProps.children);
}
2.0
shouldComponentUpdate (nextProps) {
	return this.props.children !== nextProps.children;
}

i18n

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

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

1.x
import {ButtonFactory} from '@enact/moonstone/Button';
import {ButtonBaseFactory} from '@enact/moonstone/Button';
2.0
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

1.x
import Button from '@enact/ui/Button';
2.0
import BasicButton from '@enact/ui/Button';
import TooltipDecorator from '@enact/ui/TooltipDecorator';

const Button = TooltipDecorator(BasicButton);

ContextualPopup

The popupContainerId prop has changed to popupSpotlightId.

Example

1.x
<ContextualPopup popupContainerId="popupSpotlightContainer" />
2.0
<ContextualPopup popupSpotlightId="popupSpotlightContainer" />

Dialog

The preserveCase and showDivider props have changed to casing and noDivider, respectively.

Example

1.x
<Dialog preserveCase showDivider />  // preserve casing and show divider
<Dialog preserveCase />  // preserve casing and do not show divider
2.0
<Dialog casing="preserve" /> // preserve casing and show divider
<Dialog casing="preserve" noDivider /> // preserve casing and do not show divider

Divider

The preserveCase prop has changed to casing.

Example

1.x
<Divider preserveCase />
2.0
<Divider casing="preserve" />

ExpandableInput

The onInputChange prop has changed to onChange.

Example

1.x
const handleChange = () => {
    // do something when the input changes
};
...
<ExpandableInput onInputChange={handleChange} />
2.0
const handleChange = () => {
    // do something when the input changes
};
...
<ExpandableInput onChange={handleChange} />

ExpandableList

ExpandableList now requires a unique key for Object type data. Read about keys for more information.

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

1.x
import {IconButtonFactory} from '@enact/moonstone/IconButton';
import {IconButtonBaseFactory} from '@enact/moonstone/IconButton';
2.0
import IconButton from '@enact/ui/IconButton';
import {IconButtonBase} from '@enact/ui/IconButton';

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

1.x
import {IncrementSliderFactory} from '@enact/moonstone/IncrementSlider';
import {IncrementSliderBaseFactory} from '@enact/moonstone/IncrementSlider';
2.0
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

1.x
<IncrementSlider /> // `horizontal` prop is `true` by default.
<IncrementSlider vertical />
2.0
<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

1.x
<IncrementSlider orientation="vertical" tooltip tooltipAsPercent tooltipForceSide tooltipSide="after" />
2.0
...
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.

Input

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

These components are all replaced by moonstone/SlotItem.

Marquee.MarqueeText

This component is replaced by moonstone/Marquee.

Example

1.x
import {MarqueeText} from '@enact/moonstone/Marquee';
2.0
import Marquee from '@enact/moonstone/Marquee';

MoonstoneDecorator.TextSizeDecorator

This HOC has been replaced by MoonstoneDecorator.AccessibilityDecorator.

Panels.Header

The preserveCase prop has changed to casing.

Example

1.x
<Header preserveCase />
2.0
<Header casing="preserve" />

Panels.Panel

The noAutoFocus prop has changed to autoFocus.

Example

1.x
<Panel /> // automatically focus the Panel
<Panel noAutoFocus /> // do not automatically focus the Panel
2.0
<Panel /> // automatically focus the Panel
<Panel autoFocus="none" /> // do not automatically focus the Panel

Popup

The containerId prop has changed to spotlightId.

Example

1.x
<Popup containerId="spotlightContainer" />
2.0
<Popup spotlightId="spotlightContainer" />

ProgressBar

The boolean props horizontal and vertical have been replaced by the orientation prop.

Example

1.x
<ProgressBar /> // `horizontal` prop is `true` by default.
<ProgressBar vertical />
2.0
<ProgressBar /> // `orientation` prop is `"horizontal"` by default.
<ProgressBar orientation="vertical" />

Scroller

The boolean props horizontal and vertical have been replaced by the direction prop.

Example

1.x
<Scroller /> // `horizontal` prop is `true` by default.
<Scroller vertical />
2.0
<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

1.x
...
const cbScrollTo = () => {
	this.scrollTo({indexToFocus: 1});
};
...
<VirtualList cbScrollTo={cbScrollTo} ... />
...
2.0
...
const cbScrollTo = () => {
	this.scrollTo({focus: true, index: 1});
};
...
<VirtualList cbScrollTo={cbScrollTo} ... />
...

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

1.x
import {SliderFactory} from '@enact/moonstone/Slider';
import {SliderBaseFactory} from '@enact/moonstone/Slider';
2.0
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

1.x
<Slider /> // `horizontal` prop is `true` by default.
<Slider vertical />
2.0
<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

1.x
<Slider orientation="vertical" tooltip tooltipAsPercent tooltipForceSide tooltipSide="after" />
2.0
...
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

The boolean props horizontal and vertical have been replaced by the orientation prop.

Example

1.x
<SliderTooltip /> // `horizontal` prop is `true` by default.
<SliderTooltip vertical />
2.0
<SliderTooltip /> // `orientation` prop is `"horizontal"` by default.
<SliderTooltip orientation="vertical" />

TooltipDecorator

The tooltipPreserveCase prop has changed to tooltipCasing.

Example

1.x
import BasicButton from '@enact/ui/Button';
import TooltipDecorator from '@enact/ui/TooltipDecorator';

const Button = TooltipDecorator(BasicButton);

<Button tooltipPreserveCase />
2.0
import BasicButton from '@enact/ui/Button';
import TooltipDecorator from '@enact/ui/TooltipDecorator';

const Button = TooltipDecorator({tooltipCasing: 'preserve'}, BasicButton);

<Button tooltipCasing="preserve" />

VideoPlayer

The containerId prop has changed to spotlightId.

Example

1.x
<VideoPlayer containerId="spotlightContainer" />
2.0
<VideoPlayer spotlightId="spotlightContainer" />

The tooltipHideDelay prop has been removed with no replacement.

VirtualFlexList

This component has been removed with no replacement.

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

1.x
...
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}
	...
/>
...
2.0
...
import Item from '@enact/moonstone/Item';
const items = [];
const itemRenderer = ({index}) => {
	const {title} = items[index];
	return (
		<Item>
			{title}
		</Item>
	);
};
...
<VirtualGridList
	...
	itemRenderer={itemRenderer}
	...
/>
...

VirtualGridList.GridListImageItem

This component is replaced by moonstone/GridListImageItem.

VirtualList

The scrollTo method’s indexToFocus option has been removed. Use the focus option and scroll by index or node.

Example

1.x
...
const cbScrollTo = () => {
	this.scrollTo({indexToFocus: 1});
};
...
<VirtualList cbScrollTo={cbScrollTo} ... />
...
2.0
...
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

1.x
...
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}
	...
/>
...
2.0
...
import Item from '@enact/moonstone/Item';
const items = [];
const itemRenderer = ({index}) => {
	const {title} = items[index];
	return (
		<Item>
			{title}
		</Item>
	);
};
...
<VirtualList
	...
	itemRenderer={itemRenderer}
	...
/>
...

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

1.x
...
	<MyComponent data-component-id="my-first-component" />
...
	Spotlight.focus('[data-component-id="my-first-component"]]);
...
2.0
...
	<MyComponent spotlightId="my-first-component" />
...
	Spotlight.focus('my-first-component');
...

SpotlightContainerDecorator

The containerId prop has changed to spotlightId.

Example

1.x
const MyComponent = ...;
const MyContainer = SpotlightContainerDecorator(MyComponent);
<MyContainer containerId="spotlightContainer" />
2.0
const MyComponent = ...;
const MyContainer = SpotlightContainerDecorator(MyComponent);
<MyContainer spotlightId="spotlightContainer" />

ui

Group

Group now requires a unique key for Object type data. Read about keys for more information.

Holdable

This component has been replaced by ui/Touchable.

Pressable

This component has been replaced by ui/Touchable.

Repeater

Repeater now requires a unique key for Object type data. Read about keys for more information.

Toggleable

The default prop for the default HOC configuration is changed from 'active' to 'selected'.

Example

1.x
const MyComponent = ...;
const MyToggleComponent = Toggleable(MyComponent); // toggle prop is `active`
const MyOtherToggleComponent = Toggleable({prop: 'selected'}, MyComponent); // toggle prop is `selected`
2.0
const MyComponent = ...;
const MyToggleComponent = Toggleable(MyComponent); // toggle prop is `selected`
const MyOtherToggleComponent = Toggleable({prop: 'active'}, MyComponent); // toggle prop is `active`

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.

webos

VoiceReadout

This module (which only had exported readAlert) has been replaced by webos/speech/readAlert.

Example

1.x
import {readAlert} from `@enact/webos/VoiceReadout`;
2.0
import {readAlert} from `@enact/webos/speech`;