react-downscreen
Advanced tools
Comparing version 0.0.7 to 0.0.8
@@ -80,44 +80,7 @@ 'use strict'; | ||
function _slicedToArray(arr, i) { | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); | ||
} | ||
function _arrayWithHoles(arr) { | ||
if (Array.isArray(arr)) return arr; | ||
} | ||
function _iterableToArrayLimit(arr, i) { | ||
var _arr = []; | ||
var _n = true; | ||
var _d = false; | ||
var _e = undefined; | ||
try { | ||
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { | ||
_arr.push(_s.value); | ||
if (i && _arr.length === i) break; | ||
} | ||
} catch (err) { | ||
_d = true; | ||
_e = err; | ||
} finally { | ||
try { | ||
if (!_n && _i["return"] != null) _i["return"](); | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
} | ||
return _arr; | ||
} | ||
function _nonIterableRest() { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance"); | ||
} | ||
const initialState = { | ||
isOpen: false, | ||
selectedIndex: null, | ||
highlightedIndex: 0 | ||
highlightedIndex: null, | ||
lastKey: null | ||
}; | ||
@@ -128,8 +91,13 @@ const DownscreenContext = React.createContext({ | ||
itemsLength: 0, | ||
id: '' | ||
id: '', | ||
getMenuItemsRef: () => ({ | ||
current: {} | ||
}) | ||
}); | ||
const normalizeArrowKey = event => { | ||
const key = event.key, | ||
keyCode = event.keyCode; | ||
const { | ||
key, | ||
keyCode | ||
} = event; | ||
@@ -143,2 +111,40 @@ if (keyCode >= 37 && keyCode <= 40 && key.indexOf('Arrow') !== 0) { | ||
const getFirstPossibleIndex = (itemsLength, map) => { | ||
for (let i = 0; i < itemsLength; i++) { | ||
if (map[i]) { | ||
return i; | ||
} | ||
} | ||
return null; | ||
}; | ||
const getNextIndex = (currentIndex, itemsLength, map) => { | ||
for (let i = currentIndex === null ? 0 : currentIndex + 1; i < itemsLength; i++) { | ||
if (map[i]) { | ||
return i; | ||
} | ||
} | ||
return getFirstPossibleIndex(itemsLength, map); | ||
}; | ||
const getPreviousIndex = (currentIndex, itemsLength, map) => { | ||
if (currentIndex !== null) { | ||
for (let i = currentIndex - 1; i >= 0; i--) { | ||
if (map[i]) { | ||
return i; | ||
} | ||
} | ||
} | ||
for (let i = itemsLength - 1; i >= 0; i--) { | ||
if (map[i]) { | ||
return i; | ||
} | ||
} | ||
return getFirstPossibleIndex(itemsLength, map); | ||
}; | ||
function _extends() { | ||
@@ -163,14 +169,16 @@ _extends = Object.assign || function (target) { | ||
const Button = (_ref) => { | ||
let children = _ref.children, | ||
let { | ||
children | ||
} = _ref, | ||
props = _objectWithoutProperties(_ref, ["children"]); | ||
const _React$useContext = React.useContext(DownscreenContext), | ||
state = _React$useContext.state, | ||
setState = _React$useContext.setState, | ||
itemsLength = _React$useContext.itemsLength, | ||
id = _React$useContext.id; | ||
const { | ||
state, | ||
setState, | ||
itemsLength, | ||
id, | ||
getMenuItemsRef | ||
} = React.useContext(DownscreenContext); | ||
const onBlur = React.useCallback(() => { | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: 0, | ||
isOpen: false | ||
@@ -190,4 +198,5 @@ })); | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: 0, | ||
isOpen: !s.isOpen | ||
isOpen: !s.isOpen, | ||
highlightedIndex: null, | ||
lastKey: ' ' | ||
})); | ||
@@ -203,4 +212,5 @@ break; | ||
selectedIndex: s.highlightedIndex, | ||
highlightedIndex: 0, | ||
isOpen: false | ||
highlightedIndex: null, | ||
isOpen: false, | ||
lastKey: 'Enter' | ||
})); | ||
@@ -216,4 +226,5 @@ } | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: 0, | ||
isOpen: false | ||
isOpen: false, | ||
highlightedIndex: null, | ||
lastKey: 'Escape' | ||
})); | ||
@@ -225,11 +236,13 @@ break; | ||
{ | ||
event.preventDefault(); | ||
if (state.isOpen) { | ||
event.preventDefault(); | ||
const nextIndex = state.highlightedIndex === 0 ? itemsLength - 1 : state.highlightedIndex - 1; | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: nextIndex | ||
highlightedIndex: getPreviousIndex(state.highlightedIndex, itemsLength, getMenuItemsRef().current), | ||
lastKey: 'ArrowUp' | ||
})); | ||
} else { | ||
setState(s => _objectSpread({}, s, { | ||
isOpen: true | ||
isOpen: true, | ||
lastKey: 'ArrowUp' | ||
})); | ||
@@ -246,9 +259,10 @@ } | ||
if (state.isOpen) { | ||
const nextIndex = state.highlightedIndex === itemsLength - 1 ? 0 : state.highlightedIndex + 1; | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: nextIndex | ||
highlightedIndex: getNextIndex(state.highlightedIndex, itemsLength, getMenuItemsRef().current), | ||
lastKey: 'ArrowDown' | ||
})); | ||
} else { | ||
setState(s => _objectSpread({}, s, { | ||
isOpen: true | ||
isOpen: true, | ||
lastKey: 'ArrowDown' | ||
})); | ||
@@ -260,3 +274,3 @@ } | ||
} | ||
}, [state.highlightedIndex, state.isOpen, itemsLength]); | ||
}, [itemsLength, state.highlightedIndex, state.isOpen]); | ||
const onClick = React.useCallback(event => { | ||
@@ -317,15 +331,13 @@ event.preventDefault(); | ||
const Downscreen = (_ref) => { | ||
let children = _ref.children, | ||
onChange = _ref.onChange, | ||
_ref$initial = _ref.initial, | ||
initial = _ref$initial === void 0 ? initialState : _ref$initial, | ||
itemsLength = _ref.itemsLength, | ||
id = _ref.id, | ||
let { | ||
children, | ||
onChange, | ||
initial = initialState, | ||
itemsLength, | ||
id | ||
} = _ref, | ||
props = _objectWithoutProperties(_ref, ["children", "onChange", "initial", "itemsLength", "id"]); | ||
const _React$useState = React.useState(initial), | ||
_React$useState2 = _slicedToArray(_React$useState, 2), | ||
state = _React$useState2[0], | ||
setState = _React$useState2[1]; | ||
const menuItemsRef = React.useRef({}); | ||
const [state, setState] = React.useState(initial); | ||
const value = React.useMemo(() => ({ | ||
@@ -335,14 +347,37 @@ state, | ||
itemsLength, | ||
id | ||
id, | ||
getMenuItemsRef: () => menuItemsRef | ||
}), [state, itemsLength, id]); | ||
useEffectAfterMount(() => { | ||
onChange(state.selectedIndex); | ||
}, [state.selectedIndex]); | ||
useEffectAfterMount(() => { | ||
if (state.highlightedIndex >= itemsLength) { | ||
if (state.isOpen) { | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: 0 | ||
highlightedIndex: null | ||
})); | ||
} | ||
}, [state.highlightedIndex, itemsLength]); | ||
}, [itemsLength]); | ||
useEffectAfterMount(() => { | ||
if (state.isOpen) { | ||
switch (state.lastKey) { | ||
case 'ArrowUp': | ||
{ | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: getPreviousIndex(getFirstPossibleIndex(itemsLength, menuItemsRef.current), itemsLength, menuItemsRef.current) | ||
})); | ||
break; | ||
} | ||
case 'ArrowDown': | ||
{ | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: getFirstPossibleIndex(itemsLength, menuItemsRef.current), | ||
lastKey: 'ArrowDown' | ||
})); | ||
break; | ||
} | ||
} | ||
} | ||
}, [state.isOpen]); | ||
useEffectAfterMount(() => { | ||
onChange(state.selectedIndex); | ||
}, [state.selectedIndex]); | ||
return React.createElement(DownscreenContext.Provider, { | ||
@@ -380,10 +415,12 @@ value: value | ||
const Menu = (_ref) => { | ||
let children = _ref.children, | ||
let { | ||
children | ||
} = _ref, | ||
props = _objectWithoutProperties(_ref, ["children"]); | ||
const _React$useContext = React.useContext(DownscreenContext), | ||
state = _React$useContext.state, | ||
itemsLength = _React$useContext.itemsLength, | ||
id = _React$useContext.id; | ||
const { | ||
state, | ||
itemsLength, | ||
id | ||
} = React.useContext(DownscreenContext); | ||
const menuChildren = React.useMemo(() => Array.from({ | ||
@@ -421,14 +458,27 @@ length: itemsLength | ||
const MenuItem = (_ref) => { | ||
let index = _ref.index, | ||
children = _ref.children, | ||
let { | ||
index, | ||
children | ||
} = _ref, | ||
props = _objectWithoutProperties(_ref, ["index", "children"]); | ||
const _React$useContext = React.useContext(DownscreenContext), | ||
state = _React$useContext.state, | ||
setState = _React$useContext.setState, | ||
id = _React$useContext.id; | ||
const { | ||
state, | ||
setState, | ||
id, | ||
getMenuItemsRef | ||
} = React.useContext(DownscreenContext); | ||
const shouldScroll = React.useRef(true); | ||
const scrollRef = React.useRef(null); | ||
React.useEffect(() => { | ||
getMenuItemsRef().current = _objectSpread({}, getMenuItemsRef().current, { | ||
[index]: true | ||
}); | ||
return () => { | ||
getMenuItemsRef().current = _objectSpread({}, getMenuItemsRef().current, { | ||
[index]: false | ||
}); | ||
}; | ||
}, []); | ||
React.useEffect(() => { | ||
if (state.highlightedIndex === index && shouldScroll.current && scrollRef.current) { | ||
@@ -435,0 +485,0 @@ scrollIntoViewIfNeeded(scrollRef.current, { |
@@ -6,2 +6,4 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
import normalizeArrowKey from "./normalizeArrowKey.js"; | ||
import getNextIndex from "./getNextIndex.js"; | ||
import getPreviousIndex from "./getPreviousIndex.js"; | ||
@@ -16,7 +18,7 @@ const Button = ({ | ||
itemsLength, | ||
id | ||
id, | ||
getMenuItemsRef | ||
} = React.useContext(DownscreenContext); | ||
const onBlur = React.useCallback(() => { | ||
setState(s => ({ ...s, | ||
highlightedIndex: 0, | ||
isOpen: false | ||
@@ -36,4 +38,5 @@ })); | ||
setState(s => ({ ...s, | ||
highlightedIndex: 0, | ||
isOpen: !s.isOpen | ||
isOpen: !s.isOpen, | ||
highlightedIndex: null, | ||
lastKey: ' ' | ||
})); | ||
@@ -49,4 +52,5 @@ break; | ||
selectedIndex: s.highlightedIndex, | ||
highlightedIndex: 0, | ||
isOpen: false | ||
highlightedIndex: null, | ||
isOpen: false, | ||
lastKey: 'Enter' | ||
})); | ||
@@ -62,4 +66,5 @@ } | ||
setState(s => ({ ...s, | ||
highlightedIndex: 0, | ||
isOpen: false | ||
isOpen: false, | ||
highlightedIndex: null, | ||
lastKey: 'Escape' | ||
})); | ||
@@ -71,11 +76,13 @@ break; | ||
{ | ||
event.preventDefault(); | ||
if (state.isOpen) { | ||
event.preventDefault(); | ||
const nextIndex = state.highlightedIndex === 0 ? itemsLength - 1 : state.highlightedIndex - 1; | ||
setState(s => ({ ...s, | ||
highlightedIndex: nextIndex | ||
highlightedIndex: getPreviousIndex(state.highlightedIndex, itemsLength, getMenuItemsRef().current), | ||
lastKey: 'ArrowUp' | ||
})); | ||
} else { | ||
setState(s => ({ ...s, | ||
isOpen: true | ||
isOpen: true, | ||
lastKey: 'ArrowUp' | ||
})); | ||
@@ -92,9 +99,10 @@ } | ||
if (state.isOpen) { | ||
const nextIndex = state.highlightedIndex === itemsLength - 1 ? 0 : state.highlightedIndex + 1; | ||
setState(s => ({ ...s, | ||
highlightedIndex: nextIndex | ||
highlightedIndex: getNextIndex(state.highlightedIndex, itemsLength, getMenuItemsRef().current), | ||
lastKey: 'ArrowDown' | ||
})); | ||
} else { | ||
setState(s => ({ ...s, | ||
isOpen: true | ||
isOpen: true, | ||
lastKey: 'ArrowDown' | ||
})); | ||
@@ -106,3 +114,3 @@ } | ||
} | ||
}, [state.highlightedIndex, state.isOpen, itemsLength]); | ||
}, [itemsLength, state.highlightedIndex, state.isOpen]); | ||
const onClick = React.useCallback(event => { | ||
@@ -109,0 +117,0 @@ event.preventDefault(); |
@@ -5,3 +5,5 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
import DownscreenContext, { initialState } from "./DownscreenContext.js"; | ||
import useEffectAfterMount from "./useEffectAfterMount.js"; // TODO: extract custom hooks, break them down by domain | ||
import useEffectAfterMount from "./useEffectAfterMount.js"; | ||
import getFirstPossibleIndex from "./getFirstPossibleIndex.js"; | ||
import getPreviousIndex from "./getPreviousIndex.js"; // TODO: extract custom hooks, break them down by domain | ||
// TODO: clean up state management (useReducer), memoize more for better performance (useMemo) | ||
@@ -17,2 +19,3 @@ | ||
}) => { | ||
const menuItemsRef = React.useRef({}); | ||
const [state, setState] = React.useState(initial); | ||
@@ -23,14 +26,37 @@ const value = React.useMemo(() => ({ | ||
itemsLength, | ||
id | ||
id, | ||
getMenuItemsRef: () => menuItemsRef | ||
}), [state, itemsLength, id]); | ||
useEffectAfterMount(() => { | ||
onChange(state.selectedIndex); | ||
}, [state.selectedIndex]); | ||
useEffectAfterMount(() => { | ||
if (state.highlightedIndex >= itemsLength) { | ||
if (state.isOpen) { | ||
setState(s => ({ ...s, | ||
highlightedIndex: 0 | ||
highlightedIndex: null | ||
})); | ||
} | ||
}, [state.highlightedIndex, itemsLength]); | ||
}, [itemsLength]); | ||
useEffectAfterMount(() => { | ||
if (state.isOpen) { | ||
switch (state.lastKey) { | ||
case 'ArrowUp': | ||
{ | ||
setState(s => ({ ...s, | ||
highlightedIndex: getPreviousIndex(getFirstPossibleIndex(itemsLength, menuItemsRef.current), itemsLength, menuItemsRef.current) | ||
})); | ||
break; | ||
} | ||
case 'ArrowDown': | ||
{ | ||
setState(s => ({ ...s, | ||
highlightedIndex: getFirstPossibleIndex(itemsLength, menuItemsRef.current), | ||
lastKey: 'ArrowDown' | ||
})); | ||
break; | ||
} | ||
} | ||
} | ||
}, [state.isOpen]); | ||
useEffectAfterMount(() => { | ||
onChange(state.selectedIndex); | ||
}, [state.selectedIndex]); | ||
return React.createElement(DownscreenContext.Provider, { | ||
@@ -37,0 +63,0 @@ value: value |
@@ -5,3 +5,4 @@ import * as React from 'react'; | ||
selectedIndex: null, | ||
highlightedIndex: 0 | ||
highlightedIndex: null, | ||
lastKey: null | ||
}; | ||
@@ -12,4 +13,7 @@ const DownscreenContext = React.createContext({ | ||
itemsLength: 0, | ||
id: '' | ||
id: '', | ||
getMenuItemsRef: () => ({ | ||
current: {} | ||
}) | ||
}); | ||
export default DownscreenContext; |
@@ -15,3 +15,4 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
setState, | ||
id | ||
id, | ||
getMenuItemsRef | ||
} = React.useContext(DownscreenContext); | ||
@@ -21,2 +22,12 @@ const shouldScroll = React.useRef(true); | ||
React.useEffect(() => { | ||
getMenuItemsRef().current = { ...getMenuItemsRef().current, | ||
[index]: true | ||
}; | ||
return () => { | ||
getMenuItemsRef().current = { ...getMenuItemsRef().current, | ||
[index]: false | ||
}; | ||
}; | ||
}, []); | ||
React.useEffect(() => { | ||
if (state.highlightedIndex === index && shouldScroll.current && scrollRef.current) { | ||
@@ -23,0 +34,0 @@ scrollIntoViewIfNeeded(scrollRef.current, { |
@@ -1,3 +0,2 @@ | ||
/// <reference types="react" /> | ||
declare const QuickExample: () => JSX.Element; | ||
export default QuickExample; |
import * as React from 'react'; | ||
import { State } from './DownscreenContext'; | ||
declare type Props = React.HTMLAttributes<HTMLDivElement> & { | ||
export declare type Props = React.HTMLAttributes<HTMLDivElement> & { | ||
children: React.ReactNode; | ||
@@ -8,5 +8,5 @@ onChange: (selectedIndex: State['selectedIndex']) => void; | ||
itemsLength: number; | ||
id: string; | ||
id: Required<React.HTMLAttributes<HTMLDivElement>['id']>; | ||
}; | ||
declare const Downscreen: ({ children, onChange, initial, itemsLength, id, ...props }: Props) => JSX.Element; | ||
export default Downscreen; |
@@ -5,8 +5,13 @@ import * as React from 'react'; | ||
selectedIndex: number | null; | ||
highlightedIndex: number; | ||
highlightedIndex: number | null; | ||
lastKey: ' ' | 'Enter' | 'Escape' | 'ArrowUp' | 'ArrowDown' | null; | ||
} | ||
export interface MenuItemsRef { | ||
[key: string]: boolean; | ||
} | ||
export declare const initialState: { | ||
isOpen: boolean; | ||
selectedIndex: null; | ||
highlightedIndex: number; | ||
highlightedIndex: null; | ||
lastKey: null; | ||
}; | ||
@@ -17,4 +22,5 @@ declare const DownscreenContext: React.Context<{ | ||
itemsLength: number; | ||
id: string; | ||
id: string | undefined; | ||
getMenuItemsRef: () => React.MutableRefObject<MenuItemsRef>; | ||
}>; | ||
export default DownscreenContext; |
@@ -115,3 +115,4 @@ import { createContext, useContext, useCallback, useMemo, createElement, useRef, useEffect, useState } from 'react'; | ||
selectedIndex: null, | ||
highlightedIndex: 0 | ||
highlightedIndex: null, | ||
lastKey: null | ||
}; | ||
@@ -122,3 +123,6 @@ const DownscreenContext = createContext({ | ||
itemsLength: 0, | ||
id: '' | ||
id: '', | ||
getMenuItemsRef: () => ({ | ||
current: {} | ||
}) | ||
}); | ||
@@ -137,2 +141,40 @@ | ||
const getFirstPossibleIndex = (itemsLength, map) => { | ||
for (let i = 0; i < itemsLength; i++) { | ||
if (map[i]) { | ||
return i; | ||
} | ||
} | ||
return null; | ||
}; | ||
const getNextIndex = (currentIndex, itemsLength, map) => { | ||
for (let i = currentIndex === null ? 0 : currentIndex + 1; i < itemsLength; i++) { | ||
if (map[i]) { | ||
return i; | ||
} | ||
} | ||
return getFirstPossibleIndex(itemsLength, map); | ||
}; | ||
const getPreviousIndex = (currentIndex, itemsLength, map) => { | ||
if (currentIndex !== null) { | ||
for (let i = currentIndex - 1; i >= 0; i--) { | ||
if (map[i]) { | ||
return i; | ||
} | ||
} | ||
} | ||
for (let i = itemsLength - 1; i >= 0; i--) { | ||
if (map[i]) { | ||
return i; | ||
} | ||
} | ||
return getFirstPossibleIndex(itemsLength, map); | ||
}; | ||
function _extends() { | ||
@@ -164,7 +206,7 @@ _extends = Object.assign || function (target) { | ||
itemsLength = _React$useContext.itemsLength, | ||
id = _React$useContext.id; | ||
id = _React$useContext.id, | ||
getMenuItemsRef = _React$useContext.getMenuItemsRef; | ||
const onBlur = useCallback(() => { | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: 0, | ||
isOpen: false | ||
@@ -184,4 +226,5 @@ })); | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: 0, | ||
isOpen: !s.isOpen | ||
isOpen: !s.isOpen, | ||
highlightedIndex: null, | ||
lastKey: ' ' | ||
})); | ||
@@ -197,4 +240,5 @@ break; | ||
selectedIndex: s.highlightedIndex, | ||
highlightedIndex: 0, | ||
isOpen: false | ||
highlightedIndex: null, | ||
isOpen: false, | ||
lastKey: 'Enter' | ||
})); | ||
@@ -210,4 +254,5 @@ } | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: 0, | ||
isOpen: false | ||
isOpen: false, | ||
highlightedIndex: null, | ||
lastKey: 'Escape' | ||
})); | ||
@@ -219,11 +264,13 @@ break; | ||
{ | ||
event.preventDefault(); | ||
if (state.isOpen) { | ||
event.preventDefault(); | ||
const nextIndex = state.highlightedIndex === 0 ? itemsLength - 1 : state.highlightedIndex - 1; | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: nextIndex | ||
highlightedIndex: getPreviousIndex(state.highlightedIndex, itemsLength, getMenuItemsRef().current), | ||
lastKey: 'ArrowUp' | ||
})); | ||
} else { | ||
setState(s => _objectSpread({}, s, { | ||
isOpen: true | ||
isOpen: true, | ||
lastKey: 'ArrowUp' | ||
})); | ||
@@ -240,9 +287,10 @@ } | ||
if (state.isOpen) { | ||
const nextIndex = state.highlightedIndex === itemsLength - 1 ? 0 : state.highlightedIndex + 1; | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: nextIndex | ||
highlightedIndex: getNextIndex(state.highlightedIndex, itemsLength, getMenuItemsRef().current), | ||
lastKey: 'ArrowDown' | ||
})); | ||
} else { | ||
setState(s => _objectSpread({}, s, { | ||
isOpen: true | ||
isOpen: true, | ||
lastKey: 'ArrowDown' | ||
})); | ||
@@ -254,3 +302,3 @@ } | ||
} | ||
}, [state.highlightedIndex, state.isOpen, itemsLength]); | ||
}, [itemsLength, state.highlightedIndex, state.isOpen]); | ||
const onClick = useCallback(event => { | ||
@@ -319,2 +367,4 @@ event.preventDefault(); | ||
const menuItemsRef = useRef({}); | ||
const _React$useState = useState(initial), | ||
@@ -329,14 +379,37 @@ _React$useState2 = _slicedToArray(_React$useState, 2), | ||
itemsLength, | ||
id | ||
id, | ||
getMenuItemsRef: () => menuItemsRef | ||
}), [state, itemsLength, id]); | ||
useEffectAfterMount(() => { | ||
onChange(state.selectedIndex); | ||
}, [state.selectedIndex]); | ||
useEffectAfterMount(() => { | ||
if (state.highlightedIndex >= itemsLength) { | ||
if (state.isOpen) { | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: 0 | ||
highlightedIndex: null | ||
})); | ||
} | ||
}, [state.highlightedIndex, itemsLength]); | ||
}, [itemsLength]); | ||
useEffectAfterMount(() => { | ||
if (state.isOpen) { | ||
switch (state.lastKey) { | ||
case 'ArrowUp': | ||
{ | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: getPreviousIndex(getFirstPossibleIndex(itemsLength, menuItemsRef.current), itemsLength, menuItemsRef.current) | ||
})); | ||
break; | ||
} | ||
case 'ArrowDown': | ||
{ | ||
setState(s => _objectSpread({}, s, { | ||
highlightedIndex: getFirstPossibleIndex(itemsLength, menuItemsRef.current), | ||
lastKey: 'ArrowDown' | ||
})); | ||
break; | ||
} | ||
} | ||
} | ||
}, [state.isOpen]); | ||
useEffectAfterMount(() => { | ||
onChange(state.selectedIndex); | ||
}, [state.selectedIndex]); | ||
return createElement(DownscreenContext.Provider, { | ||
@@ -421,3 +494,4 @@ value: value | ||
setState = _React$useContext.setState, | ||
id = _React$useContext.id; | ||
id = _React$useContext.id, | ||
getMenuItemsRef = _React$useContext.getMenuItemsRef; | ||
@@ -427,2 +501,12 @@ const shouldScroll = useRef(true); | ||
useEffect(() => { | ||
getMenuItemsRef().current = _objectSpread({}, getMenuItemsRef().current, { | ||
[index]: true | ||
}); | ||
return () => { | ||
getMenuItemsRef().current = _objectSpread({}, getMenuItemsRef().current, { | ||
[index]: false | ||
}); | ||
}; | ||
}, []); | ||
useEffect(() => { | ||
if (state.highlightedIndex === index && shouldScroll.current && scrollRef.current) { | ||
@@ -429,0 +513,0 @@ scrollIntoViewIfNeeded(scrollRef.current, { |
{ | ||
"name": "react-downscreen", | ||
"description": "React Downscreen ⛹️", | ||
"version": "0.0.7", | ||
"version": "0.0.8", | ||
"license": "MIT", | ||
@@ -24,13 +24,13 @@ "files": [ | ||
"devDependencies": { | ||
"@babel/core": "7.4.4", | ||
"@babel/preset-env": "7.4.4", | ||
"@babel/core": "7.4.5", | ||
"@babel/preset-env": "7.4.5", | ||
"@babel/preset-react": "7.0.0", | ||
"@babel/preset-typescript": "7.3.3", | ||
"@pika/pack": "0.3.7", | ||
"@pika/plugin-build-node": "0.3.16", | ||
"@pika/plugin-build-types": "0.3.16", | ||
"@pika/plugin-build-web": "0.3.16", | ||
"@pika/plugin-standard-pkg": "0.3.16", | ||
"@types/react": "16.8.17", | ||
"@types/styled-components": "4.1.14", | ||
"@pika/plugin-build-node": "0.4.0", | ||
"@pika/plugin-build-types": "0.4.0", | ||
"@pika/plugin-build-web": "0.4.0", | ||
"@pika/plugin-standard-pkg": "0.4.0", | ||
"@types/react": "16.8.18", | ||
"@types/styled-components": "4.1.15", | ||
"docz": "1.2.0", | ||
@@ -37,0 +37,0 @@ "docz-theme-default": "1.2.0", |
44838
29
1419