UNPKG

framer-motion

Version:

An open source and production-ready motion library for React on the web

70 lines (64 loc) • 1.65 kB
import { useState, useRef } from "react" import { wrap } from "popmotion" type Cycle = (i?: number) => void type CycleState<T> = [T, Cycle] /** * Cycles through a series of visual properties. Can be used to toggle between or cycle through animations. It works similar to `useState` in React. It is provided an initial array of possible states, and returns an array of two arguments. * * @library * * ```jsx * import * as React from "react" * import { Frame, useCycle } from "framer" * * export function MyComponent() { * const [x, cycleX] = useCycle(0, 50, 100) * * return ( * <Frame * animate={{ x: x }} * onTap={() => cycleX()} * /> * ) * } * ``` * * @motion * * An index value can be passed to the returned `cycle` function to cycle to a specific index. * * ```jsx * import * as React from "react" * import { motion, useCycle } from "framer-motion" * * export const MyComponent = () => { * const [x, cycleX] = useCycle(0, 50, 100) * * return ( * <motion.div * animate={{ x: x }} * onTap={() => cycleX()} * /> * ) * } * ``` * * @param items - items to cycle through * @returns [currentState, cycleState] * * @public */ export function useCycle<T>(...items: T[]): CycleState<T> { const index = useRef(0) const [item, setItem] = useState(items[index.current]) return [ item, (next?: number) => { index.current = typeof next !== "number" ? wrap(0, items.length, index.current + 1) : next setItem(items[index.current]) }, ] }