This commit is contained in:
oneao committed 2025-09-12 17:32:27 +08:00
1 parent 14f9844430
commit 785bce1907
27 files changed
+1051 -175

No files matched your search

@@ -1,59 +1,85 @@
<script setup lang="ts">
import { useNotification } from '@ao/ao-design'
import { h } from 'vue'
const notification = useNotification()
function showCustomMessage() {
function showNotification(placement: any) {
notification.success({
title: '自定义消息',
message: () =>
h('div', { style: { color: 'red', position: 'relative' } }, [
h('p', {}, '这里是自定义内容,可以是任意 VNode'),
h('strong', {}, '加粗文本'),
// 右下角按钮容器
h(
'div',
{
style: {
position: 'absolute',
bottom: '4px',
right: '4px',
display: 'flex',
gap: '4px',
},
},
[
h(
'button',
{
style: { fontSize: '12px', padding: '2px 6px' },
onClick: () => alert('Button A clicked'),
},
'A',
),
h(
'button',
{
style: { fontSize: '12px', padding: '2px 6px' },
onClick: () => alert('Button B clicked'),
},
'B',
),
],
),
]),
type: 'success',
showClose: true,
title: `这里是 ${placement} 标题`,
message: `这里是 ${placement} 提示`,
placement,
})
}
function closeOne() {
}
function showNotificationType(type: any) {
notification.success({
theme: 'light',
title: `这里是 ${type} 标题`,
message: `这里是 ${type} 提示`,
type,
duration: 0,
})
}
</script>
<template>
<div class="demo">
<AButton status="primary" @click="showCustomMessage">
自定义 h 函数消息
</AButton>
<div class="row">
<AButton status="primary" @click="showNotification('top-start')">
Top Start
</AButton>
<AButton status="primary" @click="showNotification('top-end')">
Top End
</AButton>
</div>
<div class="row">
<AButton status="primary" @click="showNotification('bottom-start')">
Bottom Start
</AButton>
<AButton status="primary" @click="showNotification('bottom-end')">
Bottom End
</AButton>
</div>
<div class="row">
<AButton status="primary" @click="notification.closeAll">
Close All
</AButton>
<AButton
status="primary" @click="closeOne"
>
Show No Close
</AButton>
</div>
<div class="row">
<AButton status="primary" @click="showNotificationType('default')">
default
</AButton>
<AButton status="primary" @click="showNotificationType('info')">
info
</AButton>
<AButton status="primary" @click="showNotificationType('success')">
success
</AButton>
<AButton status="primary" @click="showNotificationType('warning')">
warning
</AButton>
<AButton status="primary" @click="showNotificationType('danger')">
error
</AButton>
<AButton status="primary" @click="showNotificationType('loading')">
loading
</AButton>
<AButton status="primary" @click="showNotificationType('question')">
question
</AButton>
</div>
</div>
</template>
@@ -65,4 +91,9 @@ function showCustomMessage() {
gap: 16px;
margin-top: 40px;
}
.row {
display: flex;
gap: 12px;
}
</style>
@@ -24,7 +24,6 @@ $notification-prefix: #{$prefix}-notification;
border: 0;
margin: 0;
display: flex;
background-color: #ecf7ec;
&-icon {
text-align: center;
@@ -47,8 +46,6 @@ $notification-prefix: #{$prefix}-notification;
&-title {
font-size: 16px;
font-weight: 600;
line-height: 1;
small {
margin: 0px 6px;
font-size: 14px;
@@ -76,26 +73,35 @@ $notification-prefix: #{$prefix}-notification;
word-break: break-all;
}
&-footer {
}
&-info {
color: $primary-color;
.#{$notification-prefix}-icon {
color: $primary-color;
}
}
&-success {
color: $success-color;
.#{$notification-prefix}-icon {
color: $success-color;
}
}
&-warning {
color: $warning-color;
.#{$notification-prefix}-icon {
color: $warning-color;
}
}
&-error {
color: $danger-color;
&-danger {
.#{$notification-prefix}-icon {
color: $danger-color;
}
}
&-question {
color: $primary-color;
.#{$notification-prefix}-icon {
color: $primary-color;
}
}
&-loading {
color: $primary-color;
.#{$notification-prefix}-icon {
color: $primary-color;
}
}
&-placement {
@@ -125,3 +131,27 @@ $notification-prefix: #{$prefix}-notification;
}
}
}
.#{$notification-prefix}-theme-normal.#{$notification-prefix} {
background-color: $status-base-bg-color;
}
.#{$notification-prefix}-theme-light.#{$notification-prefix}-default {
background-color: $status-base-bg-color;
}
.#{$notification-prefix}-theme-light.#{$notification-prefix}-info {
background-color: $status-info-bg-color;
}
.#{$notification-prefix}-theme-light.#{$notification-prefix}-success {
background-color: $status-success-bg-color;
}
.#{$notification-prefix}-theme-light.#{$notification-prefix}-warning {
background-color: $status-warning-bg-color;
}
.#{$notification-prefix}-theme-light.#{$notification-prefix}-danger {
background-color: $status-danger-bg-color;
}
.#{$notification-prefix}-theme-light.#{$notification-prefix}-loading {
background-color: $status-info-bg-color;
}
.#{$notification-prefix}-theme-light.#{$notification-prefix}-question {
background-color: $status-info-bg-color;
}
@@ -9,13 +9,14 @@ type Placement
| 'bottom-start'
| 'bottom-end'
type NotificationType = 'info' | 'success' | 'warning' | 'error' | 'loading' | 'question'
type NotificationType = 'default' | 'info' | 'success' | 'warning' | 'danger' | 'loading' | 'question'
type NotificationTheme = 'normal' | 'light'
interface NotificationOptions {
message: string | VNode | (() => VNode)
title: string
subTitle?: string
theme?: NotificationTheme
type?: NotificationType
placement?: Placement
duration?: number
@@ -28,10 +29,11 @@ interface NotificationHandle {
interface MessageFn {
(msg: NotificationOptions): NotificationHandle
open: (msg: NotificationOptions) => NotificationHandle
info: (msg: NotificationOptions) => NotificationHandle
success: (msg: NotificationOptions) => NotificationHandle
warning: (msg: NotificationOptions) => NotificationHandle
error: (msg: NotificationOptions) => NotificationHandle
danger: (msg: NotificationOptions) => NotificationHandle
closeAll: () => void
}
@@ -65,9 +67,9 @@ function getTransform(placement: Placement, hidden: boolean) {
export function useNotification(): MessageFn {
const createNotification = (
opts: NotificationOptions,
defaultType: NotificationType = 'info',
defaultType: NotificationType = 'default',
): NotificationHandle => {
const { message, title, subTitle, type = defaultType, placement = 'top-end', duration = 3000, showClose } = opts
const { message, title, subTitle, type = defaultType, theme, placement = 'top-end', duration = 3000, showClose } = opts
const container = getContainer(placement)
let timer: number | undefined
@@ -77,6 +79,7 @@ export function useNotification(): MessageFn {
render() {
return h(MessageItem, {
type,
theme,
title,
subTitle,
message,
@@ -136,10 +139,11 @@ export function useNotification(): MessageFn {
}
const api = ((msg: NotificationOptions) => createNotification(msg)) as MessageFn
api.open = msg => createNotification(msg, 'default')
api.info = msg => createNotification(msg, 'info')
api.success = msg => createNotification(msg, 'success')
api.warning = msg => createNotification(msg, 'warning')
api.error = msg => createNotification(msg, 'error')
api.danger = msg => createNotification(msg, 'danger')
api.closeAll = () => {
instances.slice().forEach(instance => instance.close())
}
@@ -8,7 +8,8 @@ const prefixCls = getPrefixCls('notification')
export default defineComponent({
name: 'NotificationItem',
props: {
type: { type: String, default: 'info' },
type: { type: String, default: 'default' },
theme: { type: String, default: 'normal' },
title: { type: String, required: true },
message: {
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
@@ -25,7 +26,7 @@ export default defineComponent({
setup(props) {
const iconMap: Record<string, string> = {
success: 'ix:success-filled',
error: 'ix:error-filled',
danger: 'ix:error-filled',
warning: 'ix:warning-filled',
info: 'ix:info-filled',
question: 'ix:question-filled',
@@ -38,15 +39,16 @@ export default defineComponent({
}
return () => (
<div
class={`${prefixCls}`}
class={`${prefixCls} ${prefixCls}-theme-${props.theme ?? 'normal'} ${prefixCls}-${props.type ?? 'info'}`}
>
<Icon
icon={iconMap[props.type ?? 'info']}
size={22}
class={`${prefixCls}-icon ${prefixCls}-${props.type ?? 'info'}`}
spin={props.type === 'loading'}
/>
{props.type !== 'default' && (
<Icon
icon={iconMap[props.type ?? 'info']}
size={22}
class={`${prefixCls}-icon`}
spin={props.type === 'loading'}
/>
)}
<div class={`${prefixCls}-main`}>
<div class={`${prefixCls}-title-wrapper`}>
<span class={`${prefixCls}-title`}>