motion-v 0.8.0 → 0.9.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.
@@ -0,0 +1,71 @@
1
+ import { MotionProps } from '../motion';
2
+ import { ElementType } from '../../types';
3
+ export interface GroupProps<T extends ElementType, K = unknown, V = unknown> extends MotionProps<T, K> {
4
+ /**
5
+ * The axis to reorder along. By default, items will be draggable on this axis.
6
+ * To make draggable on both axes, set `<Reorder.Item drag />`
7
+ *
8
+ * @public
9
+ */
10
+ 'axis'?: 'x' | 'y';
11
+ /**
12
+ * A callback to fire with the new value order. For instance, if the values
13
+ * are provided as a state from `useState`, this could be the set state function.
14
+ *
15
+ * @public
16
+ */
17
+ 'onUpdate:values'?: (newOrder: V[]) => void;
18
+ /**
19
+ * The latest values state.
20
+ *
21
+ * ```jsx
22
+ * function Component() {
23
+ * const [items, setItems] = useState([0, 1, 2])
24
+ *
25
+ * return (
26
+ * <Reorder.Group values={items} onReorder={setItems}>
27
+ * {items.map((item) => <Reorder.Item key={item} value={item} />)}
28
+ * </Reorder.Group>
29
+ * )
30
+ * }
31
+ * ```
32
+ *
33
+ * @public
34
+ */
35
+ 'values': V[];
36
+ }
37
+ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<GroupProps<keyof import('vue').IntrinsicElementAttributes, unknown, unknown>>, {
38
+ as: string;
39
+ axis: string;
40
+ }>, {}, unknown, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<GroupProps<keyof import('vue').IntrinsicElementAttributes, unknown, unknown>>, {
41
+ as: string;
42
+ axis: string;
43
+ }>>>, {
44
+ as: keyof import('vue').IntrinsicElementAttributes;
45
+ axis: "x" | "y";
46
+ }, {}>, {
47
+ default?(_: {}): any;
48
+ }>;
49
+ export default _default;
50
+ type __VLS_WithDefaults<P, D> = {
51
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
52
+ default: D[K];
53
+ }> : P[K];
54
+ };
55
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
56
+ type __VLS_TypePropsToOption<T> = {
57
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
58
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
59
+ } : {
60
+ type: import('vue').PropType<T[K]>;
61
+ required: true;
62
+ };
63
+ };
64
+ type __VLS_WithTemplateSlots<T, S> = T & {
65
+ new (): {
66
+ $slots: S;
67
+ };
68
+ };
69
+ type __VLS_PrettifyLocal<T> = {
70
+ [K in keyof T]: T[K];
71
+ } & {};
@@ -0,0 +1,131 @@
1
+ import { defineComponent, toRefs, onUpdated, useAttrs, openBlock, createBlock, unref, normalizeProps, guardReactiveProps, withCtx, renderSlot, createTextVNode, toDisplayString } from "vue";
2
+ import { invariant } from "hey-listen";
3
+ import { reorderContextProvider } from "./context.mjs";
4
+ import { compareMin, checkReorder, getValue } from "./utils.mjs";
5
+ import _sfc_main$1 from "../motion/Motion.vue.mjs";
6
+ const _sfc_main = /* @__PURE__ */ defineComponent({
7
+ ...{
8
+ name: "ReorderGroup",
9
+ inheritAttrs: false
10
+ },
11
+ __name: "Group",
12
+ props: {
13
+ axis: { default: "y" },
14
+ "onUpdate:values": {},
15
+ values: {},
16
+ as: { default: "ul" },
17
+ asChild: { type: Boolean },
18
+ whileDrag: {},
19
+ custom: {},
20
+ initial: { type: [String, Object, Boolean] },
21
+ animate: {},
22
+ exit: {},
23
+ variants: {},
24
+ style: {},
25
+ transformTemplate: {},
26
+ transition: {},
27
+ layoutGroup: {},
28
+ motionConfig: {},
29
+ onAnimationComplete: {},
30
+ onUpdate: {},
31
+ layout: { type: [Boolean, String] },
32
+ layoutId: {},
33
+ layoutScroll: { type: Boolean },
34
+ layoutRoot: { type: Boolean },
35
+ "data-framer-portal-id": {},
36
+ crossfade: { type: Boolean },
37
+ onBeforeLayoutMeasure: {},
38
+ onLayoutMeasure: {},
39
+ onLayoutAnimationStart: {},
40
+ onLayoutAnimationComplete: {},
41
+ globalPressTarget: { type: Boolean },
42
+ press: {},
43
+ onPressStart: {},
44
+ onPress: {},
45
+ onPressCancel: {},
46
+ hover: {},
47
+ onHoverStart: {},
48
+ onHoverEnd: {},
49
+ inViewOptions: {},
50
+ inView: {},
51
+ onViewportEnter: {},
52
+ onViewportLeave: {},
53
+ drag: { type: [Boolean, String] },
54
+ dragSnapToOrigin: { type: Boolean },
55
+ dragDirectionLock: { type: Boolean },
56
+ dragPropagation: { type: Boolean },
57
+ dragConstraints: { type: [Boolean, Object] },
58
+ dragElastic: { type: [Boolean, Number, Object] },
59
+ dragMomentum: { type: Boolean },
60
+ dragTransition: {},
61
+ dragListener: { type: Boolean },
62
+ dragControls: {},
63
+ onDragStart: {},
64
+ onDragEnd: {},
65
+ onDrag: {},
66
+ onDirectionLock: {},
67
+ onDragTransitionEnd: {},
68
+ onMeasureDragConstraints: {},
69
+ onPanSessionStart: {},
70
+ onPanStart: {},
71
+ onPan: {},
72
+ onPanEnd: {},
73
+ focus: {},
74
+ onFocus: {},
75
+ onBlur: {}
76
+ },
77
+ setup(__props) {
78
+ const props = __props;
79
+ const { axis } = toRefs(props);
80
+ const order = [];
81
+ let isReordering = false;
82
+ function warning() {
83
+ invariant(Boolean(props.values), "Reorder.Group must be provided a values prop");
84
+ }
85
+ onUpdated(() => {
86
+ isReordering = false;
87
+ });
88
+ reorderContextProvider({
89
+ axis,
90
+ registerItem: (value, layout) => {
91
+ const idx = order.findIndex((entry) => value === entry.value);
92
+ if (idx !== -1) {
93
+ order[idx].layout = layout[axis.value];
94
+ } else {
95
+ order.push({ value, layout: layout[axis.value] });
96
+ }
97
+ order.sort(compareMin);
98
+ },
99
+ updateOrder: (item, offset, velocity) => {
100
+ if (isReordering)
101
+ return;
102
+ const newOrder = checkReorder(order, item, offset, velocity);
103
+ if (order !== newOrder) {
104
+ isReordering = true;
105
+ props["onUpdate:values"](
106
+ newOrder.map(getValue).filter((value) => props.values.includes(value))
107
+ );
108
+ }
109
+ }
110
+ });
111
+ const attrs = useAttrs();
112
+ function bindProps() {
113
+ return {
114
+ ...attrs,
115
+ ...props
116
+ };
117
+ }
118
+ return (_ctx, _cache) => {
119
+ return openBlock(), createBlock(unref(_sfc_main$1), normalizeProps(guardReactiveProps(bindProps())), {
120
+ default: withCtx(() => [
121
+ renderSlot(_ctx.$slots, "default"),
122
+ createTextVNode(" " + toDisplayString(warning()), 1)
123
+ ]),
124
+ _: 3
125
+ }, 16);
126
+ };
127
+ }
128
+ });
129
+ export {
130
+ _sfc_main as default
131
+ };
@@ -0,0 +1,4 @@
1
+ import _sfc_main from "./Group.vue.mjs";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,88 @@
1
+ import { MotionProps } from '../motion';
2
+ import { ElementType } from '../../types';
3
+ export interface GroupItemProps<T extends ElementType, K = unknown, V = unknown> extends MotionProps<T, K> {
4
+ /**
5
+ * The value in the list that this component represents.
6
+ *
7
+ * @public
8
+ */
9
+ value: V;
10
+ /**
11
+ * A subset of layout options primarily used to disable layout="size"
12
+ *
13
+ * @public
14
+ * @default true
15
+ */
16
+ layout?: true | 'position';
17
+ }
18
+ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<GroupItemProps<keyof import('vue').IntrinsicElementAttributes, unknown, unknown>>, {
19
+ layout: boolean;
20
+ as: ElementType;
21
+ initial: any;
22
+ animate: any;
23
+ hover: any;
24
+ inView: any;
25
+ layoutId: any;
26
+ layoutScroll: boolean;
27
+ layoutRoot: boolean;
28
+ dragListener: boolean;
29
+ dragElastic: number;
30
+ dragMomentum: boolean;
31
+ whileDrag: any;
32
+ crossfade: boolean;
33
+ }>, {}, unknown, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<GroupItemProps<keyof import('vue').IntrinsicElementAttributes, unknown, unknown>>, {
34
+ layout: boolean;
35
+ as: ElementType;
36
+ initial: any;
37
+ animate: any;
38
+ hover: any;
39
+ inView: any;
40
+ layoutId: any;
41
+ layoutScroll: boolean;
42
+ layoutRoot: boolean;
43
+ dragListener: boolean;
44
+ dragElastic: number;
45
+ dragMomentum: boolean;
46
+ whileDrag: any;
47
+ crossfade: boolean;
48
+ }>>>, {
49
+ layout: true | "position";
50
+ layoutId: string;
51
+ layoutScroll: boolean;
52
+ layoutRoot: boolean;
53
+ crossfade: boolean;
54
+ initial: string | import('../../types').Variant | boolean;
55
+ animate: string | import('../../types').Variant | import('../../animation/types').AnimationControls;
56
+ inView: string | import('../../types').Variant;
57
+ hover: string | import('../../types').Variant;
58
+ whileDrag: import('../../types').Options["whileDrag"];
59
+ dragElastic: number;
60
+ dragMomentum: boolean;
61
+ dragListener: boolean;
62
+ as: keyof import('vue').IntrinsicElementAttributes;
63
+ }, {}>, {
64
+ default?(_: {}): any;
65
+ }>;
66
+ export default _default;
67
+ type __VLS_WithDefaults<P, D> = {
68
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
69
+ default: D[K];
70
+ }> : P[K];
71
+ };
72
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
73
+ type __VLS_TypePropsToOption<T> = {
74
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
75
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
76
+ } : {
77
+ type: import('vue').PropType<T[K]>;
78
+ required: true;
79
+ };
80
+ };
81
+ type __VLS_WithTemplateSlots<T, S> = T & {
82
+ new (): {
83
+ $slots: S;
84
+ };
85
+ };
86
+ type __VLS_PrettifyLocal<T> = {
87
+ [K in keyof T]: T[K];
88
+ } & {};
@@ -0,0 +1,131 @@
1
+ import { defineComponent, toRefs, useAttrs, computed, openBlock, createBlock, unref, mergeProps, withCtx, renderSlot, createTextVNode, toDisplayString } from "vue";
2
+ import { useReorderContext } from "./context.mjs";
3
+ import { useDefaultMotionValue } from "./utils.mjs";
4
+ import { invariant } from "hey-listen";
5
+ import { useTransform } from "../../value/use-transform.mjs";
6
+ import _sfc_main$1 from "../motion/Motion.vue.mjs";
7
+ const _sfc_main = /* @__PURE__ */ defineComponent({
8
+ ...{
9
+ name: "ReorderItem",
10
+ inheritAttrs: false
11
+ },
12
+ __name: "Item",
13
+ props: {
14
+ value: {},
15
+ layout: { type: [Boolean, String], default: true },
16
+ as: { default: "li" },
17
+ asChild: { type: Boolean },
18
+ whileDrag: { default: void 0 },
19
+ custom: {},
20
+ initial: { type: [String, Object, Boolean], default: void 0 },
21
+ animate: { default: void 0 },
22
+ exit: {},
23
+ variants: {},
24
+ style: {},
25
+ transformTemplate: {},
26
+ transition: {},
27
+ layoutGroup: {},
28
+ motionConfig: {},
29
+ onAnimationComplete: {},
30
+ onUpdate: {},
31
+ layoutId: { default: void 0 },
32
+ layoutScroll: { type: Boolean, default: false },
33
+ layoutRoot: { type: Boolean, default: false },
34
+ "data-framer-portal-id": {},
35
+ crossfade: { type: Boolean, default: true },
36
+ onBeforeLayoutMeasure: {},
37
+ onLayoutMeasure: {},
38
+ onLayoutAnimationStart: {},
39
+ onLayoutAnimationComplete: {},
40
+ globalPressTarget: { type: Boolean },
41
+ press: {},
42
+ onPressStart: {},
43
+ onPress: {},
44
+ onPressCancel: {},
45
+ hover: { default: void 0 },
46
+ onHoverStart: {},
47
+ onHoverEnd: {},
48
+ inViewOptions: {},
49
+ inView: { default: void 0 },
50
+ onViewportEnter: {},
51
+ onViewportLeave: {},
52
+ drag: { type: [Boolean, String] },
53
+ dragSnapToOrigin: { type: Boolean },
54
+ dragDirectionLock: { type: Boolean },
55
+ dragPropagation: { type: Boolean },
56
+ dragConstraints: { type: [Boolean, Object] },
57
+ dragElastic: { type: [Boolean, Number, Object], default: 0.5 },
58
+ dragMomentum: { type: Boolean, default: true },
59
+ dragTransition: {},
60
+ dragListener: { type: Boolean, default: true },
61
+ dragControls: {},
62
+ onDragStart: {},
63
+ onDragEnd: {},
64
+ onDrag: {},
65
+ onDirectionLock: {},
66
+ onDragTransitionEnd: {},
67
+ onMeasureDragConstraints: {},
68
+ onPanSessionStart: {},
69
+ onPanStart: {},
70
+ onPan: {},
71
+ onPanEnd: {},
72
+ focus: {},
73
+ onFocus: {},
74
+ onBlur: {}
75
+ },
76
+ setup(__props) {
77
+ var _a, _b;
78
+ const props = __props;
79
+ const { style } = toRefs(props);
80
+ const context = useReorderContext(null);
81
+ const point = {
82
+ x: useDefaultMotionValue((_a = style.value) == null ? void 0 : _a.x),
83
+ y: useDefaultMotionValue((_b = style.value) == null ? void 0 : _b.y)
84
+ };
85
+ const zIndex = useTransform([point.x, point.y], ([latestX, latestY]) => latestX || latestY ? 1 : "unset");
86
+ function warning() {
87
+ invariant(Boolean(context), "Reorder.Item must be a child of Reorder.Group");
88
+ }
89
+ const { axis, registerItem, updateOrder } = context || {};
90
+ const attrs = useAttrs();
91
+ function bindProps() {
92
+ return {
93
+ ...attrs,
94
+ ...props,
95
+ style: {
96
+ ...style.value,
97
+ x: point.x,
98
+ y: point.y,
99
+ zIndex
100
+ }
101
+ };
102
+ }
103
+ const drag = computed(() => {
104
+ if (props.drag) {
105
+ return props.drag;
106
+ }
107
+ return axis.value;
108
+ });
109
+ return (_ctx, _cache) => {
110
+ return openBlock(), createBlock(unref(_sfc_main$1), mergeProps(bindProps(), {
111
+ drag: drag.value,
112
+ "drag-snap-to-origin": true,
113
+ onDrag: _cache[0] || (_cache[0] = (event, gesturePoint) => {
114
+ const { velocity } = gesturePoint;
115
+ velocity[unref(axis)] && unref(updateOrder)(_ctx.value, point[unref(axis)].get(), velocity[unref(axis)]);
116
+ _ctx.onDrag && _ctx.onDrag(event, gesturePoint);
117
+ }),
118
+ onLayoutMeasure: _cache[1] || (_cache[1] = (measured) => unref(registerItem)(_ctx.value, measured))
119
+ }), {
120
+ default: withCtx(() => [
121
+ renderSlot(_ctx.$slots, "default"),
122
+ createTextVNode(" " + toDisplayString(warning()), 1)
123
+ ]),
124
+ _: 3
125
+ }, 16, ["drag"]);
126
+ };
127
+ }
128
+ });
129
+ export {
130
+ _sfc_main as default
131
+ };
@@ -0,0 +1,4 @@
1
+ import _sfc_main from "./Item.vue.mjs";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,8 @@
1
+ import { Box } from 'framer-motion';
2
+ import { Ref } from 'vue';
3
+ export interface ReorderContextProps<T> {
4
+ axis?: Ref<'x' | 'y'>;
5
+ registerItem?: (item: T, layout: Box) => void;
6
+ updateOrder?: (item: T, offset: number, velocity: number) => void;
7
+ }
8
+ export declare const useReorderContext: <T extends ReorderContextProps<any> = ReorderContextProps<any>>(fallback?: T) => T extends null ? ReorderContextProps<any> : ReorderContextProps<any>, reorderContextProvider: (contextValue: ReorderContextProps<any>) => ReorderContextProps<any>;
@@ -0,0 +1,6 @@
1
+ import { createContext } from "../../utils/createContext.mjs";
2
+ const [useReorderContext, reorderContextProvider] = createContext("ReorderContext");
3
+ export {
4
+ reorderContextProvider,
5
+ useReorderContext
6
+ };
@@ -0,0 +1,13 @@
1
+ import { DefineSetupFnComponent, IntrinsicElementAttributes } from 'vue';
2
+ import { GroupProps } from './Group';
3
+ import { GroupItemProps } from './Item';
4
+ import { ElementType, SVGAttributesWithMotionValues, SetMotionValueType } from '../../types';
5
+ type IntrinsicElementAttributesAsMotionValues = SetMotionValueType<IntrinsicElementAttributes, keyof SVGAttributesWithMotionValues>;
6
+ type ItemProps<T extends ElementType = 'li'> = GroupItemProps<T, unknown, unknown> & IntrinsicElementAttributesAsMotionValues[T];
7
+ export declare const ReorderGroup: DefineSetupFnComponent<GroupProps<ElementType, any, any>>;
8
+ export declare const ReorderItem: DefineSetupFnComponent<ItemProps<ElementType>>;
9
+ export declare const Reorder: {
10
+ Group: DefineSetupFnComponent<GroupProps<keyof IntrinsicElementAttributes, any, any>>;
11
+ Item: DefineSetupFnComponent<ItemProps<keyof IntrinsicElementAttributes>>;
12
+ };
13
+ export {};
@@ -0,0 +1,13 @@
1
+ import _sfc_main from "./Group.vue.mjs";
2
+ import _sfc_main$1 from "./Item.vue.mjs";
3
+ const ReorderGroup = _sfc_main;
4
+ const ReorderItem = _sfc_main$1;
5
+ const Reorder = {
6
+ Group: ReorderGroup,
7
+ Item: ReorderItem
8
+ };
9
+ export {
10
+ Reorder,
11
+ ReorderGroup,
12
+ ReorderItem
13
+ };
@@ -0,0 +1,5 @@
1
+ import { Axis } from 'framer-motion';
2
+ export interface ItemData<T> {
3
+ value: T;
4
+ layout: Axis;
5
+ }
@@ -0,0 +1,6 @@
1
+ import { ItemData } from './types';
2
+ export declare function compareMin<V>(a: ItemData<V>, b: ItemData<V>): number;
3
+ export declare function getValue<V>(item: ItemData<V>): V;
4
+ export declare function checkReorder<T>(order: ItemData<T>[], value: T, offset: number, velocity: number): ItemData<T>[];
5
+ export declare function moveItem<T>([...arr]: T[], fromIndex: number, toIndex: number): T[];
6
+ export declare function useDefaultMotionValue(value: any, defaultValue?: number): import('framer-motion/dom').MotionValue<any>;
@@ -0,0 +1,46 @@
1
+ import { mixNumber } from "../../utils/mix/number.mjs";
2
+ import { motionValue } from "../../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/value/index.mjs";
3
+ import { isMotionValue } from "../../utils/motion-value.mjs";
4
+ function compareMin(a, b) {
5
+ return a.layout.min - b.layout.min;
6
+ }
7
+ function getValue(item) {
8
+ return item.value;
9
+ }
10
+ function checkReorder(order, value, offset, velocity) {
11
+ if (!velocity)
12
+ return order;
13
+ const index = order.findIndex((item2) => item2.value === value);
14
+ if (index === -1)
15
+ return order;
16
+ const nextOffset = velocity > 0 ? 1 : -1;
17
+ const nextItem = order[index + nextOffset];
18
+ if (!nextItem)
19
+ return order;
20
+ const item = order[index];
21
+ const nextLayout = nextItem.layout;
22
+ const nextItemCenter = mixNumber(nextLayout.min, nextLayout.max, 0.5);
23
+ if (nextOffset === 1 && item.layout.max + offset > nextItemCenter || nextOffset === -1 && item.layout.min + offset < nextItemCenter) {
24
+ return moveItem(order, index, index + nextOffset);
25
+ }
26
+ return order;
27
+ }
28
+ function moveItem([...arr], fromIndex, toIndex) {
29
+ const startIndex = fromIndex < 0 ? arr.length + fromIndex : fromIndex;
30
+ if (startIndex >= 0 && startIndex < arr.length) {
31
+ const endIndex = toIndex < 0 ? arr.length + toIndex : toIndex;
32
+ const [item] = arr.splice(fromIndex, 1);
33
+ arr.splice(endIndex, 0, item);
34
+ }
35
+ return arr;
36
+ }
37
+ function useDefaultMotionValue(value, defaultValue = 0) {
38
+ return isMotionValue(value) ? value : motionValue(defaultValue);
39
+ }
40
+ export {
41
+ checkReorder,
42
+ compareMin,
43
+ getValue,
44
+ moveItem,
45
+ useDefaultMotionValue
46
+ };
@@ -3,7 +3,9 @@ const components = {
3
3
  "Motion",
4
4
  "AnimatePresence",
5
5
  "LayoutGroup",
6
- "MotionConfig"
6
+ "MotionConfig",
7
+ "ReorderGroup",
8
+ "ReorderItem"
7
9
  ]
8
10
  };
9
11
  const utilities = {
@@ -4,6 +4,7 @@ export declare class LayoutFeature extends Feature {
4
4
  constructor(state: MotionState);
5
5
  beforeUpdate(): void;
6
6
  update(): void;
7
+ didUpdate(): void;
7
8
  beforeMount(): void;
8
9
  mount(): void;
9
10
  beforeUnmount(): void;
@@ -11,8 +11,12 @@ class LayoutFeature extends Feature {
11
11
  this.state.willUpdate("beforeUpdate");
12
12
  }
13
13
  update() {
14
- var _a;
15
- (_a = this.state.visualElement.projection) == null ? void 0 : _a.root.didUpdate();
14
+ this.didUpdate();
15
+ }
16
+ didUpdate() {
17
+ var _a, _b;
18
+ if (this.state.options.layout || this.state.options.layoutId)
19
+ (_b = (_a = this.state.visualElement.projection) == null ? void 0 : _a.root) == null ? void 0 : _b.didUpdate();
16
20
  }
17
21
  beforeMount() {
18
22
  }
@@ -26,7 +30,7 @@ class LayoutFeature extends Feature {
26
30
  (_a = layoutGroup == null ? void 0 : layoutGroup.group) == null ? void 0 : _a.add(projection);
27
31
  }
28
32
  globalProjectionState.hasEverUpdated = true;
29
- projection == null ? void 0 : projection.root.didUpdate();
33
+ this.didUpdate();
30
34
  }
31
35
  }
32
36
  beforeUnmount() {
@@ -42,14 +46,11 @@ class LayoutFeature extends Feature {
42
46
  }
43
47
  }
44
48
  unmount() {
45
- var _a, _b;
46
49
  const layoutGroup = this.state.options.layoutGroup;
47
50
  const projection = this.state.visualElement.projection;
48
51
  if ((layoutGroup == null ? void 0 : layoutGroup.group) && projection)
49
52
  layoutGroup.group.remove(projection);
50
- if (this.state.options.layoutId || this.state.options.layout) {
51
- (_b = (_a = this.state.visualElement.projection) == null ? void 0 : _a.root) == null ? void 0 : _b.didUpdate();
52
- }
53
+ this.didUpdate();
53
54
  }
54
55
  }
55
56
  export {
@@ -4,6 +4,7 @@ import { getClosestProjectingNode } from "./utils.mjs";
4
4
  import { addScaleCorrector } from "../../external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/projection/styles/scale-correction.mjs";
5
5
  import { defaultScaleCorrector } from "./config.mjs";
6
6
  import { isHTMLElement } from "../gestures/drag/utils/is.mjs";
7
+ import { doneCallbacks } from "../../components/presence.mjs";
7
8
  class ProjectionFeature extends Feature {
8
9
  constructor(state) {
9
10
  super(state);
@@ -32,7 +33,21 @@ class ProjectionFeature extends Feature {
32
33
  // initialPromotionConfig
33
34
  layoutRoot: options.layoutRoot,
34
35
  layoutScroll: options.layoutScroll,
35
- crossfade: options.crossfade
36
+ crossfade: options.crossfade,
37
+ onExitComplete: () => {
38
+ var _a;
39
+ if (!((_a = this.state.visualElement.projection) == null ? void 0 : _a.isPresent)) {
40
+ const done = doneCallbacks.get(this.state.element);
41
+ this.state.isSafeToRemove = true;
42
+ if (done) {
43
+ done({
44
+ detail: {
45
+ isExit: true
46
+ }
47
+ }, true);
48
+ }
49
+ }
50
+ }
36
51
  });
37
52
  }
38
53
  update() {
@@ -1,4 +1,17 @@
1
- export interface LayoutOptions {
1
+ import { Box } from 'framer-motion';
2
+ export interface LayoutLifecycles {
3
+ onBeforeLayoutMeasure?: (box: Box) => void;
4
+ onLayoutMeasure?: (box: Box, prevBox: Box) => void;
5
+ /**
6
+ * @internal
7
+ */
8
+ onLayoutAnimationStart?: () => void;
9
+ /**
10
+ * @internal
11
+ */
12
+ onLayoutAnimationComplete?: () => void;
13
+ }
14
+ export interface LayoutOptions extends LayoutLifecycles {
2
15
  'layout'?: boolean | 'position' | 'size' | 'preserve-aspect';
3
16
  'layoutId'?: string;
4
17
  'layoutScroll'?: boolean;
package/dist/es/index.mjs CHANGED
@@ -41,6 +41,7 @@ import { cancelSync, sync } from "./external/.pnpm/framer-motion@11.16.6/externa
41
41
  import { cancelFrame, frame, frameData, frameSteps } from "./external/.pnpm/framer-motion@11.16.6/external/framer-motion/dist/es/frameloop/frame.mjs";
42
42
  import { motion } from "./components/motion/NameSpace.mjs";
43
43
  import { provideMotionConfig, useMotionConfig } from "./components/motion-config/context.mjs";
44
+ import { Reorder, ReorderGroup, ReorderItem } from "./components/reorder/index.mjs";
44
45
  import { useComputed } from "./value/use-computed.mjs";
45
46
  import { useCombineMotionValues } from "./value/use-combine-values.mjs";
46
47
  import { useTransform } from "./value/use-transform.mjs";
@@ -64,6 +65,9 @@ export {
64
65
  default3 as Motion,
65
66
  default5 as MotionConfig,
66
67
  MotionValue,
68
+ Reorder,
69
+ ReorderGroup,
70
+ ReorderItem,
67
71
  animate,
68
72
  animateMini,
69
73
  anticipate,