fix(05-02): rebuild Alert sans UAlert, ProseImg img natif, test.vue layout propre

This commit is contained in:
2026-04-21 15:24:22 +02:00
parent e46912d197
commit 49f7e70c9d
3 changed files with 116 additions and 32 deletions
+90 -23
View File
@@ -2,33 +2,100 @@
interface Props { interface Props {
type?: 'info' | 'warning' | 'tip' | 'danger' type?: 'info' | 'warning' | 'tip' | 'danger'
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), { type: 'info' })
type: 'info',
})
const iconMap = { const styles = {
info: 'i-heroicons-information-circle', info: {
warning: 'i-heroicons-exclamation-triangle', wrapper: 'border-blue-500 bg-blue-50 dark:bg-blue-950/40',
tip: 'i-heroicons-light-bulb', icon: 'text-blue-500',
danger: 'i-heroicons-x-circle', text: 'text-blue-900 dark:text-blue-100',
} },
const colorMap = { warning: {
info: 'info', wrapper: 'border-amber-500 bg-amber-50 dark:bg-amber-950/40',
warning: 'warning', icon: 'text-amber-500',
tip: 'success', text: 'text-amber-900 dark:text-amber-100',
danger: 'error', },
} tip: {
wrapper: 'border-emerald-500 bg-emerald-50 dark:bg-emerald-950/40',
icon: 'text-emerald-500',
text: 'text-emerald-900 dark:text-emerald-100',
},
danger: {
wrapper: 'border-red-500 bg-red-50 dark:bg-red-950/40',
icon: 'text-red-500',
text: 'text-red-900 dark:text-red-100',
},
} as const
</script> </script>
<template> <template>
<UAlert <div
:icon="iconMap[props.type]" :class="[
:color="colorMap[props.type] as any" 'not-prose my-4 flex items-start gap-3 rounded-r-lg border-l-4 px-4 py-3',
variant="soft" styles[props.type].wrapper,
class="my-4" ]"
role="note"
> >
<template #title> <!-- Info -->
<svg
v-if="props.type === 'info'"
:class="['mt-0.5 size-5 shrink-0', styles[props.type].icon]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm8.706-1.442c1.146-.573 2.437.463 2.126 1.706l-.709 2.836.042-.02a.75.75 0 01.67 1.34l-.04.022c-1.147.573-2.438-.463-2.127-1.706l.71-2.836-.042.02a.75.75 0 11-.671-1.34l.041-.022zM12 9a.75.75 0 100-1.5.75.75 0 000 1.5z"
clip-rule="evenodd"
/>
</svg>
<!-- Warning -->
<svg
v-else-if="props.type === 'warning'"
:class="['mt-0.5 size-5 shrink-0', styles[props.type].icon]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z"
clip-rule="evenodd"
/>
</svg>
<!-- Tip -->
<svg
v-else-if="props.type === 'tip'"
:class="['mt-0.5 size-5 shrink-0', styles[props.type].icon]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M12 .75a8.25 8.25 0 00-4.135 15.39c.686.398 1.115 1.008 1.134 1.623a.75.75 0 00.577.706c.352.083.71.148 1.074.195.323.041.6-.218.6-.544v-4.661a6.75 6.75 0 01-.937-.171.75.75 0 11.374-1.453 5.261 5.261 0 002.626 0 .75.75 0 11.374 1.452 6.76 6.76 0 01-.937.172v4.66c0 .327.277.586.6.545.364-.047.722-.112 1.074-.195a.75.75 0 00.577-.706c.02-.615.448-1.225 1.134-1.623A8.25 8.25 0 0012 .75z" />
<path
fill-rule="evenodd"
d="M9.013 19.9a.75.75 0 01.877-.597 11.319 11.319 0 004.22 0 .75.75 0 11.28 1.473 12.819 12.819 0 01-4.78 0 .75.75 0 01-.597-.876zM9.754 22.344a.75.75 0 01.824-.668 13.682 13.682 0 002.844 0 .75.75 0 11.156 1.492 15.156 15.156 0 01-3.156 0 .75.75 0 01-.668-.824z"
clip-rule="evenodd"
/>
</svg>
<!-- Danger -->
<svg
v-else-if="props.type === 'danger'"
:class="['mt-0.5 size-5 shrink-0', styles[props.type].icon]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zm-1.72 6.97a.75.75 0 10-1.06 1.06L10.94 12l-1.72 1.72a.75.75 0 101.06 1.06L12 13.06l1.72 1.72a.75.75 0 101.06-1.06L13.06 12l1.72-1.72a.75.75 0 10-1.06-1.06L12 10.94l-1.72-1.72z"
clip-rule="evenodd"
/>
</svg>
<div :class="['text-sm leading-relaxed', styles[props.type].text]">
<slot /> <slot />
</template> </div>
</UAlert> </div>
</template> </template>
+4 -6
View File
@@ -6,19 +6,17 @@ interface Props {
width?: string | number width?: string | number
height?: string | number height?: string | number
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), { alt: '' })
alt: '',
})
</script> </script>
<template> <template>
<NuxtImg <img
:src="props.src" :src="props.src"
:alt="props.alt" :alt="props.alt"
:title="props.title" :title="props.title"
:width="props.width" :width="props.width"
:height="props.height" :height="props.height"
format="webp" loading="lazy"
class="rounded-lg w-full" class="not-prose my-6 w-full rounded-lg"
/> />
</template> </template>
+20 -1
View File
@@ -5,7 +5,26 @@ const { data: page } = await useAsyncData('test', () =>
</script> </script>
<template> <template>
<article class="prose dark:prose-invert max-w-none p-8"> <div class="min-h-screen bg-white dark:bg-neutral-950">
<div class="mx-auto max-w-2xl px-6 py-16">
<header class="mb-10">
<div class="mb-3 text-xs font-semibold uppercase tracking-widest text-neutral-400">
Renderer Test
</div>
<h1 class="text-3xl font-bold text-neutral-900 dark:text-white">
{{ page?.title }}
</h1>
<p class="mt-2 text-neutral-500 dark:text-neutral-400">
{{ page?.description }}
</p>
</header>
<article class="prose prose-neutral dark:prose-invert max-w-none
prose-headings:font-semibold
prose-code:before:content-none prose-code:after:content-none
prose-pre:p-0 prose-pre:bg-transparent">
<ContentRenderer v-if="page" :value="page" /> <ContentRenderer v-if="page" :value="page" />
</article> </article>
</div>
</div>
</template> </template>