feat: improve validation message component

This commit is contained in:
tdgao
2026-09-04 13:57:42 -06:00
parent cea2c59573
commit 3427ed20d2
@@ -1,28 +1,34 @@
<template> <template>
<div v-if="validations.length > 0" class="flex w-full flex-col gap-1.5"> <Transition name="validation-message">
<div <div v-if="validations.length > 0" v-bind="$attrs" class="grid w-full grid-rows-[1fr]">
v-for="(validation, index) in validations" <div class="flex min-h-0 w-full flex-col gap-1.5 overflow-hidden">
:key="validation.code ?? validation.message?.id ?? index" <div
class="flex w-full items-start gap-1.5" v-for="(validation, index) in validations"
:class="{ :key="validation.code ?? validation.message?.id ?? index"
'text-red': validation.severity === 'error', class="flex w-full items-start gap-1.5"
'text-orange': validation.severity === 'warning', :class="{
'text-purple': validation.severity === 'suggestion', 'text-red': validation.severity === 'error',
}" 'text-orange': validation.severity === 'warning',
> 'text-purple': validation.severity === 'suggestion',
<component }"
:is=" >
validation.severity === 'error' <component
? XCircleIcon :is="
: validation.severity === 'suggestion' validation.severity === 'error'
? LightBulbIcon ? XCircleIcon
: TriangleAlertIcon : validation.severity === 'suggestion'
" ? LightBulbIcon
class="mt-0.5" : TriangleAlertIcon
/> "
{{ validation.message ? formatMessage(validation.message, validation.values) : undefined }} class="mt-0.5 shrink-0"
/>
{{
validation.message ? formatMessage(validation.message, validation.values) : undefined
}}
</div>
</div>
</div> </div>
</div> </Transition>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -31,6 +37,8 @@ import type { FieldValidationMessage } from '@modrinth/moderation'
import { injectProjectPageContext, useVIntl } from '@modrinth/ui' import { injectProjectPageContext, useVIntl } from '@modrinth/ui'
import { computed, onScopeDispose, ref, shallowRef, watch } from 'vue' import { computed, onScopeDispose, ref, shallowRef, watch } from 'vue'
defineOptions({ inheritAttrs: false })
type ValidationCheck = Omit<FieldValidationMessage, 'code'> & { code?: string } type ValidationCheck = Omit<FieldValidationMessage, 'code'> & { code?: string }
type ValidationCheckInput = ValidationCheck | ValidationCheck[] | null type ValidationCheckInput = ValidationCheck | ValidationCheck[] | null
@@ -111,3 +119,27 @@ const validations = computed(() => {
: [] : []
}) })
</script> </script>
<style scoped>
.validation-message-enter-active,
.validation-message-leave-active {
transition:
grid-template-rows 150ms ease,
opacity 150ms ease,
transform 150ms ease;
}
.validation-message-enter-from,
.validation-message-leave-to {
grid-template-rows: 0fr;
opacity: 0;
transform: translateY(-0.25rem);
}
@media (prefers-reduced-motion: reduce) {
.validation-message-enter-active,
.validation-message-leave-active {
transition: none;
}
}
</style>