Mission Control Dashboard - Initial implementation
This commit is contained in:
107
node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
generated
vendored
Normal file
107
node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { isHTMLElement } from 'motion-dom';
|
||||
import * as React from 'react';
|
||||
import { useId, useRef, useContext, useInsertionEffect } from 'react';
|
||||
import { MotionConfigContext } from '../../context/MotionConfigContext.mjs';
|
||||
import { useComposedRefs } from '../../utils/use-composed-ref.mjs';
|
||||
|
||||
/**
|
||||
* Measurement functionality has to be within a separate component
|
||||
* to leverage snapshot lifecycle.
|
||||
*/
|
||||
class PopChildMeasure extends React.Component {
|
||||
getSnapshotBeforeUpdate(prevProps) {
|
||||
const element = this.props.childRef.current;
|
||||
if (isHTMLElement(element) && prevProps.isPresent && !this.props.isPresent && this.props.pop !== false) {
|
||||
const parent = element.offsetParent;
|
||||
const parentWidth = isHTMLElement(parent)
|
||||
? parent.offsetWidth || 0
|
||||
: 0;
|
||||
const parentHeight = isHTMLElement(parent)
|
||||
? parent.offsetHeight || 0
|
||||
: 0;
|
||||
const computedStyle = getComputedStyle(element);
|
||||
const size = this.props.sizeRef.current;
|
||||
size.height = parseFloat(computedStyle.height);
|
||||
size.width = parseFloat(computedStyle.width);
|
||||
size.top = element.offsetTop;
|
||||
size.left = element.offsetLeft;
|
||||
size.right = parentWidth - size.width - size.left;
|
||||
size.bottom = parentHeight - size.height - size.top;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Required with getSnapshotBeforeUpdate to stop React complaining.
|
||||
*/
|
||||
componentDidUpdate() { }
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
function PopChild({ children, isPresent, anchorX, anchorY, root, pop }) {
|
||||
const id = useId();
|
||||
const ref = useRef(null);
|
||||
const size = useRef({
|
||||
width: 0,
|
||||
height: 0,
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
});
|
||||
const { nonce } = useContext(MotionConfigContext);
|
||||
/**
|
||||
* In React 19, refs are passed via props.ref instead of element.ref.
|
||||
* We check props.ref first (React 19) and fall back to element.ref (React 18).
|
||||
*/
|
||||
const childRef = children.props?.ref ??
|
||||
children?.ref;
|
||||
const composedRef = useComposedRefs(ref, childRef);
|
||||
/**
|
||||
* We create and inject a style block so we can apply this explicit
|
||||
* sizing in a non-destructive manner by just deleting the style block.
|
||||
*
|
||||
* We can't apply size via render as the measurement happens
|
||||
* in getSnapshotBeforeUpdate (post-render), likewise if we apply the
|
||||
* styles directly on the DOM node, we might be overwriting
|
||||
* styles set via the style prop.
|
||||
*/
|
||||
useInsertionEffect(() => {
|
||||
const { width, height, top, left, right, bottom } = size.current;
|
||||
if (isPresent || pop === false || !ref.current || !width || !height)
|
||||
return;
|
||||
const x = anchorX === "left" ? `left: ${left}` : `right: ${right}`;
|
||||
const y = anchorY === "bottom" ? `bottom: ${bottom}` : `top: ${top}`;
|
||||
ref.current.dataset.motionPopId = id;
|
||||
const style = document.createElement("style");
|
||||
if (nonce)
|
||||
style.nonce = nonce;
|
||||
const parent = root ?? document.head;
|
||||
parent.appendChild(style);
|
||||
if (style.sheet) {
|
||||
style.sheet.insertRule(`
|
||||
[data-motion-pop-id="${id}"] {
|
||||
position: absolute !important;
|
||||
width: ${width}px !important;
|
||||
height: ${height}px !important;
|
||||
${x}px !important;
|
||||
${y}px !important;
|
||||
}
|
||||
`);
|
||||
}
|
||||
return () => {
|
||||
ref.current?.removeAttribute("data-motion-pop-id");
|
||||
if (parent.contains(style)) {
|
||||
parent.removeChild(style);
|
||||
}
|
||||
};
|
||||
}, [isPresent]);
|
||||
return (jsx(PopChildMeasure, { isPresent: isPresent, childRef: ref, sizeRef: size, pop: pop, children: pop === false
|
||||
? children
|
||||
: React.cloneElement(children, { ref: composedRef }) }));
|
||||
}
|
||||
|
||||
export { PopChild };
|
||||
//# sourceMappingURL=PopChild.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
63
node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
generated
vendored
Normal file
63
node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import * as React from 'react';
|
||||
import { useId, useMemo } from 'react';
|
||||
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { PopChild } from './PopChild.mjs';
|
||||
|
||||
const PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, presenceAffectsLayout, mode, anchorX, anchorY, root }) => {
|
||||
const presenceChildren = useConstant(newChildrenMap);
|
||||
const id = useId();
|
||||
let isReusedContext = true;
|
||||
let context = useMemo(() => {
|
||||
isReusedContext = false;
|
||||
return {
|
||||
id,
|
||||
initial,
|
||||
isPresent,
|
||||
custom,
|
||||
onExitComplete: (childId) => {
|
||||
presenceChildren.set(childId, true);
|
||||
for (const isComplete of presenceChildren.values()) {
|
||||
if (!isComplete)
|
||||
return; // can stop searching when any is incomplete
|
||||
}
|
||||
onExitComplete && onExitComplete();
|
||||
},
|
||||
register: (childId) => {
|
||||
presenceChildren.set(childId, false);
|
||||
return () => presenceChildren.delete(childId);
|
||||
},
|
||||
};
|
||||
}, [isPresent, presenceChildren, onExitComplete]);
|
||||
/**
|
||||
* If the presence of a child affects the layout of the components around it,
|
||||
* we want to make a new context value to ensure they get re-rendered
|
||||
* so they can detect that layout change.
|
||||
*/
|
||||
if (presenceAffectsLayout && isReusedContext) {
|
||||
context = { ...context };
|
||||
}
|
||||
useMemo(() => {
|
||||
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
||||
}, [isPresent]);
|
||||
/**
|
||||
* If there's no `motion` components to fire exit animations, we want to remove this
|
||||
* component immediately.
|
||||
*/
|
||||
React.useEffect(() => {
|
||||
!isPresent &&
|
||||
!presenceChildren.size &&
|
||||
onExitComplete &&
|
||||
onExitComplete();
|
||||
}, [isPresent]);
|
||||
children = (jsx(PopChild, { pop: mode === "popLayout", isPresent: isPresent, anchorX: anchorX, anchorY: anchorY, root: root, children: children }));
|
||||
return (jsx(PresenceContext.Provider, { value: context, children: children }));
|
||||
};
|
||||
function newChildrenMap() {
|
||||
return new Map();
|
||||
}
|
||||
|
||||
export { PresenceChild };
|
||||
//# sourceMappingURL=PresenceChild.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"PresenceChild.mjs","sources":["../../../../src/components/AnimatePresence/PresenceChild.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { useId, useMemo } from \"react\"\nimport {\n PresenceContext,\n type PresenceContextProps,\n} from \"../../context/PresenceContext\"\nimport { VariantLabels } from \"../../motion/types\"\nimport { useConstant } from \"../../utils/use-constant\"\nimport { PopChild } from \"./PopChild\"\n\ninterface PresenceChildProps {\n children: React.ReactElement\n isPresent: boolean\n onExitComplete?: () => void\n initial?: false | VariantLabels\n custom?: any\n presenceAffectsLayout: boolean\n mode: \"sync\" | \"popLayout\" | \"wait\"\n anchorX?: \"left\" | \"right\"\n anchorY?: \"top\" | \"bottom\"\n root?: HTMLElement | ShadowRoot\n}\n\nexport const PresenceChild = ({\n children,\n initial,\n isPresent,\n onExitComplete,\n custom,\n presenceAffectsLayout,\n mode,\n anchorX,\n anchorY,\n root\n}: PresenceChildProps) => {\n const presenceChildren = useConstant(newChildrenMap)\n const id = useId()\n\n let isReusedContext = true\n let context = useMemo((): PresenceContextProps => {\n isReusedContext = false\n return {\n id,\n initial,\n isPresent,\n custom,\n onExitComplete: (childId: string) => {\n presenceChildren.set(childId, true)\n\n for (const isComplete of presenceChildren.values()) {\n if (!isComplete) return // can stop searching when any is incomplete\n }\n\n onExitComplete && onExitComplete()\n },\n register: (childId: string) => {\n presenceChildren.set(childId, false)\n return () => presenceChildren.delete(childId)\n },\n }\n }, [isPresent, presenceChildren, onExitComplete])\n\n /**\n * If the presence of a child affects the layout of the components around it,\n * we want to make a new context value to ensure they get re-rendered\n * so they can detect that layout change.\n */\n if (presenceAffectsLayout && isReusedContext) {\n context = { ...context }\n }\n\n useMemo(() => {\n presenceChildren.forEach((_, key) => presenceChildren.set(key, false))\n }, [isPresent])\n\n /**\n * If there's no `motion` components to fire exit animations, we want to remove this\n * component immediately.\n */\n React.useEffect(() => {\n !isPresent &&\n !presenceChildren.size &&\n onExitComplete &&\n onExitComplete()\n }, [isPresent])\n\n children = (\n <PopChild pop={mode === \"popLayout\"} isPresent={isPresent} anchorX={anchorX} anchorY={anchorY} root={root}>\n {children}\n </PopChild>\n )\n\n return (\n <PresenceContext.Provider value={context}>\n {children}\n </PresenceContext.Provider>\n )\n}\n\nfunction newChildrenMap(): Map<string, boolean> {\n return new Map()\n}\n"],"names":[],"mappings":";;;;;;;;AAyBO;AAYH;AACA;;AAGA;;;;;;;AAOQ;AACI;;AAGI;AAAiB;;;;AAKzB;AACI;;;;;AAMZ;;;;AAIG;AACH;AACI;;;AAIA;AACJ;AAEA;;;AAGG;AACH;AACI;;;AAGI;AACR;AAEA;AAMA;AAKJ;AAEA;;AAEA;;"}
|
||||
176
node_modules/framer-motion/dist/es/components/AnimatePresence/index.mjs
generated
vendored
Normal file
176
node_modules/framer-motion/dist/es/components/AnimatePresence/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
"use client";
|
||||
import { jsx, Fragment } from 'react/jsx-runtime';
|
||||
import { useMemo, useRef, useState, useContext } from 'react';
|
||||
import { LayoutGroupContext } from '../../context/LayoutGroupContext.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
|
||||
import { PresenceChild } from './PresenceChild.mjs';
|
||||
import { usePresence } from './use-presence.mjs';
|
||||
import { onlyElements, getChildKey } from './utils.mjs';
|
||||
|
||||
/**
|
||||
* `AnimatePresence` enables the animation of components that have been removed from the tree.
|
||||
*
|
||||
* When adding/removing more than a single child, every child **must** be given a unique `key` prop.
|
||||
*
|
||||
* Any `motion` components that have an `exit` property defined will animate out when removed from
|
||||
* the tree.
|
||||
*
|
||||
* ```jsx
|
||||
* import { motion, AnimatePresence } from 'framer-motion'
|
||||
*
|
||||
* export const Items = ({ items }) => (
|
||||
* <AnimatePresence>
|
||||
* {items.map(item => (
|
||||
* <motion.div
|
||||
* key={item.id}
|
||||
* initial={{ opacity: 0 }}
|
||||
* animate={{ opacity: 1 }}
|
||||
* exit={{ opacity: 0 }}
|
||||
* />
|
||||
* ))}
|
||||
* </AnimatePresence>
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* You can sequence exit animations throughout a tree using variants.
|
||||
*
|
||||
* If a child contains multiple `motion` components with `exit` props, it will only unmount the child
|
||||
* once all `motion` components have finished animating out. Likewise, any components using
|
||||
* `usePresence` all need to call `safeToRemove`.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
const AnimatePresence = ({ children, custom, initial = true, onExitComplete, presenceAffectsLayout = true, mode = "sync", propagate = false, anchorX = "left", anchorY = "top", root }) => {
|
||||
const [isParentPresent, safeToRemove] = usePresence(propagate);
|
||||
/**
|
||||
* Filter any children that aren't ReactElements. We can only track components
|
||||
* between renders with a props.key.
|
||||
*/
|
||||
const presentChildren = useMemo(() => onlyElements(children), [children]);
|
||||
/**
|
||||
* Track the keys of the currently rendered children. This is used to
|
||||
* determine which children are exiting.
|
||||
*/
|
||||
const presentKeys = propagate && !isParentPresent ? [] : presentChildren.map(getChildKey);
|
||||
/**
|
||||
* If `initial={false}` we only want to pass this to components in the first render.
|
||||
*/
|
||||
const isInitialRender = useRef(true);
|
||||
/**
|
||||
* A ref containing the currently present children. When all exit animations
|
||||
* are complete, we use this to re-render the component with the latest children
|
||||
* *committed* rather than the latest children *rendered*.
|
||||
*/
|
||||
const pendingPresentChildren = useRef(presentChildren);
|
||||
/**
|
||||
* Track which exiting children have finished animating out.
|
||||
*/
|
||||
const exitComplete = useConstant(() => new Map());
|
||||
/**
|
||||
* Track which components are currently processing exit to prevent duplicate processing.
|
||||
*/
|
||||
const exitingComponents = useRef(new Set());
|
||||
/**
|
||||
* Save children to render as React state. To ensure this component is concurrent-safe,
|
||||
* we check for exiting children via an effect.
|
||||
*/
|
||||
const [diffedChildren, setDiffedChildren] = useState(presentChildren);
|
||||
const [renderedChildren, setRenderedChildren] = useState(presentChildren);
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
isInitialRender.current = false;
|
||||
pendingPresentChildren.current = presentChildren;
|
||||
/**
|
||||
* Update complete status of exiting children.
|
||||
*/
|
||||
for (let i = 0; i < renderedChildren.length; i++) {
|
||||
const key = getChildKey(renderedChildren[i]);
|
||||
if (!presentKeys.includes(key)) {
|
||||
if (exitComplete.get(key) !== true) {
|
||||
exitComplete.set(key, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
exitComplete.delete(key);
|
||||
exitingComponents.current.delete(key);
|
||||
}
|
||||
}
|
||||
}, [renderedChildren, presentKeys.length, presentKeys.join("-")]);
|
||||
const exitingChildren = [];
|
||||
if (presentChildren !== diffedChildren) {
|
||||
let nextChildren = [...presentChildren];
|
||||
/**
|
||||
* Loop through all the currently rendered components and decide which
|
||||
* are exiting.
|
||||
*/
|
||||
for (let i = 0; i < renderedChildren.length; i++) {
|
||||
const child = renderedChildren[i];
|
||||
const key = getChildKey(child);
|
||||
if (!presentKeys.includes(key)) {
|
||||
nextChildren.splice(i, 0, child);
|
||||
exitingChildren.push(child);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* If we're in "wait" mode, and we have exiting children, we want to
|
||||
* only render these until they've all exited.
|
||||
*/
|
||||
if (mode === "wait" && exitingChildren.length) {
|
||||
nextChildren = exitingChildren;
|
||||
}
|
||||
setRenderedChildren(onlyElements(nextChildren));
|
||||
setDiffedChildren(presentChildren);
|
||||
/**
|
||||
* Early return to ensure once we've set state with the latest diffed
|
||||
* children, we can immediately re-render.
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
if (process.env.NODE_ENV !== "production" &&
|
||||
mode === "wait" &&
|
||||
renderedChildren.length > 1) {
|
||||
console.warn(`You're attempting to animate multiple children within AnimatePresence, but its mode is set to "wait". This will lead to odd visual behaviour.`);
|
||||
}
|
||||
/**
|
||||
* If we've been provided a forceRender function by the LayoutGroupContext,
|
||||
* we can use it to force a re-render amongst all surrounding components once
|
||||
* all components have finished animating out.
|
||||
*/
|
||||
const { forceRender } = useContext(LayoutGroupContext);
|
||||
return (jsx(Fragment, { children: renderedChildren.map((child) => {
|
||||
const key = getChildKey(child);
|
||||
const isPresent = propagate && !isParentPresent
|
||||
? false
|
||||
: presentChildren === renderedChildren ||
|
||||
presentKeys.includes(key);
|
||||
const onExit = () => {
|
||||
if (exitingComponents.current.has(key)) {
|
||||
return;
|
||||
}
|
||||
if (exitComplete.has(key)) {
|
||||
exitingComponents.current.add(key);
|
||||
exitComplete.set(key, true);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
let isEveryExitComplete = true;
|
||||
exitComplete.forEach((isExitComplete) => {
|
||||
if (!isExitComplete)
|
||||
isEveryExitComplete = false;
|
||||
});
|
||||
if (isEveryExitComplete) {
|
||||
forceRender?.();
|
||||
setRenderedChildren(pendingPresentChildren.current);
|
||||
propagate && safeToRemove?.();
|
||||
onExitComplete && onExitComplete();
|
||||
}
|
||||
};
|
||||
return (jsx(PresenceChild, { isPresent: isPresent, initial: !isInitialRender.current || initial
|
||||
? undefined
|
||||
: false, custom: custom, presenceAffectsLayout: presenceAffectsLayout, mode: mode, root: root, onExitComplete: isPresent ? undefined : onExit, anchorX: anchorX, anchorY: anchorY, children: child }, key));
|
||||
}) }));
|
||||
};
|
||||
|
||||
export { AnimatePresence };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/AnimatePresence/index.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/AnimatePresence/index.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
11
node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence-data.mjs
generated
vendored
Normal file
11
node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence-data.mjs
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
"use client";
|
||||
import { useContext } from 'react';
|
||||
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
||||
|
||||
function usePresenceData() {
|
||||
const context = useContext(PresenceContext);
|
||||
return context ? context.custom : undefined;
|
||||
}
|
||||
|
||||
export { usePresenceData };
|
||||
//# sourceMappingURL=use-presence-data.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence-data.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence-data.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-presence-data.mjs","sources":["../../../../src/components/AnimatePresence/use-presence-data.ts"],"sourcesContent":["\"use client\"\n\nimport { useContext } from \"react\"\nimport { PresenceContext } from \"../../context/PresenceContext\"\n\nexport function usePresenceData() {\n const context = useContext(PresenceContext)\n return context ? context.custom : undefined\n}\n"],"names":[],"mappings":";;;;;AAMI;;AAEJ;;"}
|
||||
72
node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.mjs
generated
vendored
Normal file
72
node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.mjs
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
"use client";
|
||||
import { useContext, useId, useEffect, useCallback } from 'react';
|
||||
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
||||
|
||||
/**
|
||||
* When a component is the child of `AnimatePresence`, it can use `usePresence`
|
||||
* to access information about whether it's still present in the React tree.
|
||||
*
|
||||
* ```jsx
|
||||
* import { usePresence } from "framer-motion"
|
||||
*
|
||||
* export const Component = () => {
|
||||
* const [isPresent, safeToRemove] = usePresence()
|
||||
*
|
||||
* useEffect(() => {
|
||||
* !isPresent && setTimeout(safeToRemove, 1000)
|
||||
* }, [isPresent])
|
||||
*
|
||||
* return <div />
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* If `isPresent` is `false`, it means that a component has been removed from the tree,
|
||||
* but `AnimatePresence` won't really remove it until `safeToRemove` has been called.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function usePresence(subscribe = true) {
|
||||
const context = useContext(PresenceContext);
|
||||
if (context === null)
|
||||
return [true, null];
|
||||
const { isPresent, onExitComplete, register } = context;
|
||||
// It's safe to call the following hooks conditionally (after an early return) because the context will always
|
||||
// either be null or non-null for the lifespan of the component.
|
||||
const id = useId();
|
||||
useEffect(() => {
|
||||
if (subscribe) {
|
||||
return register(id);
|
||||
}
|
||||
}, [subscribe]);
|
||||
const safeToRemove = useCallback(() => subscribe && onExitComplete && onExitComplete(id), [id, onExitComplete, subscribe]);
|
||||
return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
|
||||
}
|
||||
/**
|
||||
* Similar to `usePresence`, except `useIsPresent` simply returns whether or not the component is present.
|
||||
* There is no `safeToRemove` function.
|
||||
*
|
||||
* ```jsx
|
||||
* import { useIsPresent } from "framer-motion"
|
||||
*
|
||||
* export const Component = () => {
|
||||
* const isPresent = useIsPresent()
|
||||
*
|
||||
* useEffect(() => {
|
||||
* !isPresent && console.log("I've been removed!")
|
||||
* }, [isPresent])
|
||||
*
|
||||
* return <div />
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function useIsPresent() {
|
||||
return isPresent(useContext(PresenceContext));
|
||||
}
|
||||
function isPresent(context) {
|
||||
return context === null ? true : context.isPresent;
|
||||
}
|
||||
|
||||
export { isPresent, useIsPresent, usePresence };
|
||||
//# sourceMappingURL=use-presence.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/AnimatePresence/use-presence.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-presence.mjs","sources":["../../../../src/components/AnimatePresence/use-presence.ts"],"sourcesContent":["\"use client\"\n\nimport { useCallback, useContext, useEffect, useId } from \"react\"\nimport {\n PresenceContext,\n PresenceContextProps,\n} from \"../../context/PresenceContext\"\n\nexport type SafeToRemove = () => void\n\ntype AlwaysPresent = [true, null]\n\ntype Present = [true]\n\ntype NotPresent = [false, SafeToRemove]\n\n/**\n * When a component is the child of `AnimatePresence`, it can use `usePresence`\n * to access information about whether it's still present in the React tree.\n *\n * ```jsx\n * import { usePresence } from \"framer-motion\"\n *\n * export const Component = () => {\n * const [isPresent, safeToRemove] = usePresence()\n *\n * useEffect(() => {\n * !isPresent && setTimeout(safeToRemove, 1000)\n * }, [isPresent])\n *\n * return <div />\n * }\n * ```\n *\n * If `isPresent` is `false`, it means that a component has been removed from the tree,\n * but `AnimatePresence` won't really remove it until `safeToRemove` has been called.\n *\n * @public\n */\nexport function usePresence(\n subscribe: boolean = true\n): AlwaysPresent | Present | NotPresent {\n const context = useContext(PresenceContext)\n\n if (context === null) return [true, null]\n\n const { isPresent, onExitComplete, register } = context\n\n // It's safe to call the following hooks conditionally (after an early return) because the context will always\n // either be null or non-null for the lifespan of the component.\n\n const id = useId()\n useEffect(() => {\n if (subscribe) {\n return register(id)\n }\n }, [subscribe])\n\n const safeToRemove = useCallback(\n () => subscribe && onExitComplete && onExitComplete(id),\n [id, onExitComplete, subscribe]\n )\n\n return !isPresent && onExitComplete ? [false, safeToRemove] : [true]\n}\n\n/**\n * Similar to `usePresence`, except `useIsPresent` simply returns whether or not the component is present.\n * There is no `safeToRemove` function.\n *\n * ```jsx\n * import { useIsPresent } from \"framer-motion\"\n *\n * export const Component = () => {\n * const isPresent = useIsPresent()\n *\n * useEffect(() => {\n * !isPresent && console.log(\"I've been removed!\")\n * }, [isPresent])\n *\n * return <div />\n * }\n * ```\n *\n * @public\n */\nexport function useIsPresent() {\n return isPresent(useContext(PresenceContext))\n}\n\nexport function isPresent(context: PresenceContextProps | null) {\n return context === null ? true : context.isPresent\n}\n"],"names":[],"mappings":";;;;AAgBA;;;;;;;;;;;;;;;;;;;;;;AAsBG;AACG;AAGF;;AAEsB;;;;AAOtB;;;AAGQ;;AAER;;AAOA;AACJ;AAEA;;;;;;;;;;;;;;;;;;;AAmBG;;AAEC;AACJ;AAEM;AACF;AACJ;;"}
|
||||
15
node_modules/framer-motion/dist/es/components/AnimatePresence/utils.mjs
generated
vendored
Normal file
15
node_modules/framer-motion/dist/es/components/AnimatePresence/utils.mjs
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Children, isValidElement } from 'react';
|
||||
|
||||
const getChildKey = (child) => child.key || "";
|
||||
function onlyElements(children) {
|
||||
const filtered = [];
|
||||
// We use forEach here instead of map as map mutates the component key by preprending `.$`
|
||||
Children.forEach(children, (child) => {
|
||||
if (isValidElement(child))
|
||||
filtered.push(child);
|
||||
});
|
||||
return filtered;
|
||||
}
|
||||
|
||||
export { getChildKey, onlyElements };
|
||||
//# sourceMappingURL=utils.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/AnimatePresence/utils.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/AnimatePresence/utils.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.mjs","sources":["../../../../src/components/AnimatePresence/utils.ts"],"sourcesContent":["import { isValidElement, Children, ReactElement, ReactNode } from \"react\"\n\nexport type ComponentKey = string | number\n\nexport const getChildKey = (child: ReactElement<any>): ComponentKey =>\n child.key || \"\"\n\nexport function onlyElements(children: ReactNode): ReactElement<any>[] {\n const filtered: ReactElement<any>[] = []\n\n // We use forEach here instead of map as map mutates the component key by preprending `.$`\n Children.forEach(children, (child) => {\n if (isValidElement(child)) filtered.push(child)\n })\n\n return filtered\n}\n"],"names":[],"mappings":";;AAIO,MAAM,WAAW,GAAG,CAAC,KAAwB,KAChD,KAAK,CAAC,GAAG,IAAI;AAEX,SAAU,YAAY,CAAC,QAAmB,EAAA;IAC5C,MAAM,QAAQ,GAAwB,EAAE;;IAGxC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAI;QACjC,IAAI,cAAc,CAAC,KAAK,CAAC;AAAE,YAAA,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;AACnD,IAAA,CAAC,CAAC;AAEF,IAAA,OAAO,QAAQ;AACnB;;;;"}
|
||||
17
node_modules/framer-motion/dist/es/components/AnimateSharedLayout.mjs
generated
vendored
Normal file
17
node_modules/framer-motion/dist/es/components/AnimateSharedLayout.mjs
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { invariant } from 'motion-utils';
|
||||
import * as React from 'react';
|
||||
import { useConstant } from '../utils/use-constant.mjs';
|
||||
import { LayoutGroup } from './LayoutGroup/index.mjs';
|
||||
|
||||
let id = 0;
|
||||
const AnimateSharedLayout = ({ children }) => {
|
||||
React.useEffect(() => {
|
||||
invariant(false, "AnimateSharedLayout is deprecated: https://www.framer.com/docs/guide-upgrade/##shared-layout-animations");
|
||||
}, []);
|
||||
return (jsx(LayoutGroup, { id: useConstant(() => `asl-${id++}`), children: children }));
|
||||
};
|
||||
|
||||
export { AnimateSharedLayout };
|
||||
//# sourceMappingURL=AnimateSharedLayout.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/AnimateSharedLayout.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/AnimateSharedLayout.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"AnimateSharedLayout.mjs","sources":["../../../src/components/AnimateSharedLayout.tsx"],"sourcesContent":["\"use client\"\n\nimport { invariant } from \"motion-utils\"\nimport * as React from \"react\"\nimport { useConstant } from \"../utils/use-constant\"\nimport { LayoutGroup } from \"./LayoutGroup\"\n\nlet id = 0\nexport const AnimateSharedLayout: React.FunctionComponent<\n React.PropsWithChildren<unknown>\n> = ({ children }: React.PropsWithChildren<{}>) => {\n React.useEffect(() => {\n invariant(\n false,\n \"AnimateSharedLayout is deprecated: https://www.framer.com/docs/guide-upgrade/##shared-layout-animations\"\n )\n }, [])\n\n return (\n <LayoutGroup id={useConstant(() => `asl-${id++}`)}>\n {children}\n </LayoutGroup>\n )\n}\n"],"names":[],"mappings":";;;;;;;AAOA;;AAII;AACI;;;AAWR;;"}
|
||||
33
node_modules/framer-motion/dist/es/components/LayoutGroup/index.mjs
generated
vendored
Normal file
33
node_modules/framer-motion/dist/es/components/LayoutGroup/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { useContext, useRef, useMemo } from 'react';
|
||||
import { LayoutGroupContext } from '../../context/LayoutGroupContext.mjs';
|
||||
import { DeprecatedLayoutGroupContext } from '../../context/DeprecatedLayoutGroupContext.mjs';
|
||||
import { useForceUpdate } from '../../utils/use-force-update.mjs';
|
||||
import { nodeGroup } from 'motion-dom';
|
||||
|
||||
const shouldInheritGroup = (inherit) => inherit === true;
|
||||
const shouldInheritId = (inherit) => shouldInheritGroup(inherit === true) || inherit === "id";
|
||||
const LayoutGroup = ({ children, id, inherit = true }) => {
|
||||
const layoutGroupContext = useContext(LayoutGroupContext);
|
||||
const deprecatedLayoutGroupContext = useContext(DeprecatedLayoutGroupContext);
|
||||
const [forceRender, key] = useForceUpdate();
|
||||
const context = useRef(null);
|
||||
const upstreamId = layoutGroupContext.id || deprecatedLayoutGroupContext;
|
||||
if (context.current === null) {
|
||||
if (shouldInheritId(inherit) && upstreamId) {
|
||||
id = id ? upstreamId + "-" + id : upstreamId;
|
||||
}
|
||||
context.current = {
|
||||
id,
|
||||
group: shouldInheritGroup(inherit)
|
||||
? layoutGroupContext.group || nodeGroup()
|
||||
: nodeGroup(),
|
||||
};
|
||||
}
|
||||
const memoizedContext = useMemo(() => ({ ...context.current, forceRender }), [key]);
|
||||
return (jsx(LayoutGroupContext.Provider, { value: memoizedContext, children: children }));
|
||||
};
|
||||
|
||||
export { LayoutGroup };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/LayoutGroup/index.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/LayoutGroup/index.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../../../../src/components/LayoutGroup/index.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { MutableRefObject, useContext, useMemo, useRef } from \"react\"\nimport {\n LayoutGroupContext,\n LayoutGroupContextProps,\n} from \"../../context/LayoutGroupContext\"\nimport { DeprecatedLayoutGroupContext } from \"../../context/DeprecatedLayoutGroupContext\"\nimport { nodeGroup } from \"../../projection\"\nimport { useForceUpdate } from \"../../utils/use-force-update\"\n\ntype InheritOption = boolean | \"id\"\n\nexport interface Props {\n id?: string\n inherit?: InheritOption\n}\n\nconst shouldInheritGroup = (inherit: InheritOption) => inherit === true\nconst shouldInheritId = (inherit: InheritOption) =>\n shouldInheritGroup(inherit === true) || inherit === \"id\"\n\nexport const LayoutGroup: React.FunctionComponent<\n React.PropsWithChildren<Props>\n> = ({ children, id, inherit = true }) => {\n const layoutGroupContext = useContext(LayoutGroupContext)\n const deprecatedLayoutGroupContext = useContext(\n DeprecatedLayoutGroupContext\n )\n const [forceRender, key] = useForceUpdate()\n const context = useRef(\n null\n ) as MutableRefObject<LayoutGroupContextProps | null>\n\n const upstreamId = layoutGroupContext.id || deprecatedLayoutGroupContext\n if (context.current === null) {\n if (shouldInheritId(inherit) && upstreamId) {\n id = id ? upstreamId + \"-\" + id : upstreamId\n }\n\n context.current = {\n id,\n group: shouldInheritGroup(inherit)\n ? layoutGroupContext.group || nodeGroup()\n : nodeGroup(),\n }\n }\n\n const memoizedContext = useMemo(\n () => ({ ...context.current, forceRender }),\n [key]\n )\n\n return (\n <LayoutGroupContext.Provider value={memoizedContext}>\n {children}\n </LayoutGroupContext.Provider>\n )\n}\n"],"names":[],"mappings":";;;;;;;;AAmBA;AACA;AAGO;AAGH;AACA;;AAIA;AAIA;AACA;AACI;AACI;;;;AAKA;AACI;;;;;AAUZ;AAKJ;;"}
|
||||
69
node_modules/framer-motion/dist/es/components/LazyMotion/index.mjs
generated
vendored
Normal file
69
node_modules/framer-motion/dist/es/components/LazyMotion/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import { LazyContext } from '../../context/LazyContext.mjs';
|
||||
import { loadFeatures } from '../../motion/features/load-features.mjs';
|
||||
|
||||
/**
|
||||
* Used in conjunction with the `m` component to reduce bundle size.
|
||||
*
|
||||
* `m` is a version of the `motion` component that only loads functionality
|
||||
* critical for the initial render.
|
||||
*
|
||||
* `LazyMotion` can then be used to either synchronously or asynchronously
|
||||
* load animation and gesture support.
|
||||
*
|
||||
* ```jsx
|
||||
* // Synchronous loading
|
||||
* import { LazyMotion, m, domAnimation } from "framer-motion"
|
||||
*
|
||||
* function App() {
|
||||
* return (
|
||||
* <LazyMotion features={domAnimation}>
|
||||
* <m.div animate={{ scale: 2 }} />
|
||||
* </LazyMotion>
|
||||
* )
|
||||
* }
|
||||
*
|
||||
* // Asynchronous loading
|
||||
* import { LazyMotion, m } from "framer-motion"
|
||||
*
|
||||
* function App() {
|
||||
* return (
|
||||
* <LazyMotion features={() => import('./path/to/domAnimation')}>
|
||||
* <m.div animate={{ scale: 2 }} />
|
||||
* </LazyMotion>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function LazyMotion({ children, features, strict = false }) {
|
||||
const [, setIsLoaded] = useState(!isLazyBundle(features));
|
||||
const loadedRenderer = useRef(undefined);
|
||||
/**
|
||||
* If this is a synchronous load, load features immediately
|
||||
*/
|
||||
if (!isLazyBundle(features)) {
|
||||
const { renderer, ...loadedFeatures } = features;
|
||||
loadedRenderer.current = renderer;
|
||||
loadFeatures(loadedFeatures);
|
||||
}
|
||||
useEffect(() => {
|
||||
if (isLazyBundle(features)) {
|
||||
features().then(({ renderer, ...loadedFeatures }) => {
|
||||
loadFeatures(loadedFeatures);
|
||||
loadedRenderer.current = renderer;
|
||||
setIsLoaded(true);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
return (jsx(LazyContext.Provider, { value: { renderer: loadedRenderer.current, strict }, children: children }));
|
||||
}
|
||||
function isLazyBundle(features) {
|
||||
return typeof features === "function";
|
||||
}
|
||||
|
||||
export { LazyMotion };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/LazyMotion/index.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/LazyMotion/index.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../../../../src/components/LazyMotion/index.tsx"],"sourcesContent":["\"use client\"\n\nimport { useEffect, useRef, useState } from \"react\"\nimport { LazyContext } from \"../../context/LazyContext\"\nimport { loadFeatures } from \"../../motion/features/load-features\"\nimport { FeatureBundle, LazyFeatureBundle } from \"../../motion/features/types\"\nimport { CreateVisualElement } from \"../../render/types\"\nimport { LazyProps } from \"./types\"\n\n/**\n * Used in conjunction with the `m` component to reduce bundle size.\n *\n * `m` is a version of the `motion` component that only loads functionality\n * critical for the initial render.\n *\n * `LazyMotion` can then be used to either synchronously or asynchronously\n * load animation and gesture support.\n *\n * ```jsx\n * // Synchronous loading\n * import { LazyMotion, m, domAnimation } from \"framer-motion\"\n *\n * function App() {\n * return (\n * <LazyMotion features={domAnimation}>\n * <m.div animate={{ scale: 2 }} />\n * </LazyMotion>\n * )\n * }\n *\n * // Asynchronous loading\n * import { LazyMotion, m } from \"framer-motion\"\n *\n * function App() {\n * return (\n * <LazyMotion features={() => import('./path/to/domAnimation')}>\n * <m.div animate={{ scale: 2 }} />\n * </LazyMotion>\n * )\n * }\n * ```\n *\n * @public\n */\nexport function LazyMotion({ children, features, strict = false }: LazyProps) {\n const [, setIsLoaded] = useState(!isLazyBundle(features))\n const loadedRenderer = useRef<undefined | CreateVisualElement>(undefined)\n\n /**\n * If this is a synchronous load, load features immediately\n */\n if (!isLazyBundle(features)) {\n const { renderer, ...loadedFeatures } = features\n loadedRenderer.current = renderer\n loadFeatures(loadedFeatures)\n }\n\n useEffect(() => {\n if (isLazyBundle(features)) {\n features().then(({ renderer, ...loadedFeatures }) => {\n loadFeatures(loadedFeatures)\n loadedRenderer.current = renderer\n setIsLoaded(true)\n })\n }\n }, [])\n\n return (\n <LazyContext.Provider\n value={{ renderer: loadedRenderer.current, strict }}\n >\n {children}\n </LazyContext.Provider>\n )\n}\n\nfunction isLazyBundle(\n features: FeatureBundle | LazyFeatureBundle\n): features is LazyFeatureBundle {\n return typeof features === \"function\"\n}\n"],"names":[],"mappings":";;;;;;AASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCG;AACG;AACF;AACA;AAEA;;AAEG;AACH;;AAEI;;;;AAKA;AACI;;AAEI;;AAEJ;;;;AAWZ;AAEA;AAGI;AACJ;;"}
|
||||
53
node_modules/framer-motion/dist/es/components/MotionConfig/index.mjs
generated
vendored
Normal file
53
node_modules/framer-motion/dist/es/components/MotionConfig/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { resolveTransition } from 'motion-dom';
|
||||
import { MotionConfigContext } from '../../context/MotionConfigContext.mjs';
|
||||
import { loadExternalIsValidProp } from '../../render/dom/utils/filter-props.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
|
||||
/**
|
||||
* `MotionConfig` is used to set configuration options for all children `motion` components.
|
||||
*
|
||||
* ```jsx
|
||||
* import { motion, MotionConfig } from "framer-motion"
|
||||
*
|
||||
* export function App() {
|
||||
* return (
|
||||
* <MotionConfig transition={{ type: "spring" }}>
|
||||
* <motion.div animate={{ x: 100 }} />
|
||||
* </MotionConfig>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function MotionConfig({ children, isValidProp, ...config }) {
|
||||
isValidProp && loadExternalIsValidProp(isValidProp);
|
||||
/**
|
||||
* Inherit props from any parent MotionConfig components
|
||||
*/
|
||||
const parentConfig = useContext(MotionConfigContext);
|
||||
config = { ...parentConfig, ...config };
|
||||
config.transition = resolveTransition(config.transition, parentConfig.transition);
|
||||
/**
|
||||
* Don't allow isStatic to change between renders as it affects how many hooks
|
||||
* motion components fire.
|
||||
*/
|
||||
config.isStatic = useConstant(() => config.isStatic);
|
||||
/**
|
||||
* Creating a new config context object will re-render every `motion` component
|
||||
* every time it renders. So we only want to create a new one sparingly.
|
||||
*/
|
||||
const context = useMemo(() => config, [
|
||||
JSON.stringify(config.transition),
|
||||
config.transformPagePoint,
|
||||
config.reducedMotion,
|
||||
config.skipAnimations,
|
||||
]);
|
||||
return (jsx(MotionConfigContext.Provider, { value: context, children: children }));
|
||||
}
|
||||
|
||||
export { MotionConfig };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/MotionConfig/index.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/MotionConfig/index.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../../../../src/components/MotionConfig/index.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { useContext, useMemo } from \"react\"\nimport { resolveTransition } from \"motion-dom\"\nimport { MotionConfigContext } from \"../../context/MotionConfigContext\"\nimport {\n loadExternalIsValidProp,\n IsValidProp,\n} from \"../../render/dom/utils/filter-props\"\nimport { useConstant } from \"../../utils/use-constant\"\n\nexport interface MotionConfigProps extends Partial<MotionConfigContext> {\n children?: React.ReactNode\n isValidProp?: IsValidProp\n}\n\n/**\n * `MotionConfig` is used to set configuration options for all children `motion` components.\n *\n * ```jsx\n * import { motion, MotionConfig } from \"framer-motion\"\n *\n * export function App() {\n * return (\n * <MotionConfig transition={{ type: \"spring\" }}>\n * <motion.div animate={{ x: 100 }} />\n * </MotionConfig>\n * )\n * }\n * ```\n *\n * @public\n */\nexport function MotionConfig({\n children,\n isValidProp,\n ...config\n}: MotionConfigProps) {\n isValidProp && loadExternalIsValidProp(isValidProp)\n\n /**\n * Inherit props from any parent MotionConfig components\n */\n const parentConfig = useContext(MotionConfigContext)\n config = { ...parentConfig, ...config }\n\n config.transition = resolveTransition(\n config.transition,\n parentConfig.transition\n )\n\n /**\n * Don't allow isStatic to change between renders as it affects how many hooks\n * motion components fire.\n */\n config.isStatic = useConstant(() => config.isStatic)\n\n /**\n * Creating a new config context object will re-render every `motion` component\n * every time it renders. So we only want to create a new one sparingly.\n */\n const context = useMemo(\n () => config,\n [\n JSON.stringify(config.transition),\n config.transformPagePoint,\n config.reducedMotion,\n config.skipAnimations,\n ]\n )\n\n return (\n <MotionConfigContext.Provider value={context as MotionConfigContext}>\n {children}\n </MotionConfigContext.Provider>\n )\n}\n"],"names":[],"mappings":";;;;;;;;AAiBA;;;;;;;;;;;;;;;;AAgBG;AACG;AAKF;AAEA;;AAEG;AACH;;AAGA;AAKA;;;AAGG;AACH;AAEA;;;AAGG;;AAIK;AACA;AACA;AACA;AACH;AAGL;AAKJ;;"}
|
||||
84
node_modules/framer-motion/dist/es/components/Reorder/Group.mjs
generated
vendored
Normal file
84
node_modules/framer-motion/dist/es/components/Reorder/Group.mjs
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { forwardRef, useRef, useEffect } from 'react';
|
||||
import { ReorderContext } from '../../context/ReorderContext.mjs';
|
||||
import { motion } from '../../render/components/motion/proxy.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { checkReorder } from './utils/check-reorder.mjs';
|
||||
|
||||
function ReorderGroupComponent({ children, as = "ul", axis = "y", onReorder, values, ...props }, externalRef) {
|
||||
const Component = useConstant(() => motion[as]);
|
||||
const order = [];
|
||||
const isReordering = useRef(false);
|
||||
const groupRef = useRef(null);
|
||||
invariant(Boolean(values), "Reorder.Group must be provided a values prop", "reorder-values");
|
||||
const context = {
|
||||
axis,
|
||||
groupRef,
|
||||
registerItem: (value, layout) => {
|
||||
// If the entry was already added, update it rather than adding it again
|
||||
const idx = order.findIndex((entry) => value === entry.value);
|
||||
if (idx !== -1) {
|
||||
order[idx].layout = layout[axis];
|
||||
}
|
||||
else {
|
||||
order.push({ value: value, layout: layout[axis] });
|
||||
}
|
||||
order.sort(compareMin);
|
||||
},
|
||||
updateOrder: (item, offset, velocity) => {
|
||||
if (isReordering.current)
|
||||
return;
|
||||
const newOrder = checkReorder(order, item, offset, velocity);
|
||||
if (order !== newOrder) {
|
||||
isReordering.current = true;
|
||||
// Find which two values swapped and apply that swap
|
||||
// to the full values array. This preserves unmeasured
|
||||
// items (e.g. in virtualized lists).
|
||||
const newValues = [...values];
|
||||
for (let i = 0; i < newOrder.length; i++) {
|
||||
if (order[i].value !== newOrder[i].value) {
|
||||
const a = values.indexOf(order[i].value);
|
||||
const b = values.indexOf(newOrder[i].value);
|
||||
if (a !== -1 && b !== -1) {
|
||||
[newValues[a], newValues[b]] = [newValues[b], newValues[a]];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
onReorder(newValues);
|
||||
}
|
||||
},
|
||||
};
|
||||
useEffect(() => {
|
||||
isReordering.current = false;
|
||||
});
|
||||
// Combine refs if external ref is provided
|
||||
const setRef = (element) => {
|
||||
groupRef.current = element;
|
||||
if (typeof externalRef === "function") {
|
||||
externalRef(element);
|
||||
}
|
||||
else if (externalRef) {
|
||||
externalRef.current = element;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Disable browser scroll anchoring on the group container.
|
||||
* When items reorder, scroll anchoring can cause the browser to adjust
|
||||
* the scroll position, which interferes with drag position calculations.
|
||||
*/
|
||||
const groupStyle = {
|
||||
overflowAnchor: "none",
|
||||
...props.style,
|
||||
};
|
||||
return (jsx(Component, { ...props, style: groupStyle, ref: setRef, ignoreStrict: true, children: jsx(ReorderContext.Provider, { value: context, children: children }) }));
|
||||
}
|
||||
const ReorderGroup = /*@__PURE__*/ forwardRef(ReorderGroupComponent);
|
||||
function compareMin(a, b) {
|
||||
return a.layout.min - b.layout.min;
|
||||
}
|
||||
|
||||
export { ReorderGroup, ReorderGroupComponent };
|
||||
//# sourceMappingURL=Group.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/Reorder/Group.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/Reorder/Group.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
43
node_modules/framer-motion/dist/es/components/Reorder/Item.mjs
generated
vendored
Normal file
43
node_modules/framer-motion/dist/es/components/Reorder/Item.mjs
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { isMotionValue } from 'motion-dom';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { forwardRef, useContext } from 'react';
|
||||
import { ReorderContext } from '../../context/ReorderContext.mjs';
|
||||
import { motion } from '../../render/components/motion/proxy.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useMotionValue } from '../../value/use-motion-value.mjs';
|
||||
import { useTransform } from '../../value/use-transform.mjs';
|
||||
import { autoScrollIfNeeded, resetAutoScrollState } from './utils/auto-scroll.mjs';
|
||||
|
||||
function useDefaultMotionValue(value, defaultValue = 0) {
|
||||
return isMotionValue(value) ? value : useMotionValue(defaultValue);
|
||||
}
|
||||
function ReorderItemComponent({ children, style = {}, value, as = "li", onDrag, onDragEnd, layout = true, ...props }, externalRef) {
|
||||
const Component = useConstant(() => motion[as]);
|
||||
const context = useContext(ReorderContext);
|
||||
const point = {
|
||||
x: useDefaultMotionValue(style.x),
|
||||
y: useDefaultMotionValue(style.y),
|
||||
};
|
||||
const zIndex = useTransform([point.x, point.y], ([latestX, latestY]) => latestX || latestY ? 1 : "unset");
|
||||
invariant(Boolean(context), "Reorder.Item must be a child of Reorder.Group", "reorder-item-child");
|
||||
const { axis, registerItem, updateOrder, groupRef } = context;
|
||||
return (jsx(Component, { drag: axis, ...props, dragSnapToOrigin: true, style: { ...style, x: point.x, y: point.y, zIndex }, layout: layout, onDrag: (event, gesturePoint) => {
|
||||
const { velocity, point: pointerPoint } = gesturePoint;
|
||||
const offset = point[axis].get();
|
||||
// Always attempt to update order - checkReorder handles the logic
|
||||
updateOrder(value, offset, velocity[axis]);
|
||||
autoScrollIfNeeded(groupRef.current, pointerPoint[axis], axis, velocity[axis]);
|
||||
onDrag && onDrag(event, gesturePoint);
|
||||
}, onDragEnd: (event, gesturePoint) => {
|
||||
resetAutoScrollState();
|
||||
onDragEnd && onDragEnd(event, gesturePoint);
|
||||
}, onLayoutMeasure: (measured) => {
|
||||
registerItem(value, measured);
|
||||
}, ref: externalRef, ignoreStrict: true, children: children }));
|
||||
}
|
||||
const ReorderItem = /*@__PURE__*/ forwardRef(ReorderItemComponent);
|
||||
|
||||
export { ReorderItem, ReorderItemComponent };
|
||||
//# sourceMappingURL=Item.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/Reorder/Item.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/Reorder/Item.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Item.mjs","sources":["../../../../src/components/Reorder/Item.tsx"],"sourcesContent":["\"use client\"\n\nimport { isMotionValue } from \"motion-dom\"\nimport { invariant } from \"motion-utils\"\nimport * as React from \"react\"\nimport { forwardRef, FunctionComponent, useContext } from \"react\"\nimport { ReorderContext } from \"../../context/ReorderContext\"\nimport { motion } from \"../../render/components/motion/proxy\"\nimport { HTMLMotionProps } from \"../../render/html/types\"\nimport { useConstant } from \"../../utils/use-constant\"\nimport { useMotionValue } from \"../../value/use-motion-value\"\nimport { useTransform } from \"../../value/use-transform\"\n\nimport { DefaultItemElement, ReorderElementTag } from \"./types\"\nimport {\n autoScrollIfNeeded,\n resetAutoScrollState,\n} from \"./utils/auto-scroll\"\n\nexport interface Props<\n V,\n TagName extends ReorderElementTag = DefaultItemElement\n> {\n /**\n * A HTML element to render this component as. Defaults to `\"li\"`.\n *\n * @public\n */\n as?: TagName\n\n /**\n * The value in the list that this component represents.\n *\n * @public\n */\n value: V\n\n /**\n * A subset of layout options primarily used to disable layout=\"size\"\n *\n * @public\n * @default true\n */\n layout?: true | \"position\"\n}\n\nfunction useDefaultMotionValue(value: any, defaultValue: number = 0) {\n return isMotionValue(value) ? value : useMotionValue(defaultValue)\n}\n\ntype ReorderItemProps<\n V,\n TagName extends ReorderElementTag = DefaultItemElement\n> = Props<V, TagName> &\n Omit<HTMLMotionProps<TagName>, \"value\" | \"layout\"> &\n React.PropsWithChildren<{}>\n\nexport function ReorderItemComponent<\n V,\n TagName extends ReorderElementTag = DefaultItemElement\n>(\n {\n children,\n style = {},\n value,\n as = \"li\" as TagName,\n onDrag,\n onDragEnd,\n layout = true,\n ...props\n }: ReorderItemProps<V, TagName>,\n externalRef?: React.ForwardedRef<any>\n): React.JSX.Element {\n const Component = useConstant(\n () => motion[as as keyof typeof motion]\n ) as FunctionComponent<\n React.PropsWithChildren<HTMLMotionProps<any> & { ref?: React.Ref<any> }>\n >\n\n const context = useContext(ReorderContext)\n const point = {\n x: useDefaultMotionValue(style.x),\n y: useDefaultMotionValue(style.y),\n }\n\n const zIndex = useTransform([point.x, point.y], ([latestX, latestY]) =>\n latestX || latestY ? 1 : \"unset\"\n )\n\n invariant(\n Boolean(context),\n \"Reorder.Item must be a child of Reorder.Group\",\n \"reorder-item-child\"\n )\n\n const { axis, registerItem, updateOrder, groupRef } = context!\n\n return (\n <Component\n drag={axis}\n {...props}\n dragSnapToOrigin\n style={{ ...style, x: point.x, y: point.y, zIndex }}\n layout={layout}\n onDrag={(event, gesturePoint) => {\n const { velocity, point: pointerPoint } = gesturePoint\n const offset = point[axis].get()\n\n // Always attempt to update order - checkReorder handles the logic\n updateOrder(value, offset, velocity[axis])\n\n autoScrollIfNeeded(\n groupRef.current,\n pointerPoint[axis],\n axis,\n velocity[axis]\n )\n\n onDrag && onDrag(event, gesturePoint)\n }}\n onDragEnd={(event, gesturePoint) => {\n resetAutoScrollState()\n onDragEnd && onDragEnd(event, gesturePoint)\n }}\n onLayoutMeasure={(measured) => {\n registerItem(value, measured)\n }}\n ref={externalRef}\n ignoreStrict\n >\n {children}\n </Component>\n )\n}\n\nexport const ReorderItem = /*@__PURE__*/ forwardRef(ReorderItemComponent) as <\n V,\n TagName extends ReorderElementTag = DefaultItemElement\n>(\n props: ReorderItemProps<V, TagName> & { ref?: React.ForwardedRef<any> }\n) => ReturnType<typeof ReorderItemComponent>\n"],"names":[],"mappings":";;;;;;;;;;;;AA8CA;AACI;AACJ;AASM;AAgBF;AAMA;AACA;AACI;AACA;;AAGJ;;;;;;;;AA0BY;AAOA;;AAGA;AACA;AACJ;AAEI;;AAQhB;AAEO;;"}
|
||||
3
node_modules/framer-motion/dist/es/components/Reorder/namespace.mjs
generated
vendored
Normal file
3
node_modules/framer-motion/dist/es/components/Reorder/namespace.mjs
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export { ReorderGroup as Group } from './Group.mjs';
|
||||
export { ReorderItem as Item } from './Item.mjs';
|
||||
//# sourceMappingURL=namespace.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/Reorder/namespace.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/Reorder/namespace.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"namespace.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
||||
124
node_modules/framer-motion/dist/es/components/Reorder/utils/auto-scroll.mjs
generated
vendored
Normal file
124
node_modules/framer-motion/dist/es/components/Reorder/utils/auto-scroll.mjs
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
const threshold = 50;
|
||||
const maxSpeed = 25;
|
||||
const overflowStyles = new Set(["auto", "scroll"]);
|
||||
// Track initial scroll limits per scrollable element (Bug 1 fix)
|
||||
const initialScrollLimits = new WeakMap();
|
||||
const activeScrollEdge = new WeakMap();
|
||||
// Track which group element is currently dragging to clear state on end
|
||||
let currentGroupElement = null;
|
||||
function resetAutoScrollState() {
|
||||
if (currentGroupElement) {
|
||||
const scrollableAncestor = findScrollableAncestor(currentGroupElement, "y");
|
||||
if (scrollableAncestor) {
|
||||
activeScrollEdge.delete(scrollableAncestor);
|
||||
initialScrollLimits.delete(scrollableAncestor);
|
||||
}
|
||||
// Also try x axis
|
||||
const scrollableAncestorX = findScrollableAncestor(currentGroupElement, "x");
|
||||
if (scrollableAncestorX && scrollableAncestorX !== scrollableAncestor) {
|
||||
activeScrollEdge.delete(scrollableAncestorX);
|
||||
initialScrollLimits.delete(scrollableAncestorX);
|
||||
}
|
||||
currentGroupElement = null;
|
||||
}
|
||||
}
|
||||
function isScrollableElement(element, axis) {
|
||||
const style = getComputedStyle(element);
|
||||
const overflow = axis === "x" ? style.overflowX : style.overflowY;
|
||||
const isDocumentScroll = element === document.body ||
|
||||
element === document.documentElement;
|
||||
return overflowStyles.has(overflow) || isDocumentScroll;
|
||||
}
|
||||
function findScrollableAncestor(element, axis) {
|
||||
let current = element?.parentElement;
|
||||
while (current) {
|
||||
if (isScrollableElement(current, axis)) {
|
||||
return current;
|
||||
}
|
||||
current = current.parentElement;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function getScrollAmount(pointerPosition, scrollElement, axis) {
|
||||
const rect = scrollElement.getBoundingClientRect();
|
||||
const start = axis === "x" ? Math.max(0, rect.left) : Math.max(0, rect.top);
|
||||
const end = axis === "x" ? Math.min(window.innerWidth, rect.right) : Math.min(window.innerHeight, rect.bottom);
|
||||
const distanceFromStart = pointerPosition - start;
|
||||
const distanceFromEnd = end - pointerPosition;
|
||||
if (distanceFromStart < threshold) {
|
||||
const intensity = 1 - distanceFromStart / threshold;
|
||||
return { amount: -maxSpeed * intensity * intensity, edge: "start" };
|
||||
}
|
||||
else if (distanceFromEnd < threshold) {
|
||||
const intensity = 1 - distanceFromEnd / threshold;
|
||||
return { amount: maxSpeed * intensity * intensity, edge: "end" };
|
||||
}
|
||||
return { amount: 0, edge: null };
|
||||
}
|
||||
function autoScrollIfNeeded(groupElement, pointerPosition, axis, velocity) {
|
||||
if (!groupElement)
|
||||
return;
|
||||
// Track the group element for cleanup
|
||||
currentGroupElement = groupElement;
|
||||
const scrollableAncestor = findScrollableAncestor(groupElement, axis);
|
||||
if (!scrollableAncestor)
|
||||
return;
|
||||
// Convert pointer position from page coordinates to viewport coordinates.
|
||||
// The gesture system uses pageX/pageY but getBoundingClientRect() returns
|
||||
// viewport-relative coordinates, so we need to account for page scroll.
|
||||
const viewportPointerPosition = pointerPosition - (axis === "x" ? window.scrollX : window.scrollY);
|
||||
const { amount: scrollAmount, edge } = getScrollAmount(viewportPointerPosition, scrollableAncestor, axis);
|
||||
// If not in any threshold zone, clear all state
|
||||
if (edge === null) {
|
||||
activeScrollEdge.delete(scrollableAncestor);
|
||||
initialScrollLimits.delete(scrollableAncestor);
|
||||
return;
|
||||
}
|
||||
const currentActiveEdge = activeScrollEdge.get(scrollableAncestor);
|
||||
const isDocumentScroll = scrollableAncestor === document.body ||
|
||||
scrollableAncestor === document.documentElement;
|
||||
// If not currently scrolling this edge, check velocity to see if we should start
|
||||
if (currentActiveEdge !== edge) {
|
||||
// Only start scrolling if velocity is towards the edge
|
||||
const shouldStart = (edge === "start" && velocity < 0) ||
|
||||
(edge === "end" && velocity > 0);
|
||||
if (!shouldStart)
|
||||
return;
|
||||
// Activate this edge
|
||||
activeScrollEdge.set(scrollableAncestor, edge);
|
||||
// Record initial scroll limit (prevents infinite scroll)
|
||||
const maxScroll = axis === "x"
|
||||
? scrollableAncestor.scrollWidth - (isDocumentScroll ? window.innerWidth : scrollableAncestor.clientWidth)
|
||||
: scrollableAncestor.scrollHeight - (isDocumentScroll ? window.innerHeight : scrollableAncestor.clientHeight);
|
||||
initialScrollLimits.set(scrollableAncestor, maxScroll);
|
||||
}
|
||||
// Cap scrolling at initial limit (prevents infinite scroll)
|
||||
if (scrollAmount > 0) {
|
||||
const initialLimit = initialScrollLimits.get(scrollableAncestor);
|
||||
const currentScroll = axis === "x"
|
||||
? (isDocumentScroll ? window.scrollX : scrollableAncestor.scrollLeft)
|
||||
: (isDocumentScroll ? window.scrollY : scrollableAncestor.scrollTop);
|
||||
if (currentScroll >= initialLimit)
|
||||
return;
|
||||
}
|
||||
// Apply scroll
|
||||
if (axis === "x") {
|
||||
if (isDocumentScroll) {
|
||||
window.scrollBy({ left: scrollAmount });
|
||||
}
|
||||
else {
|
||||
scrollableAncestor.scrollLeft += scrollAmount;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isDocumentScroll) {
|
||||
window.scrollBy({ top: scrollAmount });
|
||||
}
|
||||
else {
|
||||
scrollableAncestor.scrollTop += scrollAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { autoScrollIfNeeded, resetAutoScrollState };
|
||||
//# sourceMappingURL=auto-scroll.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/Reorder/utils/auto-scroll.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/Reorder/utils/auto-scroll.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
25
node_modules/framer-motion/dist/es/components/Reorder/utils/check-reorder.mjs
generated
vendored
Normal file
25
node_modules/framer-motion/dist/es/components/Reorder/utils/check-reorder.mjs
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import { mixNumber } from 'motion-dom';
|
||||
import { moveItem } from 'motion-utils';
|
||||
|
||||
function checkReorder(order, value, offset, velocity) {
|
||||
if (!velocity)
|
||||
return order;
|
||||
const index = order.findIndex((item) => item.value === value);
|
||||
if (index === -1)
|
||||
return order;
|
||||
const nextOffset = velocity > 0 ? 1 : -1;
|
||||
const nextItem = order[index + nextOffset];
|
||||
if (!nextItem)
|
||||
return order;
|
||||
const item = order[index];
|
||||
const nextLayout = nextItem.layout;
|
||||
const nextItemCenter = mixNumber(nextLayout.min, nextLayout.max, 0.5);
|
||||
if ((nextOffset === 1 && item.layout.max + offset > nextItemCenter) ||
|
||||
(nextOffset === -1 && item.layout.min + offset < nextItemCenter)) {
|
||||
return moveItem(order, index, index + nextOffset);
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
export { checkReorder };
|
||||
//# sourceMappingURL=check-reorder.mjs.map
|
||||
1
node_modules/framer-motion/dist/es/components/Reorder/utils/check-reorder.mjs.map
generated
vendored
Normal file
1
node_modules/framer-motion/dist/es/components/Reorder/utils/check-reorder.mjs.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"check-reorder.mjs","sources":["../../../../../src/components/Reorder/utils/check-reorder.ts"],"sourcesContent":["import { mixNumber } from \"motion-dom\"\nimport { moveItem } from \"motion-utils\"\nimport { ItemData } from \"../types\"\n\nexport function checkReorder<T>(\n order: ItemData<T>[],\n value: T,\n offset: number,\n velocity: number\n): ItemData<T>[] {\n if (!velocity) return order\n\n const index = order.findIndex((item) => item.value === value)\n\n if (index === -1) return order\n\n const nextOffset = velocity > 0 ? 1 : -1\n const nextItem = order[index + nextOffset]\n\n if (!nextItem) return order\n\n const item = order[index]\n const nextLayout = nextItem.layout\n const nextItemCenter = mixNumber(nextLayout.min, nextLayout.max, 0.5)\n\n if (\n (nextOffset === 1 && item.layout.max + offset > nextItemCenter) ||\n (nextOffset === -1 && item.layout.min + offset < nextItemCenter)\n ) {\n return moveItem(order, index, index + nextOffset)\n }\n\n return order\n}\n"],"names":[],"mappings":";;;AAIM,SAAU,YAAY,CACxB,KAAoB,EACpB,KAAQ,EACR,MAAc,EACd,QAAgB,EAAA;AAEhB,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,KAAK;AAE3B,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;IAE7D,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,KAAK;AAE9B,IAAA,MAAM,UAAU,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE;IACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC;AAE1C,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,KAAK;AAE3B,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;AACzB,IAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM;AAClC,IAAA,MAAM,cAAc,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;AAErE,IAAA,IACI,CAAC,UAAU,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,GAAG,cAAc;AAC9D,SAAC,UAAU,KAAK,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,GAAG,cAAc,CAAC,EAClE;QACE,OAAO,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU,CAAC;IACrD;AAEA,IAAA,OAAO,KAAK;AAChB;;;;"}
|
||||
Reference in New Issue
Block a user