Skip to content

Commit d8060da

Browse files
authored
fix(styled kit): allow consumer to pass onInput$ with two way data-binding & fix forms (#1118)
* fix(styled kit): allow consumer to pass onInput$ with two way data-binding & fix forms * chore: changeset * docs: update components docs
1 parent 75db031 commit d8060da

File tree

7 files changed

+33
-24
lines changed

7 files changed

+33
-24
lines changed

.changeset/sour-walls-lay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik-ui/styled': patch
3+
---
4+
5+
PATCH: The styled Input, Checkbox and Textarea components now properly handle two way data-binding and allow passing onInput$ outside and inside of forms.

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,23 @@ qwik-ui add checkbox
3030
import { $, type PropsOf, component$ } from '@builder.io/qwik';
3131
import { cn } from '@qwik-ui/utils';
3232

33-
export const Checkbox = component$<PropsOf<'input'>>(
34-
({ id, name, ['bind:checked']: checkedSig, checked, onInput$, ...props }) => {
33+
export const Checkbox = component$<Partial<PropsOf<'input'> & { type?: 'checkbox' }>>(
34+
({ id, name, ['bind:checked']: bindSig, checked, onInput$, ...props }) => {
3535
const inputId = id || name;
3636
return (
3737
<input
38-
type="checkbox"
3938
{...props}
39+
type="checkbox"
4040
// workaround to support two way data-binding on the Input component (https://github.com/QwikDev/qwik/issues/3926)
41-
checked={checkedSig ? checkedSig.value : checked}
42-
onInput$={checkedSig ? $((_, el) => (checkedSig.value = el.checked)) : onInput$}
43-
data-checked={checked || checkedSig?.value || ''}
41+
checked={bindSig ? bindSig.value : checked}
42+
onInput$={[bindSig && $((_, el) => (bindSig.value = el.checked)), onInput$]}
43+
data-checked={checked || bindSig?.value || ''}
4444
class={cn(
4545
'peer h-4 w-4 shrink-0 border-primary text-primary accent-primary ring-offset-background focus:ring-ring focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
4646
props.class,
4747
)}
4848
id={inputId}
49+
name={name}
4950
/>
5051
);
5152
},

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,27 @@ type InputProps = PropsOf<'input'> & {
3131
};
3232

3333
export const Input = component$<InputProps>(
34-
({ name, error, id, ['bind:value']: valueSig, value, onInput$, ...props }) => {
34+
({ name, error, id, ['bind:value']: bindSig, value, onInput$, ...props }) => {
3535
const inputId = id || name;
3636

3737
return (
3838
<>
3939
<input
4040
{...props}
4141
aria-errormessage={`${inputId}-error`}
42-
aria-invaid={!!error}
42+
aria-invalid={!!error}
4343
// workaround to support two way data-binding on the Input component (https://github.com/QwikDev/qwik/issues/3926)
44-
value={valueSig ? valueSig.value : value}
45-
onInput$={valueSig ? $((__, el) => (valueSig.value = el.value)) : onInput$}
44+
value={bindSig ? bindSig.value : value}
45+
onInput$={[bindSig && $((_, el) => (bindSig.value = el.value)), onInput$]}
4646
class={cn(
4747
'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',
4848
props.class,
4949
)}
5050
id={inputId}
51+
name={name}
5152
/>
5253
{error && (
53-
<div id={`${inputId}-error`} class="text-alert mt-1 text-sm">
54+
<div id={`${inputId}-error`} class="mt-1 text-sm text-alert">
5455
{error}
5556
</div>
5657
)}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,21 @@ type TextareaProps = PropsOf<'textarea'> & {
3131
};
3232

3333
export const Textarea = component$<TextareaProps>(
34-
({ id, name, error, ['bind:value']: valueSig, value, onInput$, ...props }) => {
34+
({ id, name, error, ['bind:value']: bindSig, value, onInput$, ...props }) => {
3535
const textareaId = id || name;
3636
return (
3737
<>
3838
<textarea
3939
{...props}
4040
// workaround to support two way data-binding on the Input component (https://github.com/QwikDev/qwik/issues/3926)
41-
value={valueSig ? valueSig.value : value}
42-
onInput$={valueSig ? $((__, el) => (valueSig.value = el.value)) : onInput$}
41+
value={bindSig ? bindSig.value : value}
42+
onInput$={[bindSig && $((_, el) => (bindSig.value = el.value)), onInput$]}
4343
class={cn(
4444
'[&::-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',
4545
props.class,
4646
)}
4747
id={textareaId}
48+
name={name}
4849
/>
4950
{error && <div id={`${textareaId}-error`}>{error}</div>}
5051
</>

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

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

44
export const Checkbox = component$<Partial<PropsOf<'input'> & { type?: 'checkbox' }>>(
5-
({ id, name, ['bind:checked']: checkedSig, checked, onInput$, ...props }) => {
5+
({ id, name, ['bind:checked']: bindSig, checked, onInput$, ...props }) => {
66
const inputId = id || name;
77
return (
88
<input
99
{...props}
1010
type="checkbox"
1111
// workaround to support two way data-binding on the Input component (https://github.com/QwikDev/qwik/issues/3926)
12-
checked={checkedSig ? checkedSig.value : checked}
13-
onInput$={checkedSig ? $((_, el) => (checkedSig.value = el.checked)) : onInput$}
14-
data-checked={checked || checkedSig?.value || ''}
12+
checked={bindSig ? bindSig.value : checked}
13+
onInput$={[bindSig && $((_, el) => (bindSig.value = el.checked)), onInput$]}
14+
data-checked={checked || bindSig?.value || ''}
1515
class={cn(
1616
'peer h-4 w-4 shrink-0 border-primary text-primary accent-primary ring-offset-background focus:ring-ring focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
1717
props.class,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ type InputProps = PropsOf<'input'> & {
66
};
77

88
export const Input = component$<InputProps>(
9-
({ name, error, id, ['bind:value']: valueSig, value, onInput$, ...props }) => {
9+
({ name, error, id, ['bind:value']: bindSig, value, onInput$, ...props }) => {
1010
const inputId = id || name;
1111

1212
return (
@@ -16,8 +16,8 @@ export const Input = component$<InputProps>(
1616
aria-errormessage={`${inputId}-error`}
1717
aria-invalid={!!error}
1818
// workaround to support two way data-binding on the Input component (https://github.com/QwikDev/qwik/issues/3926)
19-
value={valueSig ? valueSig.value : value}
20-
onInput$={valueSig ? $((__, el) => (valueSig.value = el.value)) : onInput$}
19+
value={bindSig ? bindSig.value : value}
20+
onInput$={[bindSig && $((_, el) => (bindSig.value = el.value)), onInput$]}
2121
class={cn(
2222
'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',
2323
props.class,

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@ type TextareaProps = PropsOf<'textarea'> & {
66
};
77

88
export const Textarea = component$<TextareaProps>(
9-
({ id, name, error, ['bind:value']: valueSig, value, onInput$, ...props }) => {
9+
({ id, name, error, ['bind:value']: bindSig, value, onInput$, ...props }) => {
1010
const textareaId = id || name;
1111
return (
1212
<>
1313
<textarea
1414
{...props}
1515
// 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$}
16+
value={bindSig ? bindSig.value : value}
17+
onInput$={[bindSig && $((_, el) => (bindSig.value = el.value)), onInput$]}
1818
class={cn(
1919
'[&::-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',
2020
props.class,
2121
)}
2222
id={textareaId}
23+
name={name}
2324
/>
2425
{error && <div id={`${textareaId}-error`}>{error}</div>}
2526
</>

0 commit comments

Comments
 (0)