Fix two issues with Transitions

* TransitionChild's initial state was wrong with unmount=false
* entered classes were not being removed correctly at the start of a transition
This commit is contained in:
Ryan Gossiaux
2021-12-22 11:59:18 -08:00
parent d21287eace
commit 96b165acc0
3 changed files with 30 additions and 11 deletions

View File

@@ -40,16 +40,19 @@
const dispatch = createEventDispatcher();
let container: HTMLElement | null = null;
let state = TreeStates.Visible;
let transitionContext = useTransitionContext();
let nestingContext = useParentNesting();
let state =
$transitionContext.initialShow || $$props.unmount !== false
? TreeStates.Visible
: TreeStates.Hidden;
let initial = true;
let id = useId();
let isTransitioning = false;
$: strategy =
$$props.unmount === false ? RenderStrategy.Hidden : RenderStrategy.Unmount;
let nesting: Writable<NestingContextValues> = writable(
useNesting(() => {
@@ -68,7 +71,7 @@
$: {
(() => {
// If we are in another mode than the Hidden mode then ignore
/* if (strategy.value !== RenderStrategy.Hidden) return */
if (strategy !== RenderStrategy.Hidden) return;
if (!id) return;
// Make sure that we are visible
@@ -90,13 +93,15 @@
.filter((className) => className.trim().length > 1);
}
let enterClasses = splitClasses(enter);
let enterFromClasses = splitClasses(enterFrom);
let enterToClasses = splitClasses(enterTo);
$: enterClasses = splitClasses(enter);
$: enterFromClasses = splitClasses(enterFrom);
$: enterToClasses = splitClasses(enterTo);
let leaveClasses = splitClasses(leave);
let leaveFromClasses = splitClasses(leaveFrom);
let leaveToClasses = splitClasses(leaveTo);
$: enteredClasses = splitClasses(entered);
$: leaveClasses = splitClasses(leave);
$: leaveFromClasses = splitClasses(leaveFrom);
$: leaveToClasses = splitClasses(leaveTo);
let mounted = false;
onMount(() => (mounted = true));
@@ -120,6 +125,7 @@
enterClasses,
enterFromClasses,
enterToClasses,
enteredClasses,
(reason) => {
isTransitioning = false;
if (reason === Reason.Finished) dispatch("afterEnter");
@@ -130,6 +136,7 @@
leaveClasses,
leaveFromClasses,
leaveToClasses,
enteredClasses,
(reason) => {
isTransitioning = false;

View File

@@ -15,6 +15,12 @@
interface TransitionContextValues {
show: boolean;
appear: boolean;
// This is not part of base Headless UI, but we need it because TransitionRoot does not render.
// In base Headless UI, for a component with unmount=false, the initial state for the Child is
// still "visible". It still works, because the parent still is hidden and has display: none
// In our version the parent renders nothing, so we need to send down the correct initial state
// ourselves.
initialShow: boolean;
}
const TRANSITION_CONTEXT_NAME = "headlessui-transition-context";
@@ -148,6 +154,9 @@
show,
openClosedState !== undefined ? $openClosedState : undefined
);
let initialShow = shouldShow;
$: {
shouldShow = computeShow(
show,
@@ -172,6 +181,7 @@
$: transitionBag.set({
show: !!shouldShow,
appear: appear || !initial,
initialShow: !!initialShow,
});
onMount(() => {

View File

@@ -62,12 +62,13 @@ export function transition(
base: string[],
from: string[],
to: string[],
entered: string[],
done?: (reason: Reason) => void
) {
let d = disposables();
let _done = done !== undefined ? once(done) : () => { };
removeClasses(node);
removeClasses(node, ...entered);
addClasses(node, ...base, ...from);
d.nextFrame(() => {
@@ -77,6 +78,7 @@ export function transition(
d.add(
waitForTransition(node, (reason) => {
removeClasses(node, ...to, ...base);
addClasses(node, ...entered);
return _done(reason);
})
);