diff --git a/examples/react-mui/src/component-map.ts b/examples/react-mui/src/component-map.ts index 502e8df..94889ee 100644 --- a/examples/react-mui/src/component-map.ts +++ b/examples/react-mui/src/component-map.ts @@ -1,4 +1,5 @@ import type { FieldComponentMap } from '@formhaus/react'; +import { AutocompleteField } from './fields/AutocompleteField'; import { CheckboxField } from './fields/CheckboxField'; import { FileField } from './fields/FileField'; import { RadioField } from './fields/RadioField'; @@ -14,7 +15,9 @@ export const components: FieldComponentMap = { number: TextField, password: TextField, date: TextField, + datetime: TextField, select: SelectField, + autocomplete: AutocompleteField, multiselect: SelectField, checkbox: CheckboxField, radio: RadioField, diff --git a/examples/react-mui/src/definition.json b/examples/react-mui/src/definition.json index cbe1c70..45836e2 100644 --- a/examples/react-mui/src/definition.json +++ b/examples/react-mui/src/definition.json @@ -30,9 +30,9 @@ }, { "key": "country", - "type": "select", + "type": "autocomplete", "label": "Country", - "placeholder": "Select a country", + "placeholder": "Type to filter…", "options": [ { "value": "US", "label": "United States" }, { "value": "MX", "label": "Mexico" }, @@ -41,6 +41,12 @@ { "value": "IN", "label": "India" } ], "validation": { "required": true } + }, + { + "key": "meetingTime", + "type": "datetime", + "label": "Preferred meeting time", + "helperText": "We'll confirm by email" } ] } diff --git a/examples/react-mui/src/fields/AutocompleteField.tsx b/examples/react-mui/src/fields/AutocompleteField.tsx new file mode 100644 index 0000000..ca01a3d --- /dev/null +++ b/examples/react-mui/src/fields/AutocompleteField.tsx @@ -0,0 +1,47 @@ +import type { FieldComponentProps } from '@formhaus/react'; +import Autocomplete from '@mui/material/Autocomplete'; +import MuiTextField from '@mui/material/TextField'; + +interface Option { + value: string; + label: string; +} + +export function AutocompleteField({ + field, + value, + error, + loading, + disabled, + onChange, + onBlur, + onFocus, +}: FieldComponentProps) { + const options = (field.options ?? []) as Option[]; + const selected = options.find((o) => o.value === value) ?? null; + + return ( + opt.label} + isOptionEqualToValue={(a, b) => a.value === b.value} + onChange={(_, opt) => onChange(opt?.value ?? '')} + onBlur={onBlur} + onFocus={onFocus} + disabled={disabled || loading} + fullWidth + renderInput={(params) => ( + + )} + /> + ); +} diff --git a/examples/react-mui/src/fields/TextField.tsx b/examples/react-mui/src/fields/TextField.tsx index a2ef78d..a29338d 100644 --- a/examples/react-mui/src/fields/TextField.tsx +++ b/examples/react-mui/src/fields/TextField.tsx @@ -14,9 +14,12 @@ export function TextField({ : field.type === 'password' ? 'password' : field.type === 'number' ? 'number' : field.type === 'date' ? 'date' + : field.type === 'datetime' ? 'datetime-local' : field.type === 'phone' ? 'tel' : 'text'; + const shrinkLabel = field.type === 'date' || field.type === 'datetime'; + return ( ); diff --git a/examples/vue-vuetify/src/component-map.ts b/examples/vue-vuetify/src/component-map.ts index eb5bced..a2be461 100644 --- a/examples/vue-vuetify/src/component-map.ts +++ b/examples/vue-vuetify/src/component-map.ts @@ -1,4 +1,5 @@ import type { FieldComponentMap } from '@formhaus/vue'; +import AutocompleteField from './fields/AutocompleteField.vue'; import CheckboxField from './fields/CheckboxField.vue'; import FileField from './fields/FileField.vue'; import RadioField from './fields/RadioField.vue'; @@ -14,7 +15,9 @@ export const components: Partial = { number: TextField, password: TextField, date: TextField, + datetime: TextField, select: SelectField, + autocomplete: AutocompleteField, multiselect: SelectField, checkbox: CheckboxField, radio: RadioField, diff --git a/examples/vue-vuetify/src/definition.json b/examples/vue-vuetify/src/definition.json index cbe1c70..45836e2 100644 --- a/examples/vue-vuetify/src/definition.json +++ b/examples/vue-vuetify/src/definition.json @@ -30,9 +30,9 @@ }, { "key": "country", - "type": "select", + "type": "autocomplete", "label": "Country", - "placeholder": "Select a country", + "placeholder": "Type to filter…", "options": [ { "value": "US", "label": "United States" }, { "value": "MX", "label": "Mexico" }, @@ -41,6 +41,12 @@ { "value": "IN", "label": "India" } ], "validation": { "required": true } + }, + { + "key": "meetingTime", + "type": "datetime", + "label": "Preferred meeting time", + "helperText": "We'll confirm by email" } ] } diff --git a/examples/vue-vuetify/src/fields/AutocompleteField.vue b/examples/vue-vuetify/src/fields/AutocompleteField.vue new file mode 100644 index 0000000..8c54c86 --- /dev/null +++ b/examples/vue-vuetify/src/fields/AutocompleteField.vue @@ -0,0 +1,30 @@ + + + diff --git a/examples/vue-vuetify/src/fields/TextField.vue b/examples/vue-vuetify/src/fields/TextField.vue index 9a9817f..82b961e 100644 --- a/examples/vue-vuetify/src/fields/TextField.vue +++ b/examples/vue-vuetify/src/fields/TextField.vue @@ -14,6 +14,7 @@ const inputType = : props.field.type === 'password' ? 'password' : props.field.type === 'number' ? 'number' : props.field.type === 'date' ? 'date' + : props.field.type === 'datetime' ? 'datetime-local' : props.field.type === 'phone' ? 'tel' : 'text';