feat: add state propagation mechanism support to sui components

This commit is contained in:
Max 2024-07-30 10:52:13 +08:00
parent 0870332e8b
commit db397f8cda

View file

@ -51,7 +51,7 @@ const libsuisource = `
}
const $utils = {
RemoveClass: (element, className) => {
const classes = Array.isArray(className) ? className : className.split(" ");
classes.forEach((c) => {
@ -80,10 +80,32 @@ const libsuisource = `
function __sui_state(component) {
this.handlers = component.watch || {};
this.Set = async function (key, value) {
this.Set = async function (key, value, target) {
const handler = this.handlers[key];
target = target || component.root;
if (handler && typeof handler === "function") {
await handler(value);
const stateObj = {
target: target,
stopPropagation: function () {
target.setAttribute("state-propagation", "true");
},
}
await handler(value, stateObj);
const isStopPropagation = target ? target.getAttribute("state-propagation") === "true" : false;
if (isStopPropagation) {
return;
}
let parent = component.root.parentElement;
while (parent && !parent.getAttribute("s:cn")) {
parent = parent.parentElement;
}
if ( parent == document.body || parent == null) {
return;
}
// Dispatch the state change custom event to parent component
const event = new CustomEvent("state:change", { detail: { key: key, value: value, target:component.root } });
parent.dispatchEvent(event);
}
}
}
@ -268,6 +290,19 @@ const componentInitScriptTmpl = `
this.root = %s;
this.store = new __sui_store(this.root);
this.props = new __sui_props(this.root);
if (!this.root.getAttribute("initialized")) {
this.root.setAttribute("initialized", 'true');
this.root.addEventListener("state:change", function (event) {
const name = this.getAttribute("s:cn");
const target = event.detail.target;
const key = event.detail.key;
const value = event.detail.value;
const component = new window[name](this);
const state = new __sui_state(component);
state.Set(key, value, target)
});
}
`
// Inject code