Skip to content

Commit 11c7cd5

Browse files
Feat: Add read-only binding focused (#11271)
* Feat: Add readonly binding focused * prettier * simplify test * revert * simplify implementation * changeset --------- Co-authored-by: Rich Harris <[email protected]> Co-authored-by: Rich Harris <[email protected]>
1 parent b91a67b commit 11c7cd5

File tree

7 files changed

+52
-2
lines changed

7 files changed

+52
-2
lines changed

.changeset/thick-swans-type.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: add read-only `bind:focused`

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2727,7 +2727,9 @@ export const template_visitors = {
27272727
case 'checked':
27282728
call_expr = b.call(`$.bind_checked`, state.node, getter, setter);
27292729
break;
2730-
2730+
case 'focused':
2731+
call_expr = b.call(`$.bind_focused`, state.node, setter);
2732+
break;
27312733
case 'group': {
27322734
/** @type {import('estree').CallExpression[]} */
27332735
const indexes = [];

packages/svelte/src/compiler/phases/bindings.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const binding_properties = {
2121
event: 'durationchange',
2222
omit_in_ssr: true
2323
},
24+
focused: {},
2425
paused: {
2526
valid_elements: ['audio', 'video'],
2627
omit_in_ssr: true

packages/svelte/src/internal/client/dom/elements/bindings/universal.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { render_effect } from '../../../reactivity/effects.js';
2+
import { listen } from './shared.js';
23

34
/**
45
* @param {'innerHTML' | 'textContent' | 'innerText'} property
@@ -67,3 +68,14 @@ export function bind_property(property, event_name, type, element, get_value, up
6768
}
6869
});
6970
}
71+
72+
/**
73+
* @param {HTMLElement} element
74+
* @param {(value: unknown) => void} update
75+
* @returns {void}
76+
*/
77+
export function bind_focused(element, update) {
78+
listen(element, ['focus', 'blur'], () => {
79+
update(element === document.activeElement);
80+
});
81+
}

packages/svelte/src/internal/client/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ export { bind_prop } from './dom/elements/bindings/props.js';
4444
export { bind_select_value, init_select, select_option } from './dom/elements/bindings/select.js';
4545
export { bind_element_size, bind_resize_observer } from './dom/elements/bindings/size.js';
4646
export { bind_this } from './dom/elements/bindings/this.js';
47-
export { bind_content_editable, bind_property } from './dom/elements/bindings/universal.js';
47+
export {
48+
bind_content_editable,
49+
bind_property,
50+
bind_focused
51+
} from './dom/elements/bindings/universal.js';
4852
export { bind_window_scroll, bind_window_size } from './dom/elements/bindings/window.js';
4953
export {
5054
once,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { flushSync } from 'svelte';
2+
3+
import { test } from '../../test';
4+
5+
export default test({
6+
async test({ assert, component, target, window }) {
7+
const [in1, in2] = target.querySelectorAll('input');
8+
9+
flushSync(() => in1.focus());
10+
assert.equal(window.document.activeElement, in1);
11+
assert.equal(component.a, true);
12+
assert.equal(component.b, false);
13+
14+
flushSync(() => in2.focus());
15+
assert.equal(window.document.activeElement, in2);
16+
assert.equal(component.a, false);
17+
assert.equal(component.b, true);
18+
}
19+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
export let a;
3+
export let b;
4+
</script>
5+
6+
<input bind:focused={a} />
7+
<input bind:focused={b} />

0 commit comments

Comments
 (0)