@agnos-ui/core
Version:
Framework-agnostic headless component library.
176 lines (175 loc) • 6.69 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const tansu = require("@amadeus-it-group/tansu");
const utils_writables = require("../../writables-Bn3uhKEG.cjs");
const promise = require("../../promise-CxCD3NYv.cjs");
const utils_func = require("../../utils/func.cjs");
const utils_stores = require("../../utils/stores.cjs");
const utils_directive = require("../../dom-CuBx1JPZ.cjs");
const neverEndingPromise = new Promise(utils_func.noop);
const noAnimation = (element, direction) => {
element.style.display = direction === "show" ? "" : "none";
};
const defaultValues = {
animated: true,
animatedOnInit: false,
initDone: null,
visible: true,
transition: noAnimation,
onShown: utils_func.noop,
onHidden: utils_func.noop,
onVisibleChange: utils_func.noop
};
const configValidator = {
animated: utils_writables.typeBoolean,
animatedOnInit: utils_writables.typeBoolean,
visible: utils_writables.typeBoolean,
transition: utils_writables.typeFunction,
onShown: utils_writables.typeFunction,
onHidden: utils_writables.typeFunction,
onVisibleChange: utils_writables.typeFunction,
initDone: utils_writables.typeBooleanOrNull
};
const createTransition = (config) => {
const [{ animated$, initDone$, visible$: requestedVisible$, transition$, onShown$, onHidden$, onVisibleChange$, animatedOnInit$ }, patch] = utils_stores.writablesForProps(defaultValues, config, configValidator);
const { element$, directive: storeDirective } = utils_directive.createStoreDirective();
const elementPresent$ = tansu.computed(() => !!element$());
const visible$ = utils_stores.bindableDerived(onVisibleChange$, [requestedVisible$], ([visible]) => visible);
const currentTransition$ = tansu.writable(
null
);
const stop = () => {
let context;
currentTransition$.update((currentTransition) => {
currentTransition == null ? void 0 : currentTransition.abort.abort();
context = currentTransition == null ? void 0 : currentTransition.context;
return null;
});
return context;
};
const runTransition = (visible, animated, element, transitionFn) => tansu.batch(() => {
const abort = new AbortController();
const signal = abort.signal;
const context = stop() ?? {};
const { promise: promise$1, resolve } = promise.promiseWithResolve();
const currentTransition = {
abort,
animated,
visible,
context,
element,
transitionFn,
promise: promise$1
};
currentTransition$.set(currentTransition);
resolve(
(async () => {
var _a;
try {
await transitionFn(element, visible ? "show" : "hide", animated, signal, context);
} finally {
if (signal.aborted) {
await neverEndingPromise;
} else {
currentTransition$.set(null);
(_a = (visible ? onShown$ : onHidden$)()) == null ? void 0 : _a();
}
}
})()
);
return currentTransition;
});
const effectiveAnimation$ = tansu.computed(() => initDone$() ? animated$() : animatedOnInit$());
const animationFromToggle$ = tansu.writable(null);
let previousElement;
let previousVisible = requestedVisible$();
let pendingTransition = null;
const visibleAction$ = tansu.derived(
[visible$, element$, effectiveAnimation$, animationFromToggle$, transition$, currentTransition$],
([visible, element, animated, animationFromToggle, transition, currentTransition]) => {
const elementChanged = previousElement !== element;
previousElement = element;
const visibleChanged = previousVisible !== visible;
previousVisible = visible;
if (element) {
if (initDone$() == null) {
initDone$.set(true);
}
const interruptAnimation = animationFromToggle != null && currentTransition && currentTransition.animated != animationFromToggle;
if (elementChanged || visibleChanged || interruptAnimation) {
if (visibleChanged || animationFromToggle != null) {
pendingTransition = null;
}
const animate = animationFromToggle ?? (pendingTransition == null ? void 0 : pendingTransition.animated) ?? (elementChanged && !visible ? false : animated);
currentTransition = runTransition(visible, animate, element, transition);
pendingTransition == null ? void 0 : pendingTransition.resolve(currentTransition.promise);
pendingTransition = null;
}
} else {
if (elementChanged) {
stop();
currentTransition = null;
}
if (visibleChanged || visible && (pendingTransition == null ? void 0 : pendingTransition.animated) !== animationFromToggle) {
pendingTransition = visible && animationFromToggle != null ? {
// toggle was called to display the element, but the element is not yet in the DOM
// let's keep the animation setting from toggle and provide the promise for the end of toggle
animated: animationFromToggle,
...promise.promiseWithResolve()
} : null;
}
}
return (pendingTransition == null ? void 0 : pendingTransition.promise) ?? (currentTransition == null ? void 0 : currentTransition.promise);
}
);
let lastToggle = {};
const toggle = async (visible = !requestedVisible$(), animated = effectiveAnimation$()) => {
const currentToggle = {};
lastToggle = currentToggle;
try {
await tansu.batch(() => {
try {
animationFromToggle$.set(animated);
requestedVisible$.set(visible);
return visibleAction$();
} finally {
animationFromToggle$.set(null);
}
});
} finally {
if (lastToggle !== currentToggle) {
await neverEndingPromise;
}
}
};
const transitioning$ = tansu.computed(() => {
if (elementPresent$()) {
void visibleAction$();
}
return !!currentTransition$();
});
const shown$ = tansu.computed(() => !transitioning$() && visible$() && elementPresent$());
const hidden$ = tansu.computed(() => !transitioning$() && !visible$());
const directive = utils_directive.mergeDirectives(storeDirective, utils_directive.directiveSubscribe(visibleAction$));
return {
...utils_stores.stateStores({
visible$,
element$,
elementPresent$,
transitioning$,
shown$,
hidden$
}),
patch,
directives: {
directive
},
api: {
show: toggle.bind(null, true),
hide: toggle.bind(null, false),
toggle
}
};
};
exports.createTransition = createTransition;
exports.noAnimation = noAnimation;