framer-motion 9.0.2 → 9.0.3

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.
Files changed (76) hide show
  1. package/dist/cjs/index.js +3344 -3260
  2. package/dist/es/animation/hooks/use-animated-state.mjs +3 -3
  3. package/dist/es/animation/index.mjs +3 -5
  4. package/dist/es/animation/legacy-popmotion/index.mjs +6 -2
  5. package/dist/es/animation/legacy-popmotion/inertia.mjs +4 -5
  6. package/dist/es/components/AnimatePresence/use-presence.mjs +0 -1
  7. package/dist/es/events/add-dom-event.mjs +6 -0
  8. package/dist/es/events/add-pointer-event.mjs +8 -0
  9. package/dist/es/events/use-dom-event.mjs +2 -5
  10. package/dist/es/gestures/drag/VisualElementDragControls.mjs +31 -30
  11. package/dist/es/gestures/drag/index.mjs +27 -0
  12. package/dist/es/gestures/focus.mjs +42 -0
  13. package/dist/es/gestures/hover.mjs +32 -0
  14. package/dist/es/gestures/{PanSession.mjs → pan/PanSession.mjs} +8 -8
  15. package/dist/es/gestures/pan/index.mjs +38 -0
  16. package/dist/es/gestures/press.mjs +109 -0
  17. package/dist/es/index.mjs +1 -1
  18. package/dist/es/motion/features/Feature.mjs +9 -0
  19. package/dist/es/motion/features/animation/exit.mjs +32 -0
  20. package/dist/es/motion/features/animation/index.mjs +38 -0
  21. package/dist/es/motion/features/animations.mjs +8 -37
  22. package/dist/es/motion/features/definitions.mjs +17 -23
  23. package/dist/es/motion/features/drag.mjs +12 -5
  24. package/dist/es/motion/features/gestures.mjs +16 -9
  25. package/dist/es/motion/features/layout/MeasureLayout.mjs +5 -5
  26. package/dist/es/motion/features/layout.mjs +11 -0
  27. package/dist/es/motion/features/load-features.mjs +4 -6
  28. package/dist/es/motion/features/viewport/index.mjs +96 -0
  29. package/dist/es/motion/index.mjs +12 -13
  30. package/dist/es/motion/utils/use-visual-element.mjs +8 -2
  31. package/dist/es/projection/geometry/delta-apply.mjs +9 -2
  32. package/dist/es/projection/geometry/delta-calc.mjs +2 -2
  33. package/dist/es/projection/geometry/delta-remove.mjs +2 -2
  34. package/dist/es/projection/node/DocumentProjectionNode.mjs +1 -1
  35. package/dist/es/projection/node/create-projection-node.mjs +65 -57
  36. package/dist/es/projection/node/group.mjs +5 -3
  37. package/dist/es/projection/shared/stack.mjs +7 -5
  38. package/dist/es/render/VisualElement.mjs +68 -47
  39. package/dist/es/render/dom/DOMVisualElement.mjs +1 -2
  40. package/dist/es/render/dom/features-max.mjs +2 -4
  41. package/dist/es/render/dom/motion.mjs +5 -6
  42. package/dist/es/render/dom/utils/create-config.mjs +1 -2
  43. package/dist/es/render/dom/value-types/animatable-none.mjs +3 -2
  44. package/dist/es/render/svg/SVGVisualElement.mjs +2 -2
  45. package/dist/es/render/utils/animation-state.mjs +6 -2
  46. package/dist/es/render/utils/animation.mjs +4 -4
  47. package/dist/es/render/utils/motion-values.mjs +1 -1
  48. package/dist/es/render/utils/setters.mjs +14 -9
  49. package/dist/es/value/index.mjs +1 -1
  50. package/dist/es/value/utils/is-motion-value.mjs +1 -1
  51. package/dist/framer-motion.dev.js +3341 -3257
  52. package/dist/framer-motion.js +1 -1
  53. package/dist/index.d.ts +85 -77
  54. package/dist/projection.dev.js +217 -177
  55. package/dist/size-rollup-dom-animation-assets.js +1 -1
  56. package/dist/size-rollup-dom-animation-m.js +1 -1
  57. package/dist/size-rollup-dom-animation.js +1 -1
  58. package/dist/size-rollup-dom-max-assets.js +1 -1
  59. package/dist/size-rollup-dom-max.js +1 -1
  60. package/dist/size-rollup-m.js +1 -1
  61. package/dist/size-rollup-motion.js +1 -1
  62. package/dist/size-webpack-dom-animation.js +1 -1
  63. package/dist/size-webpack-dom-max.js +1 -1
  64. package/dist/size-webpack-m.js +1 -1
  65. package/dist/three-entry.d.ts +74 -38
  66. package/package.json +8 -8
  67. package/dist/es/events/use-pointer-event.mjs +0 -11
  68. package/dist/es/gestures/drag/use-drag.mjs +0 -20
  69. package/dist/es/gestures/use-focus-gesture.mjs +0 -37
  70. package/dist/es/gestures/use-hover-gesture.mjs +0 -32
  71. package/dist/es/gestures/use-pan-gesture.mjs +0 -46
  72. package/dist/es/gestures/use-tap-gesture.mjs +0 -115
  73. package/dist/es/motion/features/layout/index.mjs +0 -7
  74. package/dist/es/motion/features/viewport/use-viewport.mjs +0 -97
  75. package/dist/es/motion/utils/VisualElementHandler.mjs +0 -19
  76. package/dist/es/motion/utils/make-renderless-component.mjs +0 -6
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import * as React$1 from 'react';
2
+ import * as react from 'react';
3
3
  import { SVGAttributes, CSSProperties, RefObject, useEffect } from 'react';
4
4
 
5
5
  declare type EasingFunction = (v: number) => number;
@@ -919,7 +919,7 @@ interface MotionConfigContext {
919
919
  /**
920
920
  * @public
921
921
  */
922
- declare const MotionConfigContext: React$1.Context<MotionConfigContext>;
922
+ declare const MotionConfigContext: react.Context<MotionConfigContext>;
923
923
 
924
924
  declare class NodeStack {
925
925
  lead?: IProjectionNode;
@@ -1102,7 +1102,7 @@ declare type SwitchLayoutGroupContext = SwitchLayoutGroup & InitialPromotionConf
1102
1102
  /**
1103
1103
  * Internal, exported only for usage in Framer
1104
1104
  */
1105
- declare const SwitchLayoutGroupContext: React$1.Context<SwitchLayoutGroupContext>;
1105
+ declare const SwitchLayoutGroupContext: react.Context<SwitchLayoutGroupContext>;
1106
1106
 
1107
1107
  interface VisualState<Instance, RenderState> {
1108
1108
  renderState: RenderState;
@@ -1117,27 +1117,46 @@ interface UseVisualStateConfig<Instance, RenderState> {
1117
1117
  }
1118
1118
  declare const makeUseVisualState: <I, RS>(config: UseVisualStateConfig<I, RS>) => UseVisualState<I, RS>;
1119
1119
 
1120
- /**
1121
- * @public
1122
- */
1123
- interface FeatureProps<T = unknown> extends MotionProps {
1124
- visualElement: VisualElement<T>;
1120
+ declare abstract class Feature<T> {
1121
+ isMounted: boolean;
1122
+ node: VisualElement<T>;
1123
+ constructor(node: VisualElement<T>);
1124
+ abstract mount(): void;
1125
+ abstract unmount(): void;
1126
+ update(): void;
1125
1127
  }
1126
- declare type FeatureComponent = React$1.ComponentType<React$1.PropsWithChildren<FeatureProps>>;
1127
- interface FeatureComponents {
1128
- animation?: FeatureComponent;
1129
- exit?: FeatureComponent;
1130
- drag?: FeatureComponent;
1131
- tap?: FeatureComponent;
1132
- focus?: FeatureComponent;
1133
- hover?: FeatureComponent;
1134
- pan?: FeatureComponent;
1135
- inView?: FeatureComponent;
1136
- measureLayout?: FeatureComponent;
1128
+
1129
+ declare function MeasureLayout(props: MotionProps & {
1130
+ visualElement: VisualElement;
1131
+ }): JSX.Element;
1132
+
1133
+ declare type HydratedFeatureDefinition = {
1134
+ isEnabled: (props: MotionProps) => boolean;
1135
+ Feature: typeof Feature<any>;
1136
+ ProjectionNode?: any;
1137
+ MeasureLayout?: typeof MeasureLayout;
1138
+ };
1139
+ interface HydratedFeatureDefinitions {
1140
+ animation?: HydratedFeatureDefinition;
1141
+ exit?: HydratedFeatureDefinition;
1142
+ drag?: HydratedFeatureDefinition;
1143
+ tap?: HydratedFeatureDefinition;
1144
+ focus?: HydratedFeatureDefinition;
1145
+ hover?: HydratedFeatureDefinition;
1146
+ pan?: HydratedFeatureDefinition;
1147
+ inView?: HydratedFeatureDefinition;
1148
+ layout?: HydratedFeatureDefinition;
1137
1149
  }
1138
- interface FeatureBundle extends FeatureComponents {
1150
+ declare type FeaturePackage = {
1151
+ Feature?: HydratedFeatureDefinition["Feature"];
1152
+ ProjectionNode?: HydratedFeatureDefinition["ProjectionNode"];
1153
+ MeasureLayout?: HydratedFeatureDefinition["MeasureLayout"];
1154
+ };
1155
+ declare type FeaturePackages = {
1156
+ [K in keyof HydratedFeatureDefinitions]: FeaturePackage;
1157
+ };
1158
+ interface FeatureBundle extends FeaturePackages {
1139
1159
  renderer: CreateVisualElement<any>;
1140
- projectionNodeConstructor?: any;
1141
1160
  }
1142
1161
 
1143
1162
  declare enum AnimationType {
@@ -1180,6 +1199,18 @@ interface AnimationTypeState {
1180
1199
  prevProp?: VariantLabels | TargetAndTransition;
1181
1200
  }
1182
1201
 
1202
+ /**
1203
+ * @public
1204
+ */
1205
+ interface PresenceContextProps {
1206
+ id: string;
1207
+ isPresent: boolean;
1208
+ register: (id: string | number) => () => void;
1209
+ onExitComplete?: (id: string | number) => void;
1210
+ initial?: false | VariantLabels;
1211
+ custom?: any;
1212
+ }
1213
+
1183
1214
  /**
1184
1215
  * A VisualElement is an imperative abstraction around UI elements such as
1185
1216
  * HTMLElement, SVGElement, Three.Object3D etc.
@@ -1318,11 +1349,6 @@ declare abstract class VisualElement<Instance = unknown, RenderState = unknown,
1318
1349
  * value might be provided externally by the component via props.
1319
1350
  */
1320
1351
  values: Map<string, MotionValue<any>>;
1321
- /**
1322
- * Tracks whether this VisualElement's React component is currently present
1323
- * within the defined React tree.
1324
- */
1325
- isPresent: boolean;
1326
1352
  /**
1327
1353
  * The AnimationState, this is hydrated by the animation Feature.
1328
1354
  */
@@ -1335,7 +1361,14 @@ declare abstract class VisualElement<Instance = unknown, RenderState = unknown,
1335
1361
  /**
1336
1362
  * A reference to the latest props provided to the VisualElement's host React component.
1337
1363
  */
1338
- protected props: MotionProps;
1364
+ props: MotionProps;
1365
+ prevProps?: MotionProps;
1366
+ presenceContext: PresenceContextProps | null;
1367
+ prevPresenceContext?: PresenceContextProps | null;
1368
+ /**
1369
+ * Cleanup functions for active features (hover/tap/exit etc)
1370
+ */
1371
+ private features;
1339
1372
  /**
1340
1373
  * A map of every subscription that binds the provided or generated
1341
1374
  * motion values onChange listeners to this visual element.
@@ -1375,12 +1408,13 @@ declare abstract class VisualElement<Instance = unknown, RenderState = unknown,
1375
1408
  * VisualElement.on(), but only one of those can be defined via the onUpdate prop.
1376
1409
  */
1377
1410
  private propEventSubscriptions;
1378
- constructor({ parent, props, reducedMotionConfig, visualState, }: VisualElementOptions<Instance, RenderState>, options?: Options);
1411
+ constructor({ parent, props, presenceContext, reducedMotionConfig, visualState, }: VisualElementOptions<Instance, RenderState>, options?: Options);
1379
1412
  mount(instance: Instance): void;
1380
1413
  unmount(): void;
1381
1414
  private bindToMotionValue;
1382
1415
  sortNodePosition(other: VisualElement<Instance>): number;
1383
- loadFeatures({ children, ...renderedProps }: MotionProps, isStrict: boolean, preloadedFeatures?: FeatureBundle, projectionId?: number, ProjectionNodeConstructor?: any, initialLayoutGroupConfig?: SwitchLayoutGroupContext): JSX.Element[];
1416
+ loadFeatures({ children, ...renderedProps }: MotionProps, isStrict: boolean, preloadedFeatures?: FeatureBundle, projectionId?: number, initialLayoutGroupConfig?: SwitchLayoutGroupContext): react.ComponentType<MotionProps> | undefined;
1417
+ updateFeatures(): void;
1384
1418
  notifyUpdate: () => void;
1385
1419
  triggerBuild(): void;
1386
1420
  render: () => void;
@@ -1405,7 +1439,7 @@ declare abstract class VisualElement<Instance = unknown, RenderState = unknown,
1405
1439
  * Update the provided props. Ensure any newly-added motion values are
1406
1440
  * added to our map, old ones removed, and listeners updated.
1407
1441
  */
1408
- setProps(props: MotionProps): void;
1442
+ update(props: MotionProps, presenceContext: PresenceContextProps | null): void;
1409
1443
  getProps(): MotionProps;
1410
1444
  /**
1411
1445
  * Returns the variant definition with a given name.
@@ -1784,7 +1818,7 @@ declare class DragControls {
1784
1818
  *
1785
1819
  * @public
1786
1820
  */
1787
- start(event: React$1.PointerEvent | PointerEvent, options?: DragControlOptions): void;
1821
+ start(event: react.PointerEvent | PointerEvent, options?: DragControlOptions): void;
1788
1822
  }
1789
1823
 
1790
1824
  declare type DragElastic = boolean | number | Partial<BoundingBox>;
@@ -2285,7 +2319,7 @@ interface PanHandlers {
2285
2319
  * - `offset`: Offset from the original pan event.
2286
2320
  * - `velocity`: Current velocity of the pointer.
2287
2321
  */
2288
- onPan?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void;
2322
+ onPan?(event: PointerEvent, info: PanInfo): void;
2289
2323
  /**
2290
2324
  * Callback function that fires when the pan gesture begins on this element.
2291
2325
  *
@@ -2305,7 +2339,7 @@ interface PanHandlers {
2305
2339
  * - `offset`: Offset from the original pan event.
2306
2340
  * - `velocity`: Current velocity of the pointer.
2307
2341
  */
2308
- onPanStart?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void;
2342
+ onPanStart?(event: PointerEvent, info: PanInfo): void;
2309
2343
  /**
2310
2344
  * Callback function that fires when we begin detecting a pan gesture. This
2311
2345
  * is analogous to `onMouseStart` or `onTouchStart`.
@@ -2323,7 +2357,7 @@ interface PanHandlers {
2323
2357
  *
2324
2358
  * - `point`: Relative to the device or page.
2325
2359
  */
2326
- onPanSessionStart?(event: MouseEvent | TouchEvent | PointerEvent, info: EventInfo): void;
2360
+ onPanSessionStart?(event: PointerEvent, info: EventInfo): void;
2327
2361
  /**
2328
2362
  * Callback function that fires when the pan gesture ends on this element.
2329
2363
  *
@@ -2343,7 +2377,7 @@ interface PanHandlers {
2343
2377
  * - `offset`: Offset from the original pan event.
2344
2378
  * - `velocity`: Current velocity of the pointer.
2345
2379
  */
2346
- onPanEnd?(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void;
2380
+ onPanEnd?(event: PointerEvent, info: PanInfo): void;
2347
2381
  }
2348
2382
  /**
2349
2383
  * @public
@@ -2381,6 +2415,9 @@ interface ViewportOptions {
2381
2415
  once?: boolean;
2382
2416
  margin?: string;
2383
2417
  amount?: "some" | "all" | number;
2418
+ /**
2419
+ * @deprecated IntersectionObserver fallback will always be disabled from 10.0. Prefer polyfill for older browser support.
2420
+ */
2384
2421
  fallback?: boolean;
2385
2422
  }
2386
2423
  interface ViewportProps {
@@ -2664,7 +2701,7 @@ declare type VisualElementOptions<Instance, RenderState = any> = {
2664
2701
  visualState: VisualState<Instance, RenderState>;
2665
2702
  parent?: VisualElement<unknown>;
2666
2703
  variantParent?: VisualElement<unknown>;
2667
- presenceId?: string | undefined;
2704
+ presenceContext: PresenceContextProps | null;
2668
2705
  props: MotionProps;
2669
2706
  blockInitialAnimation?: boolean;
2670
2707
  reducedMotionConfig?: ReducedMotionConfig;
@@ -2680,7 +2717,6 @@ interface VisualElementEventCallbacks {
2680
2717
  LayoutMeasure: (layout: Box, prevLayout?: Box) => void;
2681
2718
  LayoutUpdate: (layout: Axis, prevLayout: Axis) => void;
2682
2719
  Update: (latest: ResolvedValues) => void;
2683
- Render: () => void;
2684
2720
  AnimationStart: (definition: AnimationDefinition) => void;
2685
2721
  AnimationComplete: (definition: AnimationDefinition) => void;
2686
2722
  LayoutAnimationStart: () => void;
@@ -2750,7 +2786,7 @@ interface AnimationLifecycles {
2750
2786
  declare type EventProps = LayoutLifecycles & AnimationLifecycles;
2751
2787
  declare type CreateVisualElement<Instance> = (Component: string | React.ComponentType<React.PropsWithChildren<unknown>>, options: VisualElementOptions<Instance>) => VisualElement<Instance>;
2752
2788
 
2753
- declare const animations: FeatureComponents;
2789
+ declare const animations: FeaturePackages;
2754
2790
 
2755
2791
  declare function useVisualElementContext(): VisualElement<unknown, unknown, {}> | undefined;
2756
2792
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "framer-motion",
3
- "version": "9.0.2",
3
+ "version": "9.0.3",
4
4
  "description": "A simple and powerful React animation library",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/es/index.mjs",
@@ -76,28 +76,28 @@
76
76
  },
77
77
  {
78
78
  "path": "./dist/size-rollup-m.js",
79
- "maxSize": "4.78 kB"
79
+ "maxSize": "4.68 kB"
80
80
  },
81
81
  {
82
82
  "path": "./dist/size-rollup-dom-animation.js",
83
- "maxSize": "14.97kB"
83
+ "maxSize": "14.88 kB"
84
84
  },
85
85
  {
86
86
  "path": "./dist/size-rollup-dom-max.js",
87
- "maxSize": "25.75 kB"
87
+ "maxSize": "25.56 kB"
88
88
  },
89
89
  {
90
90
  "path": "./dist/size-webpack-m.js",
91
- "maxSize": "4.99 kB"
91
+ "maxSize": "4.8 kB"
92
92
  },
93
93
  {
94
94
  "path": "./dist/size-webpack-dom-animation.js",
95
- "maxSize": "19.05 kB"
95
+ "maxSize": "18.91 kB"
96
96
  },
97
97
  {
98
98
  "path": "./dist/size-webpack-dom-max.js",
99
- "maxSize": "30.68 kB"
99
+ "maxSize": "30.43 kB"
100
100
  }
101
101
  ],
102
- "gitHead": "caab57697ca24152a57bdbb9dd4618400880863e"
102
+ "gitHead": "80400267dedc1e899949428217cd496a1ba687c3"
103
103
  }
@@ -1,11 +0,0 @@
1
- import { addDomEvent, useDomEvent } from './use-dom-event.mjs';
2
- import { addPointerInfo } from './event-info.mjs';
3
-
4
- function addPointerEvent(target, eventName, handler, options) {
5
- return addDomEvent(target, eventName, addPointerInfo(handler), options);
6
- }
7
- function usePointerEvent(ref, eventName, handler, options) {
8
- return useDomEvent(ref, eventName, handler && addPointerInfo(handler), options);
9
- }
10
-
11
- export { addPointerEvent, usePointerEvent };
@@ -1,20 +0,0 @@
1
- import { useEffect } from 'react';
2
- import { VisualElementDragControls } from './VisualElementDragControls.mjs';
3
- import { useConstant } from '../../utils/use-constant.mjs';
4
-
5
- /**
6
- * A hook that allows an element to be dragged.
7
- *
8
- * @internal
9
- */
10
- function useDrag(props) {
11
- const { dragControls: groupDragControls, visualElement } = props;
12
- const dragControls = useConstant(() => new VisualElementDragControls(visualElement));
13
- // If we've been provided a DragControls for manual control over the drag gesture,
14
- // subscribe this component to it on mount.
15
- useEffect(() => groupDragControls && groupDragControls.subscribe(dragControls), [dragControls, groupDragControls]);
16
- // Apply the event listeners to the element
17
- useEffect(() => dragControls.addListeners(), [dragControls]);
18
- }
19
-
20
- export { useDrag };
@@ -1,37 +0,0 @@
1
- import { AnimationType } from '../render/utils/types.mjs';
2
- import { useDomEvent } from '../events/use-dom-event.mjs';
3
- import { useRef, useCallback } from 'react';
4
-
5
- function useFocusGesture({ whileFocus, visualElement, }) {
6
- const isFocusActive = useRef(false);
7
- const { animationState } = visualElement;
8
- const onFocus = useCallback(() => {
9
- let isFocusVisible = false;
10
- /**
11
- * If this element doesn't match focus-visible then don't
12
- * apply whileHover. But, if matches throws that focus-visible
13
- * is not a valid selector then in that browser outline styles will be applied
14
- * to the element by default and we want to match that behaviour with whileFocus.
15
- */
16
- try {
17
- isFocusVisible = visualElement.current.matches(":focus-visible");
18
- }
19
- catch (e) {
20
- isFocusVisible = true;
21
- }
22
- if (!isFocusVisible || !animationState)
23
- return;
24
- animationState.setActive(AnimationType.Focus, true);
25
- isFocusActive.current = true;
26
- }, [animationState]);
27
- const onBlur = useCallback(() => {
28
- if (!isFocusActive.current || !animationState)
29
- return;
30
- animationState.setActive(AnimationType.Focus, false);
31
- isFocusActive.current = false;
32
- }, [animationState]);
33
- useDomEvent(visualElement, "focus", whileFocus ? onFocus : undefined);
34
- useDomEvent(visualElement, "blur", whileFocus ? onBlur : undefined);
35
- }
36
-
37
- export { useFocusGesture };
@@ -1,32 +0,0 @@
1
- import { AnimationType } from '../render/utils/types.mjs';
2
- import { usePointerEvent } from '../events/use-pointer-event.mjs';
3
- import { isDragActive } from './drag/utils/lock.mjs';
4
- import { useMemo } from 'react';
5
-
6
- function createHoverEvent(visualElement, isActive, applyVariants, callback) {
7
- return (event, info) => {
8
- if (event.type === "touch" || isDragActive())
9
- return;
10
- /**
11
- * Ensure we trigger animations before firing event callback
12
- */
13
- if (applyVariants && visualElement.animationState) {
14
- visualElement.animationState.setActive(AnimationType.Hover, isActive);
15
- }
16
- callback && callback(event, info);
17
- };
18
- }
19
- function useHoverGesture({ onHoverStart, onHoverEnd, whileHover, visualElement, }) {
20
- usePointerEvent(visualElement, "pointerenter", useMemo(() => {
21
- return onHoverStart || whileHover
22
- ? createHoverEvent(visualElement, true, Boolean(whileHover), onHoverStart)
23
- : undefined;
24
- }, [onHoverStart, Boolean(whileHover), visualElement]), { passive: !onHoverStart });
25
- usePointerEvent(visualElement, "pointerleave", useMemo(() => {
26
- return onHoverEnd || whileHover
27
- ? createHoverEvent(visualElement, false, Boolean(whileHover), onHoverEnd)
28
- : undefined;
29
- }, [onHoverStart, Boolean(whileHover), visualElement]), { passive: !onHoverEnd });
30
- }
31
-
32
- export { useHoverGesture };
@@ -1,46 +0,0 @@
1
- import { useRef, useContext, useEffect } from 'react';
2
- import { MotionConfigContext } from '../context/MotionConfigContext.mjs';
3
- import { useUnmountEffect } from '../utils/use-unmount-effect.mjs';
4
- import { usePointerEvent } from '../events/use-pointer-event.mjs';
5
- import { PanSession } from './PanSession.mjs';
6
-
7
- /**
8
- *
9
- * @param handlers -
10
- * @param ref -
11
- *
12
- * @privateRemarks
13
- * Currently this sets new pan gesture functions every render. The memo route has been explored
14
- * in the past but ultimately we're still creating new functions every render. An optimisation
15
- * to explore is creating the pan gestures and loading them into a `ref`.
16
- *
17
- * @internal
18
- */
19
- function usePanGesture({ onPan, onPanStart, onPanEnd, onPanSessionStart, visualElement, }) {
20
- const hasPanEvents = onPan || onPanStart || onPanEnd || onPanSessionStart;
21
- const panSession = useRef(null);
22
- const { transformPagePoint } = useContext(MotionConfigContext);
23
- const handlers = {
24
- onSessionStart: onPanSessionStart,
25
- onStart: onPanStart,
26
- onMove: onPan,
27
- onEnd: (event, info) => {
28
- panSession.current = null;
29
- onPanEnd && onPanEnd(event, info);
30
- },
31
- };
32
- useEffect(() => {
33
- if (panSession.current !== null) {
34
- panSession.current.updateHandlers(handlers);
35
- }
36
- });
37
- function onPointerDown(event) {
38
- panSession.current = new PanSession(event, handlers, {
39
- transformPagePoint,
40
- });
41
- }
42
- usePointerEvent(visualElement, "pointerdown", hasPanEvents && onPointerDown);
43
- useUnmountEffect(() => panSession.current && panSession.current.end());
44
- }
45
-
46
- export { usePanGesture };
@@ -1,115 +0,0 @@
1
- import { useRef, useCallback } from 'react';
2
- import { isNodeOrChild } from './utils/is-node-or-child.mjs';
3
- import { addPointerEvent, usePointerEvent } from '../events/use-pointer-event.mjs';
4
- import { useUnmountEffect } from '../utils/use-unmount-effect.mjs';
5
- import { AnimationType } from '../render/utils/types.mjs';
6
- import { isDragActive } from './drag/utils/lock.mjs';
7
- import { pipe } from '../utils/pipe.mjs';
8
- import { addDomEvent, useDomEvent } from '../events/use-dom-event.mjs';
9
- import { extractEventInfo } from '../events/event-info.mjs';
10
-
11
- function fireSyntheticPointerEvent(name, handler) {
12
- if (!handler)
13
- return;
14
- const syntheticPointerEvent = new PointerEvent("pointer" + name);
15
- handler(syntheticPointerEvent, extractEventInfo(syntheticPointerEvent));
16
- }
17
- /**
18
- * @param handlers -
19
- * @internal
20
- */
21
- function useTapGesture({ onTap, onTapStart, onTapCancel, whileTap, visualElement, ...props }) {
22
- const hasPressListeners = onTap || onTapStart || onTapCancel || whileTap;
23
- const isPressing = useRef(false);
24
- const cancelPointerEndListeners = useRef(null);
25
- /**
26
- * Only set listener to passive if there are no external listeners.
27
- */
28
- const eventOptions = {
29
- passive: !(onTapStart ||
30
- onTap ||
31
- onTapCancel ||
32
- props["onPointerDown"]),
33
- };
34
- function removePointerEndListener() {
35
- cancelPointerEndListeners.current && cancelPointerEndListeners.current();
36
- cancelPointerEndListeners.current = null;
37
- }
38
- function checkPointerEnd() {
39
- removePointerEndListener();
40
- isPressing.current = false;
41
- const latestProps = visualElement.getProps();
42
- if (latestProps.whileTap && visualElement.animationState) {
43
- visualElement.animationState.setActive(AnimationType.Tap, false);
44
- }
45
- return !isDragActive();
46
- }
47
- function onPointerUp(event, info) {
48
- var _a, _b, _c, _d;
49
- if (!checkPointerEnd())
50
- return;
51
- /**
52
- * We only count this as a tap gesture if the event.target is the same
53
- * as, or a child of, this component's element
54
- */
55
- !isNodeOrChild(visualElement.current, event.target)
56
- ? (_b = (_a = visualElement.getProps()).onTapCancel) === null || _b === void 0 ? void 0 : _b.call(_a, event, info)
57
- : (_d = (_c = visualElement.getProps()).onTap) === null || _d === void 0 ? void 0 : _d.call(_c, event, info);
58
- }
59
- function onPointerCancel(event, info) {
60
- var _a, _b;
61
- if (!checkPointerEnd())
62
- return;
63
- (_b = (_a = visualElement.getProps()).onTapCancel) === null || _b === void 0 ? void 0 : _b.call(_a, event, info);
64
- }
65
- function onPointerStart(event, info) {
66
- var _a;
67
- const latestProps = visualElement.getProps();
68
- /**
69
- * Ensure we trigger animations before firing event callback
70
- */
71
- if (latestProps.whileTap && visualElement.animationState) {
72
- visualElement.animationState.setActive(AnimationType.Tap, true);
73
- }
74
- (_a = latestProps.onTapStart) === null || _a === void 0 ? void 0 : _a.call(latestProps, event, info);
75
- }
76
- const callbackDependencies = [
77
- Boolean(onTapStart),
78
- Boolean(onTap),
79
- Boolean(whileTap),
80
- visualElement,
81
- ];
82
- const startPress = useCallback((event, info) => {
83
- removePointerEndListener();
84
- if (isPressing.current)
85
- return;
86
- isPressing.current = true;
87
- cancelPointerEndListeners.current = pipe(addPointerEvent(window, "pointerup", onPointerUp, eventOptions), addPointerEvent(window, "pointercancel", onPointerCancel, eventOptions));
88
- onPointerStart(event, info);
89
- }, callbackDependencies);
90
- usePointerEvent(visualElement, "pointerdown", hasPressListeners ? startPress : undefined, eventOptions);
91
- const startAccessiblePress = useCallback(() => {
92
- const stopKeydownListener = addDomEvent(visualElement.current, "keydown", (event) => {
93
- if (event.key !== "Enter" || isPressing.current)
94
- return;
95
- isPressing.current = true;
96
- cancelPointerEndListeners.current = addDomEvent(visualElement.current, "keyup", () => {
97
- if (event.key !== "Enter" || !checkPointerEnd())
98
- return;
99
- fireSyntheticPointerEvent("up", visualElement.getProps().onTap);
100
- }, eventOptions);
101
- fireSyntheticPointerEvent("down", onPointerStart);
102
- });
103
- const stopBlurListener = addDomEvent(visualElement.current, "blur", () => {
104
- stopKeydownListener();
105
- stopBlurListener();
106
- if (isPressing.current) {
107
- fireSyntheticPointerEvent("cancel", onPointerCancel);
108
- }
109
- });
110
- }, callbackDependencies);
111
- useDomEvent(visualElement, "focus", hasPressListeners ? startAccessiblePress : undefined);
112
- useUnmountEffect(removePointerEndListener);
113
- }
114
-
115
- export { useTapGesture };
@@ -1,7 +0,0 @@
1
- import { MeasureLayout } from './MeasureLayout.mjs';
2
-
3
- const layoutFeatures = {
4
- measureLayout: MeasureLayout,
5
- };
6
-
7
- export { layoutFeatures };
@@ -1,97 +0,0 @@
1
- import { useRef, useEffect } from 'react';
2
- import { AnimationType } from '../../../render/utils/types.mjs';
3
- import { warnOnce } from '../../../utils/warn-once.mjs';
4
- import { observeIntersection } from './observers.mjs';
5
-
6
- function useViewport({ visualElement, whileInView, onViewportEnter, onViewportLeave, viewport = {}, }) {
7
- const state = useRef({
8
- hasEnteredView: false,
9
- isInView: false,
10
- });
11
- let shouldObserve = Boolean(whileInView || onViewportEnter || onViewportLeave);
12
- if (viewport.once && state.current.hasEnteredView)
13
- shouldObserve = false;
14
- const useObserver = typeof IntersectionObserver === "undefined"
15
- ? useMissingIntersectionObserver
16
- : useIntersectionObserver;
17
- useObserver(shouldObserve, state.current, visualElement, viewport);
18
- }
19
- const thresholdNames = {
20
- some: 0,
21
- all: 1,
22
- };
23
- function useIntersectionObserver(shouldObserve, state, visualElement, { root, margin: rootMargin, amount = "some", once }) {
24
- useEffect(() => {
25
- if (!shouldObserve || !visualElement.current)
26
- return;
27
- const options = {
28
- root: root === null || root === void 0 ? void 0 : root.current,
29
- rootMargin,
30
- threshold: typeof amount === "number" ? amount : thresholdNames[amount],
31
- };
32
- const intersectionCallback = (entry) => {
33
- const { isIntersecting } = entry;
34
- /**
35
- * If there's been no change in the viewport state, early return.
36
- */
37
- if (state.isInView === isIntersecting)
38
- return;
39
- state.isInView = isIntersecting;
40
- /**
41
- * Handle hasEnteredView. If this is only meant to run once, and
42
- * element isn't visible, early return. Otherwise set hasEnteredView to true.
43
- */
44
- if (once && !isIntersecting && state.hasEnteredView) {
45
- return;
46
- }
47
- else if (isIntersecting) {
48
- state.hasEnteredView = true;
49
- }
50
- if (visualElement.animationState) {
51
- visualElement.animationState.setActive(AnimationType.InView, isIntersecting);
52
- }
53
- /**
54
- * Use the latest committed props rather than the ones in scope
55
- * when this observer is created
56
- */
57
- const props = visualElement.getProps();
58
- const callback = isIntersecting
59
- ? props.onViewportEnter
60
- : props.onViewportLeave;
61
- callback && callback(entry);
62
- };
63
- return observeIntersection(visualElement.current, options, intersectionCallback);
64
- }, [shouldObserve, root, rootMargin, amount]);
65
- }
66
- /**
67
- * If IntersectionObserver is missing, we activate inView and fire onViewportEnter
68
- * on mount. This way, the page will be in the state the author expects users
69
- * to see it in for everyone.
70
- */
71
- function useMissingIntersectionObserver(shouldObserve, state, visualElement, { fallback = true }) {
72
- useEffect(() => {
73
- if (!shouldObserve || !fallback)
74
- return;
75
- if (process.env.NODE_ENV !== "production") {
76
- warnOnce(false, "IntersectionObserver not available on this device. whileInView animations will trigger on mount.");
77
- }
78
- /**
79
- * Fire this in an rAF because, at this point, the animation state
80
- * won't have flushed for the first time and there's certain logic in
81
- * there that behaves differently on the initial animation.
82
- *
83
- * This hook should be quite rarely called so setting this in an rAF
84
- * is preferred to changing the behaviour of the animation state.
85
- */
86
- requestAnimationFrame(() => {
87
- state.hasEnteredView = true;
88
- const { onViewportEnter } = visualElement.getProps();
89
- onViewportEnter && onViewportEnter(null);
90
- if (visualElement.animationState) {
91
- visualElement.animationState.setActive(AnimationType.InView, true);
92
- }
93
- });
94
- }, [shouldObserve]);
95
- }
96
-
97
- export { useViewport };
@@ -1,19 +0,0 @@
1
- import React__default from 'react';
2
-
3
- class VisualElementHandler extends React__default.Component {
4
- /**
5
- * Update visual element props as soon as we know this update is going to be commited.
6
- */
7
- getSnapshotBeforeUpdate() {
8
- const { visualElement, props } = this.props;
9
- if (visualElement)
10
- visualElement.setProps(props);
11
- return null;
12
- }
13
- componentDidUpdate() { }
14
- render() {
15
- return this.props.children;
16
- }
17
- }
18
-
19
- export { VisualElementHandler };