Skip to content

Commit

Permalink
Merge pull request #7198 from QwikDev/v2-updating-var-props
Browse files Browse the repository at this point in the history
fix: updating signal-based var props
  • Loading branch information
Varixo authored Dec 27, 2024
2 parents d21ff10 + 0166199 commit cef6a0d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/brown-ravens-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@qwik.dev/core': patch
---

fix: updating signal-based props
8 changes: 6 additions & 2 deletions packages/qwik/src/core/client/vnode-diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Slot } from '../shared/jsx/slot.public';
import type { JSXNodeInternal, JSXOutput } from '../shared/jsx/types/jsx-node';
import type { JSXChildren } from '../shared/jsx/types/jsx-qwik-attributes';
import { SSRComment, SSRRaw, SkipRender } from '../shared/jsx/utils.public';
import { trackSignalAndAssignHost, untrack } from '../use/use-core';
import { trackSignalAndAssignHost } from '../use/use-core';
import { TaskFlags, cleanupTask, isTask } from '../use/use-task';
import { EMPTY_OBJ } from '../shared/utils/flyweight';
import {
Expand Down Expand Up @@ -787,7 +787,11 @@ export const vnode_diff = (
}

if (isSignal(value)) {
value = untrack(() => value.value);
const signalData = new EffectPropData({
$scopedStyleIdPrefix$: scopedStyleIdPrefix,
$isConst$: false,
});
value = trackSignalAndAssignHost(value, vnode, key, container, signalData);
}

vnode_setAttr(journal, vnode, key, serializeAttribute(key, value, scopedStyleIdPrefix));
Expand Down
49 changes: 48 additions & 1 deletion packages/qwik/src/core/tests/attributes.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing';
import { describe, expect, it } from 'vitest';
import { component$, useSignal, useStore, Fragment as Component, Fragment } from '@qwik.dev/core';
import {
component$,
useSignal,
useStore,
Fragment as Component,
Fragment,
type PropsOf,
useComputed$,
} from '@qwik.dev/core';

const debug = false; //true;
Error.stackTraceLimit = 100;
Expand Down Expand Up @@ -336,4 +344,43 @@ describe.each([
</Component>
);
});

it('should update signal-based var prop', async () => {
const PasswordInput = component$<PropsOf<'input'>>((props) => {
const showPassword = useSignal<boolean>(false);
const inputType = useComputed$(() => (showPassword.value ? 'text' : 'password'));
return (
<>
<input type={inputType.value} {...props} />
<button
onClick$={() => {
showPassword.value = !showPassword.value;
}}
></button>
</>
);
});

const { vNode, document } = await render(<PasswordInput />, { debug });

expect(vNode).toMatchVDOM(
<Component>
<Fragment>
<input type="password" />
<button></button>
</Fragment>
</Component>
);

await trigger(document.body, 'button', 'click');

expect(vNode).toMatchVDOM(
<Component>
<Fragment>
<input type="text" />
<button></button>
</Fragment>
</Component>
);
});
});

0 comments on commit cef6a0d

Please sign in to comment.