UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

116 lines (112 loc) 3.74 kB
"use client"; import { useSafeLayoutEffect } from "../../utils/effect.js"; import { utils_exports } from "../../utils/index.js"; import { createSlotComponent } from "../../core/components/create-component.js"; import { motion } from "../motion/factory.js"; import { useControllableState } from "../../hooks/use-controllable-state/index.js"; import { flipStyle } from "./flip.style.js"; import { useMemo, useRef, useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; //#region src/components/flip/flip.tsx const flipVariants = { enter: ({ ident, orientation, visible }) => ({ [orientation === "horizontal" ? "rotateY" : "rotateX"]: ident === "from" ? visible ? 180 : 0 : visible ? 0 : 180 }), exit: ({ ident, orientation }) => ({ [orientation === "horizontal" ? "rotateY" : "rotateX"]: ident === "from" ? 0 : 180 }) }; const { PropsContext: FlipPropsContext, usePropsContext: useFlipPropsContext, withContext, withProvider } = createSlotComponent("flip", flipStyle); /** * `Flip` is an animation component that alternates between flipping two elements. * * @see https://yamada-ui.com/docs/components/flip */ const Flip = withProvider(({ defaultValue = "from", delay = 0, disabled, duration = .4, from, orientation = "horizontal", readOnly, to, transition = {}, value: valueProp, onChange, onClick: onClickProp,...rest }) => { const [{ height, width }, setRect] = useState({}); const fromRef = useRef(null); const toRef = useRef(null); const [value, setValue] = useControllableState({ defaultValue, value: valueProp, onChange }); const visible = value === "to"; const style = useMemo(() => ({ height: height ? `${height}px` : "auto", width: width ? `${width}px` : "auto" }), [width, height]); const onClick = () => { if (readOnly) return; setValue((prev) => prev === "from" ? "to" : "from"); }; useSafeLayoutEffect(() => { const from$1 = fromRef.current; const to$1 = toRef.current; if (!from$1 || !to$1) return; if (from$1.offsetWidth !== to$1.offsetWidth || from$1.offsetHeight !== to$1.offsetHeight) console.warn(`Flip: "from" element (width: ${from$1.offsetWidth}px, height: ${from$1.offsetHeight}px) does not match "to" element (width: ${to$1.offsetWidth}px, height: ${to$1.offsetHeight}px). Please ensure both elements have the same dimensions.`); setRect({ height: from$1.offsetHeight, width: from$1.offsetWidth }); }, [fromRef, toRef]); return /* @__PURE__ */ jsxs(motion.button, { type: "button", style, "data-disabled": (0, utils_exports.dataAttr)(disabled), "data-orientation": orientation, "data-readonly": (0, utils_exports.dataAttr)(readOnly), "data-value": value, disabled, onClick: (0, utils_exports.handlerAll)(onClickProp, onClick), ...rest, children: [/* @__PURE__ */ jsx(FlipFrom, { ref: fromRef, custom: { orientation, visible }, transition: { delay, duration, ...transition }, children: from }), /* @__PURE__ */ jsx(FlipTo, { ref: toRef, custom: { orientation, visible }, transition: { delay, duration, ...transition }, children: to })] }); }, "root")(); const FlipFrom = withContext(({ custom,...rest }) => { return /* @__PURE__ */ jsx(motion.span, { animate: "enter", custom: { ident: "from", ...custom }, initial: "exit", variants: flipVariants, ...rest }); }, ["item", "from"])(); const FlipTo = withContext(({ custom,...rest }) => { return /* @__PURE__ */ jsx(motion.span, { animate: "enter", custom: { ident: "to", ...custom }, initial: "exit", variants: flipVariants, ...rest }); }, ["item", "to"])(); //#endregion export { Flip, FlipPropsContext, useFlipPropsContext }; //# sourceMappingURL=flip.js.map