Skip to content

Commit c716329

Browse files
feat: fix accessors and support migration of accessors (#13456)
* feat: fix accessors and support migration of accessors * fix: exclude slots * fix: remove call to proxy for accessors props Co-authored-by: Simon H <[email protected]> * chore: add test for accessors * chore: fix lint --------- Co-authored-by: Simon H <[email protected]>
1 parent dfe0138 commit c716329

File tree

7 files changed

+85
-1
lines changed

7 files changed

+85
-1
lines changed

.changeset/large-rules-hang.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
feat: fix accessors and support migration of accessors

packages/svelte/src/compiler/migrate/index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { get_rune } from '../phases/scope.js';
1212
import { reset, reset_warning_filter } from '../state.js';
1313
import { extract_identifiers } from '../utils/ast.js';
1414
import { migrate_svelte_ignore } from '../utils/extract_svelte_ignore.js';
15-
import { determine_slot } from '../utils/slot.js';
1615
import { validate_component_options } from '../validate-options.js';
1716
import { is_svg, is_void } from '../../utils.js';
1817

@@ -55,6 +54,8 @@ export function migrate(source) {
5554
const analysis = analyze_component(parsed, source, combined_options);
5655
const indent = guess_indent(source);
5756

57+
str.replaceAll(/(<svelte:options\s.*?\s?)accessors\s?/g, (_, $1) => $1);
58+
5859
for (const content of style_contents) {
5960
str.overwrite(content[0], content[0] + style_placeholder.length, content[1]);
6061
}
@@ -269,6 +270,13 @@ export function migrate(source) {
269270
);
270271
}
271272

273+
if (state.props.length > 0 && state.analysis.accessors) {
274+
str.appendRight(
275+
insertion_point,
276+
`\n${indent}export {${state.props.reduce((acc, prop) => (prop.slot_name ? acc : `${acc}\n${indent}\t${prop.local},`), '')}\n${indent}}\n`
277+
);
278+
}
279+
272280
if (!parsed.instance && need_script) {
273281
str.appendRight(insertion_point, '\n</script>\n\n');
274282
}

packages/svelte/src/compiler/phases/3-transform/client/transform-client.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,10 @@ export function client_component(analysis, options) {
276276
}
277277
}
278278

279+
if (binding?.kind === 'prop' || binding?.kind === 'bindable_prop') {
280+
return [getter, b.set(alias ?? name, [b.stmt(b.call(name, b.id('$$value')))])];
281+
}
282+
279283
if (binding?.kind === 'state' || binding?.kind === 'raw_state') {
280284
const value = binding.kind === 'state' ? b.call('$.proxy', b.id('$$value')) : b.id('$$value');
281285
return [getter, b.set(alias ?? name, [b.stmt(b.call('$.set', b.id(name), value))])];
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script lang="ts">
2+
type $$Props = {
3+
test: string;
4+
}
5+
6+
export let count = 0;
7+
export let stuff;
8+
</script>
9+
10+
<button>
11+
<slot name="cool" />
12+
</button>
13+
14+
<svelte:options accessors immutable/>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script lang="ts">
2+
3+
4+
interface Props {
5+
test: string;
6+
count?: number;
7+
stuff: any;
8+
cool?: import('svelte').Snippet;
9+
}
10+
11+
let {
12+
test,
13+
count = 0,
14+
stuff,
15+
cool
16+
}: Props = $props();
17+
18+
export {
19+
test,
20+
count,
21+
stuff,
22+
}
23+
</script>
24+
25+
<button>
26+
{@render cool?.()}
27+
</button>
28+
29+
<svelte:options immutable/>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ok, test } from '../../test';
2+
import { flushSync } from 'svelte';
3+
4+
export default test({
5+
html: `<p>0</p>`,
6+
7+
async test({ assert, target, instance }) {
8+
const p = target.querySelector('p');
9+
ok(p);
10+
flushSync(() => {
11+
instance.count++;
12+
});
13+
assert.equal(p.innerHTML, '1');
14+
}
15+
});
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
let { count=0 } = $props();
3+
4+
export {
5+
count
6+
}
7+
</script>
8+
9+
<p>{count}</p>

0 commit comments

Comments
 (0)