chore: better bind_property implementation (#11904)

- better name for bidirectional bindings
- cleanup implementation
pull/11944/head
Rich Harris 1 month ago committed by GitHub
parent ba017db89d
commit fdecad6cdd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -2747,10 +2747,9 @@ export const template_visitors = {
'$.bind_property', '$.bind_property',
b.literal(node.name), b.literal(node.name),
b.literal(property.event), b.literal(property.event),
b.literal(property.type ?? 'get'),
state.node, state.node,
getter, setter,
setter property.bidirectional && getter
); );
} else { } else {
// special cases // special cases

@ -2,7 +2,7 @@
* @typedef BindingProperty * @typedef BindingProperty
* @property {string} [event] This is set if the binding corresponds to the property name on the dom element it's bound to * @property {string} [event] This is set if the binding corresponds to the property name on the dom element it's bound to
* and there's an event that notifies of a change to that property * and there's an event that notifies of a change to that property
* @property {string} [type] Set this to `set` if updates are written to the dom property * @property {boolean} [bidirectional] Set this to `true` if updates are written to the dom property
* @property {boolean} [omit_in_ssr] Set this to true if the binding should not be included in SSR * @property {boolean} [omit_in_ssr] Set this to true if the binding should not be included in SSR
* @property {string[]} [valid_elements] If this is set, the binding is only valid on the given elements * @property {string[]} [valid_elements] If this is set, the binding is only valid on the given elements
* @property {string[]} [invalid_elements] If this is set, the binding is invalid on the given elements * @property {string[]} [invalid_elements] If this is set, the binding is invalid on the given elements
@ -175,7 +175,7 @@ export const binding_properties = {
// checkbox/radio // checkbox/radio
indeterminate: { indeterminate: {
event: 'change', event: 'change',
type: 'set', bidirectional: true,
valid_elements: ['input'], valid_elements: ['input'],
omit_in_ssr: true // no corresponding attribute omit_in_ssr: true // no corresponding attribute
}, },
@ -200,7 +200,7 @@ export const binding_properties = {
}, },
open: { open: {
event: 'toggle', event: 'toggle',
type: 'set', bidirectional: true,
valid_elements: ['details'] valid_elements: ['details']
}, },
value: { value: {

@ -33,40 +33,36 @@ export function bind_content_editable(property, element, get_value, update) {
/** /**
* @param {string} property * @param {string} property
* @param {string} event_name * @param {string} event_name
* @param {'get' | 'set'} type
* @param {Element} element * @param {Element} element
* @param {() => unknown} get_value * @param {(value: unknown) => void} set
* @param {(value: unknown) => void} update * @param {() => unknown} [get]
* @returns {void} * @returns {void}
*/ */
export function bind_property(property, event_name, type, element, get_value, update) { export function bind_property(property, event_name, element, set, get) {
var target_handler = () => { var handler = () => {
// @ts-ignore // @ts-ignore
update(element[property]); set(element[property]);
}; };
element.addEventListener(event_name, target_handler); element.addEventListener(event_name, handler);
if (type === 'set') { if (get) {
render_effect(() => { render_effect(() => {
// @ts-ignore // @ts-ignore
element[property] = get_value(); element[property] = get();
}); });
} else {
handler();
} }
if (type === 'get') { // @ts-ignore
// @ts-ignore if (element === document.body || element === window || element === document) {
update(element[property]); render_effect(() => {
}
render_effect(() => {
// @ts-ignore
if (element === document.body || element === window || element === document) {
return () => { return () => {
element.removeEventListener(event_name, target_handler); element.removeEventListener(event_name, handler);
}; };
} });
}); }
} }
/** /**

Loading…
Cancel
Save