import { AnimatedCursor } from '@hanzo/ui'
One cursor for the whole page: a dot with an eight-point trail that grows over a button, turns into a bar over a text field and squares over anything marked `data-cursor="grab"`; the first button puts the native cursor back.
Drag me
export function Default() {const [on, setOn] = useState(false)return (<YStack gap="$3" items="flex-start"><AnimatedCursor isVisible={on} hideOnTouch={false} hoverScale={2} /><Button variant={on ? "primary" : "outline"} onPress={() => setOn(!on)}>{on ? "Native cursor" : "Animated cursor"}</Button><XStack gap="$3" items="center" flexWrap="wrap"><Button variant="outline">A button</Button><Input type="text" placeholder="A text field" /><Paragraph data-cursor="grab" color="$quiet">Drag me</Paragraph></XStack></YStack>)}
`difference` inverts whatever the dot crosses; a larger dot, no trail, and a slower settle.
Move over this inverted panel
export function BlendMode() {const [on, setOn] = useState(false)return (<YStack gap="$3" items="flex-start"><AnimatedCursor isVisible={on} hideOnTouch={false} blendMode="difference" color="#ffffff" showTrail={false} size={32} animationDuration={400} /><Button variant={on ? "primary" : "outline"} onPress={() => setOn(!on)}>{on ? "Native cursor" : "Animated cursor"}</Button><YStack p="$5" rounded="$4" bg="$ink"><Paragraph color="$sunken">Move over this inverted panel</Paragraph></YStack></YStack>)}
export type AnimatedCursorBlendMode =| 'normal'| 'multiply'| 'screen'| 'overlay'| 'darken'| 'lighten'| 'color-dodge'| 'color-burn'| 'hard-light'| 'soft-light'| 'difference'| 'exclusion'
export type AnimatedCursorShape = 'default' | 'pointer' | 'text' | 'grab' | 'grabbing'
export type CursorPosition = { x: number; y: number }
export type CursorState = {position: CursorPositionisHovering: booleanisClicking: booleancursorType: AnimatedCursorShape}
export type AnimatedCursorProps = {/** Whether the cursor renders at all; off, the native cursor is untouched. */isVisible?: boolean/** Diameter of the dot, in px. */size?: number/** Fill of the dot: a theme token such as `$color`, or a CSS colour. */color?: string/** Fill of each trailing dot; by default the fill at a third of its strength. */trailColor?: string/** How long the dot and the ring take to settle, in ms. */animationDuration?: number/** Whether a fading trail of past positions renders behind the dot. */showTrail?: boolean/** How many past positions the trail keeps. */trailLength?: number/** `mix-blend-mode` for the dot, the trail and the hover ring. */blendMode?: AnimatedCursorBlendMode/** Scale the dot reaches while hovering an interactive element. */hoverScale?: number/** Render nothing on a device that reports touch support. */hideOnTouch?: boolean/** Class notation for the fixed frame. */className?: string/** How long the click scale takes to release, in ms. */clickAnimationDuration?: number/** Stacking context of the frame, and of the dot within it; the trail and ring sit just under. */zIndex?: number}