Browse Source

simple binding util

master
Stephanie Gredell 3 weeks ago
parent
commit
7f0386b4ae
  1. 85
      binding.js

85
binding.js

@ -0,0 +1,85 @@
/**
* @fileoverview Reactive data binding system.
* Creates a deep reactive Proxy that auto-updates DOM elements with data-bind attributes.
*/
/**
* Gets a nested property value from an object using dot notation.
* @param {Object} obj - The object to get the value from
* @param {string} path - Dot notation path (e.g., "supplies.lemons")
* @returns {*} The value at the path
*/
function getByPath(obj, path) {
return path.split('.').reduce((current, key) => current?.[key], obj);
}
/**
* Formats a value based on the format type.
* @param {*} value - The value to format
* @param {string} [format] - The format type (e.g., "currency", "number")
* @returns {string} The formatted value
*/
function formatValue(value, format) {
if (format === 'currency') {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(value);
}
if (format === 'number') {
return new Intl.NumberFormat('en-US').format(value);
}
return value;
}
/**
* Updates all DOM elements with data-bind attributes to reflect current state.
* @param {Object} state - The state object to read values from
*/
export function updateBindings(state) {
const elements = document.querySelectorAll('[data-bind]');
elements.forEach(el => {
const path = el.dataset.bind;
const format = el.dataset.format;
const value = getByPath(state, path);
if (value !== undefined) {
el.textContent = formatValue(value, format);
}
});
}
/**
* Creates a deep reactive Proxy that auto-updates DOM bindings on change.
* @param {Object} target - The initial state object
* @returns {Proxy} A reactive proxy that updates DOM on changes
*/
export function createReactiveState(target) {
const handler = {
get(obj, prop) {
const value = obj[prop];
// If the value is an object, wrap it in a proxy too (deep reactivity)
if (typeof value === 'object' && value !== null) {
return new Proxy(value, handler);
}
return value;
},
set(obj, prop, value) {
obj[prop] = value;
// Update all bound DOM elements
updateBindings(target);
return true;
}
};
return new Proxy(target, handler);
}
Loading…
Cancel
Save