@hua-labs/motion-core 2.2.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as react from 'react';
2
- import { CSSProperties, RefObject } from 'react';
2
+ import react__default, { CSSProperties, RefObject } from 'react';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
4
 
4
5
  /**
5
6
  * HUA Motion Core - 의존성 제로 모션 엔진
@@ -35,7 +36,7 @@ interface MotionOptions {
35
36
  onComplete?: () => void;
36
37
  onCancel?: () => void;
37
38
  }
38
- interface Motion {
39
+ interface Motion$1 {
39
40
  id: string;
40
41
  element: HTMLElement;
41
42
  isRunning: boolean;
@@ -72,7 +73,7 @@ declare class MotionEngine {
72
73
  /**
73
74
  * 모션 상태 확인
74
75
  */
75
- getMotion(motionId: string): Motion | undefined;
76
+ getMotion(motionId: string): Motion$1 | undefined;
76
77
  /**
77
78
  * 실행 중인 모션 수
78
79
  */
@@ -133,6 +134,10 @@ declare class TransitionEffects {
133
134
  private static instance;
134
135
  private activeTransitions;
135
136
  static getInstance(): TransitionEffects;
137
+ /**
138
+ * 공통 전환 실행 헬퍼
139
+ */
140
+ private executeTransition;
136
141
  /**
137
142
  * 페이드 인/아웃 전환
138
143
  */
@@ -188,130 +193,6 @@ declare class TransitionEffects {
188
193
  }
189
194
  declare const transitionEffects: TransitionEffects;
190
195
 
191
- /**
192
- * HUA Motion Core - 성능 최적화 시스템
193
- *
194
- * GPU 가속, 레이어 관리, 메모리 최적화를 위한 유틸리티들
195
- * 브라우저별 최적화 전략 포함
196
- */
197
- interface PerformanceOptimizerMetrics {
198
- fps: number;
199
- memoryUsage?: number;
200
- gpuTime?: number;
201
- cpuTime?: number;
202
- layerCount: number;
203
- activeMotions: number;
204
- }
205
- interface OptimizationConfig {
206
- enableGPUAcceleration: boolean;
207
- enableLayerSeparation: boolean;
208
- enableMemoryOptimization: boolean;
209
- targetFPS: number;
210
- maxLayerCount: number;
211
- memoryThreshold: number;
212
- }
213
- declare class PerformanceOptimizer {
214
- private static instance;
215
- private config;
216
- private performanceObserver;
217
- private metrics;
218
- private layerRegistry;
219
- private isMonitoring;
220
- constructor();
221
- static getInstance(): PerformanceOptimizer;
222
- /**
223
- * 성능 모니터링 초기화
224
- */
225
- private initializePerformanceMonitoring;
226
- /**
227
- * 성능 메트릭 업데이트
228
- */
229
- private updatePerformanceMetrics;
230
- /**
231
- * FPS 계산
232
- */
233
- private calculateFPS;
234
- /**
235
- * GPU 가속 활성화
236
- */
237
- enableGPUAcceleration(element: HTMLElement): void;
238
- /**
239
- * 레이어 분리 및 최적화
240
- */
241
- createOptimizedLayer(element: HTMLElement): void;
242
- /**
243
- * 레이어 등록
244
- */
245
- private registerLayer;
246
- /**
247
- * 레이어 제거
248
- */
249
- removeLayer(element: HTMLElement): void;
250
- /**
251
- * 레이어 수 제한 체크
252
- */
253
- private checkLayerLimit;
254
- /**
255
- * 오래된 레이어 정리
256
- */
257
- private cleanupOldLayers;
258
- /**
259
- * 메모리 사용량 체크
260
- */
261
- private checkMemoryUsage;
262
- /**
263
- * 메모리 정리
264
- */
265
- private cleanupMemory;
266
- /**
267
- * 성능 최적화 설정 업데이트
268
- */
269
- updateConfig(newConfig: Partial<OptimizationConfig>): void;
270
- /**
271
- * 모든 GPU 가속 비활성화
272
- */
273
- private disableAllGPUAcceleration;
274
- /**
275
- * 모든 레이어 비활성화
276
- */
277
- private disableAllLayers;
278
- /**
279
- * 성능 메트릭 가져오기
280
- */
281
- getMetrics(): PerformanceOptimizerMetrics;
282
- /**
283
- * 성능 모니터링 시작
284
- */
285
- startMonitoring(): void;
286
- /**
287
- * 성능 모니터링 중지
288
- */
289
- stopMonitoring(): void;
290
- /**
291
- * 메트릭 업데이트
292
- */
293
- private updateMetrics;
294
- /**
295
- * 성능 리포트 생성
296
- */
297
- generateReport(): string;
298
- /**
299
- * 바이트 단위 포맷팅
300
- */
301
- private formatBytes;
302
- /**
303
- * 성능 최적화 권장사항
304
- */
305
- getOptimizationRecommendations(): string[];
306
- /**
307
- * 정리
308
- */
309
- destroy(): void;
310
- private lastFrameTime?;
311
- private monitoringInterval?;
312
- }
313
- declare const performanceOptimizer: PerformanceOptimizer;
314
-
315
196
  type MotionElement = HTMLDivElement | HTMLSpanElement | HTMLButtonElement | HTMLHeadingElement | HTMLParagraphElement | HTMLImageElement;
316
197
  type MotionStyle = CSSProperties & {
317
198
  '--motion-delay'?: string;
@@ -588,7 +469,7 @@ interface MotionPreset {
588
469
  interface PresetConfig {
589
470
  [key: string]: MotionPreset;
590
471
  }
591
- interface SpringConfig {
472
+ interface SpringConfig$1 {
592
473
  mass?: number;
593
474
  stiffness?: number;
594
475
  damping?: number;
@@ -677,9 +558,25 @@ declare function useSmartMotion<T extends HTMLElement = HTMLDivElement>(options?
677
558
  * 내부에서 선택된 type에 맞는 로직만 실행 (6개 훅 동시 호출 제거)
678
559
  */
679
560
 
561
+ interface MotionEffects {
562
+ fade?: boolean | {
563
+ targetOpacity?: number;
564
+ };
565
+ slide?: boolean | {
566
+ direction?: 'up' | 'down' | 'left' | 'right';
567
+ distance?: number;
568
+ };
569
+ scale?: boolean | {
570
+ from?: number;
571
+ to?: number;
572
+ };
573
+ bounce?: boolean;
574
+ }
680
575
  interface UseUnifiedMotionOptions extends Omit<BaseMotionOptions, 'autoStart'> {
681
- /** Motion type to use */
682
- type: EntranceType;
576
+ /** Motion type to use (single effect mode) */
577
+ type?: EntranceType;
578
+ /** Multiple effects to combine (multi-effect mode) */
579
+ effects?: MotionEffects;
683
580
  /** Auto start animation @default true */
684
581
  autoStart?: boolean;
685
582
  /** Slide distance (px) for slide types @default 50 */
@@ -1044,6 +941,383 @@ declare function useGestureMotion(options: GestureMotionOptions): {
1044
941
  isActive: boolean;
1045
942
  };
1046
943
 
944
+ interface ButtonEffectOptions extends BaseMotionOptions {
945
+ type?: 'scale' | 'ripple' | 'glow' | 'shake' | 'bounce' | 'slide' | 'custom';
946
+ scaleAmount?: number;
947
+ rippleColor?: string;
948
+ rippleSize?: number;
949
+ rippleDuration?: number;
950
+ glowColor?: string;
951
+ glowSize?: number;
952
+ glowIntensity?: number;
953
+ shakeAmount?: number;
954
+ shakeFrequency?: number;
955
+ bounceHeight?: number;
956
+ bounceStiffness?: number;
957
+ slideDistance?: number;
958
+ slideDirection?: 'left' | 'right' | 'up' | 'down';
959
+ hoverScale?: number;
960
+ hoverRotate?: number;
961
+ hoverTranslateY?: number;
962
+ hoverTranslateX?: number;
963
+ activeScale?: number;
964
+ activeRotate?: number;
965
+ activeTranslateY?: number;
966
+ activeTranslateX?: number;
967
+ focusScale?: number;
968
+ focusGlow?: boolean;
969
+ disabled?: boolean;
970
+ disabledOpacity?: number;
971
+ autoStart?: boolean;
972
+ }
973
+ declare function useButtonEffect<T extends MotionElement = HTMLButtonElement>(options?: ButtonEffectOptions): BaseMotionReturn<T> & {
974
+ buttonType: string;
975
+ isPressed: boolean;
976
+ isHovered: boolean;
977
+ isFocused: boolean;
978
+ ripplePosition: {
979
+ x: number;
980
+ y: number;
981
+ };
982
+ currentGlowIntensity: number;
983
+ shakeOffset: number;
984
+ bounceOffset: number;
985
+ slideOffset: number;
986
+ pressButton: () => void;
987
+ releaseButton: () => void;
988
+ setButtonState: (state: 'idle' | 'hover' | 'active' | 'focus' | 'disabled') => void;
989
+ };
990
+
991
+ interface VisibilityToggleOptions extends BaseMotionOptions {
992
+ showScale?: number;
993
+ showOpacity?: number;
994
+ showRotate?: number;
995
+ showTranslateY?: number;
996
+ showTranslateX?: number;
997
+ hideScale?: number;
998
+ hideOpacity?: number;
999
+ hideRotate?: number;
1000
+ hideTranslateY?: number;
1001
+ hideTranslateX?: number;
1002
+ }
1003
+ declare function useVisibilityToggle<T extends MotionElement = HTMLDivElement>(options?: VisibilityToggleOptions): InteractionReturn<T>;
1004
+
1005
+ interface ScrollToggleOptions extends BaseMotionOptions {
1006
+ showScale?: number;
1007
+ showOpacity?: number;
1008
+ showRotate?: number;
1009
+ showTranslateY?: number;
1010
+ showTranslateX?: number;
1011
+ hideScale?: number;
1012
+ hideOpacity?: number;
1013
+ hideRotate?: number;
1014
+ hideTranslateY?: number;
1015
+ hideTranslateX?: number;
1016
+ scrollThreshold?: number;
1017
+ scrollDirection?: 'up' | 'down' | 'both';
1018
+ }
1019
+ declare function useScrollToggle<T extends MotionElement = HTMLDivElement>(options?: ScrollToggleOptions): BaseMotionReturn<T>;
1020
+
1021
+ interface CardListOptions extends BaseMotionOptions {
1022
+ staggerDelay?: number;
1023
+ cardScale?: number;
1024
+ cardOpacity?: number;
1025
+ cardRotate?: number;
1026
+ cardTranslateY?: number;
1027
+ cardTranslateX?: number;
1028
+ initialScale?: number;
1029
+ initialOpacity?: number;
1030
+ initialRotate?: number;
1031
+ initialTranslateY?: number;
1032
+ initialTranslateX?: number;
1033
+ gridColumns?: number;
1034
+ gridGap?: number;
1035
+ }
1036
+ declare function useCardList<T extends MotionElement = HTMLDivElement>(options?: CardListOptions): BaseMotionReturn<T> & {
1037
+ cardStyles: React.CSSProperties[];
1038
+ staggerDelay: number;
1039
+ gridColumns: number;
1040
+ gridGap: number;
1041
+ };
1042
+
1043
+ interface LoadingSpinnerOptions extends BaseMotionOptions {
1044
+ type?: 'rotate' | 'pulse' | 'bounce' | 'wave' | 'dots' | 'bars' | 'custom';
1045
+ rotationSpeed?: number;
1046
+ pulseSpeed?: number;
1047
+ bounceHeight?: number;
1048
+ waveCount?: number;
1049
+ dotCount?: number;
1050
+ barCount?: number;
1051
+ color?: string;
1052
+ backgroundColor?: string;
1053
+ size?: number;
1054
+ thickness?: number;
1055
+ autoStart?: boolean;
1056
+ infinite?: boolean;
1057
+ }
1058
+ declare function useLoadingSpinner<T extends MotionElement = HTMLDivElement>(options?: LoadingSpinnerOptions): BaseMotionReturn<T> & {
1059
+ isLoading: boolean;
1060
+ spinnerType: string;
1061
+ rotationAngle: number;
1062
+ pulseScale: number;
1063
+ bounceOffset: number;
1064
+ waveProgress: number;
1065
+ dotProgress: number;
1066
+ barProgress: number;
1067
+ startLoading: () => void;
1068
+ stopLoading: () => void;
1069
+ setLoadingState: (loading: boolean) => void;
1070
+ };
1071
+
1072
+ interface NavigationOptions extends BaseMotionOptions {
1073
+ type?: 'slide' | 'fade' | 'scale' | 'rotate' | 'custom';
1074
+ slideDirection?: 'left' | 'right' | 'up' | 'down';
1075
+ staggerDelay?: number;
1076
+ itemScale?: number;
1077
+ itemOpacity?: number;
1078
+ itemRotate?: number;
1079
+ itemTranslateY?: number;
1080
+ itemTranslateX?: number;
1081
+ initialScale?: number;
1082
+ initialOpacity?: number;
1083
+ initialRotate?: number;
1084
+ initialTranslateY?: number;
1085
+ initialTranslateX?: number;
1086
+ activeScale?: number;
1087
+ activeOpacity?: number;
1088
+ activeRotate?: number;
1089
+ activeTranslateY?: number;
1090
+ activeTranslateX?: number;
1091
+ hoverScale?: number;
1092
+ hoverOpacity?: number;
1093
+ hoverRotate?: number;
1094
+ hoverTranslateY?: number;
1095
+ hoverTranslateX?: number;
1096
+ itemCount?: number;
1097
+ autoStart?: boolean;
1098
+ }
1099
+ declare function useNavigation<T extends MotionElement = HTMLDivElement>(options?: NavigationOptions): BaseMotionReturn<T> & {
1100
+ isOpen: boolean;
1101
+ activeIndex: number;
1102
+ itemStyles: React.CSSProperties[];
1103
+ openMenu: () => void;
1104
+ closeMenu: () => void;
1105
+ toggleMenu: () => void;
1106
+ setActiveItem: (index: number) => void;
1107
+ goToNext: () => void;
1108
+ goToPrevious: () => void;
1109
+ };
1110
+
1111
+ interface SkeletonOptions extends BaseMotionOptions {
1112
+ /** 스켈레톤 배경색 */
1113
+ backgroundColor?: string;
1114
+ /** 스켈레톤 하이라이트 색상 */
1115
+ highlightColor?: string;
1116
+ /** 모션 속도 (ms) */
1117
+ motionSpeed?: number;
1118
+ /** 스켈레톤 높이 */
1119
+ height?: number;
1120
+ /** 스켈레톤 너비 */
1121
+ width?: number | string;
1122
+ /** 보더 반지름 */
1123
+ borderRadius?: number;
1124
+ /** 웨이브 모션 활성화 여부 */
1125
+ wave?: boolean;
1126
+ /** 펄스 모션 활성화 여부 */
1127
+ pulse?: boolean;
1128
+ }
1129
+ declare function useSkeleton<T extends MotionElement = HTMLDivElement>(options?: SkeletonOptions): BaseMotionReturn<T>;
1130
+
1131
+ interface TypewriterOptions {
1132
+ /** 타이핑할 텍스트 */
1133
+ text: string;
1134
+ /** 글자당 딜레이 (ms) @default 50 */
1135
+ speed?: number;
1136
+ /** 시작 딜레이 (ms) @default 0 */
1137
+ delay?: number;
1138
+ /** 활성화 여부 @default true */
1139
+ enabled?: boolean;
1140
+ /** 완료 콜백 */
1141
+ onComplete?: () => void;
1142
+ }
1143
+ interface TypewriterReturn {
1144
+ /** 현재 표시 중인 텍스트 */
1145
+ displayText: string;
1146
+ /** 타이핑 진행 중 여부 */
1147
+ isTyping: boolean;
1148
+ /** 진행률 (0-1) */
1149
+ progress: number;
1150
+ /** 타이핑 재시작 */
1151
+ restart: () => void;
1152
+ }
1153
+ /**
1154
+ * useTypewriter - 타이핑 효과 훅
1155
+ *
1156
+ * @example
1157
+ * ```tsx
1158
+ * const { displayText, isTyping } = useTypewriter({ text: 'Hello, world!' })
1159
+ * return <h1>{displayText}<span className="animate-pulse">|</span></h1>
1160
+ * ```
1161
+ */
1162
+ declare function useTypewriter(options: TypewriterOptions): TypewriterReturn;
1163
+
1164
+ interface CustomCursorOptions {
1165
+ /** 활성화 여부 @default true */
1166
+ enabled?: boolean;
1167
+ /** 커서 크기 (px) @default 32 */
1168
+ size?: number;
1169
+ /** 스프링 스무딩 (0-1, 낮을수록 부드러움) @default 0.15 */
1170
+ smoothing?: number;
1171
+ /** 호버 시 스케일 @default 1.5 */
1172
+ hoverScale?: number;
1173
+ /** data-cursor 속성 요소 감지 @default true */
1174
+ detectLabels?: boolean;
1175
+ }
1176
+ interface CustomCursorReturn {
1177
+ /** 커서 x 좌표 (smoothed) */
1178
+ x: number;
1179
+ /** 커서 y 좌표 (smoothed) */
1180
+ y: number;
1181
+ /** 호버 중인 요소의 data-cursor 값 */
1182
+ label: string | null;
1183
+ /** 호버 상태 여부 */
1184
+ isHovering: boolean;
1185
+ /** 커서 스타일 (CSS variables 포함) */
1186
+ style: CSSProperties;
1187
+ /** 커서 가시 여부 */
1188
+ isVisible: boolean;
1189
+ }
1190
+ /**
1191
+ * useCustomCursor - 커스텀 커서 효과 훅
1192
+ *
1193
+ * 마우스를 따라다니는 커스텀 커서를 구현합니다.
1194
+ * 스프링 보간으로 부드러운 추적, data-cursor 라벨 감지.
1195
+ *
1196
+ * @example
1197
+ * ```tsx
1198
+ * const cursor = useCustomCursor()
1199
+ * return (
1200
+ * <>
1201
+ * <div style={cursor.style} className="custom-cursor" />
1202
+ * <button data-cursor="Click me">Hover me</button>
1203
+ * </>
1204
+ * )
1205
+ * ```
1206
+ */
1207
+ declare function useCustomCursor(options?: CustomCursorOptions): CustomCursorReturn;
1208
+
1209
+ interface MagneticCursorOptions {
1210
+ /** 자석 끌림 강도 (0-1) @default 0.3 */
1211
+ strength?: number;
1212
+ /** 자석 작동 반경 (px) @default 100 */
1213
+ radius?: number;
1214
+ /** 활성화 여부 @default true */
1215
+ enabled?: boolean;
1216
+ }
1217
+ interface MagneticCursorReturn<T extends HTMLElement = HTMLElement> {
1218
+ /** 자석 대상 요소에 연결할 ref */
1219
+ ref: React.RefObject<T | null>;
1220
+ /** 마우스 이벤트 핸들러 */
1221
+ handlers: {
1222
+ onMouseMove: (e: React.MouseEvent) => void;
1223
+ onMouseLeave: () => void;
1224
+ };
1225
+ /** 요소에 적용할 transform 스타일 */
1226
+ style: CSSProperties;
1227
+ }
1228
+ /**
1229
+ * useMagneticCursor - 자석 커서 효과 훅
1230
+ *
1231
+ * 마우스가 요소 근처에 오면 요소가 마우스 쪽으로 끌려오는 효과.
1232
+ * 버튼, 아이콘 등에 적용하면 인터랙티브 느낌 향상.
1233
+ *
1234
+ * @example
1235
+ * ```tsx
1236
+ * const magnetic = useMagneticCursor<HTMLButtonElement>({ strength: 0.4 })
1237
+ * return <button ref={magnetic.ref} style={magnetic.style} {...magnetic.handlers}>Click</button>
1238
+ * ```
1239
+ */
1240
+ declare function useMagneticCursor<T extends HTMLElement = HTMLElement>(options?: MagneticCursorOptions): MagneticCursorReturn<T>;
1241
+
1242
+ interface SmoothScrollOptions {
1243
+ /** 활성화 여부 @default true */
1244
+ enabled?: boolean;
1245
+ /** 스무딩 계수 (0-1, 낮을수록 부드러움) @default 0.1 */
1246
+ lerp?: number;
1247
+ /** 마우스 휠 배율 @default 1 */
1248
+ wheelMultiplier?: number;
1249
+ /** 터치 배율 @default 2 */
1250
+ touchMultiplier?: number;
1251
+ /** 방향 @default 'vertical' */
1252
+ direction?: 'vertical' | 'horizontal';
1253
+ /** 콜백: 스크롤 값 변경 시 */
1254
+ onScroll?: (scroll: number) => void;
1255
+ }
1256
+ interface SmoothScrollReturn {
1257
+ /** 현재 스크롤 위치 (smoothed) */
1258
+ scroll: number;
1259
+ /** 목표 스크롤 위치 */
1260
+ targetScroll: number;
1261
+ /** 스크롤 진행률 (0-1) */
1262
+ progress: number;
1263
+ /** 특정 위치로 스크롤 */
1264
+ scrollTo: (target: number | HTMLElement, options?: {
1265
+ offset?: number;
1266
+ }) => void;
1267
+ /** 스크롤 중지 */
1268
+ stop: () => void;
1269
+ }
1270
+ /**
1271
+ * useSmoothScroll - 부드러운 스크롤 훅
1272
+ *
1273
+ * lenis 스타일의 smooth scrolling. 네이티브 스크롤을 가로채서
1274
+ * lerp 보간으로 부드러운 스크롤 경험을 제공합니다.
1275
+ *
1276
+ * @example
1277
+ * ```tsx
1278
+ * const { scroll, progress, scrollTo } = useSmoothScroll({ lerp: 0.08 })
1279
+ * return <button onClick={() => scrollTo(document.getElementById('section')!)}>Go</button>
1280
+ * ```
1281
+ */
1282
+ declare function useSmoothScroll(options?: SmoothScrollOptions): SmoothScrollReturn;
1283
+
1284
+ interface ElementProgressOptions {
1285
+ /** 요소가 뷰포트 아래에서 시작되는 위치 (0 = 하단, 1 = 상단) @default 0 */
1286
+ start?: number;
1287
+ /** 요소가 뷰포트 위에서 끝나는 위치 @default 1 */
1288
+ end?: number;
1289
+ /** 클램프 여부 @default true */
1290
+ clamp?: boolean;
1291
+ }
1292
+ interface ElementProgressReturn<T extends HTMLElement = HTMLElement> {
1293
+ /** 대상 요소 ref */
1294
+ ref: React.RefObject<T | null>;
1295
+ /** 요소의 스크롤 진행률 (0-1) */
1296
+ progress: number;
1297
+ /** 요소가 뷰포트 안에 있는지 */
1298
+ isInView: boolean;
1299
+ }
1300
+ /**
1301
+ * useElementProgress - 요소 단위 스크롤 진행률 훅
1302
+ *
1303
+ * useScrollProgress의 확장판. 페이지 전체가 아니라
1304
+ * 특정 요소가 뷰포트를 통과하는 진행률을 추적합니다.
1305
+ *
1306
+ * 공유 스크롤 리스너(subscribeScroll)를 사용해 N개 인스턴스도
1307
+ * 단 하나의 scroll/resize 이벤트 + rAF 배칭으로 처리됩니다.
1308
+ *
1309
+ * @example
1310
+ * ```tsx
1311
+ * const { ref, progress, isInView } = useElementProgress<HTMLDivElement>()
1312
+ * return (
1313
+ * <div ref={ref} style={{ opacity: progress }}>
1314
+ * Fades in as you scroll
1315
+ * </div>
1316
+ * )
1317
+ * ```
1318
+ */
1319
+ declare function useElementProgress<T extends HTMLElement = HTMLElement>(options?: ElementProgressOptions): ElementProgressReturn<T>;
1320
+
1047
1321
  declare const MOTION_PRESETS: PresetConfig;
1048
1322
  declare const PAGE_MOTIONS: Record<PageType, PageMotionsConfig>;
1049
1323
  /**
@@ -1059,6 +1333,172 @@ declare function getPagePreset(pageType: PageType): PageMotionsConfig;
1059
1333
  */
1060
1334
  declare function getMotionPreset(type: string): MotionPreset;
1061
1335
 
1336
+ /** 프로필 전체의 기본 모션 디폴트 */
1337
+ interface MotionProfileBase {
1338
+ /** 기본 duration (ms) */
1339
+ duration: number;
1340
+ /** 기본 easing (CSS 또는 named preset) */
1341
+ easing: string;
1342
+ /** IntersectionObserver 임계값 */
1343
+ threshold: number;
1344
+ /** 한 번만 트리거할지 여부 */
1345
+ triggerOnce: boolean;
1346
+ }
1347
+ /** 입장 애니메이션 디폴트 */
1348
+ interface MotionProfileEntrance {
1349
+ slide: {
1350
+ /** 슬라이드 거리 (px) */
1351
+ distance: number;
1352
+ /** 슬라이드 전용 이징 */
1353
+ easing: string;
1354
+ };
1355
+ fade: {
1356
+ /** 초기 투명도 */
1357
+ initialOpacity: number;
1358
+ };
1359
+ scale: {
1360
+ /** 초기 스케일 (useScrollReveal/useStagger용, 0.95 등 미세 변화) */
1361
+ from: number;
1362
+ };
1363
+ bounce: {
1364
+ /** 바운스 강도 */
1365
+ intensity: number;
1366
+ /** 바운스 전용 이징 */
1367
+ easing: string;
1368
+ };
1369
+ }
1370
+ /** 스태거 디폴트 */
1371
+ interface MotionProfileStagger {
1372
+ /** 아이템 간 딜레이 (ms) */
1373
+ perItem: number;
1374
+ /** 첫 아이템 전 딜레이 (ms) */
1375
+ baseDelay: number;
1376
+ }
1377
+ /** 인터랙션 디폴트 */
1378
+ interface MotionProfileInteraction {
1379
+ hover: {
1380
+ /** 호버 시 스케일 */
1381
+ scale: number;
1382
+ /** 호버 시 Y 오프셋 (px) */
1383
+ y: number;
1384
+ /** 호버 duration (ms) */
1385
+ duration: number;
1386
+ /** 호버 이징 */
1387
+ easing: string;
1388
+ };
1389
+ }
1390
+ /** 스프링 물리 디폴트 */
1391
+ interface MotionProfileSpring {
1392
+ /** 질량 */
1393
+ mass: number;
1394
+ /** 강성 */
1395
+ stiffness: number;
1396
+ /** 감쇠 */
1397
+ damping: number;
1398
+ /** 정지 임계값 */
1399
+ restDelta: number;
1400
+ /** 정지 속도 */
1401
+ restSpeed: number;
1402
+ }
1403
+ /** reduced motion 전략 */
1404
+ type ReducedMotionStrategy = 'skip' | 'fade-only' | 'minimal';
1405
+ /** 전체 Motion Profile */
1406
+ interface MotionProfile {
1407
+ /** 프로필 이름 */
1408
+ name: string;
1409
+ /** 공통 디폴트 */
1410
+ base: MotionProfileBase;
1411
+ /** 입장 애니메이션 */
1412
+ entrance: MotionProfileEntrance;
1413
+ /** 스태거 */
1414
+ stagger: MotionProfileStagger;
1415
+ /** 인터랙션 */
1416
+ interaction: MotionProfileInteraction;
1417
+ /** 스프링 물리 */
1418
+ spring: MotionProfileSpring;
1419
+ /** reduced motion 전략 */
1420
+ reducedMotion: ReducedMotionStrategy;
1421
+ }
1422
+ /** 내장 프로필 이름 */
1423
+ type BuiltInProfileName = 'neutral' | 'hua';
1424
+ /** DeepPartial 유틸리티 */
1425
+ type DeepPartial<T> = {
1426
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
1427
+ };
1428
+
1429
+ /**
1430
+ * neutral 프로필 — 기존 하드코딩 디폴트와 동일.
1431
+ * Provider 없을 때 fallback으로 사용되므로 하위 호환 100% 보장.
1432
+ */
1433
+ declare const neutral: MotionProfile;
1434
+
1435
+ /**
1436
+ * HUA 프로필 — 스르륵 쫀뜩한 브랜드 시그니처.
1437
+ *
1438
+ * 특징:
1439
+ * - CSS ease-out 기반이되 끝에 미세한 오버슈트 (1.04~1.06)
1440
+ * - 도착점을 살짝 지나쳤다가 돌아오는 탄성
1441
+ * - 바운스 없이 쫀뜩 (높은 감쇠 + 높은 강성)
1442
+ * - neutral보다 짧은 duration, 좁은 distance → 더 정교한 느낌
1443
+ */
1444
+ declare const hua: MotionProfile;
1445
+
1446
+ interface MotionProfileProviderProps {
1447
+ /** 내장 프로필 이름 또는 커스텀 프로필 객체 */
1448
+ profile?: BuiltInProfileName | MotionProfile;
1449
+ /** 선택한 프로필 위에 부분 오버라이드 */
1450
+ overrides?: DeepPartial<MotionProfile>;
1451
+ children: React.ReactNode;
1452
+ }
1453
+ declare function MotionProfileProvider({ profile, overrides, children, }: MotionProfileProviderProps): react.FunctionComponentElement<react.ProviderProps<MotionProfile>>;
1454
+ /**
1455
+ * 현재 프로필을 가져옴.
1456
+ * Provider 밖에서 호출 시 neutral 프로필 반환 (하위 호환).
1457
+ */
1458
+ declare function useMotionProfile(): MotionProfile;
1459
+
1460
+ /** 이름 또는 객체에서 프로필 resolve */
1461
+ declare function resolveProfile(profile: BuiltInProfileName | MotionProfile): MotionProfile;
1462
+ /** 프로필에 오버라이드를 깊은 병합 */
1463
+ declare function mergeProfileOverrides(base: MotionProfile, overrides: DeepPartial<MotionProfile>): MotionProfile;
1464
+
1465
+ /**
1466
+ * Shared IntersectionObserver Pool
1467
+ *
1468
+ * threshold|rootMargin 조합별로 하나의 IntersectionObserver를 공유합니다.
1469
+ * N개 훅 = K개 observer (K = 고유 옵션 조합 수, 보통 1~3).
1470
+ *
1471
+ * sharedScroll.ts와 동일한 singleton pool 패턴.
1472
+ *
1473
+ * @example
1474
+ * ```ts
1475
+ * useEffect(() => {
1476
+ * if (!ref.current) return
1477
+ * return observeElement(
1478
+ * ref.current,
1479
+ * (entry) => { if (entry.isIntersecting) start() },
1480
+ * { threshold: 0.1 },
1481
+ * true // once
1482
+ * )
1483
+ * }, [])
1484
+ * ```
1485
+ */
1486
+ type EntryCallback = (entry: IntersectionObserverEntry) => void;
1487
+ /**
1488
+ * element를 공유 IntersectionObserver에 등록.
1489
+ * 반환 함수를 호출하면 구독 해제.
1490
+ *
1491
+ * @param element - 관찰할 DOM element
1492
+ * @param callback - intersection 변화 시 호출되는 콜백 (해당 element의 entry만 전달)
1493
+ * @param options - threshold, rootMargin
1494
+ * @param once - true이면 첫 intersection 후 자동 unsubscribe
1495
+ * @returns unsubscribe 함수
1496
+ */
1497
+ declare function observeElement(element: Element, callback: EntryCallback, options?: {
1498
+ threshold?: number | number[];
1499
+ rootMargin?: string;
1500
+ }, once?: boolean): () => void;
1501
+
1062
1502
  type EasingFunction = (t: number) => number;
1063
1503
  declare const linear: EasingFunction;
1064
1504
  declare const easeIn: EasingFunction;
@@ -1086,4 +1526,102 @@ declare const easingPresets: {
1086
1526
  };
1087
1527
  declare function getPresetEasing(preset: keyof typeof easingPresets): EasingFunction;
1088
1528
 
1089
- export { type BaseMotionOptions, type BaseMotionReturn, type BounceOptions, type EasingFunction, type EasingType, type EntranceType, type FadeInOptions, type GestureConfig, type GestureOptions$1 as GestureOptions, type GradientOptions, type HoverMotionOptions, type InViewOptions, type InViewReturn, type InteractionReturn, MOTION_PRESETS, type Motion, type MotionCallback, type MotionConfig, type MotionDirection$1 as MotionDirection, type MotionEasing, type MotionElement, MotionEngine, type MotionFrame, type MotionOptions, type MotionPreset, type MotionProgressCallback, type MotionState$1 as MotionState, type MotionStateCallback, type MotionTrigger, type MotionType$1 as MotionType, type MouseOptions, type MouseReturn, type OptimizationConfig, type OrchestrationConfig, PAGE_MOTIONS, type PageMotionElement, type PageMotionRef, type PageMotionsConfig, type PageType, type PerformanceMetrics, PerformanceOptimizer, type PerformanceOptimizerMetrics, type PresetConfig, type PulseOptions, type ReducedMotionReturn, type RepeatOptions, type ScaleOptions, type ScrollRevealMotionType, type ScrollRevealOptions, type SlideOptions, type SpringConfig, type SpringOptions, type ToggleMotionOptions, TransitionEffects, type TransitionOptions, type TransitionType, type UseUnifiedMotionOptions, type WindowSizeOptions, type WindowSizeReturn, applyEasing, easeIn, easeInOut, easeInOutQuad, easeInQuad, easeOut, easeOutQuad, easingPresets, getAvailableEasings, getEasing, getMotionPreset, getPagePreset, getPresetEasing, isEasingFunction, isValidEasing, linear, mergeWithPreset, motionEngine, performanceOptimizer, safeApplyEasing, transitionEffects, useBounceIn, useClickToggle, useFadeIn, useFocusToggle, useGesture, useGestureMotion, useGradient, useHoverMotion, useInView, useMotionState, useMouse, usePageMotions, usePulse, useReducedMotion, useRepeat, useScaleIn, useScrollProgress, useScrollReveal, useSimplePageMotion, useSlideDown, useSlideLeft, useSlideRight, useSlideUp, useSmartMotion, useSpringMotion, useToggleMotion, useUnifiedMotion, useWindowSize };
1529
+ /**
1530
+ * Spring physics calculation (Hooke's Law + damping)
1531
+ *
1532
+ * Pure function — no side effects, fully testable.
1533
+ */
1534
+ interface SpringConfig {
1535
+ stiffness: number;
1536
+ damping: number;
1537
+ mass: number;
1538
+ }
1539
+ interface SpringResult {
1540
+ value: number;
1541
+ velocity: number;
1542
+ }
1543
+ /**
1544
+ * Calculate one step of a damped spring simulation.
1545
+ *
1546
+ * @param currentValue Current position
1547
+ * @param currentVelocity Current velocity
1548
+ * @param targetValue Equilibrium (target) position
1549
+ * @param deltaTime Time step in seconds
1550
+ * @param config Spring parameters (stiffness, damping, mass)
1551
+ */
1552
+ declare function calculateSpring(currentValue: number, currentVelocity: number, targetValue: number, deltaTime: number, config: SpringConfig): SpringResult;
1553
+
1554
+ type MotionAs = 'div' | 'span' | 'section' | 'article' | 'header' | 'footer' | 'main' | 'nav';
1555
+ interface MotionProps extends react__default.HTMLAttributes<HTMLElement> {
1556
+ /** HTML 요소 타입 @default 'div' */
1557
+ as?: MotionAs;
1558
+ /** 모션 타입 */
1559
+ type?: EntranceType;
1560
+ /** 멀티이펙트 */
1561
+ effects?: MotionEffects;
1562
+ /** 스크롤 기반 reveal 모드 */
1563
+ scroll?: boolean | ScrollRevealOptions;
1564
+ /** 딜레이 (ms) */
1565
+ delay?: number;
1566
+ /** 지속시간 (ms) */
1567
+ duration?: number;
1568
+ children: react__default.ReactNode;
1569
+ }
1570
+ /**
1571
+ * Motion wrapper component
1572
+ *
1573
+ * ref/style 수동 연결 없이 모션을 적용하는 래퍼 컴포넌트.
1574
+ *
1575
+ * @example
1576
+ * // 기본 fadeIn
1577
+ * <Motion>content</Motion>
1578
+ *
1579
+ * // 스크롤 reveal
1580
+ * <Motion scroll delay={200} className="grid grid-cols-3">...</Motion>
1581
+ *
1582
+ * // 커스텀 요소 + 타입
1583
+ * <Motion as="section" type="slideUp" duration={800}>...</Motion>
1584
+ */
1585
+ declare function Motion({ as: Component, type, effects, scroll, delay, duration, children, className, style: userStyle, ...rest }: MotionProps): react_jsx_runtime.JSX.Element;
1586
+
1587
+ interface UseStaggerOptions {
1588
+ /** 자식 아이템 개수 */
1589
+ count: number;
1590
+ /** 아이템 간 딜레이 (ms) @default 100 */
1591
+ staggerDelay?: number;
1592
+ /** 전체 시작 딜레이 (ms) @default 0 */
1593
+ baseDelay?: number;
1594
+ /** 애니메이션 지속시간 (ms) @default 700 */
1595
+ duration?: number;
1596
+ /** 모션 타입 @default 'fadeIn' */
1597
+ motionType?: ScrollRevealMotionType;
1598
+ /** IntersectionObserver 임계값 @default 0.1 */
1599
+ threshold?: number;
1600
+ /** 이징 함수 @default 'ease-out' */
1601
+ easing?: string;
1602
+ }
1603
+ interface UseStaggerReturn {
1604
+ /** 부모 컨테이너 ref — IntersectionObserver 연결 */
1605
+ containerRef: RefObject<HTMLDivElement | null>;
1606
+ /** 자식 아이템별 style 배열 */
1607
+ styles: CSSProperties[];
1608
+ /** 전체 visible 여부 */
1609
+ isVisible: boolean;
1610
+ }
1611
+ /**
1612
+ * useStagger — 리스트 아이템에 순차 딜레이를 적용하는 훅
1613
+ *
1614
+ * 단일 IntersectionObserver로 컨테이너를 관찰하고,
1615
+ * 자식 아이템별로 CSS transition-delay를 자동 계산합니다.
1616
+ *
1617
+ * @example
1618
+ * const stagger = useStagger({ count: items.length, staggerDelay: 100 });
1619
+ * <div ref={stagger.containerRef}>
1620
+ * {items.map((item, i) => (
1621
+ * <div style={stagger.styles[i]} key={i}>{item}</div>
1622
+ * ))}
1623
+ * </div>
1624
+ */
1625
+ declare function useStagger(options: UseStaggerOptions): UseStaggerReturn;
1626
+
1627
+ export { type BaseMotionOptions, type BaseMotionReturn, type BounceOptions, type BuiltInProfileName, type ButtonEffectOptions, type CardListOptions, type CustomCursorOptions, type CustomCursorReturn, type DeepPartial, type EasingFunction, type EasingType, type ElementProgressOptions, type ElementProgressReturn, type EntranceType, type FadeInOptions, type GestureConfig, type GestureOptions$1 as GestureOptions, type GradientOptions, type HoverMotionOptions, type InViewOptions, type InViewReturn, type InteractionReturn, type LoadingSpinnerOptions, MOTION_PRESETS, type MagneticCursorOptions, type MagneticCursorReturn, Motion, type MotionCallback, type MotionConfig, type MotionDirection$1 as MotionDirection, type MotionEasing, type MotionEffects, type MotionElement, MotionEngine, type MotionFrame, type Motion$1 as MotionInstance, type MotionOptions, type MotionPreset, type MotionProfile, type MotionProfileBase, type MotionProfileEntrance, type MotionProfileInteraction, MotionProfileProvider, type MotionProfileProviderProps, type MotionProfileSpring, type MotionProfileStagger, type MotionProgressCallback, type MotionProps, type MotionState$1 as MotionState, type MotionStateCallback, type MotionTrigger, type MotionType$1 as MotionType, type MouseOptions, type MouseReturn, type NavigationOptions, type OrchestrationConfig, PAGE_MOTIONS, type PageMotionElement, type PageMotionRef, type PageMotionsConfig, type PageType, type PerformanceMetrics, type PresetConfig, type PulseOptions, type ReducedMotionReturn, type ReducedMotionStrategy, type RepeatOptions, type ScaleOptions, type ScrollRevealMotionType, type ScrollRevealOptions, type ScrollToggleOptions, type SkeletonOptions, type SlideOptions, type SmoothScrollOptions, type SmoothScrollReturn, type SpringConfig$1 as SpringConfig, type SpringOptions, type SpringConfig as SpringPhysicsConfig, type SpringResult, type ToggleMotionOptions, TransitionEffects, type TransitionOptions, type TransitionType, type TypewriterOptions, type TypewriterReturn, type UseStaggerOptions, type UseStaggerReturn, type UseUnifiedMotionOptions, type VisibilityToggleOptions, type WindowSizeOptions, type WindowSizeReturn, applyEasing, calculateSpring, easeIn, easeInOut, easeInOutQuad, easeInQuad, easeOut, easeOutQuad, easingPresets, getAvailableEasings, getEasing, getMotionPreset, getPagePreset, getPresetEasing, hua, isEasingFunction, isValidEasing, linear, mergeProfileOverrides, mergeWithPreset, motionEngine, neutral, observeElement, resolveProfile, safeApplyEasing, transitionEffects, useBounceIn, useButtonEffect, useCardList, useClickToggle, useCustomCursor, useElementProgress, useFadeIn, useFocusToggle, useGesture, useGestureMotion, useGradient, useHoverMotion, useInView, useLoadingSpinner, useMagneticCursor, useMotionProfile, useMotionState, useMouse, useNavigation, usePageMotions, usePulse, useReducedMotion, useRepeat, useScaleIn, useScrollProgress, useScrollReveal, useScrollToggle, useSimplePageMotion, useSkeleton, useSlideDown, useSlideLeft, useSlideRight, useSlideUp, useSmartMotion, useSmoothScroll, useSpringMotion, useStagger, useToggleMotion, useTypewriter, useUnifiedMotion, useVisibilityToggle, useWindowSize };