From 5fd4bca95d7c7f5c0f8e2f132d0ce4972da6b6b0 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Mon, 22 Mar 2021 11:39:11 -0400 Subject: [PATCH] run watch decorator after update completes --- docs/getting-started/changelog.md | 1 + src/components/input/input.ts | 3 +-- src/components/textarea/textarea.ts | 3 +-- src/internal/decorators.ts | 21 ++++++++++----------- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/docs/getting-started/changelog.md b/docs/getting-started/changelog.md index 2d174d91..2cb6b352 100644 --- a/docs/getting-started/changelog.md +++ b/docs/getting-started/changelog.md @@ -11,6 +11,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis - Fixed a bug in `sl-animation` where `sl-cancel` and `sl-finish` events would never fire - Fixed a bug where `sl-alert` wouldn't always transition properly - Fixed a bug where using `sl-menu` inside a shadow root would break keyboard selections [#382](https://github.com/shoelace-style/shoelace/issues/382) +- Improved `@watch` decorator to run after update instead of during - Updated `sl-menu-item` checked icon to `check` instead of `check2` ## 2.0.0-beta.34 diff --git a/src/components/input/input.ts b/src/components/input/input.ts index a0648b6c..4e78f245 100644 --- a/src/components/input/input.ts +++ b/src/components/input/input.ts @@ -257,8 +257,7 @@ export default class SlInput extends LitElement { @watch('value') handleValueChange() { - // Wait for the update to complete before checking the input's validity - this.updateComplete.then(() => (this.invalid = !this.input.checkValidity())); + this.invalid = !this.input.checkValidity(); } render() { diff --git a/src/components/textarea/textarea.ts b/src/components/textarea/textarea.ts index 280bece5..fa5c0317 100644 --- a/src/components/textarea/textarea.ts +++ b/src/components/textarea/textarea.ts @@ -238,8 +238,7 @@ export default class SlTextarea extends LitElement { @watch('value') handleValueChange() { - // Wait for the update to complete before checking the input's validity - this.updateComplete.then(() => (this.invalid = !this.input.checkValidity())); + this.invalid = !this.input.checkValidity(); } setTextareaHeight() { diff --git a/src/internal/decorators.ts b/src/internal/decorators.ts index 78408986..ca8d70bf 100644 --- a/src/internal/decorators.ts +++ b/src/internal/decorators.ts @@ -63,8 +63,11 @@ export class EventEmitter { // @watch decorator // -// Runs when an observed property changes, e.g. @property or @internalProperty. This will only run after the first -// update, so initial values will not trigger the watch function. +// Runs after an observed property changes, e.g. @property or @internalProperty. This will only run after the first +// update, so initial attribute => property mappings will not trigger the watch handler. +// +// Note that changing props in a watch handler *will* trigger a rerender. To make pre-update changes to observed +// properties, use the `update()` method instead. // // Usage: // @@ -74,15 +77,10 @@ export class EventEmitter { // export function watch(propName: string) { return (protoOrDescriptor: any, name: string): any => { - const { firstUpdated, update } = protoOrDescriptor; + const { updated } = protoOrDescriptor; - protoOrDescriptor.firstUpdated = function (changedProps: Map) { - firstUpdated.call(this, changedProps); - this.__didFirstUpdate = true; - }; - - protoOrDescriptor.update = function (changedProps: Map) { - if (this.__didFirstUpdate && changedProps.has(propName)) { + protoOrDescriptor.updated = function (changedProps: Map) { + if (this.__hasBeenUpdated && changedProps.has(propName)) { const oldValue = changedProps.get(propName); const newValue = this[propName]; @@ -91,7 +89,8 @@ export function watch(propName: string) { } } - update.call(this, changedProps); + updated.call(this, changedProps); + this.__hasBeenUpdated = true; }; }; }