From 0c57ace670eac3a5f00407bffa5f2477d84f671f Mon Sep 17 00:00:00 2001 From: deMGoncalves Date: Mon, 9 Sep 2024 16:59:32 -0300 Subject: [PATCH] feat: implementando o repaint sobre o getters e notificacao de que o paint foi rodado --- package.json | 2 +- src/dom/paint/paint.js | 1 + src/dom/repaint/repaint.js | 86 ++++++++++++++++++++++++++------------ vite.config.js | 1 + 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 1f53044..31f0efa 100644 --- a/package.json +++ b/package.json @@ -62,5 +62,5 @@ "source": "src/index.js", "type": "module", "types": "types.d.ts", - "version": "0.0.46" + "version": "0.0.47" } diff --git a/src/dom/paint/paint.js b/src/dom/paint/paint.js index 38c7964..8c7ba06 100644 --- a/src/dom/paint/paint.js +++ b/src/dom/paint/paint.js @@ -50,6 +50,7 @@ const paint = requestAnimationFrame(() => { (this.shadowRoot ?? document).adoptedStyleSheets = style(this); (this.shadowRoot ?? this).innerHTML = component(this); + this.isPainted = true; resolve(); }); }; diff --git a/src/dom/repaint/repaint.js b/src/dom/repaint/repaint.js index 758e930..c3149e0 100644 --- a/src/dom/repaint/repaint.js +++ b/src/dom/repaint/repaint.js @@ -1,11 +1,11 @@ import { paintCallback } from "../interfaces"; /** - * Decorator para chamar o callback de pintura após a execução do método original. + * Decorator para chamar o callback de pintura após a execução do método ou atualização de propriedade original. * - * O decorator garante que o callback `paintCallback` seja chamado após a execução do método original, - * caso o elemento esteja conectado ao DOM. É útil para garantir que ações de pintura sejam feitas - * no momento certo do ciclo de vida do componente. + * O decorator garante que o callback `paintCallback` seja chamado após a execução do método original + * ou após a atribuição de um novo valor para uma propriedade, caso o elemento esteja conectado ao DOM. + * É útil para garantir que ações de pintura sejam feitas no momento certo do ciclo de vida do componente. * * @param {Object} _target - O alvo do decorator (classe ou protótipo). * @param {string} _propertyKey - O nome da propriedade/método decorado. @@ -13,13 +13,14 @@ import { paintCallback } from "../interfaces"; * @returns {void} * * @description - * O decorator `repaint` é utilizado para assegurar que, após a execução de um método decorado, - * o callback `paintCallback` seja chamado se o elemento estiver conectado ao DOM. Isso permite - * que a lógica de pintura do componente seja invocada de forma automática e no momento certo, - * garantindo a consistência visual e comportamental do Custom Element. + * O decorator `repaint` é utilizado para assegurar que, após a execução de um método decorado + * ou a atualização de uma propriedade decorada, o callback `paintCallback` seja chamado se o + * elemento estiver conectado ao DOM. Isso permite que a lógica de pintura do componente seja invocada + * de forma automática e no momento certo, garantindo a consistência visual e comportamental do Custom Element. * * Esse decorator é especialmente útil em cenários onde o componente precisa atualizar sua interface - * visual ou realizar outras ações relacionadas à pintura, sempre que um método específico for executado. + * visual ou realizar outras ações relacionadas à pintura, sempre que um método específico ou propriedade + * for atualizado. * * @example * class MyComponent extends HTMLElement { @@ -27,31 +28,62 @@ import { paintCallback } from "../interfaces"; * console.log('Callback de pintura chamado'); * } * + * // Usando em um método * @repaint * handlePaint() { * console.log('Método original executado'); * } + * + * // Usando em uma propriedade + * #color; + * + * @repaint + * set color(value) { + * this.#color = value; + * } + * + * get color() { + * return this.#color; + * } * } */ const repaint = (_target, _propertyKey, descriptor) => { - // Obtém o valor original do método ou define uma função padrão vazia - const originalMethod = descriptor.value ?? (() => undefined); - - // Modifica o descritor para adicionar a lógica de chamada do callback de pintura - Object.assign(descriptor, { - async value(...args) { - // Executa o método original - await Reflect.apply(originalMethod, this, args); - - // Se o elemento estiver conectado, chama o callback de pintura - if (this.isConnected) { - await this[paintCallback](); - } - - // Retorna a instância do componente - return this; - }, - }); + if (descriptor.value) { + // Caso seja um método + const originalMethod = descriptor.value; + + Object.assign(descriptor, { + async value(...args) { + // Executa o método original + await Reflect.apply(originalMethod, this, args); + + // Se o elemento estiver conectado, chama o callback de pintura + if (this.isPainted) { + await this[paintCallback](); + } + + // Retorna a instância do componente + return this; + }, + }); + } + + if (descriptor.set) { + // Caso seja um setter + const originalSetter = descriptor.set; + + Object.assign(descriptor, { + async set(value) { + // Chama o setter original + await Reflect.apply(originalSetter, this, [value]); + + // Se o elemento estiver conectado, chama o callback de pintura + if (this.isPainted) { + await this[paintCallback](); + } + }, + }); + } }; export default repaint; diff --git a/vite.config.js b/vite.config.js index 55c948f..255bebc 100644 --- a/vite.config.js +++ b/vite.config.js @@ -13,5 +13,6 @@ export default defineConfig({ formats: ["cjs", "es"], }, outDir: "dist", + sourcemap: true, }, });