useUnionLayout
useUnionLayout(...) lets you activate only one branch among several FormField instances.
Signature
ts
useUnionLayout(
[
["kindA", fieldA],
["kindB", fieldB],
],
{
defaultKind,
class?: string,
template?: Templates["union"],
},
);Parameters
formFieldUnionElements: array of[kind, formField]tuples.defaultKind: active branch at startup.class: CSS class added to theuniontemplate.template: local override of theuniontemplate.
Produced value
Current value
ts
{
kind: string;
value: unknown;
updateKind(kind: string, value?: unknown): void;
}Validated value
ts
{
kind: string;
value: unknown;
}union template contract
Props
ts
{
fieldKey: string;
kinds: string[];
getCurrentValue(): unknown;
getCurrentKind(): string;
}Emits
ts
{
changeKind: [kind: string];
}Slots
ts
{
formField(): any;
}Small template example
vue
<script setup lang="ts">
import { type UnionTemplateProperties } from "@duplojs/form/vue";
defineProps<UnionTemplateProperties["props"]>();
defineSlots<UnionTemplateProperties["slots"]>();
defineEmits<UnionTemplateProperties["emits"]>();
</script>
<template>
<div>
<select @change="$emit('changeKind', ($event.target as HTMLSelectElement).value)">
<option
v-for="kind in kinds"
:key="kind"
:selected="kind === getCurrentKind()"
:value="kind"
>
{{ kind }}
</option>
</select>
<slot name="formField" />
</div>
</template>ts
import { createTemplate } from "@duplojs/form/vue";
import MyUnionTemplate from "./unionTemplate.vue";
export const useMyUnionTemplate = createTemplate(
"union",
MyUnionTemplate,
);Example
ts
import { useUnionLayout } from "@duplojs/form/vue";
import { useTextInput } from "@duplojs/form/vueDesignSystem";
export const preferredChannel = useUnionLayout(
[
["email", useTextInput({ label: "Email" })],
["phone", useTextInput({ label: "Phone" })],
],
{ defaultKind: "email" },
);Use cases
- email or phone;
- individual or company;
- credit card or bank transfer.
