Some checks failed
Production PR / QA Tests (pull_request) Failing after 13s
50 lines
1.3 KiB
Vue
50 lines
1.3 KiB
Vue
<script setup lang="ts">
|
|
import type { HTMLAttributes } from "vue";
|
|
import { computed } from "vue";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
const props = defineProps<{
|
|
class?: HTMLAttributes["class"];
|
|
errors?: Array<string | { message: string | undefined } | undefined>;
|
|
}>();
|
|
|
|
const content = computed(() => {
|
|
if (!props.errors || props.errors.length === 0) return null;
|
|
|
|
const uniqueErrors = [
|
|
...new Map(
|
|
props.errors.filter(Boolean).map((error) => {
|
|
const message = typeof error === "string" ? error : error?.message;
|
|
return [message, error];
|
|
})
|
|
).values(),
|
|
];
|
|
|
|
if (uniqueErrors.length === 1 && uniqueErrors[0]) {
|
|
return typeof uniqueErrors[0] === "string" ? uniqueErrors[0] : uniqueErrors[0].message;
|
|
}
|
|
|
|
return uniqueErrors.map((error) => (typeof error === "string" ? error : error?.message));
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
v-if="$slots.default || content"
|
|
role="alert"
|
|
data-slot="field-error"
|
|
:class="cn('text-destructive text-sm font-normal', props.class)"
|
|
>
|
|
<slot v-if="$slots.default" />
|
|
|
|
<template v-else-if="typeof content === 'string'">
|
|
{{ content }}
|
|
</template>
|
|
|
|
<ul v-else-if="Array.isArray(content)" class="ml-4 flex list-disc flex-col gap-1">
|
|
<li v-for="(error, index) in content" :key="index">
|
|
{{ error }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</template>
|