| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- "use client";
- import { jsx } from 'react/jsx-runtime';
- import { frame, microtask } from 'motion-dom';
- import { useContext, Component } from 'react';
- import { usePresence } from '../../../components/AnimatePresence/use-presence.mjs';
- import { LayoutGroupContext } from '../../../context/LayoutGroupContext.mjs';
- import { SwitchLayoutGroupContext } from '../../../context/SwitchLayoutGroupContext.mjs';
- import { globalProjectionState } from '../../../projection/node/state.mjs';
- import { correctBorderRadius } from '../../../projection/styles/scale-border-radius.mjs';
- import { correctBoxShadow } from '../../../projection/styles/scale-box-shadow.mjs';
- import { addScaleCorrector } from '../../../projection/styles/scale-correction.mjs';
- class MeasureLayoutWithContext extends Component {
- /**
- * This only mounts projection nodes for components that
- * need measuring, we might want to do it for all components
- * in order to incorporate transforms
- */
- componentDidMount() {
- const { visualElement, layoutGroup, switchLayoutGroup, layoutId } = this.props;
- const { projection } = visualElement;
- addScaleCorrector(defaultScaleCorrectors);
- if (projection) {
- if (layoutGroup.group)
- layoutGroup.group.add(projection);
- if (switchLayoutGroup && switchLayoutGroup.register && layoutId) {
- switchLayoutGroup.register(projection);
- }
- projection.root.didUpdate();
- projection.addEventListener("animationComplete", () => {
- this.safeToRemove();
- });
- projection.setOptions({
- ...projection.options,
- onExitComplete: () => this.safeToRemove(),
- });
- }
- globalProjectionState.hasEverUpdated = true;
- }
- getSnapshotBeforeUpdate(prevProps) {
- const { layoutDependency, visualElement, drag, isPresent } = this.props;
- const projection = visualElement.projection;
- if (!projection)
- return null;
- /**
- * TODO: We use this data in relegate to determine whether to
- * promote a previous element. There's no guarantee its presence data
- * will have updated by this point - if a bug like this arises it will
- * have to be that we markForRelegation and then find a new lead some other way,
- * perhaps in didUpdate
- */
- projection.isPresent = isPresent;
- if (drag ||
- prevProps.layoutDependency !== layoutDependency ||
- layoutDependency === undefined ||
- prevProps.isPresent !== isPresent) {
- projection.willUpdate();
- }
- else {
- this.safeToRemove();
- }
- if (prevProps.isPresent !== isPresent) {
- if (isPresent) {
- projection.promote();
- }
- else if (!projection.relegate()) {
- /**
- * If there's another stack member taking over from this one,
- * it's in charge of the exit animation and therefore should
- * be in charge of the safe to remove. Otherwise we call it here.
- */
- frame.postRender(() => {
- const stack = projection.getStack();
- if (!stack || !stack.members.length) {
- this.safeToRemove();
- }
- });
- }
- }
- return null;
- }
- componentDidUpdate() {
- const { projection } = this.props.visualElement;
- if (projection) {
- projection.root.didUpdate();
- microtask.postRender(() => {
- if (!projection.currentAnimation && projection.isLead()) {
- this.safeToRemove();
- }
- });
- }
- }
- componentWillUnmount() {
- const { visualElement, layoutGroup, switchLayoutGroup: promoteContext, } = this.props;
- const { projection } = visualElement;
- if (projection) {
- projection.scheduleCheckAfterUnmount();
- if (layoutGroup && layoutGroup.group)
- layoutGroup.group.remove(projection);
- if (promoteContext && promoteContext.deregister)
- promoteContext.deregister(projection);
- }
- }
- safeToRemove() {
- const { safeToRemove } = this.props;
- safeToRemove && safeToRemove();
- }
- render() {
- return null;
- }
- }
- function MeasureLayout(props) {
- const [isPresent, safeToRemove] = usePresence();
- const layoutGroup = useContext(LayoutGroupContext);
- return (jsx(MeasureLayoutWithContext, { ...props, layoutGroup: layoutGroup, switchLayoutGroup: useContext(SwitchLayoutGroupContext), isPresent: isPresent, safeToRemove: safeToRemove }));
- }
- const defaultScaleCorrectors = {
- borderRadius: {
- ...correctBorderRadius,
- applyTo: [
- "borderTopLeftRadius",
- "borderTopRightRadius",
- "borderBottomLeftRadius",
- "borderBottomRightRadius",
- ],
- },
- borderTopLeftRadius: correctBorderRadius,
- borderTopRightRadius: correctBorderRadius,
- borderBottomLeftRadius: correctBorderRadius,
- borderBottomRightRadius: correctBorderRadius,
- boxShadow: correctBoxShadow,
- };
- export { MeasureLayout };
|