Skip to content

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
ts
import { createInput } from "@duplojs/form/vue";

const useMyInput = createInput(component, defaultParams);

Puis :

ts
ts
const field = useMyInput(params);

Paramètres de createInput(...)

ts
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: template input par défaut.

Paramètres de useMyInput(...)

ts
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 template input.

Contrat du composant Vue d'input

Le composant doit :

  • accepter modelValue ;
  • émettre update:modelValue ;
  • accepter un id injecté par la librairie.

Il peut aussi exposer :

ts
ts
{
	check?(): Either;
	reset?(): void;
	dispose?(): void;
}

Contrat du template input

Props

ts
ts
{
	getLabel?(): string;
	getCurrentValue(): unknown;
	getErrorMessage?(): string | null;
	fieldKey: string;
}

Slots

ts
ts
{
	input(): any;
}

Petit exemple de template

vue
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
ts
import { createTemplate } from "@duplojs/form/vue";
import MyInputTemplate from "./inputTemplate.vue";

export const useMyInputTemplate = createTemplate(
	"input",
	MyInputTemplate,
);

Exemple minimal

ts
ts
import { createInput } from "@duplojs/form/vue";
import BasicTextInput from "./BasicTextInput.vue";

export const useBasicTextInput = createInput(
	BasicTextInput,
	{
		defaultValue: "",
	},
);

Exemple avec validation locale

vue
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.

Released under the MIT License.