From 0870332e8b26521a10537105fabc7c20ba37a11e Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 30 Jul 2024 09:33:43 +0800 Subject: [PATCH 1/2] Add $utils object in libsui for enhanced utility functions --- sui/core/injections.go | 61 ++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/sui/core/injections.go b/sui/core/injections.go index 12fe01fe..7528537c 100644 --- a/sui/core/injections.go +++ b/sui/core/injections.go @@ -30,6 +30,47 @@ func libsui(minify bool) (string, error) { const libsuisource = ` + function $$(selector) { + elm = null; + if (typeof selector === "string" ){ + elm = document.querySelector(selector); + } + + if (selector instanceof HTMLElement) { + elm = selector; + } + + if (elm) { + cn = elm.getAttribute("s:cn"); + if (cn != "" && typeof window[cn] === "function") { + const component = new window[cn](elm); + return new __sui_component(elm, component); + } + } + return null; + } + + const $utils = { + + RemoveClass: (element, className) => { + const classes = Array.isArray(className) ? className : className.split(" "); + classes.forEach((c) => { + const v = c.replace(/[\n\r\s]/g, ""); + if (v === "") return; + element.classList.remove(v); + }); + }, + + AddClass: (element, className) => { + const classes = Array.isArray(className) ? className : className.split(" "); + classes.forEach((c) => { + const v = c.replace(/[\n\r\s]/g, ""); + if (v === "") return; + element.classList.add(v); + }); + }, + } + function __sui_component_root(elm, name) { while (elm && elm.getAttribute("s:cn") !== name) { elm = elm.parentElement; @@ -99,26 +140,6 @@ const libsuisource = ` this.state = component ? new __sui_state(component) : {}; } - function $$(selector) { - elm = null; - if (typeof selector === "string" ){ - elm = document.querySelector(selector); - } - - if (selector instanceof HTMLElement) { - elm = selector; - } - - if (elm) { - cn = elm.getAttribute("s:cn"); - if (cn != "" && typeof window[cn] === "function") { - const component = new window[cn](elm); - return new __sui_component(elm, component); - } - } - return null; - } - function __sui_event_handler(event, dataKeys, jsonKeys, target, root, handler) { const data = {}; target = target || null; From db397f8cda127ff5a4ef4a1436c61999f1e9b706 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 30 Jul 2024 10:52:13 +0800 Subject: [PATCH 2/2] 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