Skip to content

Commit

Permalink
fix(runtime): allow watchers to fire w/ no Stencil members (#5855)
Browse files Browse the repository at this point in the history
* fix(runtime): allow watchers to fire w/ no Stencil members

Fixes #5854

STENCIL-1338

* resolve test failures
  • Loading branch information
tanner-reits authored Jun 25, 2024
1 parent 6ac07ec commit 850ad4f
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/compiler/app-core/app-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const getBuildFeatures = (cmps: ComponentCompilerMeta[]): BuildFeatures =
member: cmps.some((c) => c.hasMember),
method: cmps.some((c) => c.hasMethod),
mode: cmps.some((c) => c.hasMode),
observeAttribute: cmps.some((c) => c.hasAttribute),
observeAttribute: cmps.some((c) => c.hasAttribute || c.hasWatchCallback),
prop: cmps.some((c) => c.hasProp),
propBoolean: cmps.some((c) => c.hasPropBoolean),
propNumber: cmps.some((c) => c.hasPropNumber),
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/proxy-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ export const proxyComponent = (
);
}

if (BUILD.member && cmpMeta.$members$) {
if (BUILD.watchCallback && Cstr.watchers) {
if ((BUILD.member && cmpMeta.$members$) || (BUILD.watchCallback && (cmpMeta.$watchers$ || Cstr.watchers))) {
if (BUILD.watchCallback && Cstr.watchers && !cmpMeta.$watchers$) {
cmpMeta.$watchers$ = Cstr.watchers;
}
// It's better to have a const than two Object.entries()
const members = Object.entries(cmpMeta.$members$);
const members = Object.entries(cmpMeta.$members$ ?? {});
members.map(([memberName, [memberFlags]]) => {
if (
(BUILD.prop || BUILD.state) &&
Expand Down
24 changes: 24 additions & 0 deletions test/wdio/watch-native-attributes/cmp-no-members.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { h } from '@stencil/core';
import { render } from '@wdio/browser-runner/stencil';

describe('watch native attributes w/ no Stencil members', () => {
beforeEach(() => {
render({
template: () => (
<watch-native-attributes-no-members aria-label="myStartingLabel"></watch-native-attributes-no-members>
),
});
});

it('triggers the callback for the watched attribute', async () => {
const $cmp = $('watch-native-attributes-no-members');
await $cmp.waitForExist();

await expect($cmp).toHaveText('Label: myStartingLabel\nCallback triggered: false');

const cmp = document.querySelector('watch-native-attributes-no-members');
cmp.setAttribute('aria-label', 'myNewLabel');

await expect($cmp).toHaveText('Label: myNewLabel\nCallback triggered: true');
});
});
23 changes: 23 additions & 0 deletions test/wdio/watch-native-attributes/cmp-no-members.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Component, Element, forceUpdate, h, Watch } from '@stencil/core';

@Component({
tag: 'watch-native-attributes-no-members',
})
export class WatchNativeAttributesNoMembers {
@Element() el!: HTMLElement;

private callbackTriggered = false;

@Watch('aria-label')
onAriaLabelChange() {
this.callbackTriggered = true;
forceUpdate(this);
}

render() {
return [
<p>Label: {this.el.getAttribute('aria-label')}</p>,
<p>Callback triggered: {`${this.callbackTriggered}`}</p>,
];
}
}

0 comments on commit 850ad4f

Please sign in to comment.