Skip to content

Commit

Permalink
Explode ViewStack so that other components sharing the API can… (#1260)
Browse files Browse the repository at this point in the history
Explode ViewStack so that other components sharing the API can be made
  • Loading branch information
ptbrowne authored Nov 22, 2019
2 parents 7b24dcd + a012db5 commit 303ac4d
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 31 deletions.
36 changes: 5 additions & 31 deletions react/ViewStack/index.jsx → react/ViewStack/ViewStack.jsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,12 @@
import React, { useState, useContext } from 'react'
import React from 'react'
import SwipeableViews from 'react-swipeable-views'
import { useStack } from './hooks'
import { ViewStackContext } from './context'

// This is guessed, I could not see how to interface properly with
// react-swipeable-views's onTransitionEnd
const STEPPER_TRANSITION_DURATION_MS = 500

export const ViewStackContext = React.createContext()
export const useViewStack = () => useContext(ViewStackContext)

const sleep = duration => new Promise(resolve => setTimeout(resolve, duration))

const useStack = initialState => {
const [arr, setArray] = useState(initialState)
const [curIndex, setCurIndex] = useState(initialState.length - 1)

const push = item => {
const newArr = [...arr, item]
setArray(newArr)
setCurIndex(curIndex + 1)
}

const pop = async () => {
if (arr.length <= 1) {
return
}
const newArr = arr.slice(0, -1)
setCurIndex(curIndex - 1)
await sleep(STEPPER_TRANSITION_DURATION_MS)
setArray(newArr)
}

return [arr, curIndex, push, pop]
}

/**
* Wraps children to builds an animated carrousel where children
* can push/pop views.
Expand All @@ -44,11 +18,11 @@ const useStack = initialState => {
*/
const ViewStack = ({ children }) => {
const [stChildren, curIndex, stackPush, stackPop] = useStack(
React.Children.toArray(children)
React.Children.toArray(children),
{ popDelay: STEPPER_TRANSITION_DURATION_MS }
)

const contextValue = { stackPush, stackPop }

return (
<ViewStackContext.Provider value={contextValue}>
<SwipeableViews animateHeight disabled index={curIndex}>
Expand Down
4 changes: 4 additions & 0 deletions react/ViewStack/context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import React, { useContext } from 'react'

export const ViewStackContext = React.createContext()
export const useViewStack = () => useContext(ViewStackContext)
30 changes: 30 additions & 0 deletions react/ViewStack/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useState } from 'react'

const sleep = duration => new Promise(resolve => setTimeout(resolve, duration))

const useStack = (initialState, options = {}) => {
const [arr, setArray] = useState(initialState)
const [curIndex, setCurIndex] = useState(initialState.length - 1)

const push = (item, itemOptions) => {
const newArr = [...arr, itemOptions ? [item, itemOptions] : item]
setArray(newArr)
setCurIndex(curIndex + 1)
}

const pop = async () => {
if (arr.length <= 1) {
return
}
const newArr = arr.slice(0, -1)
setCurIndex(curIndex - 1)
if (options.popDelay) {
await sleep(options.popDelay)
}
setArray(newArr)
}

return [arr, curIndex, push, pop]
}

export { useStack }
2 changes: 2 additions & 0 deletions react/ViewStack/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './ViewStack'
export { useViewStack, ViewStackContext } from './context'
1 change: 1 addition & 0 deletions react/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export { default as QuotaAlert } from './QuotaAlert'
export { default as ThresholdBar } from './ThresholdBar'
export {
default as ViewStack,
ModalStack,
useViewStack,
ViewStackContext
} from './ViewStack'

0 comments on commit 303ac4d

Please sign in to comment.