
* feat(validator): server-side rendered validation errors * test(form): field should render error * refactor: remove comment * fix: incorrect imports * chore: update deps * chore: update build commands
98 lines
2.2 KiB
Text
98 lines
2.2 KiB
Text
---
|
|
import type { FormControl } from '../core/form-control';
|
|
|
|
export interface Props {
|
|
control: FormControl;
|
|
showValidationHints: boolean;
|
|
showErrors?: boolean;
|
|
showOnlyLabel?: boolean;
|
|
}
|
|
|
|
const { control, showValidationHints, showErrors = false, showOnlyLabel = false } = Astro.props;
|
|
|
|
const { validators = [] } = control;
|
|
|
|
const isRequired: boolean = showValidationHints && validators.includes('validator-required');
|
|
|
|
const hasErrors: boolean = showValidationHints && !!control.errors?.length;
|
|
|
|
const validatorAttributes: Record<string, string> = validators?.reduce(
|
|
(prev, validator) => {
|
|
const split: string[] = validator.split(':');
|
|
const label: string = `data-${split[0]}` || 'invalid';
|
|
const value: string | null = split.length > 1 ? split[1] ?? null : 'true';
|
|
|
|
return {
|
|
...prev,
|
|
[label]: value,
|
|
};
|
|
},
|
|
|
|
{}
|
|
);
|
|
---
|
|
|
|
<div
|
|
class="field"
|
|
data-validator-hints={showValidationHints?.toString()}
|
|
data-validator-haserrors={hasErrors ? hasErrors?.toString() : null}
|
|
>
|
|
{
|
|
control.label && control.labelPosition === 'left' && (
|
|
<label for={control?.id ?? control.name}>
|
|
{isRequired && <span>*</span>}
|
|
{control.label}
|
|
</label>
|
|
)
|
|
}
|
|
|
|
{
|
|
!showOnlyLabel && (
|
|
<input
|
|
name={control.name}
|
|
id={control?.id ?? control.name}
|
|
type={control.type}
|
|
value={control.value?.toString()}
|
|
checked={control.value === 'checked'}
|
|
placeholder={control.placeholder}
|
|
data-label={control.label}
|
|
data-label-position={control.labelPosition}
|
|
data-validator-haserrors={hasErrors ? hasErrors?.toString() : null}
|
|
class:list={[{ 'has-errors': hasErrors }]}
|
|
{...validatorAttributes}
|
|
/>
|
|
)
|
|
}
|
|
|
|
{
|
|
showErrors &&
|
|
hasErrors &&
|
|
control.errors.map((error) => (
|
|
<li>
|
|
{error.error} {error.limit}
|
|
</li>
|
|
))
|
|
}
|
|
|
|
{
|
|
control.label && control.labelPosition === 'right' && (
|
|
<label for={control?.id ?? control.name}>
|
|
{isRequired && <span>*</span>}
|
|
{control.label}
|
|
</label>
|
|
)
|
|
}
|
|
</div>
|
|
|
|
<style>
|
|
/**
|
|
TODO: remove usage of data-validator-haserrors,
|
|
class has-errors is sufficient
|
|
*/
|
|
[data-validator-hints='true'][data-validator-haserrors='true'],
|
|
[data-validator-hints='true'] [data-validator-haserrors='true'],
|
|
.has-errors {
|
|
color: red;
|
|
border-color: red;
|
|
}
|
|
</style>
|