When a form has fields that depend on a condition or a toggle (discriminated unions), use createVariant to declare the different states and narrowVariant to safely access fields within specific UI blocks. This ensures that fields are only accessible when the current state of the form makes them valid, maintaining both runtime safety and TypeScript accuracy.
<template>
<div v-if="narrowVariant(r$, 'type', 'EMAIL')">
<!-- `email` is a known field only in this block -->
<input v-model="r$.email.$value" placeholder='Email'/>
<Errors :errors="r$.email.$errors"/>
</div>
<div v-else-if="narrowVariant(r$, 'type', 'GITHUB')">
<!-- `username` is a known field only in this block -->
<input v-model="r$.username.$value" placeholder='Email'/>
<Errors :errors="r$.username.$errors"/>
</div>
</template>
<script setup lang='ts'>
import { useRegle, createVariant, narrowVariant } from '@regle/core';
const state = ref<FormState>({})
const {r$} = useRegle(state, () => {
const variant = createVariant(state, 'type', [
{type: { literal: literal('EMAIL')}, email: { required, email }},
{type: { literal: literal('GITHUB')}, username: { required }},
{type: { required }},
]);
return {
firstName: { required },
...variant.value,
};
})
</script>