Input
L'input n'est pas un layout nommé useInputLayout, mais il reste une forme fondamentale de FormField.
L'API concernée est createInput(...).
Signature
ts
import { createInput } from "@duplojs/form/vue";
const useMyInput = createInput(component, defaultParams);Puis :
ts
const field = useMyInput(params);Paramètres de createInput(...)
ts
createInput(component, {
defaultValue,
props?,
template?,
});component: composant Vue compatible avec le contrat des inputs.defaultValue: valeur par défaut du champ. Obligatoire.props: props par défaut injectées dans le composant.template: templateinputpar défaut.
Paramètres de useMyInput(...)
ts
useMyInput({
label?,
defaultValue?,
props?,
dataParser?,
class?,
template?,
});label: libellé transmis au template.defaultValue: surcharge locale de la valeur initiale.props: props locales passées au composant.dataParser: validation et transformation postérieures au composant.class: classe CSS ajoutée au template.template: surcharge locale du templateinput.
Contrat du composant Vue d'input
Le composant doit :
- accepter
modelValue; - émettre
update:modelValue; - accepter un
idinjecté par la librairie.
Il peut aussi exposer :
ts
{
check?(): Either;
reset?(): void;
dispose?(): void;
}Contrat du template input
Props
ts
{
getLabel?(): string;
getCurrentValue(): unknown;
getErrorMessage?(): string | null;
fieldKey: string;
}Slots
ts
{
input(): any;
}Petit exemple de template
vue
<script setup lang="ts">
import { type InputTemplateProperties } from "@duplojs/form/vue";
defineProps<InputTemplateProperties["props"]>();
defineSlots<InputTemplateProperties["slots"]>();
</script>
<template>
<div>
<label v-if="getLabel">
{{ getLabel() }}
</label>
<slot name="input" />
<small v-if="getErrorMessage">
{{ getErrorMessage() }}
</small>
</div>
</template>ts
import { createTemplate } from "@duplojs/form/vue";
import MyInputTemplate from "./inputTemplate.vue";
export const useMyInputTemplate = createTemplate(
"input",
MyInputTemplate,
);Exemple minimal
ts
import { createInput } from "@duplojs/form/vue";
import BasicTextInput from "./BasicTextInput.vue";
export const useBasicTextInput = createInput(
BasicTextInput,
{
defaultValue: "",
},
);Exemple avec validation locale
vue
<script setup lang="ts">
import * as EE from "@duplojs/utils/either";
import { type ExposeInputProperties } from "@duplojs/form/vue";
import { ref } from "vue";
export interface Props {
id: string;
label: string;
required?: boolean;
errorMessage?: string;
}
const props = withDefaults(
defineProps<Props>(),
{
required: false,
errorMessage: "You must accept this condition.",
},
);
const model = defineModel<boolean>({ default: false });
const currentError = ref<string | null>(null);
defineExpose<ExposeInputProperties>({
check: () => {
if (!props.required || model.value) {
currentError.value = null;
return EE.success(model.value);
}
currentError.value = props.errorMessage;
return EE.error([{ key: props.id }]);
},
reset: () => {
currentError.value = null;
},
});
</script>
<template>
<div>
<label>
<input
v-model="model"
type="checkbox"
:id="props.id"
/>
{{ props.label }}
</label>
<small v-if="currentError">
{{ currentError }}
</small>
</div>
</template>À retenir
- un input est déjà un
FormField; createInput(...)fabrique une factory de champs ;- la validation peut se faire dans le composant, dans
dataParser, ou dans les deux.
