mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-12-21 04:50:14 +08:00
feat(message-provider): add placement prop (#851)
* feat:n-input Support hidden password * feat(form): support require-mark-placement(#171) * Revert "feat(form): support require-mark-placement(#171)" This reverts commit0627777693
. * Revert "feat:n-input Support hidden password" This reverts commitea6491783d
. * feat(message provider): add placement prop(wip) * feat(message provider): add placement prop * feat: add demo * feat: fix demo code * feat: fix code * feat: fix code * Update CHANGELOG.en-US.md * feat: fix style code
This commit is contained in:
parent
95d0efa4d3
commit
3d7f96dd00
@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
### Feats
|
### Feats
|
||||||
|
|
||||||
- `n-message-provider` add `container-style` prop
|
- `n-message-provider` add `container-style` prop.
|
||||||
|
- `n-message-provider` add `placement` prop.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
### Feats
|
### Feats
|
||||||
|
|
||||||
- `n-message-provider` 新增 `container-style` 属性
|
- `n-message-provider` 新增 `container-style` 属性
|
||||||
|
- `n-message-provider` 新增 `placement` 属性
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
|
@ -21,10 +21,10 @@ import { defineComponent } from 'vue'
|
|||||||
|
|
||||||
// content
|
// content
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup () {
|
setup() {
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
return {
|
return {
|
||||||
warning () {
|
warning() {
|
||||||
message.warning('...')
|
message.warning('...')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,6 +45,7 @@ modify-content
|
|||||||
manually-close
|
manually-close
|
||||||
about-theme
|
about-theme
|
||||||
multiple-line
|
multiple-line
|
||||||
|
placement
|
||||||
```
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
@ -56,6 +57,7 @@ multiple-line
|
|||||||
| closable | `boolean` | All messages whether to show close icon. |
|
| closable | `boolean` | All messages whether to show close icon. |
|
||||||
| duration | `number` | `3000` | All messages's default duration. |
|
| duration | `number` | `3000` | All messages's default duration. |
|
||||||
| max | `number` | `undefined` | Limit the number of message to display. |
|
| max | `number` | `undefined` | Limit the number of message to display. |
|
||||||
|
| placement | `top \| top-left \| top-right \| bottom \| bottom-left \| bottom-right ` | `top` | All message's placement. |
|
||||||
| to | `string \| HTMLElement` | `'body'` | Container node of message container. |
|
| to | `string \| HTMLElement` | `'body'` | Container node of message container. |
|
||||||
|
|
||||||
### MessageProvider Injection API
|
### MessageProvider Injection API
|
||||||
|
119
src/message/demos/enUS/placement.demo.md
Normal file
119
src/message/demos/enUS/placement.demo.md
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# Placement
|
||||||
|
|
||||||
|
```html
|
||||||
|
<n-message-provider :placement="placement">
|
||||||
|
<Buttons @changePlacement="changePlacement" />
|
||||||
|
</n-message-provider>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { useMessage, NButton } from 'naive-ui'
|
||||||
|
import { h, ref } from 'vue'
|
||||||
|
|
||||||
|
const Buttons = {
|
||||||
|
emits: ['changePlacement'],
|
||||||
|
setup() {
|
||||||
|
const message = useMessage()
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return [
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'top')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => 'Top' }
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'bottom')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => 'Bottom' }
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'top-left')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => 'TopLeft' }
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'top-right')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => 'TopRight' }
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'bottom-left')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => 'BottomLeft' }
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'bottom-right')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => 'BottomRight' }
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Buttons
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const placement = ref('top')
|
||||||
|
return {
|
||||||
|
placement,
|
||||||
|
changePlacement: (val) => {
|
||||||
|
placement.value = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@ -21,10 +21,10 @@ import { defineComponent } from 'vue'
|
|||||||
|
|
||||||
// content
|
// content
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup () {
|
setup() {
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
return {
|
return {
|
||||||
warning () {
|
warning() {
|
||||||
message.warning('...')
|
message.warning('...')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,6 +45,7 @@ modify-content
|
|||||||
manually-close
|
manually-close
|
||||||
about-theme
|
about-theme
|
||||||
multiple-line
|
multiple-line
|
||||||
|
placement
|
||||||
```
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
@ -56,6 +57,7 @@ multiple-line
|
|||||||
| closable | `boolean` | 所有 Message 是否显示 close 图标 |
|
| closable | `boolean` | 所有 Message 是否显示 close 图标 |
|
||||||
| duration | `number` | `3000` | 所有 Message 默认的持续时长 |
|
| duration | `number` | `3000` | 所有 Message 默认的持续时长 |
|
||||||
| max | `number` | `undefined` | 限制提示信息显示的个数 |
|
| max | `number` | `undefined` | 限制提示信息显示的个数 |
|
||||||
|
| placement | `top \| top-left \| top-right \| bottom \| bottom-left \| bottom-right ` | `top` | 所有 Message 显示的位置 |
|
||||||
| to | `string \| HTMLElement` | `'body'` | Message 容器节点的位置 |
|
| to | `string \| HTMLElement` | `'body'` | Message 容器节点的位置 |
|
||||||
|
|
||||||
### MessageProvider Injection API
|
### MessageProvider Injection API
|
||||||
|
119
src/message/demos/zhCN/placement.demo.md
Normal file
119
src/message/demos/zhCN/placement.demo.md
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# 位置
|
||||||
|
|
||||||
|
```html
|
||||||
|
<n-message-provider :placement="placement">
|
||||||
|
<Buttons @changePlacement="changePlacement" />
|
||||||
|
</n-message-provider>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { useMessage, NButton } from 'naive-ui'
|
||||||
|
import { h, ref } from 'vue'
|
||||||
|
|
||||||
|
const Buttons = {
|
||||||
|
emits: ['changePlacement'],
|
||||||
|
setup() {
|
||||||
|
const message = useMessage()
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return [
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'top')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => '顶部' }
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'bottom')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => '底部' }
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'top-left')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => '左上' }
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'top-right')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => '右上' }
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'bottom-left')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => '左下' }
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
|
{
|
||||||
|
onClick: () => {
|
||||||
|
this.$emit('changePlacement', 'bottom-right')
|
||||||
|
this.message.info('How many roads must a man walk down')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginRight: '10px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => '右下' }
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Buttons
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const placement = ref('top')
|
||||||
|
return {
|
||||||
|
placement,
|
||||||
|
changePlacement: (val) => {
|
||||||
|
placement.value = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@ -35,7 +35,7 @@ const iconMap = {
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Message',
|
name: 'Message',
|
||||||
props: messageProps,
|
props: messageProps,
|
||||||
setup (props) {
|
setup(props) {
|
||||||
const {
|
const {
|
||||||
props: messageProviderProps,
|
props: messageProviderProps,
|
||||||
mergedClsPrefixRef
|
mergedClsPrefixRef
|
||||||
@ -51,7 +51,7 @@ export default defineComponent({
|
|||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
mergedClsPrefix: mergedClsPrefixRef,
|
mergedClsPrefix: mergedClsPrefixRef,
|
||||||
handleClose () {
|
handleClose() {
|
||||||
props.onClose?.()
|
props.onClose?.()
|
||||||
},
|
},
|
||||||
cssVars: computed(() => {
|
cssVars: computed(() => {
|
||||||
@ -106,10 +106,11 @@ export default defineComponent({
|
|||||||
'--line-height': lineHeight,
|
'--line-height': lineHeight,
|
||||||
'--border-radius': borderRadius
|
'--border-radius': borderRadius
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
|
placement: messageProviderProps.placement
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render () {
|
render() {
|
||||||
const {
|
const {
|
||||||
icon,
|
icon,
|
||||||
type,
|
type,
|
||||||
@ -122,7 +123,12 @@ export default defineComponent({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
class={`${mergedClsPrefix}-message-wrapper`}
|
class={`${mergedClsPrefix}-message-wrapper`}
|
||||||
style={cssVars as CSSProperties}
|
style={{
|
||||||
|
...(cssVars as CSSProperties),
|
||||||
|
alignItems: this.placement.startsWith('top')
|
||||||
|
? 'flex-start'
|
||||||
|
: 'flex-end'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div class={`${mergedClsPrefix}-message`}>
|
<div class={`${mergedClsPrefix}-message`}>
|
||||||
<div
|
<div
|
||||||
@ -150,7 +156,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function createIconVNode (
|
function createIconVNode(
|
||||||
icon: undefined | (() => VNodeChild),
|
icon: undefined | (() => VNodeChild),
|
||||||
type: MessageType,
|
type: MessageType,
|
||||||
clsPrefix: string
|
clsPrefix: string
|
||||||
|
@ -72,6 +72,17 @@ const messageProviderProps = {
|
|||||||
default: 3000
|
default: 3000
|
||||||
},
|
},
|
||||||
max: Number,
|
max: Number,
|
||||||
|
placement: {
|
||||||
|
type: String as PropType<
|
||||||
|
| 'top'
|
||||||
|
| 'top-left'
|
||||||
|
| 'top-right'
|
||||||
|
| 'bottom'
|
||||||
|
| 'bottom-left'
|
||||||
|
| 'bottom-right'
|
||||||
|
>,
|
||||||
|
default: 'top'
|
||||||
|
},
|
||||||
closable: Boolean,
|
closable: Boolean,
|
||||||
containerStyle: [String, Object] as PropType<string | CSSProperties>
|
containerStyle: [String, Object] as PropType<string | CSSProperties>
|
||||||
}
|
}
|
||||||
@ -164,7 +175,10 @@ export default defineComponent({
|
|||||||
{this.messageList.length ? (
|
{this.messageList.length ? (
|
||||||
<Teleport to={this.to ?? 'body'}>
|
<Teleport to={this.to ?? 'body'}>
|
||||||
<div
|
<div
|
||||||
class={`${this.mergedClsPrefix}-message-container`}
|
class={[
|
||||||
|
`${this.mergedClsPrefix}-message-container`,
|
||||||
|
`${this.mergedClsPrefix}-message-container--${this.placement}`
|
||||||
|
]}
|
||||||
key="message-container"
|
key="message-container"
|
||||||
style={this.containerStyle}
|
style={this.containerStyle}
|
||||||
>
|
>
|
||||||
|
@ -29,6 +29,7 @@ export default c([
|
|||||||
margin: var(--margin);
|
margin: var(--margin);
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
transform-origin: top center;
|
transform-origin: top center;
|
||||||
|
display: flex;
|
||||||
`, [
|
`, [
|
||||||
fadeInHeightExpand({
|
fadeInHeightExpand({
|
||||||
overflow: 'visible',
|
overflow: 'visible',
|
||||||
@ -108,13 +109,48 @@ export default c([
|
|||||||
cB('message-container', `
|
cB('message-container', `
|
||||||
z-index: 6000;
|
z-index: 6000;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 12px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 0;
|
height: 0;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
`, [
|
||||||
|
cM('top', `
|
||||||
|
top: 12px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
`),
|
||||||
|
cM('top-left', `
|
||||||
|
top: 12px;
|
||||||
|
left: 12px;
|
||||||
|
right: 0;
|
||||||
|
align-items: flex-start;
|
||||||
|
`),
|
||||||
|
cM('top-right', `
|
||||||
|
top: 12px;
|
||||||
|
left: 0;
|
||||||
|
right: 12px;
|
||||||
|
align-items: flex-end;
|
||||||
|
`),
|
||||||
|
cM('bottom', `
|
||||||
|
bottom: 4px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
justify-content: flex-end;
|
||||||
|
`),
|
||||||
|
cM('bottom-left', `
|
||||||
|
bottom: 4px;
|
||||||
|
left: 12px;
|
||||||
|
right: 0;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-start;
|
||||||
|
`),
|
||||||
|
cM('bottom-right', `
|
||||||
|
bottom: 4px;
|
||||||
|
left: 0;
|
||||||
|
right: 12px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-end;
|
||||||
`)
|
`)
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
Loading…
Reference in New Issue
Block a user