UNPKG

rani-motion

Version:

A simple and powerful React animation library with TypeScript support - animated.div style components with accessibility-first approach

846 lines (823 loc) 31.7 kB
import React, { useState, useRef, useEffect, createContext, useContext } from 'react'; var jsxRuntime = {exports: {}}; var reactJsxRuntime_production = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var hasRequiredReactJsxRuntime_production; function requireReactJsxRuntime_production () { if (hasRequiredReactJsxRuntime_production) return reactJsxRuntime_production; hasRequiredReactJsxRuntime_production = 1; var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"); function jsxProd(type, config, maybeKey) { var key = null; void 0 !== maybeKey && (key = "" + maybeKey); void 0 !== config.key && (key = "" + config.key); if ("key" in config) { maybeKey = {}; for (var propName in config) "key" !== propName && (maybeKey[propName] = config[propName]); } else maybeKey = config; config = maybeKey.ref; return { $$typeof: REACT_ELEMENT_TYPE, type: type, key: key, ref: void 0 !== config ? config : null, props: maybeKey }; } reactJsxRuntime_production.Fragment = REACT_FRAGMENT_TYPE; reactJsxRuntime_production.jsx = jsxProd; reactJsxRuntime_production.jsxs = jsxProd; return reactJsxRuntime_production; } var reactJsxRuntime_development = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var hasRequiredReactJsxRuntime_development; function requireReactJsxRuntime_development () { if (hasRequiredReactJsxRuntime_development) return reactJsxRuntime_development; hasRequiredReactJsxRuntime_development = 1; "production" !== process.env.NODE_ENV && (function () { function getComponentNameFromType(type) { if (null == type) return null; if ("function" === typeof type) return type.$$typeof === REACT_CLIENT_REFERENCE ? null : type.displayName || type.name || null; if ("string" === typeof type) return type; switch (type) { case REACT_FRAGMENT_TYPE: return "Fragment"; case REACT_PROFILER_TYPE: return "Profiler"; case REACT_STRICT_MODE_TYPE: return "StrictMode"; case REACT_SUSPENSE_TYPE: return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; case REACT_ACTIVITY_TYPE: return "Activity"; } if ("object" === typeof type) switch ( ("number" === typeof type.tag && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), type.$$typeof) ) { case REACT_PORTAL_TYPE: return "Portal"; case REACT_CONTEXT_TYPE: return (type.displayName || "Context") + ".Provider"; case REACT_CONSUMER_TYPE: return (type._context.displayName || "Context") + ".Consumer"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; type = type.displayName; type || ((type = innerType.displayName || innerType.name || ""), (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef")); return type; case REACT_MEMO_TYPE: return ( (innerType = type.displayName || null), null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo" ); case REACT_LAZY_TYPE: innerType = type._payload; type = type._init; try { return getComponentNameFromType(type(innerType)); } catch (x) {} } return null; } function testStringCoercion(value) { return "" + value; } function checkKeyStringCoercion(value) { try { testStringCoercion(value); var JSCompiler_inline_result = !1; } catch (e) { JSCompiler_inline_result = !0; } if (JSCompiler_inline_result) { JSCompiler_inline_result = console; var JSCompiler_temp_const = JSCompiler_inline_result.error; var JSCompiler_inline_result$jscomp$0 = ("function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag]) || value.constructor.name || "Object"; JSCompiler_temp_const.call( JSCompiler_inline_result, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", JSCompiler_inline_result$jscomp$0 ); return testStringCoercion(value); } } function getTaskName(type) { if (type === REACT_FRAGMENT_TYPE) return "<>"; if ( "object" === typeof type && null !== type && type.$$typeof === REACT_LAZY_TYPE ) return "<...>"; try { var name = getComponentNameFromType(type); return name ? "<" + name + ">" : "<...>"; } catch (x) { return "<...>"; } } function getOwner() { var dispatcher = ReactSharedInternals.A; return null === dispatcher ? null : dispatcher.getOwner(); } function UnknownOwner() { return Error("react-stack-top-frame"); } function hasValidKey(config) { if (hasOwnProperty.call(config, "key")) { var getter = Object.getOwnPropertyDescriptor(config, "key").get; if (getter && getter.isReactWarning) return !1; } return void 0 !== config.key; } function defineKeyPropWarningGetter(props, displayName) { function warnAboutAccessingKey() { specialPropKeyWarningShown || ((specialPropKeyWarningShown = !0), console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", displayName )); } warnAboutAccessingKey.isReactWarning = !0; Object.defineProperty(props, "key", { get: warnAboutAccessingKey, configurable: !0 }); } function elementRefGetterWithDeprecationWarning() { var componentName = getComponentNameFromType(this.type); didWarnAboutElementRef[componentName] || ((didWarnAboutElementRef[componentName] = !0), console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )); componentName = this.props.ref; return void 0 !== componentName ? componentName : null; } function ReactElement( type, key, self, source, owner, props, debugStack, debugTask ) { self = props.ref; type = { $$typeof: REACT_ELEMENT_TYPE, type: type, key: key, props: props, _owner: owner }; null !== (void 0 !== self ? self : null) ? Object.defineProperty(type, "ref", { enumerable: !1, get: elementRefGetterWithDeprecationWarning }) : Object.defineProperty(type, "ref", { enumerable: !1, value: null }); type._store = {}; Object.defineProperty(type._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }); Object.defineProperty(type, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }); Object.defineProperty(type, "_debugStack", { configurable: !1, enumerable: !1, writable: !0, value: debugStack }); Object.defineProperty(type, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: debugTask }); Object.freeze && (Object.freeze(type.props), Object.freeze(type)); return type; } function jsxDEVImpl( type, config, maybeKey, isStaticChildren, source, self, debugStack, debugTask ) { var children = config.children; if (void 0 !== children) if (isStaticChildren) if (isArrayImpl(children)) { for ( isStaticChildren = 0; isStaticChildren < children.length; isStaticChildren++ ) validateChildKeys(children[isStaticChildren]); Object.freeze && Object.freeze(children); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else validateChildKeys(children); if (hasOwnProperty.call(config, "key")) { children = getComponentNameFromType(type); var keys = Object.keys(config).filter(function (k) { return "key" !== k; }); isStaticChildren = 0 < keys.length ? "{key: someKey, " + keys.join(": ..., ") + ": ...}" : "{key: someKey}"; didWarnAboutKeySpread[children + isStaticChildren] || ((keys = 0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}"), console.error( 'A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />', isStaticChildren, children, keys, children ), (didWarnAboutKeySpread[children + isStaticChildren] = !0)); } children = null; void 0 !== maybeKey && (checkKeyStringCoercion(maybeKey), (children = "" + maybeKey)); hasValidKey(config) && (checkKeyStringCoercion(config.key), (children = "" + config.key)); if ("key" in config) { maybeKey = {}; for (var propName in config) "key" !== propName && (maybeKey[propName] = config[propName]); } else maybeKey = config; children && defineKeyPropWarningGetter( maybeKey, "function" === typeof type ? type.displayName || type.name || "Unknown" : type ); return ReactElement( type, children, self, source, getOwner(), maybeKey, debugStack, debugTask ); } function validateChildKeys(node) { "object" === typeof node && null !== node && node.$$typeof === REACT_ELEMENT_TYPE && node._store && (node._store.validated = 1); } var React$1 = React, REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"); var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React$1.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function () { return null; }; React$1 = { react_stack_bottom_frame: function (callStackForError) { return callStackForError(); } }; var specialPropKeyWarningShown; var didWarnAboutElementRef = {}; var unknownOwnerDebugStack = React$1.react_stack_bottom_frame.bind( React$1, UnknownOwner )(); var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner)); var didWarnAboutKeySpread = {}; reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE; reactJsxRuntime_development.jsx = function (type, config, maybeKey, source, self) { var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++; return jsxDEVImpl( type, config, maybeKey, !1, source, self, trackActualOwner ? Error("react-stack-top-frame") : unknownOwnerDebugStack, trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask ); }; reactJsxRuntime_development.jsxs = function (type, config, maybeKey, source, self) { var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++; return jsxDEVImpl( type, config, maybeKey, !0, source, self, trackActualOwner ? Error("react-stack-top-frame") : unknownOwnerDebugStack, trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask ); }; })(); return reactJsxRuntime_development; } if (process.env.NODE_ENV === 'production') { jsxRuntime.exports = requireReactJsxRuntime_production(); } else { jsxRuntime.exports = requireReactJsxRuntime_development(); } var jsxRuntimeExports = jsxRuntime.exports; const animationPresets = { fadeIn: { initial: { opacity: 0 }, animate: { opacity: 1 } }, fadeInUp: { initial: { opacity: 0, transform: 'translateY(30px)' }, animate: { opacity: 1, transform: 'translateY(0)' } }, fadeInDown: { initial: { opacity: 0, transform: 'translateY(-30px)' }, animate: { opacity: 1, transform: 'translateY(0)' } }, fadeInLeft: { initial: { opacity: 0, transform: 'translateX(-30px)' }, animate: { opacity: 1, transform: 'translateX(0)' } }, fadeInRight: { initial: { opacity: 0, transform: 'translateX(30px)' }, animate: { opacity: 1, transform: 'translateX(0)' } }, slideInUp: { initial: { transform: 'translateY(100%)' }, animate: { transform: 'translateY(0)' } }, slideInDown: { initial: { transform: 'translateY(-100%)' }, animate: { transform: 'translateY(0)' } }, slideInLeft: { initial: { transform: 'translateX(-100%)' }, animate: { transform: 'translateX(0)' } }, slideInRight: { initial: { transform: 'translateX(100%)' }, animate: { transform: 'translateX(0)' } }, scaleIn: { initial: { opacity: 0, transform: 'scale(0.8)' }, animate: { opacity: 1, transform: 'scale(1)' } }, scaleInUp: { initial: { opacity: 0, transform: 'scale(0.8) translateY(30px)' }, animate: { opacity: 1, transform: 'scale(1) translateY(0)' } }, zoomIn: { initial: { opacity: 0, transform: 'scale(0.3)' }, animate: { opacity: 1, transform: 'scale(1)' } }, rotateIn: { initial: { opacity: 0, transform: 'rotate(-180deg) scale(0.8)' }, animate: { opacity: 1, transform: 'rotate(0deg) scale(1)' } }, rotateInLeft: { initial: { opacity: 0, transform: 'rotate(-90deg)' }, animate: { opacity: 1, transform: 'rotate(0deg)' } }, rotateInRight: { initial: { opacity: 0, transform: 'rotate(90deg)' }, animate: { opacity: 1, transform: 'rotate(0deg)' } }, bounceIn: { initial: { opacity: 0, transform: 'scale(0.3)' }, animate: { opacity: 1, transform: 'scale(1)' } }, bounceInUp: { initial: { opacity: 0, transform: 'translateY(100px)' }, animate: { opacity: 1, transform: 'translateY(0)' } }, flipInX: { initial: { opacity: 0, transform: 'perspective(400px) rotateX(-90deg)' }, animate: { opacity: 1, transform: 'perspective(400px) rotateX(0deg)' } }, flipInY: { initial: { opacity: 0, transform: 'perspective(400px) rotateY(-90deg)' }, animate: { opacity: 1, transform: 'perspective(400px) rotateY(0deg)' } }, lightSpeedIn: { initial: { opacity: 0, transform: 'translateX(100%) skewX(-30deg)' }, animate: { opacity: 1, transform: 'translateX(0) skewX(0deg)' } }, rollIn: { initial: { opacity: 0, transform: 'translateX(-100%) rotate(-120deg)' }, animate: { opacity: 1, transform: 'translateX(0) rotate(0deg)' } } }; const hoverPresets = { scale: { default: { transform: 'scale(1)' }, hover: { transform: 'scale(1.05)' } }, scaleDown: { default: { transform: 'scale(1)' }, hover: { transform: 'scale(0.95)' } }, lift: { default: { transform: 'translateY(0)', boxShadow: '0 2px 10px rgba(0,0,0,0.1)' }, hover: { transform: 'translateY(-5px)', boxShadow: '0 10px 25px rgba(0,0,0,0.15)' } }, rotate: { default: { transform: 'rotate(0deg)' }, hover: { transform: 'rotate(5deg)' } }, skew: { default: { transform: 'skew(0deg)' }, hover: { transform: 'skew(-2deg)' } }, glow: { default: { boxShadow: '0 0 0px rgba(59, 130, 246, 0)', transform: 'scale(1)' }, hover: { boxShadow: '0 0 20px rgba(59, 130, 246, 0.5)', transform: 'scale(1.02)' } }, bounce: { default: { transform: 'translateY(0) scale(1)' }, hover: { transform: 'translateY(-10px) scale(1.02)' } }, wobble: { default: { transform: 'rotate(0deg)' }, hover: { transform: 'rotate(-5deg)' } } }; const clickPresets = { pulse: { default: { transform: 'scale(1)' }, active: { transform: 'scale(0.95)' } }, shake: { default: { transform: 'translateX(0)' }, active: { transform: 'translateX(-2px)' } }, ripple: { default: { position: 'relative', overflow: 'hidden' }, active: { position: 'relative', overflow: 'hidden' } } }; const useIntersectionObserver = (options = {}) => { const { threshold = 0.1, rootMargin = '0px', triggerOnce = true } = options; const [isIntersecting, setIsIntersecting] = useState(false); const [hasIntersected, setHasIntersected] = useState(false); const elementRef = useRef(null); useEffect(() => { const observer = new IntersectionObserver(([entry]) => { const isElementIntersecting = entry.isIntersecting; if (isElementIntersecting && (!triggerOnce || !hasIntersected)) { setIsIntersecting(true); setHasIntersected(true); } else if (!triggerOnce && !isElementIntersecting) { setIsIntersecting(false); } }, { threshold, rootMargin }); if (elementRef.current) { observer.observe(elementRef.current); } return () => observer.disconnect(); }, [threshold, rootMargin, triggerOnce, hasIntersected]); return { elementRef, isIntersecting }; }; const useReducedMotion = () => { const [prefersReducedMotion, setPrefersReducedMotion] = useState(false); useEffect(() => { const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)'); setPrefersReducedMotion(mediaQuery.matches); const handleChange = (event) => { setPrefersReducedMotion(event.matches); }; mediaQuery.addEventListener('change', handleChange); return () => mediaQuery.removeEventListener('change', handleChange); }, []); return prefersReducedMotion; }; const RaniOnView = ({ children, animation = 'fadeInUp', customAnimation, duration = 600, delay = 0, easing = 'easeOutQuart', triggerOnce = true, threshold = 0.1, className = '', style = {}, ...props }) => { const [isVisible, setIsVisible] = useState(false); const prefersReducedMotion = useReducedMotion(); const { elementRef, isIntersecting } = useIntersectionObserver({ threshold, triggerOnce }); useEffect(() => { if (isIntersecting) { setTimeout(() => { setIsVisible(true); }, delay); } else if (!triggerOnce) { setIsVisible(false); } }, [isIntersecting, delay, triggerOnce]); const getAnimationStyle = () => { const selectedAnimation = customAnimation || animationPresets[animation] || animationPresets.fadeInUp; const currentStyle = isVisible ? selectedAnimation.animate : selectedAnimation.initial; // 접근성 고려: 사용자가 모션 감소를 선호하면 애니메이션 최소화 const finalDuration = prefersReducedMotion ? Math.min(duration, 200) : duration; return { ...currentStyle, transition: `all ${finalDuration}ms cubic-bezier(0.25, 0.46, 0.45, 0.94)`, willChange: prefersReducedMotion ? 'opacity' : 'transform, opacity' }; }; return (jsxRuntimeExports.jsx("div", { ref: elementRef, className: className, style: { ...getAnimationStyle(), ...style }, ...props, children: children })); }; const RaniHover = ({ children, animation = 'scale', customAnimation, duration = 300, className = '', style = {}, ...props }) => { const [isHovered, setIsHovered] = useState(false); const prefersReducedMotion = useReducedMotion(); const getHoverStyle = () => { const selectedAnimation = customAnimation || hoverPresets[animation] || hoverPresets.scale; const currentStyle = isHovered ? selectedAnimation.hover : selectedAnimation.default; // 접근성 고려: 모션 감소 시 애니메이션 최소화 const finalDuration = prefersReducedMotion ? Math.min(duration, 150) : duration; return { ...currentStyle, transition: `all ${finalDuration}ms cubic-bezier(0.4, 0, 0.2, 1)`, cursor: 'pointer' }; }; return (jsxRuntimeExports.jsx("div", { className: className, style: { ...getHoverStyle(), ...style }, onMouseEnter: () => !prefersReducedMotion && setIsHovered(true), onMouseLeave: () => setIsHovered(false), ...props, children: children })); }; const RaniClick = ({ children, animation = 'ripple', customAnimation, className = '', style = {}, onClick, ...props }) => { const [isClicked, setIsClicked] = useState(false); const elementRef = useRef(null); const prefersReducedMotion = useReducedMotion(); const handleClick = (e) => { if (!prefersReducedMotion) { setIsClicked(true); if (animation === 'ripple' && elementRef.current) { const rect = elementRef.current.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = e.clientX - rect.left - size / 2; const y = e.clientY - rect.top - size / 2; const ripple = document.createElement('div'); ripple.style.cssText = ` position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.6); transform: scale(0); animation: ripple-animation 0.6s linear; left: ${x}px; top: ${y}px; width: ${size}px; height: ${size}px; pointer-events: none; `; elementRef.current.appendChild(ripple); setTimeout(() => { if (ripple.parentNode) { ripple.parentNode.removeChild(ripple); } }, 600); } setTimeout(() => setIsClicked(false), 200); } if (onClick) onClick(e); }; const getClickStyle = () => { const selectedAnimation = customAnimation || clickPresets[animation] || clickPresets.pulse; const currentStyle = isClicked ? selectedAnimation.active : selectedAnimation.default; return { ...currentStyle, transition: 'transform 0.1s ease', cursor: 'pointer' }; }; useEffect(() => { if (!document.querySelector('#ripple-keyframes')) { const style = document.createElement('style'); style.id = 'ripple-keyframes'; style.textContent = ` @keyframes ripple-animation { to { transform: scale(4); opacity: 0; } } `; document.head.appendChild(style); } }, []); return (jsxRuntimeExports.jsx("div", { ref: elementRef, className: className, style: { ...getClickStyle(), ...style }, onClick: handleClick, ...props, children: children })); }; const RaniStagger = ({ children, staggerDelay = 100, animation = 'fadeInUp', customAnimation, duration = 600, ...props }) => { return (jsxRuntimeExports.jsx("div", { ...props, children: children.map((child, index) => (jsxRuntimeExports.jsx(RaniOnView, { animation: animation, customAnimation: customAnimation, duration: duration, delay: index * staggerDelay, children: child }, index))) })); }; const RaniContext = createContext({ globalDuration: 600, globalEasing: 'easeOutQuart', globalDelay: 0, reducedMotion: false }); const RaniProvider = ({ children, globalDuration = 600, globalEasing = 'easeOutQuart', globalDelay = 0, reducedMotion = false }) => { const value = { globalDuration, globalEasing, globalDelay, reducedMotion }; return (jsxRuntimeExports.jsx(RaniContext.Provider, { value: value, children: children })); }; const useRaniAnimation = () => { const context = useContext(RaniContext); if (!context) { throw new Error('useRaniAnimation must be used within a RaniProvider'); } return context; }; // 애니메이션 로직을 담은 컴포넌트 생성 함수 function createAnimatedElement(tag) { const Component = React.forwardRef((props, ref) => { const { animation = 'fadeInUp', customAnimation, duration = 600, delay = 0, easing = 'easeOutQuart', triggerOnce = true, threshold = 0.1, style = {}, children, ...htmlProps } = props; const [isVisible, setIsVisible] = useState(false); const prefersReducedMotion = useReducedMotion(); const internalRef = useRef(null); const { elementRef, isIntersecting } = useIntersectionObserver({ threshold, triggerOnce }); useEffect(() => { if (isIntersecting) { setTimeout(() => { setIsVisible(true); }, delay); } else if (!triggerOnce) { setIsVisible(false); } }, [isIntersecting, delay, triggerOnce]); const getAnimationStyle = () => { const selectedAnimation = customAnimation || animationPresets[animation] || animationPresets.fadeInUp; const currentStyle = isVisible ? selectedAnimation.animate : selectedAnimation.initial; const finalDuration = prefersReducedMotion ? Math.min(duration, 200) : duration; return { ...currentStyle, transition: `all ${finalDuration}ms cubic-bezier(0.25, 0.46, 0.45, 0.94)`, willChange: prefersReducedMotion ? 'opacity' : 'transform, opacity' }; }; return React.createElement(tag, { ref: (el) => { // intersection observer ref 설정 elementRef.current = el; // 내부 ref 설정 internalRef.current = el; // 외부 ref 설정 if (ref) { if (typeof ref === 'function') { ref(el); } else { ref.current = el; } } }, style: { ...getAnimationStyle(), ...style }, ...htmlProps }, children); }); Component.displayName = `animated.${String(tag)}`; return Component; } // animated 객체 생성 (타입 체크 우회) const animated = { div: createAnimatedElement('div'), span: createAnimatedElement('span'), section: createAnimatedElement('section'), article: createAnimatedElement('article'), header: createAnimatedElement('header'), footer: createAnimatedElement('footer'), main: createAnimatedElement('main'), nav: createAnimatedElement('nav'), h1: createAnimatedElement('h1'), h2: createAnimatedElement('h2'), h3: createAnimatedElement('h3'), h4: createAnimatedElement('h4'), h5: createAnimatedElement('h5'), h6: createAnimatedElement('h6'), p: createAnimatedElement('p'), a: createAnimatedElement('a'), button: createAnimatedElement('button'), img: createAnimatedElement('img'), ul: createAnimatedElement('ul'), ol: createAnimatedElement('ol'), li: createAnimatedElement('li') }; const easingPresets = { linear: (t) => t, easeIn: (t) => t * t, easeOut: (t) => t * (2 - t), easeInOut: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t, easeOutQuart: (t) => 1 - (--t) * t * t * t, easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1, easeOutBounce: (t) => { if (t < 1 / 2.75) { return 7.5625 * t * t; } else if (t < 2 / 2.75) { return 7.5625 * (t -= 1.5 / 2.75) * t + 0.75; } else if (t < 2.5 / 2.75) { return 7.5625 * (t -= 2.25 / 2.75) * t + 0.9375; } else { return 7.5625 * (t -= 2.625 / 2.75) * t + 0.984375; } }, easeOutElastic: (t) => { const c4 = (2 * Math.PI) / 3; return t === 0 ? 0 : t === 1 ? 1 : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1; } }; export { RaniClick, RaniHover, RaniOnView, RaniProvider, RaniStagger, animated, animationPresets, easingPresets, useIntersectionObserver, useRaniAnimation, useReducedMotion }; //# sourceMappingURL=index.esm.js.map