Usage API Source code
SfInput is a single-line text field allows users to enter any combination of letters, numbers, or symbols. It adds default styles to the native <input type="text"> and supports supports adding content before/after the text input.
SfInput supports 3 sizes that can be set with the size prop: 'sm', base, and 'lg'.
Preview Code
import { component$ } from '@builder.io/qwik' ;
import { SfInput } from 'qwik-storefront-ui' ;
export default component$ (() => {
return (
< div class = "flex flex-col gap-y-5" >
< SfInput size = "sm" aria-label = "Label size sm" />
< SfInput aria-label = "Label size base" />
< SfInput size = "lg" aria-label = "Label size lg" />
</ div >
);
}); You can insert content before and after your input using the prefix and suffix slots.
This can be useful for adding icons or buttons to your input.
Preview Code
import { component$ } from '@builder.io/qwik' ;
import { SfIconLockOpen , SfIconPerson , SfInput } from 'qwik-storefront-ui' ;
export default component$ (() => {
return (
< label >
< span class = "text-sm font-medium" >Label</ span >
< SfInput slotPrefix = { true } slotSuffix = { true } >
< div q : slot = "prefix" >
< SfIconPerson />
</ div >
< div q : slot = "suffix" >
< SfIconLockOpen />
</ div >
</ SfInput >
</ label >
);
}); SfInput comes with out-of-the-box styles for a disabled input.
Preview Code
import { component$ } from '@builder.io/qwik' ;
import { SfInput } from 'qwik-storefront-ui' ;
export default component$ (() => {
return (
<>
< label >
< span class = "text-sm font-medium cursor-not-allowed text-disabled-900" >
Label
</ span >
< SfInput
disabled
wrapperClass = "!bg-disabled-100 !ring-disabled-300 !ring-1"
/>
</ label >
< div class = "flex justify-between" >
< div >
< p class = "text-xs text-disabled-500 mt-0.5" >Help Text</ p >
</ div >
</ div >
</>
);
}); SfInput comes with out-of-the-box styles for a readonly input.
Preview Code
import { component$ , useSignal } from '@builder.io/qwik' ;
import { SfInput } from 'qwik-storefront-ui' ;
export default component$ (() => {
const valueSignal = useSignal ( 'value' );
return (
<>
< label >
< span class = "text-sm font-medium" >Label</ span >
< SfInput
value = { valueSignal . value }
onChange$ = { ( event ) => {
valueSignal . value = event . target . value ;
} }
wrapperClass = "!bg-disabled-100 !ring-disabled-300 !ring-1"
readOnly
/>
</ label >
< div class = "flex justify-between" >
< div >
< p class = "text-xs text-neutral-500 mt-0.5" >Help Text</ p >
</ div >
</ div >
</>
);
}); If you pass the invalid prop, the input will be styled to indicate an invalid state.
Preview Code
import { component$ } from '@builder.io/qwik' ;
import { SfInput } from 'qwik-storefront-ui' ;
export default component$ (() => {
return (
<>
< label >
< span class = "text-sm font-medium" >Label</ span >
< SfInput invalid />
</ label >
< div class = "flex justify-between" >
< div >
< p class = "text-sm text-negative-700 font-medium mt-0.5" >Error</ p >
< p class = "text-xs text-neutral-500 mt-0.5" >Help Text</ p >
</ div >
</ div >
</>
);
}); This is an example of what SfInput might look like in your end code. It has a label, help text, character counting, and different styles depending on the input state.
Preview Code
import { component$ , useComputed$ , useSignal } from '@builder.io/qwik' ;
import { SfInput } from 'qwik-storefront-ui' ;
export default component$ (() => {
const characterLimit = 25 ;
const label = 'Label' ;
const placeholder = 'placeholder' ;
const disabled = false ;
const readonly = false ;
const invalid = false ;
const helpText = 'Help text' ;
const required = false ;
const requiredText = 'Required' ;
const errorText = 'Error' ;
const valueSignal = useSignal ( '' );
const isAboveLimitSignal = useComputed$ (() =>
characterLimit ? valueSignal . value . length > characterLimit : false
);
const charsCountSignal = useComputed$ (() =>
characterLimit ? characterLimit - valueSignal . value . length : null
);
const getCharacterLimitClassSignal = useComputed$ (() =>
isAboveLimitSignal . value
? 'text-negative-700 font-medium'
: 'text-neutral-500'
);
return (
<>
< label >
< span
class = { `text-sm font-medium ${
disabled ? 'cursor-not-allowed text-disabled-500' : ''
} ` }
>
{ label }
</ span >
< SfInput
size = "base"
invalid = { false }
placeholder = { placeholder }
disabled = { disabled }
readOnly = { readonly }
wrapperClass = { ` ${
disabled || readonly
? 'peer !bg-disabled-100 !ring-disabled-300 !ring-1 !text-disabled-500'
: ''
} ` }
value = { valueSignal . value }
onChange$ = { ( event ) => {
valueSignal . value = event . target . value ;
} }
/>
</ label >
< div class = "flex justify-between" >
< div >
{ invalid && ! disabled && (
< p class = "text-sm text-negative-700 font-medium mt-0.5" >
{ errorText }
</ p >
) }
{ helpText && (
< p
class = { `text-xs mt-0.5 ${
disabled ? 'text-disabled-500' : 'text-neutral-500'
} ` }
>
{ helpText }
</ p >
) }
{ requiredText && required ? (
< p class = "mt-1 text-sm font-normal text-neutral-500 before:content-['*']" >
{ requiredText }
</ p >
) : null }
</ div >
{ characterLimit && ! readonly ? (
< p
class = { `text-xs mt-0.5 ${
disabled
? 'text-disabled-500'
: getCharacterLimitClassSignal . value
} ` }
>
{ charsCountSignal . value }
</ p >
) : null }
</ div >
</>
);
}); All non-prop attributes and styles added to SfInput component are passed directly to the native input element. This means that you can add all of the input attributes directly to SfInput. If you want to style the wrapper div, you can pass your classes via the wrapperClass.
Since, size is a specified prop of SfInput, you won't be able to pass the native size attribute to your input element. Instead, you can use the width property with ch unit instead (eg. width: 10ch).