[feat] Add options w/ direction to transitions (#8068)

pull/8087/head
Pat Cavit 2 years ago committed by GitHub
parent 14f33cfe61
commit 84d61c61f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -971,7 +971,7 @@ transition:fn|local={params}
```js
transition = (node: HTMLElement, params: any) => {
transition = (node: HTMLElement, params: any, options: { direction: 'in' | 'out' | 'both' }) => {
delay?: number,
duration?: number,
easing?: (t: number) => number,
@ -1091,6 +1091,11 @@ A custom transition function can also return a `tick` function, which is called
If a transition returns a function instead of a transition object, the function will be called in the next microtask. This allows multiple transitions to coordinate, making [crossfade effects](/tutorial/deferred-transitions) possible.
Transition functions also receive a third argument, `options`, which contains information about the transition.
Available values in the `options` object are:
* `direction` - one of `in`, `out`, or `bidirectional` depending on the type of transition
##### Transition events

@ -86,10 +86,12 @@ export function transition_out(block: Fragment, local: 0 | 1, detach?: 0 | 1, ca
const null_transition: TransitionConfig = { duration: 0 };
type TransitionFn = (node: Element, params: any) => TransitionConfig;
type TransitionOptions = { direction: 'in' | 'out' | 'both' };
type TransitionFn = (node: Element, params: any, options: TransitionOptions) => TransitionConfig;
export function create_in_transition(node: Element & ElementCSSInlineStyle, fn: TransitionFn, params: any) {
let config = fn(node, params);
const options: TransitionOptions = { direction: 'in' };
let config = fn(node, params, options);
let running = false;
let animation_name;
let task;
@ -150,7 +152,7 @@ export function create_in_transition(node: Element & ElementCSSInlineStyle, fn:
delete_rule(node);
if (is_function(config)) {
config = config();
config = config(options);
wait().then(go);
} else {
go();
@ -171,7 +173,8 @@ export function create_in_transition(node: Element & ElementCSSInlineStyle, fn:
}
export function create_out_transition(node: Element & ElementCSSInlineStyle, fn: TransitionFn, params: any) {
let config = fn(node, params);
const options: TransitionOptions = { direction: 'out' };
let config = fn(node, params, options);
let running = true;
let animation_name;
@ -224,7 +227,7 @@ export function create_out_transition(node: Element & ElementCSSInlineStyle, fn:
if (is_function(config)) {
wait().then(() => {
// @ts-ignore
config = config();
config = config(options);
go();
});
} else {
@ -264,7 +267,8 @@ interface Program {
}
export function create_bidirectional_transition(node: Element & ElementCSSInlineStyle, fn: TransitionFn, params: any, intro: boolean) {
let config = fn(node, params);
const options: TransitionOptions = { direction: 'both' };
let config = fn(node, params, options);
let t = intro ? 0 : 1;
@ -373,7 +377,7 @@ export function create_bidirectional_transition(node: Element & ElementCSSInline
if (is_function(config)) {
wait().then(() => {
// @ts-ignore
config = config();
config = config(options);
go(b);
});
} else {

@ -0,0 +1,19 @@
export default {
test({ assert, component, target }) {
component.visible = true;
const div_in = target.querySelector('#in');
const div_out = target.querySelector('#out');
const div_both = target.querySelector('#both');
assert.equal(div_in.initial, 'in');
assert.equal(div_out.initial, 'out');
assert.equal(div_both.initial, 'both');
return Promise.resolve().then(() => {
assert.equal(div_in.later, 'in');
assert.equal(div_out.later, 'out');
assert.equal(div_both.later, 'both');
});
}
};

@ -0,0 +1,24 @@
<script>
export let visible;
function foo(node, _params, options) {
node.initial = options.direction;
return (opts) => {
node.later = opts.direction;
return {
duration: 10
};
};
}
</script>
{#if visible}
<div id="both" transition:foo></div>
<div id="in" in:foo></div>
{/if}
{#if !visible}
<div id="out" out:foo></div>
{/if}

@ -0,0 +1,13 @@
export default {
test({ assert, component, target }) {
component.visible = true;
const div_in = target.querySelector('#in');
const div_out = target.querySelector('#out');
const div_both = target.querySelector('#both');
assert.equal(div_in.direction, 'in');
assert.equal(div_out.direction, 'out');
assert.equal(div_both.direction, 'both');
}
};

@ -0,0 +1,20 @@
<script>
export let visible = false;
function foo(node, _params, options) {
node.direction = options.direction;
return {
duration: 10
};
}
</script>
{#if visible}
<div id="both" transition:foo></div>
<div id="in" in:foo></div>
{/if}
{#if !visible}
<div id="out" out:foo></div>
{/if}
Loading…
Cancel
Save