@yamada-ui/transitions
Version:
Yamada UI transitions components
141 lines (139 loc) • 4.07 kB
JavaScript
"use client"
// src/flip.tsx
import { omitThemeProps, useComponentMultiStyle } from "@yamada-ui/core";
import { motion, motionForwardRef } from "@yamada-ui/motion";
import { useControllableState } from "@yamada-ui/use-controllable-state";
import { cx, dataAttr, useSafeLayoutEffect } from "@yamada-ui/utils";
import { useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
var variants = {
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
})
};
var flipProps = {
animate: "enter",
initial: "exit",
variants
};
var Flip = motionForwardRef((props, ref) => {
const [dimensions, setDimensions] = useState({});
const fromRef = useRef(null);
const toRef = useRef(null);
const [styles, mergedProps] = useComponentMultiStyle("Flip", props);
const {
className,
defaultValue = "from",
delay = 0,
isDisabled,
disabled = isDisabled,
duration = 0.4,
from,
isReadOnly,
orientation = "horizontal",
readOnly = isReadOnly,
to,
transition: transitionProp = {},
value: valueProp,
onChange: onChangeProp,
...rest
} = omitThemeProps(mergedProps);
const [value, setValue] = useControllableState({
defaultValue,
value: valueProp,
onChange: onChangeProp
});
const visible = value === "to";
const css = {
h: dimensions.height ? `${dimensions.height}px` : "auto",
w: dimensions.width ? `${dimensions.width}px` : "auto",
...styles.container
};
const transition = {
delay,
duration,
...transitionProp
};
const onClick = () => {
if (readOnly) return;
setValue((prev) => prev === "from" ? "to" : "from");
};
useSafeLayoutEffect(() => {
const fromElement = fromRef.current;
const toElement = toRef.current;
if (!fromElement || !toElement) return;
const fromWidth = fromElement.offsetWidth;
const fromHeight = fromElement.offsetHeight;
const toWidth = toElement.offsetWidth;
const toHeight = toElement.offsetHeight;
if (fromWidth !== toWidth || fromHeight !== toHeight) {
console.warn(
`Dimensions do not match:
"from" element (Width: ${fromWidth}px, Height: ${fromHeight}px)
does not match "to" element (Width: ${toWidth}px, Height: ${toHeight}px).
Please ensure both elements have the same dimensions.`
);
}
setDimensions({ height: fromHeight, width: fromWidth });
}, [fromRef, toRef]);
return /* @__PURE__ */ jsxs(
motion.button,
{
ref,
type: "button",
className: cx("ui-flip", `ui-flip__${orientation}`, className),
"data-disabled": dataAttr(disabled),
"data-readonly": dataAttr(readOnly),
"data-value": value,
disabled,
onClick,
__css: css,
...rest,
children: [
/* @__PURE__ */ jsx(
motion.span,
{
ref: fromRef,
className: cx(
"ui-flip__from",
`ui-flip__from--${orientation}`,
className
),
custom: { ident: "from", orientation, visible },
...flipProps,
transition,
__css: {
...styles.flipIdent,
...styles.from
},
children: from
}
),
/* @__PURE__ */ jsx(
motion.span,
{
ref: toRef,
className: cx("ui-flip__to", `ui-flip__to--${orientation}`, className),
custom: { ident: "to", orientation, visible },
...flipProps,
transition,
__css: {
...styles.flipIdent,
...styles.to
},
children: to
}
)
]
}
);
});
Flip.displayName = "Flip";
Flip.__ui__ = "Flip";
export {
Flip
};
//# sourceMappingURL=chunk-SNNK7SQ4.mjs.map