Skip to content

Commit e8fd4b0

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

File tree

3 files changed

+39
-17
lines changed

3 files changed

+39
-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 { Textarea, 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+
<Textarea 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/textarea/index.mdx

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

7373
<Showcase name="with-text" vertical />
74+
75+
### Data binding
76+
77+
<Showcase name="data-binding" vertical />
Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
1-
import { component$, PropsOf } from '@builder.io/qwik';
1+
import { $, component$, PropsOf } from '@builder.io/qwik';
22
import { cn } from '@qwik-ui/utils';
33

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

8-
export const Textarea = component$<TextareaProps>(({ id, name, error, ...props }) => {
9-
const textareaId = id || name;
10-
return (
11-
<>
12-
<textarea
13-
{...props}
14-
class={cn(
15-
'[&::-webkit-scrollbar-track]:bg-blue flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
16-
props.class,
17-
)}
18-
id={textareaId}
19-
/>
20-
{error && <div id={`${textareaId}-error`}>{error}</div>}
21-
</>
22-
);
23-
});
8+
export const Textarea = component$<TextareaProps>(
9+
({ id, name, error, ['bind:value']: valueSig, value, onInput$, ...props }) => {
10+
const textareaId = id || name;
11+
return (
12+
<>
13+
<textarea
14+
{...props}
15+
// workaround to support two way data-binding on the Input component (https://github.com/QwikDev/qwik/issues/3926)
16+
value={valueSig ? valueSig.value : value}
17+
onInput$={valueSig ? $((__, el) => (valueSig.value = el.value)) : onInput$}
18+
class={cn(
19+
'[&::-webkit-scrollbar-track]:bg-blue flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
20+
props.class,
21+
)}
22+
id={textareaId}
23+
/>
24+
{error && <div id={`${textareaId}-error`}>{error}</div>}
25+
</>
26+
);
27+
},
28+
);

0 commit comments

Comments
 (0)