@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
1 lines • 7.97 kB
Source Map (JSON)
{"version":3,"file":"atoms.mjs","names":[],"sources":["../../src/LobeSwitch/atoms.tsx"],"sourcesContent":["'use client';\n\nimport { Switch } from '@base-ui/react/switch';\nimport { cx } from 'antd-style';\nimport type { KeyboardEvent, MouseEvent } from 'react';\nimport { createContext, useContext, useMemo, useRef, useState } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport { useMotionComponent } from '@/MotionProvider';\n\nimport { rootVariants, styles, thumbVariants } from './style';\nimport type {\n LobeSwitchChangeEventHandler,\n LobeSwitchContextType,\n LobeSwitchIconPosition,\n LobeSwitchIconProps,\n LobeSwitchRootProps,\n LobeSwitchThumbProps,\n} from './type';\n\nconst LobeSwitchContext = createContext<LobeSwitchContextType | null>(null);\n\nexport const useLobeSwitchContext = () => {\n const context = useContext(LobeSwitchContext);\n if (!context) {\n throw new Error('useLobeSwitchContext must be used within a LobeSwitchRoot');\n }\n return context;\n};\n\ntype LobeSwitchRootInternalProps = Omit<LobeSwitchRootProps, 'onCheckedChange' | 'onClick'> & {\n onCheckedChange?: LobeSwitchChangeEventHandler;\n onClick?: LobeSwitchChangeEventHandler;\n};\n\nexport const LobeSwitchRoot = ({\n checked,\n className,\n defaultChecked,\n onCheckedChange,\n onClick,\n size = 'default',\n children,\n disabled,\n readOnly,\n required,\n inputRef,\n id,\n name,\n ...rest\n}: LobeSwitchRootInternalProps) => {\n const Motion = useMotionComponent();\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 handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n lastEventRef.current = event;\n }\n (rest as any).onKeyDown?.(event);\n };\n\n return (\n <LobeSwitchContext.Provider value={contextValue}>\n <Switch.Root\n checked={isChecked}\n defaultChecked={defaultChecked}\n disabled={disabled}\n id={id}\n inputRef={inputRef}\n name={name}\n onCheckedChange={setIsChecked}\n readOnly={readOnly}\n render={\n <Motion.button\n {...rest}\n className={cx(baseClassName, className)}\n initial={false}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onTap={() => setIsPressed(false)}\n onTapCancel={() => setIsPressed(false)}\n onTapStart={() => setIsPressed(true)}\n whileTap=\"tap\"\n />\n }\n required={required}\n >\n {children}\n </Switch.Root>\n </LobeSwitchContext.Provider>\n );\n};\n\nLobeSwitchRoot.displayName = 'LobeSwitchRoot';\n\nexport const LobeSwitchThumb = ({\n className,\n pressedAnimation,\n size = 'default',\n transition = { damping: 25, stiffness: 300, type: 'spring' },\n children,\n ...rest\n}: LobeSwitchThumbProps) => {\n const Motion = useMotionComponent();\n const { isPressed } = useLobeSwitchContext();\n const baseClassName = thumbVariants({ size });\n\n const defaultPressedAnimation = {\n width: size === 'small' ? 16 : 22,\n };\n\n return (\n <Switch.Thumb\n render={\n <Motion.span\n animate={isPressed ? pressedAnimation || defaultPressedAnimation : undefined}\n className={cx(baseClassName, className)}\n layout\n transition={transition}\n {...rest}\n >\n {children}\n </Motion.span>\n }\n />\n );\n};\n\nLobeSwitchThumb.displayName = 'LobeSwitchThumb';\n\nconst getIconPositionClass = (position: LobeSwitchIconPosition, 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 LobeSwitchIcon = ({\n children,\n className,\n position,\n transition = { bounce: 0, type: 'spring' },\n ...rest\n}: LobeSwitchIconProps & { children?: React.ReactNode; size?: 'default' | 'small' }) => {\n const Motion = useMotionComponent();\n const { isChecked } = useLobeSwitchContext();\n const size = (rest as any).size || 'default';\n\n const isAnimated = useMemo(() => {\n if (position === 'right') return !isChecked;\n if (position === 'left') return isChecked;\n if (position === 'thumb') return true;\n return false;\n }, [position, isChecked]);\n\n const positionClass = getIconPositionClass(position, size);\n\n return (\n <Motion.span\n animate={isAnimated ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0 }}\n className={cx(styles.icon, positionClass, className)}\n transition={transition}\n {...rest}\n >\n {children}\n </Motion.span>\n );\n};\n\nLobeSwitchIcon.displayName = 'LobeSwitchIcon';\n\nexport { styles as lobeSwitchStyles } from './style';\n"],"mappings":"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"}