From db397f8cda127ff5a4ef4a1436c61999f1e9b706 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 30 Jul 2024 10:52:13 +0800 Subject: [PATCH] feat: add state propagation mechanism support to sui components --- sui/core/injections.go | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/sui/core/injections.go b/sui/core/injections.go index 7528537c..b63f3631 100644 --- a/sui/core/injections.go +++ b/sui/core/injections.go @@ -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