Simple and straightforward solution for selecting the next logical dataset
Live Demo
https://serhat-m.github.io/stepHandler
Install
npm i stephandler
Usage
Function Parameters: stepHandler
import stepHandler from "stepHandler"
data
{ [key: string]: unknown }[]
array of objectsdirection
'prev' | 'next'
determines the directionendBehaviour
'default' | 'jump'
behaviour after the last logical entryselector(entry) => boolean
tells stepHandler
where to look for the current state
entry
{ [key: string]: unknown }
readOnly
entry of data
valueUpdater(entry, newState) => void
used to update the current state
entry
{ [key: string]: unknown }
entry of data
newState
boolean
updated state
Example
This example navigates through the data
Array, if the keyboard keys ArrowDown
or ArrowUp
are pressed. The selected
property is used to detect and manipulate the current state.
import stepHandler from "stepHandler"
const data = [
{ id: 1, title: "Dataset 1", selected: false },
{ id: 2, title: "Dataset 2", selected: false },
{ id: 3, title: "Dataset 3", selected: false },
]
document.addEventListener("keydown", (e) => {
const direction = event.key === "ArrowDown" ? "next" : event.key === "ArrowUp" ? "prev" : false
direction &&
stepHandler(
data,
direction,
"default",
(entry) => entry.selected,
(entry, newState) => {
entry.selected = newState
},
)
})
Example Advanced
This example has the same effect as before. The difference is that the selected
property type is string
instead of boolean
.
import stepHandler from "stepHandler"
const data = [
{ id: 1, title: "Dataset 1", selected: "no" },
{ id: 2, title: "Dataset 2", selected: "no" },
{ id: 3, title: "Dataset 3", selected: "no" },
]
document.addEventListener("keydown", (e) => {
const direction = event.key === "ArrowDown" ? "next" : event.key === "ArrowUp" ? "prev" : false
direction &&
stepHandler(
data,
direction,
"default",
(entry) => entry.selected === "yes",
(entry, newState) => {
entry.selected = newState ? "yes" : "no"
},
)
})
Good to know: Immutable data
⚠️ If you are working with immutable data/state like in React, take in mind, to pass stepHandler
a mutable version of your data. Otherwise you could break your application.
Let’s look at this example, where you can update data
only with the setData
setter function:
const [data, setData] = useState([
{ id: 1, title: "Dataset 1", selected: false },
{ id: 2, title: "Dataset 2", selected: false },
{ id: 3, title: "Dataset 3", selected: false },
])
setData((prevData) =>
const dataCopy = prevData.map((entry) => ({ ...entry }))
stepHandler(dataCopy, ...)
)
setData(
produce((draft) => {
stepHandler(draft, ...)
}),
)
Example React
import stepHandler from "stepHandler"
const [data, setData] = useState([
{ id: 1, title: "Dataset 1", selected: false },
{ id: 2, title: "Dataset 2", selected: false },
{ id: 3, title: "Dataset 3", selected: false },
])
const keyDownHandler = useCallback((event) => {
const direction = event.key === "ArrowDown" ? "next" : event.key === "ArrowUp" ? "prev" : false
direction &&
setData((prevState) => {
return stepHandler(
prevState.map((entry) => ({ ...entry })),
direction,
"default",
(entry) => entry.selected,
(entry, newState) => {
entry.selected = newState
},
)
})
}, [])
useEffect(() => {
document.addEventListener("keydown", keyDownHandler)
return () => {
document.removeEventListener("keydown", keyDownHandler)
}
}, [keyDownHandler])
TypeScript
The following types are available and can be used to define e. g. typed helper functions:
Direction = "prev" | "next"
EndBehaviour = "default" | "jump”
import type { Direction, EndBehaviour } from "stepHandler"
function updateData(direction: Direction, behaviour: EndBehaviour) {
...
}
const direction: Direction | false = event.key === "ArrowDown" ? "next" : event.key === "ArrowUp" ? "prev" : false