Last active
June 13, 2024 04:22
-
-
Save HappyTiptoe/b798357efc7c6bec59af01a5fa252f99 to your computer and use it in GitHub Desktop.
Vue.js composable for consuming Vest suites and receiving reactive references to the result and classes. Written in TypeScript and JavaScript.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Form.vue --> | |
<script setup lang="ts"> | |
import { reactive } from 'vue' | |
import { useSuite } from '~/composables/useSuite' | |
import { suite } from '~/suites/example' | |
const { res, classes, validate, reset } = useSuite(suite) | |
const formData = reactive({ | |
email: '', | |
password: '' | |
}) | |
function validateField(field: string) { | |
validate(formData, field) | |
} | |
function resetForm() { | |
formData.email = '' | |
formData.password = '' | |
reset() | |
} | |
/* - - - */ | |
function handleSubmit() { | |
// check if form is invalid before submitting | |
if (!res.value.isValid()) { | |
return | |
} | |
/* ... */ | |
} | |
</script> | |
<template> | |
<form @submit.prevent="handleSubmit"> | |
<label> | |
Email: | |
<input | |
v-model="formData.email" | |
type="text" | |
:class="classes('email')" | |
@input="validateField('email')" | |
/> | |
</label> | |
<label> | |
Password: | |
<input | |
v-model="formData.password" | |
type="password" | |
:class="classes('password')" | |
@input="validateField('password')" | |
/> | |
</label> | |
<button type="submit" :disabled="!res.isValid()">Submit Form</button> | |
<button type="button" @click="resetForm">Clear Form</button> | |
</form> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* useSuite.ts */ | |
import type { Suite } from 'vest' | |
import type { CB } from 'vest-utils' | |
import { computed, ref } from 'vue' | |
import classnames from 'vest/classnames' | |
// Duplicate of unexported `SupportedClasses` interface | |
interface Classes { | |
valid?: string | |
tested?: string | |
invalid?: string | |
warning?: string | |
untested?: string | |
} | |
// Replace `undefined` with your class names of choice! | |
const DEFAULT_CLASSES: Classes = { | |
valid: undefined, | |
tested: undefined, | |
invalid: undefined, | |
warning: undefined, | |
untested: undefined | |
} | |
/** | |
* Vue composable for interacting with [Vest](https://vestjs.dev) validation suites. | |
* | |
* @param {Suite} suite - The Vest validation suite | |
* @param {Classes} [_classes] - The user-defined state-validity class names | |
*/ | |
export function useSuite<T extends CB>(suite: Suite<T>, _classes?: Classes) { | |
// reactive reference to the suite result | |
const res = ref(suite.get()) | |
// method which returns respective classes depending on field's validity status; | |
// here, we merge the user's input class names with the default class names | |
// defined above | |
const classes = computed(() => { | |
return classnames(res.value, { ...DEFAULT_CLASSES, ..._classes }) | |
}) | |
// the suite validation method | |
function validate(...args: Parameters<T>) { | |
res.value = suite(...args) | |
} | |
// the suite reset method | |
function reset() { | |
suite.reset() | |
res.value = suite.get() | |
} | |
// the suite reset method for a single field | |
function resetField(field: string) { | |
suite.resetField(field) | |
res.value = suite.get() | |
} | |
return { res, classes, validate, reset, resetField } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* useSuite.js */ | |
// Replace `undefined` with your class names of choice! | |
const DEFAULT_CLASSES = { | |
valid: undefined, | |
tested: undefined, | |
invalid: undefined, | |
warning: undefined, | |
untested: undefined | |
} | |
/** | |
* Vue composable for interacting with [Vest](https://vestjs.dev) validation suites. | |
* | |
* @param suite - The Vest validation suite | |
* @param [_classes] - The user-defined state-validity class names | |
*/ | |
export function useSuite(suite, _classes) { | |
// reactive reference to the suite result | |
const res = ref(suite.get()) | |
// method which returns respective classes depending on field's validity status; | |
// here, we merge the user's input class names with the default class names | |
// defined above | |
const classes = computed(() => { | |
return classnames(res.value, { ...DEFAULT_CLASSES, ..._classes }) | |
}) | |
// the suite validation method | |
function validate(...args) { | |
res.value = suite(...args) | |
} | |
// the suite reset method | |
function reset() { | |
suite.reset() | |
res.value = suite.get() | |
} | |
// the suite reset method for a single field | |
function resetField(field) { | |
suite.resetField(field) | |
res.value = suite.get() | |
} | |
return { res, classes, validate, reset, resetField } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice! It is live here:
https://vestjs.dev/docs/community_resources/showcase