UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

132 lines (129 loc) 4.29 kB
'use client'; import { useMotionComponent } from "../MotionProvider/index.mjs"; import { rootVariants, styles, thumbVariants } from "./style.mjs"; import { createContext, useContext, useMemo, useRef, useState } from "react"; import { jsx } from "react/jsx-runtime"; import { cx } from "antd-style"; import useControlledState from "use-merge-value"; import { Switch } from "@base-ui/react/switch"; //#region src/LobeSwitch/atoms.tsx const LobeSwitchContext = createContext(null); const useLobeSwitchContext = () => { const context = useContext(LobeSwitchContext); if (!context) throw new Error("useLobeSwitchContext must be used within a LobeSwitchRoot"); return context; }; const LobeSwitchRoot = ({ checked, className, defaultChecked, onCheckedChange, onClick, size = "default", children, disabled, readOnly, required, inputRef, id, name, ...rest }) => { const Motion = useMotionComponent(); const [isPressed, setIsPressed] = useState(false); const lastEventRef = useRef(null); const [isChecked, setIsChecked] = useControlledState(defaultChecked ?? false, { defaultValue: defaultChecked, onChange: (value) => { if (lastEventRef.current) onCheckedChange?.(value, lastEventRef.current); }, value: checked }); const baseClassName = rootVariants({ size }); const contextValue = useMemo(() => ({ isChecked: Boolean(isChecked), isPressed, setIsChecked: (value) => setIsChecked(value), setIsPressed }), [ isChecked, isPressed, setIsChecked ]); const handleClick = (event) => { lastEventRef.current = event; onClick?.(!isChecked, event); }; const handleKeyDown = (event) => { if (event.key === "Enter" || event.key === " ") lastEventRef.current = event; rest.onKeyDown?.(event); }; return /* @__PURE__ */ jsx(LobeSwitchContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(Switch.Root, { checked: isChecked, defaultChecked, disabled, id, inputRef, name, onCheckedChange: setIsChecked, readOnly, render: /* @__PURE__ */ jsx(Motion.button, { ...rest, className: cx(baseClassName, className), initial: false, onClick: handleClick, onKeyDown: handleKeyDown, onTap: () => setIsPressed(false), onTapCancel: () => setIsPressed(false), onTapStart: () => setIsPressed(true), whileTap: "tap" }), required, children }) }); }; LobeSwitchRoot.displayName = "LobeSwitchRoot"; const LobeSwitchThumb = ({ className, pressedAnimation, size = "default", transition = { damping: 25, stiffness: 300, type: "spring" }, children, ...rest }) => { const Motion = useMotionComponent(); const { isPressed } = useLobeSwitchContext(); const baseClassName = thumbVariants({ size }); const defaultPressedAnimation = { width: size === "small" ? 16 : 22 }; return /* @__PURE__ */ jsx(Switch.Thumb, { render: /* @__PURE__ */ jsx(Motion.span, { animate: isPressed ? pressedAnimation || defaultPressedAnimation : void 0, className: cx(baseClassName, className), layout: true, transition, ...rest, children }) }); }; LobeSwitchThumb.displayName = "LobeSwitchThumb"; const getIconPositionClass = (position, size) => { if (position === "thumb") return styles.iconThumb; if (position === "left") return size === "small" ? styles.iconLeftSmall : styles.iconLeft; return size === "small" ? styles.iconRightSmall : styles.iconRight; }; const LobeSwitchIcon = ({ children, className, position, transition = { bounce: 0, type: "spring" }, ...rest }) => { const Motion = useMotionComponent(); const { isChecked } = useLobeSwitchContext(); const size = rest.size || "default"; const isAnimated = useMemo(() => { if (position === "right") return !isChecked; if (position === "left") return isChecked; if (position === "thumb") return true; return false; }, [position, isChecked]); const positionClass = getIconPositionClass(position, size); return /* @__PURE__ */ jsx(Motion.span, { animate: isAnimated ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0 }, className: cx(styles.icon, positionClass, className), transition, ...rest, children }); }; LobeSwitchIcon.displayName = "LobeSwitchIcon"; //#endregion export { LobeSwitchIcon, LobeSwitchRoot, LobeSwitchThumb, useLobeSwitchContext }; //# sourceMappingURL=atoms.mjs.map