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:
@@ -40,16 +40,19 @@
|
|||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
let container: HTMLElement | null = null;
|
let container: HTMLElement | null = null;
|
||||||
let state = TreeStates.Visible;
|
|
||||||
|
|
||||||
let transitionContext = useTransitionContext();
|
let transitionContext = useTransitionContext();
|
||||||
let nestingContext = useParentNesting();
|
let nestingContext = useParentNesting();
|
||||||
|
let state =
|
||||||
|
$transitionContext.initialShow || $$props.unmount !== false
|
||||||
|
? TreeStates.Visible
|
||||||
|
: TreeStates.Hidden;
|
||||||
|
|
||||||
let initial = true;
|
let initial = true;
|
||||||
|
|
||||||
let id = useId();
|
let id = useId();
|
||||||
|
|
||||||
let isTransitioning = false;
|
let isTransitioning = false;
|
||||||
|
$: strategy =
|
||||||
|
$$props.unmount === false ? RenderStrategy.Hidden : RenderStrategy.Unmount;
|
||||||
|
|
||||||
let nesting: Writable<NestingContextValues> = writable(
|
let nesting: Writable<NestingContextValues> = writable(
|
||||||
useNesting(() => {
|
useNesting(() => {
|
||||||
@@ -68,7 +71,7 @@
|
|||||||
$: {
|
$: {
|
||||||
(() => {
|
(() => {
|
||||||
// If we are in another mode than the Hidden mode then ignore
|
// 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;
|
if (!id) return;
|
||||||
|
|
||||||
// Make sure that we are visible
|
// Make sure that we are visible
|
||||||
@@ -90,13 +93,15 @@
|
|||||||
.filter((className) => className.trim().length > 1);
|
.filter((className) => className.trim().length > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let enterClasses = splitClasses(enter);
|
$: enterClasses = splitClasses(enter);
|
||||||
let enterFromClasses = splitClasses(enterFrom);
|
$: enterFromClasses = splitClasses(enterFrom);
|
||||||
let enterToClasses = splitClasses(enterTo);
|
$: enterToClasses = splitClasses(enterTo);
|
||||||
|
|
||||||
let leaveClasses = splitClasses(leave);
|
$: enteredClasses = splitClasses(entered);
|
||||||
let leaveFromClasses = splitClasses(leaveFrom);
|
|
||||||
let leaveToClasses = splitClasses(leaveTo);
|
$: leaveClasses = splitClasses(leave);
|
||||||
|
$: leaveFromClasses = splitClasses(leaveFrom);
|
||||||
|
$: leaveToClasses = splitClasses(leaveTo);
|
||||||
|
|
||||||
let mounted = false;
|
let mounted = false;
|
||||||
onMount(() => (mounted = true));
|
onMount(() => (mounted = true));
|
||||||
@@ -120,6 +125,7 @@
|
|||||||
enterClasses,
|
enterClasses,
|
||||||
enterFromClasses,
|
enterFromClasses,
|
||||||
enterToClasses,
|
enterToClasses,
|
||||||
|
enteredClasses,
|
||||||
(reason) => {
|
(reason) => {
|
||||||
isTransitioning = false;
|
isTransitioning = false;
|
||||||
if (reason === Reason.Finished) dispatch("afterEnter");
|
if (reason === Reason.Finished) dispatch("afterEnter");
|
||||||
@@ -130,6 +136,7 @@
|
|||||||
leaveClasses,
|
leaveClasses,
|
||||||
leaveFromClasses,
|
leaveFromClasses,
|
||||||
leaveToClasses,
|
leaveToClasses,
|
||||||
|
enteredClasses,
|
||||||
(reason) => {
|
(reason) => {
|
||||||
isTransitioning = false;
|
isTransitioning = false;
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,12 @@
|
|||||||
interface TransitionContextValues {
|
interface TransitionContextValues {
|
||||||
show: boolean;
|
show: boolean;
|
||||||
appear: 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";
|
const TRANSITION_CONTEXT_NAME = "headlessui-transition-context";
|
||||||
@@ -148,6 +154,9 @@
|
|||||||
show,
|
show,
|
||||||
openClosedState !== undefined ? $openClosedState : undefined
|
openClosedState !== undefined ? $openClosedState : undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let initialShow = shouldShow;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
shouldShow = computeShow(
|
shouldShow = computeShow(
|
||||||
show,
|
show,
|
||||||
@@ -172,6 +181,7 @@
|
|||||||
$: transitionBag.set({
|
$: transitionBag.set({
|
||||||
show: !!shouldShow,
|
show: !!shouldShow,
|
||||||
appear: appear || !initial,
|
appear: appear || !initial,
|
||||||
|
initialShow: !!initialShow,
|
||||||
});
|
});
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
|||||||
@@ -62,12 +62,13 @@ export function transition(
|
|||||||
base: string[],
|
base: string[],
|
||||||
from: string[],
|
from: string[],
|
||||||
to: string[],
|
to: string[],
|
||||||
|
entered: string[],
|
||||||
done?: (reason: Reason) => void
|
done?: (reason: Reason) => void
|
||||||
) {
|
) {
|
||||||
let d = disposables();
|
let d = disposables();
|
||||||
let _done = done !== undefined ? once(done) : () => { };
|
let _done = done !== undefined ? once(done) : () => { };
|
||||||
|
|
||||||
removeClasses(node);
|
removeClasses(node, ...entered);
|
||||||
addClasses(node, ...base, ...from);
|
addClasses(node, ...base, ...from);
|
||||||
|
|
||||||
d.nextFrame(() => {
|
d.nextFrame(() => {
|
||||||
@@ -77,6 +78,7 @@ export function transition(
|
|||||||
d.add(
|
d.add(
|
||||||
waitForTransition(node, (reason) => {
|
waitForTransition(node, (reason) => {
|
||||||
removeClasses(node, ...to, ...base);
|
removeClasses(node, ...to, ...base);
|
||||||
|
addClasses(node, ...entered);
|
||||||
return _done(reason);
|
return _done(reason);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user