diff --git a/CHANGELOG.md b/CHANGELOG.md index 40acabf61c7e..41d70eedcc5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Also: * Fix edge cases in matching selectors against elements ([#1710](https://github.com/sveltejs/svelte/issues/1710)) * Fix several bugs related to interaction of `{...spread}` attributes with other features ([#2721](https://github.com/sveltejs/svelte/issues/2721), [#2916](https://github.com/sveltejs/svelte/issues/2916), [#3421](https://github.com/sveltejs/svelte/issues/3421), [#3681](https://github.com/sveltejs/svelte/issues/3681), [#3764](https://github.com/sveltejs/svelte/issues/3764), [#3790](https://github.com/sveltejs/svelte/issues/3790)) * Allow exiting a reactive block early with `break $` ([#2828](https://github.com/sveltejs/svelte/issues/2828)) +* Fix binding to props that have been renamed with `export { ... as ... }` ([#3508](https://github.com/sveltejs/svelte/issues/3508)) * Fix application of style scoping class in cases of ambiguity ([#3544](https://github.com/sveltejs/svelte/issues/3544)) * Check attributes have changed before setting them to avoid image flicker ([#3579](https://github.com/sveltejs/svelte/pull/3579)) * Fix generating malformed code for `{@debug}` tags with no dependencies ([#3588](https://github.com/sveltejs/svelte/issues/3588)) diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index 72f81cfb058f..cacac18b8791 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -223,7 +223,7 @@ export default function dom( component.rewrite_props(({ name, reassigned, export_name }) => { const value = `$${name}`; - + const insert = (reassigned || export_name) ? b`${`$$subscribe_${name}`}()` : b`@component_subscribe($$self, ${name}, #value => $$invalidate('${value}', ${value} = #value))`; @@ -426,10 +426,14 @@ export default function dom( } const prop_names = x`[]`; + const renamed_prop_names = []; // TODO find a more idiomatic way of doing this props.forEach(v => { (prop_names as any).elements.push({ type: 'Literal', value: v.export_name }); + if (v.name !== v.export_name) { + renamed_prop_names.push(p`${v.export_name}: "${v.name}"`); + } }); if (options.customElement) { @@ -440,7 +444,7 @@ export default function dom( ${css.code && b`this.shadowRoot.innerHTML = \`\`;`} - @init(this, { target: this.shadowRoot }, ${definition}, create_fragment, ${not_equal}, ${prop_names}); + @init(this, { target: this.shadowRoot }, ${definition}, create_fragment, ${not_equal}, ${prop_names}, ${renamed_prop_names.length > 0 && x`{ ${renamed_prop_names} }`}); ${dev_props_check} @@ -492,7 +496,7 @@ export default function dom( constructor(options) { super(${options.dev && `options`}); ${should_add_css && b`if (!@_document.getElementById("${component.stylesheet.id}-style")) ${add_css}();`} - @init(this, options, ${definition}, create_fragment, ${not_equal}, ${prop_names}); + @init(this, options, ${definition}, create_fragment, ${not_equal}, ${prop_names}, ${renamed_prop_names.length > 0 && x`{ ${renamed_prop_names} }`}); ${options.dev && b`@dispatch_dev("SvelteRegisterComponent", { component: this, tagName: "${name.name}", options, id: create_fragment.name });`} ${dev_props_check} diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index 2d5795eccb63..7e9897463e09 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -13,6 +13,7 @@ interface T$$ { callbacks: any; after_update: any[]; props: any; + renamed_props: any; fragment: null|any; not_equal: any; before_update: any[]; @@ -23,6 +24,9 @@ interface T$$ { export function bind(component, name, callback) { if (component.$$.props.indexOf(name) === -1) return; + if (component.$$.renamed_props && name in component.$$.renamed_props) { + name = component.$$.renamed_props[name]; + } component.$$.bound[name] = callback; callback(component.$$.ctx[name]); } @@ -70,7 +74,7 @@ function make_dirty(component, key) { component.$$.dirty[key] = true; } -export function init(component, options, instance, create_fragment, not_equal, prop_names) { +export function init(component, options, instance, create_fragment, not_equal, prop_names, renamed_props) { const parent_component = current_component; set_current_component(component); @@ -82,6 +86,7 @@ export function init(component, options, instance, create_fragment, not_equal, p // state props: prop_names, + renamed_props, update: noop, not_equal, bound: blank_object(), diff --git a/test/runtime/samples/component-binding-aliased/Widget.svelte b/test/runtime/samples/component-binding-aliased/Widget.svelte new file mode 100644 index 000000000000..7d173df21045 --- /dev/null +++ b/test/runtime/samples/component-binding-aliased/Widget.svelte @@ -0,0 +1,4 @@ + diff --git a/test/runtime/samples/component-binding-aliased/_config.js b/test/runtime/samples/component-binding-aliased/_config.js new file mode 100644 index 000000000000..4898d1e993ff --- /dev/null +++ b/test/runtime/samples/component-binding-aliased/_config.js @@ -0,0 +1,5 @@ +export default { + html: ` +