Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ install:
- npm config set prefer-offline false
- npm install -g enactjs/cli#develop
- npm install -g codecov
- git clone --branch=develop --depth 1 https://github.com/enactjs/enact ../enact
- git clone --branch=feature/WRO-478 --depth 1 https://github.com/enactjs/enact ../enact
- pushd ../enact
- npm install
- npm run lerna exec -- --ignore enact-sampler --concurrency 1 -- npm --no-package-lock install
Expand Down
6 changes: 6 additions & 0 deletions VirtualList/VirtualList.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ VirtualList.propTypes = /** @lends sandstone/VirtualList.VirtualList.prototype *
*/
direction: PropTypes.oneOf(['horizontal', 'vertical']),

editable: PropTypes.object, // TBD // FIXME

/**
* Specifies how to show horizontal scrollbar.
*
Expand Down Expand Up @@ -492,6 +494,7 @@ VirtualList.defaultProps = {
'data-spotlight-container-disabled': false,
cbScrollTo: nop,
direction: 'vertical',
editable: null,
horizontalScrollbar: 'auto',
noAffordance: false,
noScrollByDrag: false,
Expand Down Expand Up @@ -673,6 +676,8 @@ VirtualGridList.propTypes = /** @lends sandstone/VirtualList.VirtualGridList.pro
*/
direction: PropTypes.oneOf(['horizontal', 'vertical']),

editable: PropTypes.object, // TBD // FIXME

/**
* Specifies how to show horizontal scrollbar.
*
Expand Down Expand Up @@ -971,6 +976,7 @@ VirtualGridList.defaultProps = {
'data-spotlight-container-disabled': false,
cbScrollTo: nop,
direction: 'vertical',
editable: null,
horizontalScrollbar: 'auto',
noAffordance: false,
noScrollByDrag: false,
Expand Down
61 changes: 59 additions & 2 deletions VirtualList/useEvent.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {is} from '@enact/core/keymap';
import {Job} from '@enact/core/util';
import Spotlight, {getDirection} from '@enact/spotlight';
import {getTargetByDirectionFromElement} from '@enact/spotlight/src/target';
import utilDOM from '@enact/ui/useScroll/utilDOM';
Expand All @@ -20,14 +21,21 @@ const
// should return -1 if index is not a number or a negative value
return number >= 0 ? number : -1;
};
const focusFirstChild = (node) => {
if (node.children[0]) {
node.children[0].focus();
}
};

let prevKeyDownIndex = -1;

const useEventKey = (props, instances, context) => {
// Mutable value

const mutableRef = useRef({
fn: null
fn: null,
editableJob: null,
editingIndex: null
});

// Functions
Expand Down Expand Up @@ -106,11 +114,22 @@ const useEventKey = (props, instances, context) => {
return {isDownKey, isUpKey, isLeftMovement, isRightMovement, isWrapped, nextIndex};
}, [findSpottableItem, props, instances]);

const editingStartByKey = useCallback(() => {
const {scrollContentHandle: {current: {featureEditable}}} = instances;
featureEditable.editingStart(mutableRef.current.editingIndex, 'index', focusFirstChild);
}, [instances]);

// Hooks

useEffect(() => {
const {scrollContentHandle: {current: {featureEditable}}} = instances;
mutableRef.current.editableJob = new Job(editingStartByKey, featureEditable.enablingTime);
}, [instances, editingStartByKey]);

useEffect(() => {
const {scrollContainerRef, scrollContentHandle} = instances;
const {
focusByIndex,
handle5WayKeyUp,
handleDirectionKeyDown,
handlePageUpDownKeyDown,
Expand All @@ -120,11 +139,26 @@ const useEventKey = (props, instances, context) => {
function handleKeyDown (ev) {
const {keyCode, target} = ev;
const direction = getDirection(keyCode);
const {featureEditable} = scrollContentHandle.current;

if (direction) {
Spotlight.setPointerMode(false);
if (featureEditable.enabled && featureEditable.editingMode) {
const {editingIndex, editingNode, lastVisualIndex, moveItem, movingItemUpdate} = featureEditable;

if (lastVisualIndex !== null) {
const nextIndex = getNextIndex({index: lastVisualIndex, keyCode, repeat: ev.repeat}).nextIndex;
if (nextIndex !== -1) {
moveItem(editingIndex, nextIndex, {scrollIntoView: true});
if (editingNode) {
movingItemUpdate();
}
}

if (spotlightAcceleratorProcessKey(ev)) {
ev.preventDefault();
ev.stopPropagation();
}
} else if (spotlightAcceleratorProcessKey(ev)) {
ev.stopPropagation();
} else {
const {spotlightId} = props;
Expand Down Expand Up @@ -209,10 +243,33 @@ const useEventKey = (props, instances, context) => {
}
} else if (isPageUp(keyCode) || isPageDown(keyCode)) {
handlePageUpDownKeyDown();
} else if (isEnter(keyCode)) {
if (!ev.repeat && featureEditable.enabled) {
if (!featureEditable.editingMode) {
const targetIndex = target.dataset.index;
const index = targetIndex ? getNumberValue(targetIndex) : -1;
if (index !== -1) {
mutableRef.current.editingIndex = index;
mutableRef.current.editableJob.start();
}
} else {
const lastVisualIndex = featureEditable.lastVisualIndex;
featureEditable.editingFinish();
focusByIndex(lastVisualIndex);
}
}
}
}

function handleKeyUp ({keyCode}) {
const {scrollContentHandle: {current: {featureEditable}}} = instances;
if (featureEditable.enabled) {
mutableRef.current.editableJob.stop();
if (featureEditable.editingMode) {
return;
}
}

if (getDirection(keyCode) || isEnter(keyCode)) {
handle5WayKeyUp();
}
Expand Down
1 change: 1 addition & 0 deletions VirtualList/useThemeVirtualList.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const useSpottable = (props, instances) => {
useSpotlightConfig(props, {spottable: mutableRef});

const {addGlobalKeyDownEventListener, removeGlobalKeyDownEventListener} = useEventKey(props, instances, {
focusByIndex,
handlePageUpDownKeyDown: () => {
mutableRef.current.isScrolledBy5way = false;
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@
"eslint-config-enact-proxy": "^1.0.5",
"ilib": "^14.14.0"
}
}
}
32 changes: 28 additions & 4 deletions samples/qa-virtualgridlist/src/components/ImageList/ImageList.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,20 @@ import ImageItem from '../ImageItem';

import css from './ImageList.module.less';

const ImageList = ({imageitems, minHeight, minWidth, spacing, ...rest}) => {
import {
updateItemsOrder as updateItemsOrderAction
} from '../../store';

const ImageList = ({imageitems, minHeight, minWidth, updateItemsOrder, spacing, ...rest}) => {
const calculateOfSize = (size) => ri.scale(parseInt(size) || 0);

const renderItem = useCallback(({...renderRest}) => (<ImageItem {...renderRest} />), []);
const renderItem = useCallback(({editMode, ...renderRest}) => (
<ImageItem
{...renderRest}
style={editMode ? {transform: `translateY(-${ri.scaleToRem(100)})`} : {}}
/>
), []);


delete rest.dispatch;

Expand All @@ -20,8 +30,15 @@ const ImageList = ({imageitems, minHeight, minWidth, spacing, ...rest}) => {
{...rest}
className={rest.direction === 'horizontal' ? css.horizontalPadding : css.verticalPadding}
dataSize={imageitems.length}
hoverToScroll
itemRenderer={renderItem}
itemSize={{minHeight: calculateOfSize(minHeight), minWidth: calculateOfSize(minWidth)}}
editable={{
css: css,
onComplete: ({detail: {order}}) => {
updateItemsOrder(order);
}
}}
spacing={calculateOfSize(spacing)}
/>
);
Expand All @@ -33,7 +50,8 @@ ImageList.propTypes = {
imageitems: PropTypes.array,
minHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
spacing: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
spacing: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
updateItemsOrder: PropTypes.func
};

const mapStateToProps = ({data}) => ({
Expand All @@ -43,4 +61,10 @@ const mapStateToProps = ({data}) => ({
spacing: data.spacing
});

export default connect(mapStateToProps)(ImageList);
const mapDispatchToProps = (dispatch) => {
return {
updateItemsOrder: (newDataOrder) => dispatch(updateItemsOrderAction(newDataOrder))
};
};

export default connect(mapStateToProps, mapDispatchToProps)(ImageList);
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,35 @@
.horizontalPadding {
padding-bottom: 36px;
}

@keyframes selected {
0% {
transform: scale(0.95) rotate(0);
}
25% {
transform: scale(0.90) rotate(-2deg);
}
50% {
transform: scale(0.95) rotate(0);
}
75% {
transform: scale(0.90) rotate(2deg);
}
100% {
transform: scale(0.95) rotate(0);
}
}

.selected {
&::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
border: 12px solid white;
border-radius: 48px;
animation-name: selected;
animation-duration: 0.8s;
animation-iteration-count: infinite;
}
}
15 changes: 14 additions & 1 deletion samples/qa-virtualgridlist/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,24 @@ const recordSlice = createSlice({
prepare: (index, item) => {
return {payload: {index, item}};
}
},
updateItemsOrder: (state, action) => {
const newData = {};
const newDataOrder = [];

if (action.payload) {
for (let i = 0; i < action.payload.length; i++) {
newData[i] = state.data[action.payload[i]];
newDataOrder.push(i);
}
}

return Object.assign(state, {data: newData, dataOrder: newDataOrder});
}
}
});

export const {addItem, changeDataSize, changeMinHeight, changeMinWidth, changeSpacing, deleteItem, deleteSelectedItem, selectAll, selectItem, selectionEnable, setData} = recordSlice.actions;
export const {addItem, changeDataSize, changeMinHeight, changeMinWidth, changeSpacing, deleteItem, deleteSelectedItem, selectAll, selectItem, selectionEnable, setData, updateItemsOrder} = recordSlice.actions;

const rootReducer = combineReducers({
data : recordSlice.reducer
Expand Down
3 changes: 1 addition & 2 deletions useScroll/useScroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,6 @@ const useScroll = (props) => {
'data-webos-voice-disabled': voiceDisabled,
'data-webos-voice-focused': voiceFocused,
'data-webos-voice-group-label': voiceGroupLabel,
editable,
focusableScrollbar,
fadeOut,
horizontalScrollThumbAriaLabel,
Expand Down Expand Up @@ -475,7 +474,7 @@ const useScroll = (props) => {
};

assignProperties('scrollContentProps', {
...(props.itemRenderer ? {itemRefs, noAffordance, snapToCenter} : {editable, fadeOut}),
...(props.itemRenderer ? {itemRefs, noAffordance, snapToCenter} : {fadeOut}),
...voiceProps,
className: [
(props.direction === 'both' || props.direction === 'vertical') ? overscrollCss.vertical : overscrollCss.horizontal,
Expand Down