{"version":3,"file":"atoms.mjs","names":["useControlledState"],"sources":["../../../src/base-ui/Switch/atoms.tsx"],"sourcesContent":["'use client';\n\nimport { Switch } from '@base-ui/react/switch';\nimport { cx } from 'antd-style';\nimport { animate, motionValue } from 'motion';\nimport type { CSSProperties, KeyboardEvent, MouseEvent, PointerEvent } from 'react';\nimport { createContext, use, useEffect, useMemo, useRef, useState } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport { rootVariants, styles, thumbVariants } from './style';\nimport type {\n  SwitchChangeEventHandler,\n  SwitchContextType,\n  SwitchIconPosition,\n  SwitchIconProps,\n  SwitchRootProps,\n  SwitchSize,\n  SwitchThumbProps,\n} from './type';\n\nconst THUMB_METRICS: Record<\n  SwitchSize,\n  { checkedX: number; pressedCheckedX: number; pressedWidth: number; width: number }\n> = {\n  default: { checkedX: 14, pressedCheckedX: 10, pressedWidth: 22, width: 18 },\n  small: { checkedX: 12, pressedCheckedX: 8, pressedWidth: 16, width: 12 },\n};\n\nconst THUMB_SPRING = { damping: 24, stiffness: 360, type: 'spring' as const };\n\nconst SwitchContext = createContext<SwitchContextType | null>(null);\n\nexport const useSwitchContext = () => {\n  const context = use(SwitchContext);\n  if (!context) {\n    throw new Error('useSwitchContext must be used within a SwitchRoot');\n  }\n  return context;\n};\n\ntype SwitchRootInternalProps = Omit<SwitchRootProps, 'onCheckedChange' | 'onClick'> & {\n  onCheckedChange?: SwitchChangeEventHandler;\n  onClick?: SwitchChangeEventHandler;\n};\n\nexport const SwitchRoot = ({\n  checked,\n  className,\n  defaultChecked,\n  onCheckedChange,\n  onClick,\n  onKeyDown,\n  onKeyUp,\n  onPointerCancel,\n  onPointerDown,\n  onPointerLeave,\n  onPointerUp,\n  size = 'default',\n  children,\n  disabled,\n  readOnly,\n  required,\n  inputRef,\n  id,\n  name,\n  ...rest\n}: SwitchRootInternalProps) => {\n  const [isPressed, setIsPressed] = useState(false);\n  const lastEventRef = useRef<MouseEvent<HTMLButtonElement> | KeyboardEvent<HTMLButtonElement>>(\n    null,\n  );\n\n  const [isChecked, setIsChecked] = useControlledState(defaultChecked ?? false, {\n    defaultValue: defaultChecked,\n    onChange: (value: boolean) => {\n      if (lastEventRef.current) {\n        onCheckedChange?.(value, lastEventRef.current);\n      }\n    },\n    value: checked,\n  });\n\n  const baseClassName = rootVariants({ size });\n\n  const contextValue = useMemo(\n    () => ({\n      isChecked: Boolean(isChecked),\n      isPressed,\n      setIsChecked: (value: boolean) => setIsChecked(value),\n      setIsPressed,\n    }),\n    [isChecked, isPressed, setIsChecked],\n  );\n\n  const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n    lastEventRef.current = event;\n    onClick?.(!isChecked, event);\n  };\n\n  const isInteractive = !disabled && !readOnly;\n\n  const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n    if (event.key === 'Enter' || event.key === ' ') {\n      lastEventRef.current = event;\n    }\n    if (event.key === ' ' && isInteractive) {\n      setIsPressed(true);\n    }\n    onKeyDown?.(event);\n  };\n\n  const handleKeyUp = (event: KeyboardEvent<HTMLButtonElement>) => {\n    if (event.key === ' ') {\n      setIsPressed(false);\n    }\n    onKeyUp?.(event);\n  };\n\n  const handlePointerDown = (event: PointerEvent<HTMLButtonElement>) => {\n    if (isInteractive) {\n      setIsPressed(true);\n    }\n    onPointerDown?.(event);\n  };\n\n  const handlePointerUp = (event: PointerEvent<HTMLButtonElement>) => {\n    setIsPressed(false);\n    onPointerUp?.(event);\n  };\n\n  const handlePointerCancel = (event: PointerEvent<HTMLButtonElement>) => {\n    setIsPressed(false);\n    onPointerCancel?.(event);\n  };\n\n  const handlePointerLeave = (event: PointerEvent<HTMLButtonElement>) => {\n    setIsPressed(false);\n    onPointerLeave?.(event);\n  };\n\n  return (\n    <SwitchContext value={contextValue}>\n      <Switch.Root\n        nativeButton\n        checked={isChecked}\n        defaultChecked={defaultChecked}\n        disabled={disabled}\n        id={id}\n        inputRef={inputRef}\n        name={name}\n        readOnly={readOnly}\n        required={required}\n        render={\n          <button\n            {...rest}\n            className={cx(baseClassName, className)}\n            onClick={handleClick}\n            onKeyDown={handleKeyDown}\n            onKeyUp={handleKeyUp}\n            onPointerCancel={handlePointerCancel}\n            onPointerDown={handlePointerDown}\n            onPointerLeave={handlePointerLeave}\n            onPointerUp={handlePointerUp}\n          />\n        }\n        onCheckedChange={setIsChecked}\n      >\n        {children}\n      </Switch.Root>\n    </SwitchContext>\n  );\n};\n\nSwitchRoot.displayName = 'SwitchRoot';\n\nexport const SwitchThumb = ({\n  className,\n  size = 'default',\n  style,\n  children,\n  ...rest\n}: SwitchThumbProps) => {\n  const { isChecked, isPressed } = useSwitchContext();\n  const ref = useRef<HTMLSpanElement>(null);\n  const baseClassName = thumbVariants({ size });\n\n  const metrics = THUMB_METRICS[size];\n  const targetX = isChecked ? (isPressed ? metrics.pressedCheckedX : metrics.checkedX) : 0;\n  const targetWidth = isPressed ? metrics.pressedWidth : metrics.width;\n\n  const [values] = useState(() => ({\n    width: motionValue(targetWidth),\n    x: motionValue(targetX),\n  }));\n\n  // animated keys stay referentially stable so React never rewrites mid-flight inline values\n  const [initialStyle] = useState<CSSProperties>(\n    () => ({ '--switch-x': `${targetX}px`, 'width': targetWidth }) as CSSProperties,\n  );\n\n  useEffect(() => {\n    const el = ref.current;\n    if (!el) return;\n    const unsubscribeX = values.x.on('change', (x) => {\n      el.style.setProperty('--switch-x', `${x}px`);\n    });\n    const unsubscribeWidth = values.width.on('change', (width) => {\n      el.style.setProperty('width', `${width}px`);\n    });\n    return () => {\n      unsubscribeX();\n      unsubscribeWidth();\n    };\n  }, [values]);\n\n  useEffect(() => {\n    const reduceMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false;\n    const transition = reduceMotion ? { duration: 0 } : THUMB_SPRING;\n    const animations = [\n      animate(values.x, targetX, transition),\n      animate(values.width, targetWidth, transition),\n    ];\n    return () => {\n      for (const animation of animations) animation.stop();\n    };\n  }, [values, targetX, targetWidth]);\n\n  return (\n    <Switch.Thumb\n      render={\n        <span\n          {...rest}\n          className={cx(baseClassName, className)}\n          ref={ref}\n          style={{ ...initialStyle, ...style }}\n        >\n          {children}\n        </span>\n      }\n    />\n  );\n};\n\nSwitchThumb.displayName = 'SwitchThumb';\n\nconst getIconPositionClass = (position: SwitchIconPosition, size: 'default' | 'small') => {\n  if (position === 'thumb') return styles.iconThumb;\n  if (position === 'left') return size === 'small' ? styles.iconLeftSmall : styles.iconLeft;\n  return size === 'small' ? styles.iconRightSmall : styles.iconRight;\n};\n\nexport const SwitchIcon = ({\n  children,\n  className,\n  position,\n  size = 'default',\n  ...rest\n}: SwitchIconProps) => {\n  const positionClass = getIconPositionClass(position, size);\n\n  return (\n    <span className={cx(styles.icon, positionClass, className)} {...rest}>\n      {children}\n    </span>\n  );\n};\n\nSwitchIcon.displayName = 'SwitchIcon';\n\nexport { styles as switchStyles } from './style';\n"],"mappings":"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"}