mirror of
https://github.com/element-plus/element-plus.git
synced 2025-02-17 11:49:41 +08:00
feat(components): [el-message] config-provider message max attr (#5063)
* feat(components): [el-message] config-provider message max attr * chore: update test * feat: update test and message-method * chore: format config-provider.md * test: add multiple config-provider * test: config-provider nesting
This commit is contained in:
parent
53fe828273
commit
70fa3e7f26
@ -25,14 +25,23 @@ config-provider/button
|
||||
|
||||
:::
|
||||
|
||||
## message configurations
|
||||
|
||||
:::demo
|
||||
|
||||
config-provider/message
|
||||
|
||||
:::
|
||||
|
||||
## Config Provider Attributes
|
||||
|
||||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
| --------- | --------------------------------------------------------------------------- | ------------------ | --------------------------------------------------------------------------------------- | ----------------------- |
|
||||
| locale | Locale Object | Object\<Language\> | [languages](https://github.com/element-plus/element-plus/tree/dev/packages/locale/lang) | English |
|
||||
| size | global component size | string | large / default /small | default |
|
||||
| zIndex | global Initial zIndex | number | - | - |
|
||||
| button | button related configuration, [see the following table](#button-attributes) | ButtonGlobalConfig | - | see the following table |
|
||||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
| --------- | ----------------------------------------------------------------------------- | ------------------- | --------------------------------------------------------------------------------------- | ----------------------- |
|
||||
| locale | Locale Object | Object\<Language\> | [languages](https://github.com/element-plus/element-plus/tree/dev/packages/locale/lang) | English |
|
||||
| size | global component size | string | large / default /small | default |
|
||||
| zIndex | global Initial zIndex | number | - | - |
|
||||
| button | button related configuration, [see the following table](#button-attributes) | ButtonGlobalConfig | - | see the following table |
|
||||
| message | message related configuration, [see the following table](#message-attributes) | MessageGlobalConfig | - | see the following table |
|
||||
|
||||
## Button Attributes
|
||||
|
||||
@ -40,6 +49,12 @@ config-provider/button
|
||||
| --------------- | ----------------------------------------------------------- | ------- | --------------- | ------- |
|
||||
| autoInsertSpace | automatically insert a space between two chinese characters | boolean | - | false |
|
||||
|
||||
## Message Attributes
|
||||
|
||||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
| --------- | --------------------------------------------------------------------- | ------ | --------------- | ------- |
|
||||
| max | the maximum number of messages that can be displayed at the same time | number | - | - |
|
||||
|
||||
## ConfigProvider Slots
|
||||
|
||||
| Name | Description |
|
||||
|
18
docs/examples/config-provider/message.vue
Normal file
18
docs/examples/config-provider/message.vue
Normal file
@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-config-provider :message="config">
|
||||
<el-button @click="open">open</el-button>
|
||||
</el-config-provider>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
const config = reactive({
|
||||
max: 3,
|
||||
})
|
||||
const open = () => {
|
||||
ElMessage('this is a message.')
|
||||
}
|
||||
</script>
|
@ -18,6 +18,6 @@ module.exports = {
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
||||
// u can change this option to a more specific folder for test single component or util when dev
|
||||
// for example, ['<rootDir>/packages/input']
|
||||
// for example, ['<rootDir>/packages/components/input']
|
||||
roots: ['<rootDir>'],
|
||||
}
|
||||
|
@ -3,7 +3,8 @@ import { mount } from '@vue/test-utils'
|
||||
import { useLocale } from '@element-plus/hooks'
|
||||
import Chinese from '@element-plus/locale/lang/zh-cn'
|
||||
import English from '@element-plus/locale/lang/en'
|
||||
import { ElButton } from '@element-plus/components'
|
||||
import { ElButton, ElMessage } from '@element-plus/components'
|
||||
import { sleep } from '@element-plus/test-utils'
|
||||
import ConfigProvider from '../src/config-provider'
|
||||
import type { Language } from '@element-plus/locale'
|
||||
|
||||
@ -120,4 +121,87 @@ describe('config-provider', () => {
|
||||
).toBeFalsy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('message-config', () => {
|
||||
it('limit the number of messages displayed at the same time', async () => {
|
||||
const wrapper = mount({
|
||||
components: {
|
||||
[ConfigProvider.name]: ConfigProvider,
|
||||
ElButton,
|
||||
},
|
||||
setup() {
|
||||
const config = reactive({
|
||||
max: 3,
|
||||
})
|
||||
const open = () => {
|
||||
ElMessage('this is a message.')
|
||||
}
|
||||
return {
|
||||
config,
|
||||
open,
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<el-config-provider :message="config">
|
||||
<el-button @click="open">open</el-button>
|
||||
</el-config-provider>
|
||||
`,
|
||||
})
|
||||
await nextTick()
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
await nextTick()
|
||||
expect(document.querySelectorAll('.el-message').length).toBe(3)
|
||||
|
||||
wrapper.vm.config.max = 10
|
||||
await nextTick()
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
await nextTick()
|
||||
expect(document.querySelectorAll('.el-message').length).toBe(7)
|
||||
})
|
||||
|
||||
it('multiple config-provider config override', async () => {
|
||||
const wrapper = mount({
|
||||
components: {
|
||||
[ConfigProvider.name]: ConfigProvider,
|
||||
ElButton,
|
||||
},
|
||||
setup() {
|
||||
const config = reactive({
|
||||
max: 3,
|
||||
})
|
||||
const overrideConfig = reactive({
|
||||
max: 1,
|
||||
})
|
||||
const open = () => {
|
||||
ElMessage('this is a message.')
|
||||
}
|
||||
return {
|
||||
config,
|
||||
overrideConfig,
|
||||
open,
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<el-config-provider :message="config">
|
||||
<el-config-provider :message="overrideConfig">
|
||||
<el-button @click="open">open</el-button>
|
||||
</el-config-provider>
|
||||
</el-config-provider>
|
||||
`,
|
||||
})
|
||||
ElMessage.closeAll()
|
||||
await sleep(40)
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
wrapper.find('.el-button').trigger('click')
|
||||
await nextTick()
|
||||
expect(document.querySelectorAll('.el-message').length).toBe(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,8 +1,11 @@
|
||||
import { defineComponent, renderSlot } from 'vue'
|
||||
import { defineComponent, renderSlot, watch } from 'vue'
|
||||
import { buildProps, definePropType } from '@element-plus/utils/props'
|
||||
import { provideGlobalConfig } from '@element-plus/hooks'
|
||||
import type { Language } from '@element-plus/locale'
|
||||
import type { ButtonConfigContext } from '@element-plus/components/button'
|
||||
import type { MessageConfigContext } from '@element-plus/components/message'
|
||||
|
||||
export const messageConfig: MessageConfigContext = {}
|
||||
|
||||
export const configProviderProps = buildProps({
|
||||
locale: {
|
||||
@ -18,6 +21,10 @@ export const configProviderProps = buildProps({
|
||||
type: definePropType<ButtonConfigContext>(Object),
|
||||
},
|
||||
|
||||
message: {
|
||||
type: definePropType<MessageConfigContext>(Object),
|
||||
},
|
||||
|
||||
zIndex: {
|
||||
type: Number,
|
||||
},
|
||||
@ -28,6 +35,13 @@ export default defineComponent({
|
||||
props: configProviderProps,
|
||||
|
||||
setup(props, { slots }) {
|
||||
watch(
|
||||
() => props.message,
|
||||
(val) => {
|
||||
Object.assign(messageConfig, val ?? {})
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
const config = provideGlobalConfig(props)
|
||||
return () => renderSlot(slots, 'default', { config: config?.value })
|
||||
},
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { createVNode, render } from 'vue'
|
||||
import { isClient } from '@vueuse/core'
|
||||
import { isVNode } from '@element-plus/utils/util'
|
||||
import { isVNode, isNumber } from '@element-plus/utils/util'
|
||||
import { PopupManager } from '@element-plus/utils/popup-manager'
|
||||
import { debugWarn } from '@element-plus/utils/error'
|
||||
import { messageConfig } from '@element-plus/components/config-provider/src/config-provider'
|
||||
import MessageConstructor from './message.vue'
|
||||
import { messageTypes } from './message'
|
||||
|
||||
@ -16,6 +17,9 @@ let seed = 1
|
||||
|
||||
const message: MessageFn & Partial<Message> = function (options = {}) {
|
||||
if (!isClient) return { close: () => undefined }
|
||||
if (isNumber(messageConfig.max) && instances.length >= messageConfig.max) {
|
||||
return { close: () => undefined }
|
||||
}
|
||||
|
||||
if (
|
||||
!isVNode(options) &&
|
||||
|
@ -4,6 +4,10 @@ import type { VNode, ExtractPropTypes, Component } from 'vue'
|
||||
|
||||
export const messageTypes = ['success', 'info', 'warning', 'error'] as const
|
||||
|
||||
export interface MessageConfigContext {
|
||||
max?: number
|
||||
}
|
||||
|
||||
export const messageProps = buildProps({
|
||||
customClass: {
|
||||
type: String,
|
||||
|
Loading…
Reference in New Issue
Block a user