Docs/Primitives/createCycle

createCycle

createCycle returns [state, cycle] for stepping through a fixed set of values. Calling cycle() advances to the next value; cycle(i) jumps to a specific index.

import { createCycle, motion } from 'motion-solidjs'

const variants = {
  closed: { opacity: 0, y: -10 },
  open: { opacity: 1, y: 0 },
}

function Menu() {
  const [state, cycle] = createCycle('closed', 'open')
  return (
    <>
      <button onClick={() => cycle()}>Toggle</button>
      <motion.nav animate={state()} variants={variants} />
    </>
  )
}
createCycle
create-cycle.tsxOpen ↗
import { motion, createCycle } from 'motion-solidjs'

export const meta = {
  slug: 'create-cycle',
  title: 'createCycle',
  category: 'variants',
  description: 'Step through a fixed set of variants — each click advances and wraps around.',
  tag: 'createCycle',
} as const

type MenuState = 'closed' | 'open' | 'expanded'

const variants = {
  closed: { scale: 0.85, borderRadius: '50%', rotate: 0 },
  open: { scale: 1, borderRadius: '24%', rotate: 0 },
  expanded: { scale: 1.25, borderRadius: '12%', rotate: 12 },
} satisfies Record<MenuState, object>

export default function UseCycleExample() {
  const [state, cycleState] = createCycle<MenuState>('closed', 'open', 'expanded')

  return (
    <div class="flex flex-col items-center gap-3">
      <motion.div
        class="h-24 w-24 bg-grad-mint shadow-glow"
        variants={variants}
        animate={state()}
        transition={{ type: 'spring', stiffness: 260, damping: 20 }}
      />
      <button
        onClick={() => cycleState()}
        class="rounded-full border border-border bg-card px-4 py-1.5 text-xs text-fg-muted hover:text-fg"
      >
        {state()}
      </button>
    </div>
  )
}

API

  • createCycle<T>(...values: T[]) - pass two or more values
  • Returns [state, cycle]
  • cycle() - move to the next item and wrap at the end
  • cycle(i) - jump to index i