Skip to content

Commit 3d37735

Browse files
committed
feat: Add options w/ direction to transitions
Closes sveltejs#3918 and supersedes sveltejs#4019 (extremely similar change, mostly just adds tests/docs)
1 parent 91f8764 commit 3d37735

File tree

6 files changed

+99
-8
lines changed

6 files changed

+99
-8
lines changed

site/content/docs/03-template-syntax.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ transition:fn|local={params}
971971

972972

973973
```js
974-
transition = (node: HTMLElement, params: any) => {
974+
transition = (node: HTMLElement, params: any, options: { direction: 'in' | 'out' | 'both' }) => {
975975
delay?: number,
976976
duration?: number,
977977
easing?: (t: number) => number,
@@ -1014,6 +1014,16 @@ Like actions, transitions can have parameters.
10141014
{/if}
10151015
```
10161016

1017+
##### Transition options
1018+
1019+
---
1020+
1021+
Transitions also get passed an options object which provides data about the type of transition.
1022+
1023+
Possible values in the options object are:
1024+
1025+
* `direction` - one of `in`, `out`, or `both` depending on the type of transition
1026+
10171027
##### Custom transition functions
10181028

10191029
---

src/runtime/internal/transitions.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,12 @@ export function transition_out(block: Fragment, local: 0 | 1, detach?: 0 | 1, ca
8686

8787
const null_transition: TransitionConfig = { duration: 0 };
8888

89-
type TransitionFn = (node: Element, params: any) => TransitionConfig;
89+
type TransitionOptions = { direction: 'in' | 'out' | 'both' };
90+
type TransitionFn = (node: Element, params: any, options: TransitionOptions) => TransitionConfig;
9091

9192
export function create_in_transition(node: Element & ElementCSSInlineStyle, fn: TransitionFn, params: any) {
92-
let config = fn(node, params);
93+
const options: TransitionOptions = { direction: 'in' };
94+
let config = fn(node, params, options);
9395
let running = false;
9496
let animation_name;
9597
let task;
@@ -150,7 +152,7 @@ export function create_in_transition(node: Element & ElementCSSInlineStyle, fn:
150152
delete_rule(node);
151153

152154
if (is_function(config)) {
153-
config = config();
155+
config = config(options);
154156
wait().then(go);
155157
} else {
156158
go();
@@ -171,7 +173,8 @@ export function create_in_transition(node: Element & ElementCSSInlineStyle, fn:
171173
}
172174

173175
export function create_out_transition(node: Element & ElementCSSInlineStyle, fn: TransitionFn, params: any) {
174-
let config = fn(node, params);
176+
const options: TransitionOptions = { direction: 'out' };
177+
let config = fn(node, params, options);
175178
let running = true;
176179
let animation_name;
177180

@@ -224,7 +227,7 @@ export function create_out_transition(node: Element & ElementCSSInlineStyle, fn:
224227
if (is_function(config)) {
225228
wait().then(() => {
226229
// @ts-ignore
227-
config = config();
230+
config = config(options);
228231
go();
229232
});
230233
} else {
@@ -264,7 +267,8 @@ interface Program {
264267
}
265268

266269
export function create_bidirectional_transition(node: Element & ElementCSSInlineStyle, fn: TransitionFn, params: any, intro: boolean) {
267-
let config = fn(node, params);
270+
const options: TransitionOptions = { direction: 'both' };
271+
let config = fn(node, params, options);
268272

269273
let t = intro ? 0 : 1;
270274

@@ -373,7 +377,7 @@ export function create_bidirectional_transition(node: Element & ElementCSSInline
373377
if (is_function(config)) {
374378
wait().then(() => {
375379
// @ts-ignore
376-
config = config();
380+
config = config(options);
377381
go(b);
378382
});
379383
} else {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export default {
2+
test({ assert, component, target, raf }) {
3+
component.visible = true;
4+
5+
const divIn = target.querySelector('#in');
6+
const divOut = target.querySelector('#out');
7+
const divBoth = target.querySelector('#both');
8+
9+
assert.equal(divIn.initial, 'in');
10+
assert.equal(divOut.initial, 'out');
11+
assert.equal(divBoth.initial, 'both');
12+
13+
return Promise.resolve().then(() => {
14+
assert.equal(divIn.later, 'in');
15+
assert.equal(divOut.later, 'out');
16+
assert.equal(divBoth.later, 'both');
17+
});
18+
}
19+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script>
2+
export let visible;
3+
4+
function foo(node, params, options) {
5+
node.initial = options.direction
6+
7+
return (opts) => {
8+
node.later = opts.direction;
9+
10+
return {
11+
duration: 10,
12+
};
13+
};
14+
}
15+
</script>
16+
17+
{#if visible}
18+
<div id="both" transition:foo></div>
19+
<div id="in" in:foo></div>
20+
{/if}
21+
22+
{#if !visible}
23+
<div id="out" out:foo></div>
24+
{/if}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default {
2+
test({ assert, component, target }) {
3+
component.visible = true;
4+
5+
const divIn = target.querySelector('#in');
6+
const divOut = target.querySelector('#out');
7+
const divBoth = target.querySelector('#both');
8+
9+
assert.equal(divIn.direction, 'in');
10+
assert.equal(divOut.direction, 'out');
11+
assert.equal(divBoth.direction, 'both');
12+
}
13+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script>
2+
export let visible = false;
3+
4+
function foo(node, params, options) {
5+
console.log("options", options);
6+
node.direction = options.direction
7+
8+
return {
9+
duration: 10,
10+
};
11+
}
12+
</script>
13+
14+
{#if visible}
15+
<div id="both" transition:foo></div>
16+
<div id="in" in:foo></div>
17+
{/if}
18+
19+
{#if !visible}
20+
<div id="out" out:foo></div>
21+
{/if}

0 commit comments

Comments
 (0)