diff --git a/.gitignore b/.gitignore
index ee1daa2c03..22389f683c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ node_modules
/compiler.*js
/index.*js
/ssr.*js
+/action
/internal
/store
/easing
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1dd186cfcb..5df6ab56f3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Svelte changelog
+## Unreleased
+
+- Add `aria-description` to the list of allowed ARIA attributes ([#7301](https://github.com/sveltejs/svelte/issues/7301))
+- Add TypeScript interfaces for typing actions ([#6538](https://github.com/sveltejs/svelte/issues/6538))
+
## 3.46.4
* Avoid `maximum call stack size exceeded` errors on large components ([#4694](https://github.com/sveltejs/svelte/issues/4694))
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 17141d71bd..48aa238f89 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,7 +15,7 @@ There are many ways to contribute to Svelte, and many of them do not involve wri
- Look through the [open issues](https://github.com/sveltejs/svelte/issues). A good starting point would be issues tagged [good first issue](https://github.com/sveltejs/svelte/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). Provide workarounds, ask for clarification, or suggest labels. Help [triage issues](#triaging-issues-and-pull-requests).
- If you find an issue you would like to fix, [open a pull request](#your-first-pull-request).
- Read through our [tutorials](https://svelte.dev/tutorial/basics). If you find anything that is confusing or can be improved, you can make edits by clicking "Edit this chapter" at the bottom left of the tutorial page.
-- Take a look at the [features requested](https://github.com/sveltejs/svelte/labels/enhancement) by others in the community and consider opening a pull request if you see something you want to work on.
+- Take a look at the [features requested](https://github.com/sveltejs/svelte/labels/feature%20request) by others in the community and consider opening a pull request if you see something you want to work on.
Contributions are very welcome. If you think you need help planning your contribution, please ping us on Discord at [svelte.dev/chat](https://svelte.dev/chat) and let us know you are looking for a bit of help.
diff --git a/package.json b/package.json
index 2ca79c5fa8..c58f999bd3 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,9 @@
"import": "./compiler.mjs",
"require": "./compiler.js"
},
+ "./action": {
+ "types": "./types/runtime/action/index.d.ts"
+ },
"./animate": {
"types": "./types/runtime/animate/index.d.ts",
"import": "./animate/index.mjs",
diff --git a/site/content/examples/13-actions/00-actions/App.svelte b/site/content/examples/13-actions/00-actions/App.svelte
index bd990a5360..79214ec81f 100644
--- a/site/content/examples/13-actions/00-actions/App.svelte
+++ b/site/content/examples/13-actions/00-actions/App.svelte
@@ -20,6 +20,9 @@
height: var(--height);
left: calc(50% - var(--width) / 2);
top: calc(50% - var(--height) / 2);
+ display: flex;
+ align-items: center;
+ padding: 8px;
border-radius: 4px;
background-color: #ff3e00;
color: #fff;
diff --git a/site/content/faq/100-im-new-to-svelte.md b/site/content/faq/100-im-new-to-svelte.md
index cfe5eb8ec0..5bd7b96379 100644
--- a/site/content/faq/100-im-new-to-svelte.md
+++ b/site/content/faq/100-im-new-to-svelte.md
@@ -2,6 +2,6 @@
question: I'm new to Svelte. Where should I start?
---
-We think the best way to get started is playing through the interactive [Tutorial](/tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser.
+We think the best way to get started is playing through the interactive [tutorial](/tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser.
Five to ten minutes should be enough to get you up and running. An hour and a half should get you through the entire tutorial.
diff --git a/site/content/tutorial/06-bindings/09-each-block-bindings/text.md b/site/content/tutorial/06-bindings/09-each-block-bindings/text.md
index 9c352703f1..2174ec578f 100644
--- a/site/content/tutorial/06-bindings/09-each-block-bindings/text.md
+++ b/site/content/tutorial/06-bindings/09-each-block-bindings/text.md
@@ -6,15 +6,17 @@ You can even bind to properties inside an `each` block.
```html
{#each todos as todo}
-
+
+
-
+
+
{/each}
```
diff --git a/site/content/tutorial/12-actions/01-actions/app-a/App.svelte b/site/content/tutorial/12-actions/01-actions/app-a/App.svelte
index 40b4ea2673..0e78f482c5 100644
--- a/site/content/tutorial/12-actions/01-actions/app-a/App.svelte
+++ b/site/content/tutorial/12-actions/01-actions/app-a/App.svelte
@@ -20,6 +20,9 @@
height: var(--height);
left: calc(50% - var(--width) / 2);
top: calc(50% - var(--height) / 2);
+ display: flex;
+ align-items: center;
+ padding: 8px;
border-radius: 4px;
background-color: #ff3e00;
color: #fff;
diff --git a/site/content/tutorial/12-actions/01-actions/app-b/App.svelte b/site/content/tutorial/12-actions/01-actions/app-b/App.svelte
index bd990a5360..79214ec81f 100644
--- a/site/content/tutorial/12-actions/01-actions/app-b/App.svelte
+++ b/site/content/tutorial/12-actions/01-actions/app-b/App.svelte
@@ -20,6 +20,9 @@
height: var(--height);
left: calc(50% - var(--width) / 2);
top: calc(50% - var(--height) / 2);
+ display: flex;
+ align-items: center;
+ padding: 8px;
border-radius: 4px;
background-color: #ff3e00;
color: #fff;
diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts
index 92a87dd6f8..78d6c9188f 100644
--- a/src/compiler/compile/nodes/Element.ts
+++ b/src/compiler/compile/nodes/Element.ts
@@ -23,7 +23,7 @@ import compiler_errors from '../compiler_errors';
const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/;
-const aria_attributes = 'activedescendant atomic autocomplete busy checked colcount colindex colspan controls current describedby details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowcount rowindex rowspan selected setsize sort valuemax valuemin valuenow valuetext'.split(' ');
+const aria_attributes = 'activedescendant atomic autocomplete busy checked colcount colindex colspan controls current describedby description details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowcount rowindex rowspan selected setsize sort valuemax valuemin valuenow valuetext'.split(' ');
const aria_attribute_set = new Set(aria_attributes);
const aria_roles = 'alert alertdialog application article banner blockquote button caption cell checkbox code columnheader combobox complementary contentinfo definition deletion dialog directory document emphasis feed figure form generic graphics-document graphics-object graphics-symbol grid gridcell group heading img link list listbox listitem log main marquee math meter menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option paragraph presentation progressbar radio radiogroup region row rowgroup rowheader scrollbar search searchbox separator slider spinbutton status strong subscript superscript switch tab table tablist tabpanel term textbox time timer toolbar tooltip tree treegrid treeitem'.split(' ');
diff --git a/src/runtime/action/index.ts b/src/runtime/action/index.ts
new file mode 100644
index 0000000000..6d1d394139
--- /dev/null
+++ b/src/runtime/action/index.ts
@@ -0,0 +1,42 @@
+/**
+ * Actions can return an object containing the two properties defined in this interface. Both are optional.
+ * - update: An action can have a parameter. This method will be called whenever that parameter changes,
+ * immediately after Svelte has applied updates to the markup.
+ * - destroy: Method that is called after the element is unmounted
+ *
+ * Example usage:
+ * ```ts
+ * export function myAction(node: HTMLElement, paramater: Parameter): ActionReturn {
+ * // ...
+ * return {
+ * update: (updatedParameter) => {...},
+ * destroy: () => {...}
+ * };
+ * }
+ * ```
+ *
+ * Docs: https://svelte.dev/docs#template-syntax-element-directives-use-action
+ */
+export interface ActionReturn {
+ update?: (parameter: Parameter) => void;
+ destroy?: () => void;
+}
+
+/**
+ * Actions are functions that are called when an element is created.
+ * You can use this interface to type such actions.
+ * The following example defines an action that only works on `
` elements
+ * and optionally accepts a parameter which it has a default value for:
+ * ```ts
+ * export const myAction: Action = (node, param = { someProperty: true }) => {
+ * // ...
+ * }
+ * ```
+ * You can return an object with methods `update` and `destroy` from the function.
+ * See interface `ActionReturn` for more details.
+ *
+ * Docs: https://svelte.dev/docs#template-syntax-element-directives-use-action
+ */
+export interface Action {
+ (node: Node, parameter?: Parameter): void | ActionReturn;
+}