bonsaif-ui 0.1.19 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -1
- package/dist/bonsaif-ui.js +3155 -2643
- package/dist/bonsaif-ui.umd.cjs +1 -1
- package/dist/components/ui/EmailField.d.ts +7 -0
- package/dist/components/ui/EmailField.d.ts.map +1 -0
- package/dist/components/ui/InputField.d.ts +6 -2
- package/dist/components/ui/InputField.d.ts.map +1 -1
- package/dist/components/ui/MouseTooltip.d.ts.map +1 -1
- package/dist/components/ui/NumberField.d.ts +4 -0
- package/dist/components/ui/NumberField.d.ts.map +1 -0
- package/dist/components/ui/PhoneField.d.ts +22 -0
- package/dist/components/ui/PhoneField.d.ts.map +1 -0
- package/dist/components/ui/SearchableSelect.d.ts +6 -1
- package/dist/components/ui/SearchableSelect.d.ts.map +1 -1
- package/dist/components/ui/index.d.ts +7 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/phoneCountryCodes.d.ts +7 -0
- package/dist/lib/phoneCountryCodes.d.ts.map +1 -0
- package/dist/lib/validation.d.ts +23 -0
- package/dist/lib/validation.d.ts.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -32,12 +32,110 @@ The package includes reusable components migrated from `prime-auth` and new shar
|
|
|
32
32
|
|
|
33
33
|
### Forms
|
|
34
34
|
|
|
35
|
-
- `InputField`, `TextInput`, `Textarea`:
|
|
35
|
+
- `InputField`, `EmailField`, `PhoneField`, `NumberField`, `TextInput`, `Textarea`: inputs with Bonsaif styling and inline validation for email and phone values.
|
|
36
36
|
- `SearchableSelect`, `CompactFilterSelect`, `CompactSearchInput`: select and filter controls.
|
|
37
37
|
- `CalendarPicker`, `DateRangePicker`: single-date and range selection.
|
|
38
38
|
- `Checkbox`, `RadioGroup`, `Toggle`: boolean and option controls.
|
|
39
39
|
- `FormField`: label, helper, error, and required wrapper for custom controls.
|
|
40
40
|
|
|
41
|
+
#### Form Validation
|
|
42
|
+
|
|
43
|
+
Use `validateForm` with reusable validators to validate complete forms before saving. Validators run in order and return the first error per field. Add `noValidate` to the form to avoid native browser validation, then pass each error to the field with `errorDisplay="tooltip"` when the message should appear in the compact validation tooltip.
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import { useMemo, useState, type FormEvent } from "react";
|
|
47
|
+
import {
|
|
48
|
+
EmailField,
|
|
49
|
+
PhoneField,
|
|
50
|
+
emailFormat,
|
|
51
|
+
maxValue,
|
|
52
|
+
minLength,
|
|
53
|
+
minValue,
|
|
54
|
+
phoneFormat,
|
|
55
|
+
required,
|
|
56
|
+
validateForm,
|
|
57
|
+
type ValidationSchema,
|
|
58
|
+
} from "bonsaif-ui";
|
|
59
|
+
|
|
60
|
+
type AccountForm = {
|
|
61
|
+
contactName: string;
|
|
62
|
+
contactEmail: string;
|
|
63
|
+
contactCountryCode: string;
|
|
64
|
+
contactPhone: string;
|
|
65
|
+
seats: string;
|
|
66
|
+
discountCode: string;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const schema = {
|
|
70
|
+
contactName: [required("Escribe el nombre."), minLength(3)],
|
|
71
|
+
contactEmail: [required(), emailFormat()],
|
|
72
|
+
contactCountryCode: [required()],
|
|
73
|
+
contactPhone: (value, values) =>
|
|
74
|
+
phoneFormat()(`${values.contactCountryCode} ${value}`),
|
|
75
|
+
seats: [required(), minValue(1), maxValue(500)],
|
|
76
|
+
discountCode: (value, values) =>
|
|
77
|
+
Number(values.seats) > 100 && String(value).trim() === ""
|
|
78
|
+
? "Solicita un codigo para cuentas de mas de 100 usuarios."
|
|
79
|
+
: undefined,
|
|
80
|
+
} satisfies ValidationSchema<AccountForm>;
|
|
81
|
+
|
|
82
|
+
function AccountFormExample() {
|
|
83
|
+
const [form, setForm] = useState<AccountForm>({
|
|
84
|
+
contactName: "",
|
|
85
|
+
contactEmail: "",
|
|
86
|
+
contactCountryCode: "+1",
|
|
87
|
+
contactPhone: "",
|
|
88
|
+
seats: "",
|
|
89
|
+
discountCode: "",
|
|
90
|
+
});
|
|
91
|
+
const validationResult = useMemo(
|
|
92
|
+
() => validateForm(form, schema),
|
|
93
|
+
[form],
|
|
94
|
+
);
|
|
95
|
+
const errors = validationResult.errors;
|
|
96
|
+
|
|
97
|
+
function submitForm(event: FormEvent<HTMLFormElement>) {
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
if (!validationResult.valid) return;
|
|
100
|
+
|
|
101
|
+
saveAccount(form);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<form noValidate onSubmit={submitForm}>
|
|
106
|
+
<EmailField
|
|
107
|
+
label="Correo"
|
|
108
|
+
value={form.contactEmail}
|
|
109
|
+
error={errors.contactEmail}
|
|
110
|
+
validate={false}
|
|
111
|
+
errorDisplay="tooltip"
|
|
112
|
+
/>
|
|
113
|
+
<PhoneField
|
|
114
|
+
label="Telefono"
|
|
115
|
+
countryCode={form.contactCountryCode}
|
|
116
|
+
onCountryCodeChange={(countryCode) =>
|
|
117
|
+
setForm((current) => ({ ...current, contactCountryCode: countryCode }))
|
|
118
|
+
}
|
|
119
|
+
allowedCountryCodes={["+1", "+34", "+52", "+57", "+58"]}
|
|
120
|
+
value={form.contactPhone}
|
|
121
|
+
onChange={(event) =>
|
|
122
|
+
setForm((current) => ({
|
|
123
|
+
...current,
|
|
124
|
+
contactPhone: event.currentTarget.value,
|
|
125
|
+
}))
|
|
126
|
+
}
|
|
127
|
+
error={errors.contactPhone}
|
|
128
|
+
validate={false}
|
|
129
|
+
errorDisplay="tooltip"
|
|
130
|
+
/>
|
|
131
|
+
<button type="submit" disabled={!validationResult.valid}>
|
|
132
|
+
Guardar
|
|
133
|
+
</button>
|
|
134
|
+
</form>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
41
139
|
### Actions And Overlays
|
|
42
140
|
|
|
43
141
|
- `Button`, `BonsaifButton`: action buttons.
|