Skip to content

Commit

Permalink
2.2.8 release
Browse files Browse the repository at this point in the history
  • Loading branch information
JayCanuck committed Dec 10, 2018
2 parents d86ee18 + 85d4e2e commit baeba4a
Show file tree
Hide file tree
Showing 32 changed files with 602 additions and 350 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ cache:
- $(npm config get cache)
install:
- npm config set prefer-offline true
- npm install -g enactjs/cli#develop
- npm install -g enactjs/cli#5382f263d24c112195166ae3e45edca8ae96b232
- npm install
- npm run bootstrap
script:
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,21 @@

The following is a curated list of changes in the Enact project, newest changes on the top.

## [2.2.8] - 2018-12-06

### Fixed

- `moonstone/ExpandableInput` to focus labeled item on close
- `moonstone/ExpandableItem` to disable its spotlight container when the component is disabled
- `moonstone/Scroller` to correctly handle scrolling focused elements and containers into view
- `spotlight` to focus correctly within an overflow container in which the first element is another container without spottable children
- `ui/Marquee` to display an ellipsis when changing to text that no longer fits within its bounds
- `ui/VirtualList`, `ui/VirtualGridList`, and `ui/Scroller` to debounce `onScrollStop` events for non-animated scrolls

## [2.2.7] - 2018-11-21

### Fixed

- `moonstone/Picker`, `moonstone/ExpandablePicker`, `moonstone/ExpandableList`, `moonstone/IncrementSlider` to support disabling voice control
- `ui/Marquee` to avoid very small animations

Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"lerna": "2.8.0",
"version": "2.2.7",
"version": "2.2.8",
"command": {
"bootstrap": {
"npmClientArgs": [
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "enact",
"version": "2.2.7",
"version": "2.2.8",
"description": "Monorepo for all Enact front end libraries.",
"private": true,
"scripts": {
Expand Down
4 changes: 4 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

The following is a curated list of changes in the Enact core module, newest changes on the top.

## [2.2.8] - 2018-12-06

No significant changes.

## [2.2.7] - 2018-11-21

No significant changes.
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@enact/core",
"version": "2.2.7",
"version": "2.2.8",
"description": "Enact is an open source JavaScript framework containing everything you need to create a fast, scalable mobile or web application.",
"main": "index.js",
"scripts": {
Expand Down
4 changes: 4 additions & 0 deletions packages/i18n/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

The following is a curated list of changes in the Enact i18n module, newest changes on the top.

## [2.2.8] - 2018-12-06

No significant changes.

## [2.2.7] - 2018-11-21

No significant changes.
Expand Down
4 changes: 2 additions & 2 deletions packages/i18n/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@enact/i18n",
"main": "./src/index.js",
"version": "2.2.7",
"version": "2.2.8",
"description": "Internationalization support for Enact using iLib",
"scripts": {
"clean": "enact clean",
Expand Down Expand Up @@ -34,7 +34,7 @@
"extends": "enact/strict"
},
"dependencies": {
"@enact/core": "^2.2.7",
"@enact/core": "^2.2.8",
"prop-types": "^15.6.0",
"ramda": "^0.24.1",
"react": "^16.3.2",
Expand Down
8 changes: 8 additions & 0 deletions packages/moonstone/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

The following is a curated list of changes in the Enact moonstone module, newest changes on the top.

## [2.2.8] - 2018-12-06

### Fixed

- `moonstone/ExpandableInput` to focus labeled item on close
- `moonstone/ExpandableItem` to disable its spotlight container when the component is disabled
- `moonstone/Scroller` to correctly handle scrolling focused elements and containers into view

## [2.2.7] - 2018-11-21

### Fixed
Expand Down
1 change: 1 addition & 0 deletions packages/moonstone/ExpandableInput/ExpandableInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ class ExpandableInputBase extends React.Component {
if (!this.props.open && nextProps.open) {
initialValue = nextProps.value;
} else if (this.props.open && !nextProps.open) {
this.paused.resume();
initialValue = null;
}

Expand Down
1 change: 1 addition & 0 deletions packages/moonstone/ExpandableItem/ExpandableItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ const ExpandableItemBase = kind({
aria-disabled={disabled}
disabled={disabled}
ref={setContainerNode}
spotlightDisabled={spotlightDisabled || disabled}
>
<LabeledItem
{...ariaProps}
Expand Down
164 changes: 67 additions & 97 deletions packages/moonstone/Scroller/Scroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,18 @@
* @exports ScrollerBase
*/

import ri from '@enact/ui/resolution';
import {ScrollerBase as UiScrollerBase} from '@enact/ui/Scroller';
import {Spotlight} from '@enact/spotlight';
import {getTargetByDirectionFromPosition} from '@enact/spotlight/src/target';
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {Spotlight} from '@enact/spotlight';

import ri from '@enact/ui/resolution';
import Scrollable from '../Scrollable';
import ScrollableNative from '../Scrollable/ScrollableNative';

const
dataContainerDisabledAttribute = 'data-spotlight-container-disabled',
epsilon = 1,
reverseDirections = {
left: 'right',
right: 'left'
Expand Down Expand Up @@ -119,7 +118,7 @@ class ScrollerBase extends Component {
*/
getSpotlightContainerForNode = (node) => {
do {
if (node.dataset.spotlightId && node.dataset.spotlightContainer) {
if (node.dataset.spotlightId && node.dataset.spotlightContainer && !node.dataset.expandableContainer) {
return node;
}
} while ((node = node.parentNode) && node !== this.uiRef.containerRef);
Expand Down Expand Up @@ -152,98 +151,71 @@ class ScrollerBase extends Component {
* @returns {Number} Calculated `scrollTop`
* @private
*/
calculateScrollTop = (focusedItem, itemTop, itemHeight, scrollInfo, scrollPosition) => {
const
heightThreshold = ri.scale(24),
{clientHeight, scrollHeight} = this.uiRef.scrollBounds,
{top: containerTop} = this.uiRef.containerRef.getBoundingClientRect(),
currentScrollTop = (scrollPosition ? scrollPosition : this.uiRef.scrollPos.top),
// calculation based on client position
newItemTop = this.uiRef.containerRef.scrollTop + (itemTop - containerTop),
itemBottom = newItemTop + itemHeight,
scrollBottom = clientHeight + currentScrollTop;
let
newScrollTop = this.uiRef.scrollPos.top,
scrollHeightChange = 0;

// Calculations for when scrollHeight decrease.
if (scrollInfo) {
const
{scrollTop, previousScrollHeight} = scrollInfo;

scrollHeightChange = previousScrollHeight - scrollHeight;
if (scrollHeightChange > 0) {
newScrollTop = scrollTop;

const
itemBounds = focusedItem.getBoundingClientRect(),
newItemBottom = newScrollTop + itemBounds.top + itemBounds.height - containerTop;

if (newItemBottom < scrollBottom && scrollHeightChange + newItemBottom > scrollBottom) {
// When `focusedItem` is not at the very bottom of the `Scroller` and
// `scrollHeightChange` caused a scroll.
const
distanceFromBottom = scrollBottom - newItemBottom,
bottomOffset = scrollHeightChange - distanceFromBottom;
if (bottomOffset < newScrollTop) {
// guard against negative `scrollTop`
newScrollTop -= bottomOffset;
}
} else if (newItemBottom === scrollBottom) {
// when `focusedItem` is at the very bottom of the `Scroller`
if (scrollHeightChange < newScrollTop) {
// guard against negative `scrollTop`
newScrollTop -= scrollHeightChange;
}
}
calculateScrollTop = (item) => {
const roundToBoundary = (sb, st, sh) => {
const threshold = ri.scale(24);

// round to start
if (st < threshold) return 0;

// round to end
if (sh - (st + sb.height) < threshold) return sh - sb.height;

return st;
};
const isItemBeforeView = (ib, sb, d) => ib.top + d < sb.top;
const isItemAfterView = (ib, sb, d) => ib.top + d + ib.height > sb.top + sb.height;
const canItemFit = (ib, sb) => ib.height <= sb.height;
const calcItemAtStart = (ib, sb, st, d) => ib.top + st + d - sb.top;
const calcItemAtEnd = (ib, sb, st, d) => ib.top + ib.height + st + d - (sb.top + sb.height);
const calcItemInView = (ib, sb, st, sh, d) => {
if (isItemBeforeView(ib, sb, d)) {
return roundToBoundary(sb, calcItemAtStart(ib, sb, st, d), sh, d);
} else if (isItemAfterView(ib, sb, d)) {
return roundToBoundary(sb, calcItemAtEnd(ib, sb, st, d), sh, d);
}
}

if (itemHeight > clientHeight) {
// Calculations for `containerHeight` that are bigger than `clientHeight`
const
{top, height: nestedItemHeight} = focusedItem.getBoundingClientRect(),
nestedItemTop = this.uiRef.containerRef.scrollTop + (top - containerTop),
nestedItemBottom = nestedItemTop + nestedItemHeight;

if (nestedItemBottom - scrollBottom > epsilon) {
// Calculate when 5-way focus down past the bottom.
newScrollTop += nestedItemBottom - scrollBottom;
} else if (nestedItemTop - currentScrollTop < epsilon) {
// Calculate when 5-way focus up past the top.
if (newItemTop > newScrollTop) {
// Ensure that the adjusted scrollTop would at least scroll the container to the top of
// the viewport (e.g. because the container is at the bottom of the scroller and the
// nested item is at the top of the container)
newScrollTop = newItemTop;
} else {
newScrollTop += nestedItemTop - currentScrollTop;
}
} else if (newItemTop - nestedItemHeight - currentScrollTop > epsilon) {
// set scroll position so that the top of the container is at least on the top as a fallback.
newScrollTop = newItemTop - nestedItemHeight;
}
} else if (itemBottom - scrollBottom > epsilon) {
// Calculate when 5-way focus down past the bottom.
return st;
};

// if the last item is focused and have an invisible area, scroll all the way to the bottom
if (scrollHeight - itemBottom < heightThreshold) {
newScrollTop += scrollHeight - scrollBottom;
} else {
newScrollTop += itemBottom - scrollBottom;
const container = this.getSpotlightContainerForNode(item);
const scrollerBounds = this.uiRef.containerRef.getBoundingClientRect();
let {scrollHeight, scrollTop} = this.uiRef.containerRef;
let scrollTopDelta = 0;

const adjustScrollTop = (v) => {
scrollTopDelta = scrollTop - v;
scrollTop = v;
};

if (container) {
const containerBounds = container.getBoundingClientRect();

// if the entire container fits in the scroller, scroll it into view
if (canItemFit(containerBounds, scrollerBounds)) {
return calcItemInView(containerBounds, scrollerBounds, scrollTop, scrollHeight, scrollTopDelta);
}
} else if (newItemTop - currentScrollTop < epsilon && scrollHeightChange <= 0) {
// Calculate when 5-way focus up past the top.

// if the first item is focused and have an invisible area, scroll all the way to the top
if (newItemTop < heightThreshold) {
newScrollTop = 0;
} else {
newScrollTop += newItemTop - currentScrollTop;
// if the container doesn't fit, adjust the scroll top ...
if (containerBounds.top > scrollerBounds.top) {
// ... to the top of the container if the top is below the top of the scroller
adjustScrollTop(calcItemAtStart(containerBounds, scrollerBounds, scrollTop, scrollTopDelta));
}
// removing support for "snap to bottom" for 2.2.8
// } else if (containerBounds.top + containerBounds.height < scrollerBounds.top + scrollerBounds.height) {
// // ... to the bottom of the container if the bottom is above the bottom of the
// // scroller
// adjustScrollTop(calcItemAtEnd(containerBounds, scrollerBounds, scrollTop, scrollTopDelta));
// }

// N.B. if the container covers the scrollable area (its top is above the top of the
// scroller and its bottom is below the bottom of the scroller), we need not adjust the
// scroller to ensure the container is wholly in view.
}

return newScrollTop;
const itemBounds = item.getBoundingClientRect();

return calcItemInView(itemBounds, scrollerBounds, scrollTop, scrollHeight, scrollTopDelta);
}

/**
Expand All @@ -257,21 +229,19 @@ class ScrollerBase extends Component {
* @returns {Object} with keys {top, left} containing calculated top and left positions for scroll.
* @private
*/
calculatePositionOnFocus = ({item, scrollInfo, scrollPosition}) => {
calculatePositionOnFocus = ({item, scrollPosition}) => {
if (!this.uiRef.isVertical() && !this.uiRef.isHorizontal() || !item || !this.uiRef.containerRef.contains(item)) {
return;
}

const {
top: itemTop,
left: itemLeft,
height: itemHeight,
width: itemWidth
} = this.getFocusedItemBounds(item);

if (this.uiRef.isVertical()) {
this.uiRef.scrollPos.top = this.calculateScrollTop(item, itemTop, itemHeight, scrollInfo, scrollPosition);
this.uiRef.scrollPos.top = this.calculateScrollTop(item);
} else if (this.uiRef.isHorizontal()) {
const {
left: itemLeft,
width: itemWidth
} = this.getFocusedItemBounds(item);

const
{rtl} = this.props,
{clientWidth} = this.uiRef.scrollBounds,
Expand Down
Loading

0 comments on commit baeba4a

Please sign in to comment.