This commit is contained in:
Nadar
2026-03-17 13:24:22 +03:00
commit 82e5ac9d81
554 changed files with 29637 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
<template>
<div
:class="[
cn.b(),
cn.m(type),
cn.m(size),
cn.has('title', hasTitle),
cn.has('action', hasAction),
]"
>
<div :class="[cn.e('content')]">
<div
v-if="$slots.title || title"
:class="[cn.e('title')]"
>
<slot name="title">
{{ title }}
</slot>
</div>
<div :class="[cn.e('text')]">
<slot>{{ text }}</slot>
</div>
<slot name="action" />
</div>
<div :class="cn.e('icon')">
<slot name="icon">
<Component :is="resolveComponent(`ui-icon-${TYPE_ICON_MAPPING[type]}`)" />
</slot>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import useClassname from '../../composables/use-classname'
import type { AlertProps, AlertType } from './types'
import type { UiIcon } from '#build/types/ui/icons'
defineOptions({
name: 'UiAlert',
})
const props = withDefaults(defineProps<AlertProps>(), {
type: 'neutral',
size: 'normal',
})
const slots = defineSlots<{
default(props: NonNullable<unknown>): never
title(props: NonNullable<unknown>): never
action(props: NonNullable<unknown>): never
}>()
const TYPE_ICON_MAPPING: Record<AlertType, UiIcon> = {
neutral: 'exclamation-filled',
positive: 'confirmed-filled',
warning: 'danger-filled',
negative: 'cancel-filled',
marketing: 'ask-for-discount-filled',
}
const cn = useClassname('ui-alert')
const hasTitle = computed(() => !!props.title || slots.title)
const hasAction = computed(() => slots.action)
</script>
<style lang="scss">
@use 'styles';
</style>