Skip to content

Commit

Permalink
Merge pull request #7182 from JerryWu1234/v2v2v2
Browse files Browse the repository at this point in the history
fix: input's value is string when passing number
  • Loading branch information
shairez authored Jan 12, 2025
2 parents cae8268 + 96c0105 commit 42a6c35
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/neat-maps-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@qwik.dev/core': patch
---

fix: input's value is string when passing number
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,17 @@ The `bind:` is compiled away by the Qwik optimizer to a property set and an even
import { component$, useSignal } from '@qwik.dev/core';

export default component$(() => {
const count = useSignal(0);
const firstName = useSignal('');
const acceptConditions = useSignal(false);

return (
<form>
{/* For number inputs, use `valueAsNumber` instead of `value` to get the numeric value directly */}
<input type="number"
value={count.value}
onInput$={(_, el) => count.value = el.valueAsNumber }
/>
<input type="text"
value={firstName.value}
onInput$={(_, el) => firstName.value = el.value }
Expand Down
2 changes: 1 addition & 1 deletion packages/qwik/src/core/shared/jsx/types/jsx-generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ type SpecialAttrs = {
* For type: HTMLInputTypeAttribute, excluding 'button' | 'reset' | 'submit' | 'checkbox' |
* 'radio'
*/
'bind:value'?: Signal<string | undefined>;
'bind:value'?: Signal<string | undefined | number>;
enterKeyHint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send' | undefined;
height?: Size | undefined;
max?: number | string | undefined;
Expand Down
39 changes: 39 additions & 0 deletions packages/qwik/src/core/tests/use-signal.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -651,5 +651,44 @@ describe.each([
</Component>
);
});

// help me to get a description
it('should update the sum when input values change', async () => {
const AppTest = component$(() => {
const a = useSignal(1);
const b = useSignal(2);
return (
<div>
{a.value} + {b.value} = {a.value + b.value}
<input type="number" id="input1" bind:value={a} />
<input type="number" id="input2" bind:value={b} />
</div>
);
});

const { document } = await render(<AppTest />, { debug: debug });

await expect(document.querySelector('div')).toMatchDOM(
<div>
1 + 2 = 3
<input type="number" id="input1" value="1" />
<input type="number" id="input2" value="2" />
</div>
);

const input1 = document.querySelector('#input1')! as HTMLInputElement;

input1.value = '10';
input1.valueAsNumber = 10;

await trigger(document.body, input1, 'input');
await expect(document.querySelector('div')).toMatchDOM(
<div>
10 + 2 = 12
<input type="number" id="input1" value="10" />
<input type="number" id="input2" value="2" />
</div>
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const Greeter = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{
"value": value,
"onInput$": /*#__PURE__*/ inlinedQrl((_, elm)=>{
const [value] = useLexicalScope();
return value.value = elm.value;
return value.value = elm.type == "number" ? elm.valueAsNumber : elm.value;
}, "s_6IZeYpXCNXA", [
value
])
Expand All @@ -51,7 +51,7 @@ export const Greeter = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{
"checked": checked,
"onInput$": /*#__PURE__*/ inlinedQrl((_, elm)=>{
const [checked] = useLexicalScope();
return checked.value = elm.checked;
return checked.value = elm.type == "number" ? elm.valueAsNumber : elm.checked;
}, "s_JPI3bLCVnso", [
checked
])
Expand All @@ -60,7 +60,7 @@ export const Greeter = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{
"stuff": stuff,
"onChange$": /*#__PURE__*/ inlinedQrl((_, elm)=>{
const [stuff] = useLexicalScope();
return stuff.value = elm.stuff;
return stuff.value = elm.type == "number" ? elm.valueAsNumber : elm.stuff;
}, "s_eyREJ0lZTFw", [
stuff
])
Expand Down
62 changes: 52 additions & 10 deletions packages/qwik/src/optimizer/core/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1311,17 +1311,59 @@ impl<'a> QwikTransform<'a> {
),
),
op: ast::AssignOp::Assign,
right: Box::new(ast::Expr::Member(
ast::MemberExpr {
obj: Box::new(ast::Expr::Ident(elm)),
prop: ast::MemberProp::Ident(
ast::IdentName::new(
prop_name, DUMMY_SP,
),
),
right: Box::new(ast::Expr::Cond(ast::CondExpr {
test: Box::new(ast::Expr::Bin(ast::BinExpr {
left: Box::new(ast::Expr::Member(
ast::MemberExpr {
obj: Box::new(ast::Expr::Ident(
elm.clone(),
)),
prop: ast::MemberProp::Ident(
ast::IdentName::new(
"type".into(),
DUMMY_SP,
),
),
span: DUMMY_SP,
},
)),
span: DUMMY_SP,
},
)),
op: ast::BinaryOp::EqEq,
right: Box::new(ast::Expr::Lit(
ast::Lit::Str(ast::Str {
value: "number".into(),
span: DUMMY_SP,
raw: None,
}),
)),
})),
cons: Box::new(ast::Expr::Member(
ast::MemberExpr {
obj: Box::new(ast::Expr::Ident(
elm.clone(),
)),
prop: ast::MemberProp::Ident(
ast::IdentName::new(
"valueAsNumber".into(),
DUMMY_SP,
),
),
span: DUMMY_SP,
},
)),
alt: Box::new(ast::Expr::Member(
ast::MemberExpr {
obj: Box::new(ast::Expr::Ident(elm)),
prop: ast::MemberProp::Ident(
ast::IdentName::new(
prop_name, DUMMY_SP,
),
),
span: DUMMY_SP,
},
)),
span: DUMMY_SP,
})),
span: DUMMY_SP,
}),
))),
Expand Down

0 comments on commit 42a6c35

Please sign in to comment.