Skip to content

Commit 4c8bb82

Browse files
committed
fix(styled input): make one way and two way data binding work
1 parent 32d5169 commit 4c8bb82

File tree

4 files changed

+24
-17
lines changed

4 files changed

+24
-17
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { component$, useSignal } from '@builder.io/qwik';
2+
import { Input, Label } from '~/components/ui';
3+
4+
export default component$(() => {
5+
const valueSig = useSignal('[email protected]');
6+
return (
7+
<div class="grid w-full max-w-sm items-center gap-1.5">
8+
<Label for="email-2">Email</Label>
9+
<Input type="email" id="email-2" placeholder="Email" bind:value={valueSig} />
10+
<p class="text-sm text-muted-foreground">Your email is: {valueSig.value}</p>
11+
</div>
12+
);
13+
});

apps/website/src/routes/docs/styled/input/examples/hero.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Input } from '~/components/ui';
44
export default component$(() => {
55
return (
66
<>
7-
<Input type="email" placeholder="Email" value="[email protected]" />
7+
<Input type="email" placeholder="Email" />
88
</>
99
);
1010
});

apps/website/src/routes/docs/styled/input/index.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,7 @@ import { Input } from '~/components/ui';
9292
### With text
9393

9494
<Showcase name="with-text" vertical />
95+
96+
### Data-binding
97+
98+
<Showcase name="data-binding" vertical />

packages/kit-styled/src/components/input/input.tsx

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,24 @@
1-
import { component$, useSignal, type PropsOf } from '@builder.io/qwik';
1+
import { $, component$, useSignal, type PropsOf } from '@builder.io/qwik';
22
import { cn } from '@qwik-ui/utils';
33

44
type InputProps = PropsOf<'input'> & {
55
error?: string;
66
};
77

88
export const Input = component$<InputProps>(
9-
({
10-
name,
11-
error,
12-
'bind:value': valueSig,
13-
value,
14-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
15-
'bind:checked': checkedSig,
16-
id,
17-
...props
18-
}) => {
9+
({ name, error, id, ['bind:value']: valueSig, value, onInput$, ...props }) => {
1910
const inputId = id || name;
2011
const inputRef = useSignal<HTMLInputElement>();
2112

22-
// TODO: remove this when we can figure out why the optimizer forces you to have a signal rather than conditionally adding the bind:value prop.
23-
const dummySig = useSignal<string | undefined>(value?.toString());
24-
2513
return (
2614
<>
2715
<input
2816
{...props}
2917
aria-errormessage={`${inputId}-error`}
30-
aria-invalid={!!error}
31-
bind:value={valueSig ? valueSig : dummySig}
18+
aria-invaid={!!error}
19+
// workaround for one way and two way data-binding https://github.com/QwikDev/qwik/issues/3926
20+
value={valueSig ? valueSig.value : value}
21+
onInput$={valueSig ? $((__, el) => (valueSig.value = el.value)) : onInput$}
3222
ref={inputRef}
3323
class={cn(
3424
'flex h-12 w-full rounded-base border border-input bg-background px-3 py-1 text-sm text-foreground shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',

0 commit comments

Comments
 (0)