Comments (2)
my hotfix is
import { createSignal, createComputed, createEffect, mergeProps, Component, children } from 'solid-js';
type BoundingRect = {
top: number;
bottom: number;
left: number;
right: number;
width: number;
height: number;
};
type ElementInfo = {
pos: BoundingRect;
newPos?: BoundingRect;
new?: boolean;
moved?: boolean;
};
function getRect(element: Element): BoundingRect {
const { top, bottom, left, right, width, height } = element.getBoundingClientRect();
const parentRect = (element.parentNode! as Element).getBoundingClientRect();
return {
top: top - parentRect.top,
bottom,
left: left - parentRect.left,
right,
width,
height,
};
}
type TransitionGroupProps = {
name?: string;
enterActiveClass?: string;
enterClass?: string;
enterToClass?: string;
exitActiveClass?: string;
exitClass?: string;
exitToClass?: string;
moveClass?: string;
onBeforeEnter?: (el: Element) => void;
onEnter?: (el: Element, done: () => void) => void;
onAfterEnter?: (el: Element) => void;
onBeforeExit?: (el: Element) => void;
onExit?: (el: Element, done: () => void) => void;
onAfterExit?: (el: Element) => void;
children?: any;
};
export const TransitionGroup: Component<TransitionGroupProps> = (props) => {
const resolved = children(() => props.children);
const name = props.name || 's';
props = mergeProps(
{
name,
enterActiveClass: name + '-enter-active',
enterClass: name + '-enter',
enterToClass: name + '-enter-to',
exitActiveClass: name + '-exit-active',
exitClass: name + '-exit',
exitToClass: name + '-exit-to',
moveClass: name + '-move',
},
props
);
const { onBeforeEnter, onEnter, onAfterEnter, onBeforeExit, onExit, onAfterExit } = props;
const [combined, setCombined] = createSignal<Element[]>();
let p: Element[] = [];
let first = true;
createComputed(() => {
const c = resolved() as Element[];
const comb = [...c];
const next = new Set(c);
const prev = new Set(p);
const enterClasses = props.enterClass!.split(' ');
const enterActiveClasses = props.enterActiveClass!.split(' ');
const enterToClasses = props.enterToClass!.split(' ');
const exitClasses = props.exitClass!.split(' ');
const exitActiveClasses = props.exitActiveClass!.split(' ');
const exitToClasses = props.exitToClass!.split(' ');
for (let i = 0; i < c.length; i++) {
const el = c[i];
if (!first && !prev.has(el)) {
onBeforeEnter && onBeforeEnter(el);
el.classList.add(...enterClasses);
el.classList.add(...enterActiveClasses);
setTimeout(() => {
el.classList.remove(...enterClasses);
el.classList.add(...enterToClasses);
onEnter && onEnter(el, endTransition);
if (!onEnter || onEnter.length < 2) {
el.addEventListener('transitionend', handleEndTransition);
el.addEventListener('animationend', handleEndTransition);
}
}, 0);
const endTransition = () => {
if (el) {
el.classList.remove(...enterActiveClasses);
el.classList.remove(...enterToClasses);
onAfterEnter && onAfterEnter(el);
}
};
const handleEndTransition = (e: Event) => {
if (el && el === e.target) {
el.removeEventListener('transitionend', handleEndTransition);
el.removeEventListener('animationend', handleEndTransition);
el.classList.remove(...enterActiveClasses);
el.classList.remove(...enterToClasses);
onAfterEnter && onAfterEnter(el);
}
};
}
}
for (let i = 0; i < p.length; i++) {
const old = p[i];
if (!next.has(old) && old.parentNode) {
comb.splice(i, 0, old);
onBeforeExit && onBeforeExit(old);
old.classList.add(...exitClasses);
old.classList.add(...exitActiveClasses);
setTimeout(() => {
old.classList.remove(...exitClasses);
old.classList.add(...exitToClasses);
}, 0);
const endTransition = () => {
old.classList.remove(...exitActiveClasses);
old.classList.remove(...exitToClasses);
onAfterExit && onAfterExit(old);
p = p.filter((i) => i !== old);
setCombined(p);
};
const handleEndTransition = (e: Event) => {
if (old === e.target) {
old.removeEventListener('transitionend', handleEndTransition);
old.removeEventListener('animationend', handleEndTransition);
old.classList.remove(...exitActiveClasses);
old.classList.remove(...exitToClasses);
onAfterExit && onAfterExit(old);
p = p.filter((i) => i !== old);
setCombined(p);
}
};
onExit && onExit(old, endTransition);
if (!onExit || onExit.length < 2) {
old.addEventListener('transitionend', handleEndTransition);
old.addEventListener('animationend', handleEndTransition);
}
}
}
p = comb;
setCombined(comb);
});
createEffect<Map<Element, ElementInfo>>((nodes) => {
const c = combined()!;
c.forEach((child) => {
let n: ElementInfo | undefined;
if (!(n = nodes!.get(child))) {
nodes!.set(child, (n = { pos: getRect(child), new: !first }));
} else if (n.new) {
n.new = false;
n.newPos = getRect(child);
}
if (n.new) {
child.addEventListener(
'transitionend',
() => {
n!.new = false;
child.parentNode && (n!.newPos = getRect(child));
},
{ once: true }
);
}
n.newPos && (n.pos = n.newPos);
n.newPos = getRect(child);
});
if (first) {
first = false;
return nodes!;
}
c.forEach((child) => {
const c = nodes!.get(child)!;
const oldPos = c.pos;
const newPos = c.newPos!;
const dx = oldPos.left - newPos.left;
const dy = oldPos.top - newPos.top;
if (dx || dy) {
c.moved = true;
const s = (child as HTMLElement | SVGElement).style;
s.transform = `translate(${dx}px,${dy}px)`;
s.transitionDuration = '0s';
}
});
document.body.offsetHeight;
c.forEach((child) => {
const c = nodes!.get(child)!;
if (c.moved) {
c.moved = false;
const s = (child as HTMLElement | SVGElement).style;
const moveClasses = props.moveClass!.split(' ');
child.classList.add(...moveClasses);
s.transform = s.transitionDuration = '';
function endTransition(e: TransitionEvent) {
if ((e && e.target !== child) || !child.parentNode) return;
if (!e || /transform$/.test(e.propertyName)) {
(child as HTMLElement | SVGElement).removeEventListener('transitionend', endTransition as EventListener);
child.classList.remove(...moveClasses);
}
}
(child as HTMLElement | SVGElement).addEventListener('transitionend', endTransition as EventListener);
}
});
return nodes!;
}, new Map());
return combined;
};
from solid-transition-group.
Hey, could you provide some more info on the issue, like an example that would allow me to reproduce the issue?
Couple of things could change in those two years so maybe it's not an issue anymore 🙃
from solid-transition-group.
Related Issues (20)
- Simultaneously transitioning mismatching current element and previously
- String classes props ignored HOT 4
- feature request: better documentation HOT 2
- bug: TransitionGroup assumes that at least two children will be present
- TransitionGroup does not remove DOM elements HOT 2
- Using @solidjs/router lazy components with mode="outin" HOT 1
- Basic issue: trying the first example HOT 1
- How to use with <Outlet /> HOT 1
- `ReferenceError: Element is not defined`: SSR breaks when using `solid-transition-group` on cloudflare workers HOT 7
- onMount called before elements are connected in outin mode HOT 3
- Transition not working HOT 2
- Clarification on show() HOT 2
- Passing a class to the adhoc container element HOT 4
- TransitionGroup animates keyed shows before Suspense-Transition is done HOT 1
- solid start routes are duplicated
- is this maintained? HOT 2
- How to work with `<Dynamic>` HOT 2
- Loss of styles on exit transition when used with @suid HOT 1
- Add TransitionChild/Root components
- CSR navigation fails to load props.children in solid start
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from solid-transition-group.