Skip to content

Commit 9c1fa9c

Browse files
committed
Adds actions to components
Actions add additional functionality to elements within your component's template that may be difficult to add with other mechanisms. Examples of functionality which actions makes trivial to attach are: * tooltips * image lazy loaders * drag and drop functionality Actions can be added to an element with the `use` directive. ```html <img use:lazyload data-src="giant-photo.jpg> ``` Data may be passed to the action as an object literal (e.g. `use:b="{ setting: true }"`, a literal value (e.g. `use:b="'a string'"`), or a value or function from your component's state (e.g. `add:b="foo"` or `add:b="foo()"`). Actions are defined in a "actions" property on your component definition. ```html <script> export default { actions: { b(node, data) { // do something return { update(data) {}, destroy() {} } } } } </script> ``` A action is a function which receives a reference to an element and optionally the data if it is added in the HTML. This function can then attach listeners or alter the element as needed. The action can optionally return an object with the methods `update(data)` and `destroy()`. When data is added in the HTML and comes from state, the action's `update(data)` will be called if defined whenever the state is changed. When the element is removed from the DOM `destroy()` will be called if provided, allowing for cleanup of event listeners, etc. See sveltejs#469 for discussion around this feature and more examples of how it could be used.
1 parent b3fa965 commit 9c1fa9c

File tree

33 files changed

+1017
-132
lines changed

33 files changed

+1017
-132
lines changed

src/generators/Generator.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export default class Generator {
9191
components: Set<string>;
9292
events: Set<string>;
9393
transitions: Set<string>;
94+
actions: Set<string>;
9495
importedComponents: Map<string, string>;
9596
namespace: string;
9697
hasComponents: boolean;
@@ -134,6 +135,7 @@ export default class Generator {
134135
this.components = new Set();
135136
this.events = new Set();
136137
this.transitions = new Set();
138+
this.actions = new Set();
137139
this.importedComponents = new Map();
138140
this.slots = new Set();
139141

@@ -452,7 +454,7 @@ export default class Generator {
452454
templateProperties[getName(prop.key)] = prop;
453455
});
454456

455-
['helpers', 'events', 'components', 'transitions'].forEach(key => {
457+
['helpers', 'events', 'components', 'transitions', 'actions'].forEach(key => {
456458
if (templateProperties[key]) {
457459
templateProperties[key].value.properties.forEach((prop: Node) => {
458460
this[key].add(getName(prop.key));
@@ -636,6 +638,12 @@ export default class Generator {
636638
addDeclaration(getName(property.key), property.value, 'transitions');
637639
});
638640
}
641+
642+
if (templateProperties.actions) {
643+
templateProperties.actions.value.properties.forEach((property: Node) => {
644+
addDeclaration(getName(property.key), property.value, 'actions');
645+
});
646+
}
639647
}
640648

641649
if (indentationLevel) {
@@ -824,6 +832,16 @@ export default class Generator {
824832
this.skip();
825833
}
826834

835+
if (node.type === 'Action' && node.expression) {
836+
node.metadata = contextualise(node.expression, contextDependencies, indexes, false);
837+
if (node.expression.type === 'CallExpression') {
838+
node.expression.arguments.forEach((arg: Node) => {
839+
arg.metadata = contextualise(arg, contextDependencies, indexes, true);
840+
});
841+
}
842+
this.skip();
843+
}
844+
827845
if (node.type === 'Component' && node.name === ':Component') {
828846
node.metadata = contextualise(node.expression, contextDependencies, indexes, false);
829847
}

src/generators/nodes/Action.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Node from './shared/Node';
2+
3+
export default class Action extends Node {
4+
name: string;
5+
value: Node[]
6+
expression: Node
7+
}

0 commit comments

Comments
 (0)