Feat: Add read-only binding focused (#11271)

* Feat: Add readonly binding focused

* prettier

* simplify test

* revert

* simplify implementation

* changeset

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
pull/11260/head
Vaibhav Rai 1 year ago committed by GitHub
parent b91a67ba68
commit 11c7cd5495
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
feat: add read-only `bind:focused`

@ -2727,7 +2727,9 @@ export const template_visitors = {
case 'checked':
call_expr = b.call(`$.bind_checked`, state.node, getter, setter);
break;
case 'focused':
call_expr = b.call(`$.bind_focused`, state.node, setter);
break;
case 'group': {
/** @type {import('estree').CallExpression[]} */
const indexes = [];

@ -21,6 +21,7 @@ export const binding_properties = {
event: 'durationchange',
omit_in_ssr: true
},
focused: {},
paused: {
valid_elements: ['audio', 'video'],
omit_in_ssr: true

@ -1,4 +1,5 @@
import { render_effect } from '../../../reactivity/effects.js';
import { listen } from './shared.js';
/**
* @param {'innerHTML' | 'textContent' | 'innerText'} property
@ -67,3 +68,14 @@ export function bind_property(property, event_name, type, element, get_value, up
}
});
}
/**
* @param {HTMLElement} element
* @param {(value: unknown) => void} update
* @returns {void}
*/
export function bind_focused(element, update) {
listen(element, ['focus', 'blur'], () => {
update(element === document.activeElement);
});
}

@ -44,7 +44,11 @@ export { bind_prop } from './dom/elements/bindings/props.js';
export { bind_select_value, init_select, select_option } from './dom/elements/bindings/select.js';
export { bind_element_size, bind_resize_observer } from './dom/elements/bindings/size.js';
export { bind_this } from './dom/elements/bindings/this.js';
export { bind_content_editable, bind_property } from './dom/elements/bindings/universal.js';
export {
bind_content_editable,
bind_property,
bind_focused
} from './dom/elements/bindings/universal.js';
export { bind_window_scroll, bind_window_size } from './dom/elements/bindings/window.js';
export {
once,

@ -0,0 +1,19 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, component, target, window }) {
const [in1, in2] = target.querySelectorAll('input');
flushSync(() => in1.focus());
assert.equal(window.document.activeElement, in1);
assert.equal(component.a, true);
assert.equal(component.b, false);
flushSync(() => in2.focus());
assert.equal(window.document.activeElement, in2);
assert.equal(component.a, false);
assert.equal(component.b, true);
}
});

@ -0,0 +1,7 @@
<script>
export let a;
export let b;
</script>
<input bind:focused={a} />
<input bind:focused={b} />
Loading…
Cancel
Save