Skip to content

Commit

Permalink
feat(comp:alert): add alert component
Browse files Browse the repository at this point in the history
  • Loading branch information
brenner8023 committed Nov 16, 2021
1 parent 17b701c commit d9210da
Show file tree
Hide file tree
Showing 25 changed files with 645 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Alert render work 1`] = `
"<transition-stub>
<div class=\\"ix-alert ix-alert-info\\"><span class=\\"ix-alert-icon\\"><i class=\\"ix-icon ix-icon-bulb\\" role=\\"img\\" aria-label=\\"bulb\\"></i></span>
<div class=\\"ix-alert-content\\">
<!---->
</div>
<!---->
<!---->
</div>
</transition-stub>"
`;
114 changes: 114 additions & 0 deletions packages/components/alert/__tests__/alert.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { MountingOptions, mount } from '@vue/test-utils'
import { h } from 'vue'

import { renderWork } from '@tests'

import IxAlert from '../src/Alert'
import { AlertProps } from '../src/types'

describe('Alert', () => {
const AlertMount = (options?: MountingOptions<Partial<AlertProps>>) => mount(IxAlert, { ...options })

renderWork(IxAlert)

test('props type work', async () => {
const wrapper = AlertMount({ props: { type: 'success' } })

expect(wrapper.find('.ix-alert').classes()).toContain('ix-alert-success')

await wrapper.setProps({ type: 'warning' })
expect(wrapper.find('.ix-alert').classes()).toContain('ix-alert-warning')

await wrapper.setProps({ type: 'error' })
expect(wrapper.find('.ix-alert').classes()).toContain('ix-alert-error')

await wrapper.setProps({ type: 'info' })
expect(wrapper.find('.ix-alert').classes()).toContain('ix-alert-info')
})

test('props icon work', async () => {
const wrapper = AlertMount({ props: { icon: 'bug' } })

expect(wrapper.find('.ix-icon').classes()).toContain('ix-icon-bug')

await wrapper.setProps({ icon: '' })
expect(wrapper.find('.ix-icon').exists()).toBeFalsy()
})

test('props title description work', async () => {
const wrapper = AlertMount({ props: { title: 'alert title' } })

expect(wrapper.find('.ix-alert-content').text()).toContain('alert title')
expect(wrapper.find('.ix-alert').classes()).not.toContain('ix-alert-with-description')

await wrapper.setProps({ title: ['title1', 'title2'] })
expect(wrapper.find('.ix-alert-content').text()).toContain('title1title2')

await wrapper.setProps({ description: 'alert description' })
expect(wrapper.find('.ix-alert-content').text()).toContain('alert description')
expect(wrapper.find('.ix-alert').classes()).toContain('ix-alert-with-description')
})

test('props closable work', async () => {
const onClose = jest.fn()
const wrapper = AlertMount({ props: { closable: false, onClose } })

expect(wrapper.find('.ix-alert-close-icon').exists()).toBeFalsy()

await wrapper.setProps({ closable: true })
await wrapper.find('.ix-alert-close-icon').trigger('click')
expect(onClose).toHaveBeenCalledTimes(1)
})

test('props onBeforeClose work', async () => {
const onBeforeClose = jest.fn().mockResolvedValue(false)
const onClose = jest.fn()
const wrapper = AlertMount({
props: {
closable: true,
onBeforeClose,
onClose,
},
})

await wrapper.find('.ix-alert-close-icon').trigger('click')
expect(onBeforeClose).toHaveBeenCalledTimes(1)
expect(onClose).toHaveBeenCalledTimes(0)

onBeforeClose.mockReturnValue(true)
await wrapper.find('.ix-alert-close-icon').trigger('click')
expect(onBeforeClose).toHaveBeenCalledTimes(2)
expect(onClose).toHaveBeenCalledTimes(1)
})

test('multiple message work', async () => {
const wrapper = AlertMount({
slots: {
default: () => [h('div', 'message1'), h('div', 'message2')],
},
})

expect(wrapper.find('.ix-alert-content').text()).toBe('message1message2')

await wrapper.setProps({ showPagination: true })
expect(wrapper.find('.ix-alert-content').text()).toBe('message1')
expect(wrapper.find('.ix-icon-left').classes()).toContain('ix-alert-disabled-icon')
expect(wrapper.find('.ix-icon-right').classes()).not.toContain('ix-alert-disabled-icon')

await wrapper.find('.ix-icon-left').trigger('click')
expect(wrapper.find('.ix-alert-content').text()).toBe('message1')

await wrapper.find('.ix-icon-right').trigger('click')
expect(wrapper.find('.ix-alert-content').text()).toBe('message2')
expect(wrapper.find('.ix-icon-left').classes()).not.toContain('ix-alert-disabled-icon')
expect(wrapper.find('.ix-icon-right').classes()).toContain('ix-alert-disabled-icon')

await wrapper.find('.ix-icon-right').trigger('click')
expect(wrapper.find('.ix-alert-content').text()).toBe('message2')

await wrapper.find('.ix-icon-left').trigger('click')
expect(wrapper.find('.ix-alert-content').text()).toBe('message1')
expect(wrapper.find('.ix-icon-left').classes()).toContain('ix-alert-disabled-icon')
expect(wrapper.find('.ix-icon-right').classes()).not.toContain('ix-alert-disabled-icon')
})
})
9 changes: 9 additions & 0 deletions packages/components/alert/demo/Basic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
order: 0
title:
zh: 基本
---

## zh

最简单的用法,一共有四种样式,适用于简短的警告提示。
6 changes: 6 additions & 0 deletions packages/components/alert/demo/Basic.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<template>
<IxAlert title="我长话短说,但是说来话长。" type="success"></IxAlert>
<IxAlert title="据我所知,我一无所知。" type="info"></IxAlert>
<IxAlert title="能力越大,能力就越大。" type="error"></IxAlert>
<IxAlert title="在掉链子这种事情上从未掉过链子。" type="warning"></IxAlert>
</template>
9 changes: 9 additions & 0 deletions packages/components/alert/demo/Close.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
order: 5
title:
zh: 点击关闭时触发回调
---

## zh

onBeforeClose可以判断是否生效关闭,关闭时会触发close事件。
53 changes: 53 additions & 0 deletions packages/components/alert/demo/Close.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<IxAlert title="雪崩的时候,没有一片雪花是不崩的。" closable @beforeClose="onBeforeClose"></IxAlert>
<IxAlert closable @beforeClose="handleBeforeClose"> 香蕉越大,香蕉皮越大。 </IxAlert>
<IxAlert
title="如果你愿意多花一点时间读完,你就会发现你多花了一点时间。"
closable
type="success"
@close="onClose"
></IxAlert>
</template>

<script lang="ts" setup>
import { useMessage } from '@idux/components/message'
import { useModal } from '@idux/components/modal'
const { success } = useMessage()
const { confirm } = useModal()
const onBeforeClose = () => {
success('onBeforeClose执行了。')
return false
}
const handleBeforeClose = () => {
return new Promise<boolean>(resolve => {
const modalRef = confirm({
title: '确认是否关闭?',
footer: [
{
text: '确定',
mode: 'primary',
onClick: () => {
resolve(true)
modalRef.close()
},
},
{
text: '取消',
mode: 'text',
onClick: () => {
resolve(false)
modalRef.close()
},
},
],
})
})
}
const onClose = () => {
success('close事件触发了。')
}
</script>
9 changes: 9 additions & 0 deletions packages/components/alert/demo/Description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
order: 1
title:
zh: 辅助性文字介绍
---

## zh

含有辅助性文字介绍的警告提示,可以通过插槽实现。
15 changes: 15 additions & 0 deletions packages/components/alert/demo/Description.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<IxAlert
title="Vue 是什么?"
type="success"
:closable="true"
description="Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。"
></IxAlert>
<IxAlert>
What is Vue?
<template #description>
Vue is a progressive framework for building user interfaces. Unlike other monolithic frameworks, Vue is designed
from the ground up to be incrementally adoptable.
</template>
</IxAlert>
</template>
9 changes: 9 additions & 0 deletions packages/components/alert/demo/Icon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
order: 3
title:
zh: 自定义图标
---

## zh

支持自定义图标、自定义关闭按钮。
13 changes: 13 additions & 0 deletions packages/components/alert/demo/Icon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<IxAlert icon="alert" title="每次我不知道该说什么的时候就不知道该说什么。"></IxAlert>
<IxAlert title="你说的这话,抛开内容来说,我十分赞同。" type="success">
<template #icon>
<IxIcon name="check-circle-filled" />
</template>
</IxAlert>
<IxAlert type="warning" title="但凡你这话有点道理,也不至于一点道理没有。" :closable="true">
<template #closeIcon>
<IxButton mode="text">关闭</IxButton>
</template>
</IxAlert>
</template>
9 changes: 9 additions & 0 deletions packages/components/alert/demo/LongText.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
order: 2
title:
zh: 长文本
---

## zh

展示超长文本内容。
5 changes: 5 additions & 0 deletions packages/components/alert/demo/LongText.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<IxAlert closable>
挺好看的,但是有点难看,不过也是挺好看的,可惜对我来说比较难看,只是太好看了,没体现出难看的感觉,所以相对好看来说,有点难看,总体来说还是好看,美中不足就是难看了点,不过也不影响它的好看。
</IxAlert>
</template>
9 changes: 9 additions & 0 deletions packages/components/alert/demo/Pagination.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
order: 4
title:
zh: 切换提示
---

## zh

支持配置是否切换展示多条告警提示。
30 changes: 30 additions & 0 deletions packages/components/alert/demo/Pagination.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<template>
<IxAlert>
<div>
上次见到你的时候还是在上次。
<IxButton mode="link" size="sm">查看详情</IxButton>
</div>
<div>
上次看到这么无语的话,还是在上次。
<IxButton mode="link" size="sm">忽略</IxButton>
</div>
<div> 上次看到这么的发言还是上次。 </div>
</IxAlert>
<IxAlert closable show-pagination>
<div v-for="(item, idx) in messageList" :key="idx">
{{ `${idx + 1}. ${item}` }}
<IxButton v-if="idx === 1" mode="link" size="sm">忽略</IxButton>
</div>
</IxAlert>
<IxButton @click="onClick"> 添加提示 </IxButton>
</template>

<script lang="ts" setup>
import { reactive } from 'vue'
const messageList = reactive(['上次看到这句话的时候还是上次。'])
const onClick = () => {
messageList.push('上次看到这句话的时候还是上次。')
}
</script>
33 changes: 33 additions & 0 deletions packages/components/alert/docs/Index.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
category: components
type: 反馈
title: Alert
subtitle: 警告提示
cover:
---

警告提示,展现需要引起用户关注的信息。

何时使用:

- 当需要提供系统级别的信息提示,较重要的平台提示或告警信息,如:系统故障、授权升级等
- 常用于页面内容的补充说明、操作后果提示、功能作用提示等
- 提示信息通常情况下不会自动消失,用户可以主动关闭提示

## API

### IxAlert

#### Props

| 名称 | 说明 | 类型 | 默认值 | 全局配置 | 备注 |
| --- | --- | --- | --- | --- | --- |
| `closable` | 信息提示是否可关闭 | `boolean` | `false` ||- |
| `closeIcon` | 自定义关闭按钮 | `string \| #closeIcon` | `close` | - | - |
| `description` | 辅助性文字介绍 | `string \| #description` | - | - |- |
| `icon` | 自定义图标 | `string \| #icon` | - || 若要隐藏图标则传空串 |
| `showPagination` | 是否开启分页切换效果 | `boolean` | `false` | - | - |
| `type` | 设置提示类型 | `'success' \| 'info' \| 'warning' \| 'error'` | `info` | - |- |
| `title` | 信息提示内容 | `string \| string[] \| #default` | - | - |- |
| `onBeforeClose` | 关闭提示前会触发的回调函数 | `() => boolean \| Promise<boolean>` | - | - | - |
| `onClose` | 关闭提示会触发的回调函数 | `() => void` | - | - | - |
16 changes: 16 additions & 0 deletions packages/components/alert/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @license
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import type { AlertComponent } from './src/types'

import Alert from './src/Alert'

const IxAlert = Alert as unknown as AlertComponent

export { IxAlert }

export type { AlertInstance, AlertPublicProps as AlertProps } from './src/types'
Loading

0 comments on commit d9210da

Please sign in to comment.