| import { useMemo } from 'react' |
| import { stringWidth } from '../../ink/stringWidth.js' |
| import { type DOMElement, useAnimationFrame } from '../../ink.js' |
| import type { SpinnerMode } from './types.js' |
|
|
| export function useShimmerAnimation( |
| mode: SpinnerMode, |
| message: string, |
| isStalled: boolean, |
| ): [ref: (element: DOMElement | null) => void, glimmerIndex: number] { |
| const glimmerSpeed = mode === 'requesting' ? 50 : 200 |
| |
| |
| |
| |
| |
| const [ref, time] = useAnimationFrame(isStalled ? null : glimmerSpeed) |
| const messageWidth = useMemo(() => stringWidth(message), [message]) |
|
|
| if (isStalled) { |
| return [ref, -100] |
| } |
|
|
| const cyclePosition = Math.floor(time / glimmerSpeed) |
| const cycleLength = messageWidth + 20 |
|
|
| if (mode === 'requesting') { |
| return [ref, (cyclePosition % cycleLength) - 10] |
| } |
| return [ref, messageWidth + 10 - (cyclePosition % cycleLength)] |
| } |
|
|