feat(components): [message-box] MessageBox can drag overflow the viewport (#15674)

feat(components): [message-box] can drag overflow the viewport
This commit is contained in:
kooriookami
2024-01-26 10:20:08 +08:00
committed by GitHub
parent 1f6537af4c
commit ee7a21f670
15 changed files with 83 additions and 81 deletions

View File

@ -113,7 +113,7 @@ message-box/customized-icon
MessageBox can be draggable.
:::demo Setting `draggable` to `true` allows user to drag MessageBox.
:::demo Setting `draggable` to `true` allows user to drag MessageBox. Set `overflow` ^(2.5.4) to `true` can drag overflow the viewport.
message-box/draggable
@ -159,7 +159,7 @@ The corresponding methods are: `ElMessageBox`, `ElMessageBox.alert`, `ElMessageB
### Options
| Name | Description | Type | Default |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------ |
|------------------------------|------------------------------------------------------------------------------------------------------------------------------------------| ---------------------------------------------------------------------------------- | ------------------------------------------------ |
| autofocus | auto focus when open MessageBox | ^[boolean] | true |
| title | title of the MessageBox | ^[string] | '' |
| message | content of the MessageBox | ^[string] / ^[VNode] / ^[Function]`() => VNode` ^(2.2.17) | — |
@ -191,6 +191,7 @@ The corresponding methods are: `ElMessageBox`, `ElMessageBox.alert`, `ElMessageB
| input-error-message | error message when validation fails | ^[string] | Illegal input |
| center | whether to align the content in center | ^[boolean] | false |
| draggable | whether MessageBox is draggable | ^[boolean] | false |
| overflow ^(2.5.4) | draggable MessageBox can overflow the viewport | ^[boolean] | false |
| round-button | whether to use round button | ^[boolean] | false |
| button-size | custom size of confirm and cancel buttons | ^[string]`'small' \| 'default' \| 'large'` | default |
| append-to ^(2.2.19) | set the root element for the message box | ^[string] / ^[HTMLElement] | — |

View File

@ -1,5 +1,5 @@
<template>
<el-button text @click="open">Click to open the Message Box</el-button>
<el-button plain @click="open">Click to open the Message Box</el-button>
</template>
<script lang="ts" setup>

View File

@ -1,5 +1,5 @@
<template>
<el-button text @click="open">Click to open Message Box</el-button>
<el-button plain @click="open">Click to open Message Box</el-button>
</template>
<script lang="ts" setup>

View File

@ -1,5 +1,5 @@
<template>
<el-button text @click="open">Click to open the Message Box</el-button>
<el-button plain @click="open">Click to open the Message Box</el-button>
</template>
<script lang="ts" setup>

View File

@ -1,5 +1,5 @@
<template>
<el-button text @click="open">Click to open Message Box</el-button>
<el-button plain @click="open">Click to open Message Box</el-button>
</template>
<script lang="ts" setup>

View File

@ -1,5 +1,5 @@
<template>
<el-button text @click="open">Click to open Message Box</el-button>
<el-button plain @click="open">Click to open Message Box</el-button>
</template>
<script lang="ts" setup>

View File

@ -1,5 +1,5 @@
<template>
<el-button text @click="open">Click to open Message Box</el-button>
<el-button plain @click="open">Click to open Message Box</el-button>
</template>
<script lang="ts" setup>

View File

@ -1,5 +1,8 @@
<template>
<el-button text @click="open">Click to open Message Box</el-button>
<el-button plain @click="open">Open a draggable Message Box</el-button>
<el-button plain @click="open2">
Open a overflow draggable Message Box
</el-button>
</template>
<script lang="ts" setup>
@ -29,4 +32,30 @@ const open = () => {
})
})
}
const open2 = () => {
ElMessageBox.confirm(
'proxy will permanently delete the file. Continue?',
'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning',
draggable: true,
overflow: true,
}
)
.then(() => {
ElMessage({
type: 'success',
message: 'Delete completed',
})
})
.catch(() => {
ElMessage({
type: 'info',
message: 'Delete canceled',
})
})
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<el-button text @click="open">Click to open Message Box</el-button>
<el-button plain @click="open">Click to open Message Box</el-button>
</template>
<script lang="ts" setup>

View File

@ -1,5 +1,5 @@
<template>
<el-button text @click="open">Click to open Message Box</el-button>
<el-button plain @click="open">Click to open Message Box</el-button>
</template>
<script lang="ts" setup>

View File

@ -38,7 +38,7 @@
<div
v-if="title !== null && title !== undefined"
ref="headerRef"
:class="ns.e('header')"
:class="[ns.e('header'), { 'show-close': showClose }]"
>
<div :class="ns.e('title')">
<el-icon
@ -178,7 +178,7 @@ import { ElIcon } from '@element-plus/components/icon'
import ElFocusTrap from '@element-plus/components/focus-trap'
import { useGlobalComponentSettings } from '@element-plus/components/config-provider'
import type { ComponentPublicInstance, DefineComponent, PropType } from 'vue'
import type { ComponentPublicInstance, PropType } from 'vue'
import type { ComponentSize } from '@element-plus/constants'
import type {
Action,
@ -231,6 +231,7 @@ export default defineComponent({
},
center: Boolean,
draggable: Boolean,
overflow: Boolean,
roundButton: {
default: false,
type: Boolean,
@ -365,7 +366,8 @@ export default defineComponent({
)
const draggable = computed(() => props.draggable)
useDraggable(rootRef, headerRef, draggable)
const overflow = computed(() => props.overflow)
useDraggable(rootRef, headerRef, draggable, overflow)
onMounted(async () => {
await nextTick()
@ -499,5 +501,5 @@ export default defineComponent({
t,
}
},
}) as DefineComponent
})
</script>

View File

@ -102,6 +102,9 @@ export interface ElMessageBoxOptions {
/** Whether MessageBox can be drag */
draggable?: boolean
/** Draggable MessageBox can overflow the viewport */
overflow?: boolean
/** Content of the MessageBox */
message?: string | VNode | (() => VNode)

View File

@ -516,11 +516,13 @@ $messagebox: map.merge(
'title-color': getCssVar('text-color-primary'),
'width': 420px,
'border-radius': 4px,
'box-shadow': getCssVar('box-shadow'),
'font-size': getCssVar('font-size-large'),
'content-font-size': getCssVar('font-size-base'),
'content-color': getCssVar('text-color-regular'),
'error-font-size': 12px,
'padding-primary': 15px,
'padding-primary': 12px,
'font-line-height': getCssVar('font-line-height-primary'),
),
$messagebox
);

View File

@ -17,6 +17,7 @@
box-sizing: border-box;
padding: getCssVar('dialog', 'padding-primary');
width: var(#{getCssVarName('dialog-width')}, 50%);
overflow-wrap: break-word;
&:focus {
outline: none !important;

View File

@ -11,20 +11,21 @@
@include b(message-box) {
display: inline-block;
position: relative;
max-width: getCssVar('messagebox-width');
width: 100%;
padding-bottom: 10px;
padding: getCssVar('messagebox-padding-primary');
vertical-align: middle;
background-color: getCssVar('bg-color');
border-radius: getCssVar('messagebox-border-radius');
border: 1px solid getCssVar('border-color-lighter');
font-size: getCssVar('messagebox-font-size');
box-shadow: getCssVar('box-shadow-light');
box-shadow: getCssVar('messagebox-box-shadow');
text-align: left;
overflow: hidden;
backface-visibility: hidden;
// To avoid small screen overflowing, see #11919
box-sizing: border-box;
overflow-wrap: break-word;
&:focus {
outline: none !important;
@ -59,24 +60,29 @@
}
@include e(header) {
position: relative;
padding: getCssVar('messagebox-padding-primary');
padding-bottom: 10px;
padding-bottom: getCssVar('messagebox-padding-primary');
&.show-close {
padding-right: calc(getCssVar('messagebox-padding-primary') + var(
#{getCssVarName('message-close-size')},
map.get($message, 'close-size')
));
}
}
@include e(title) {
padding-left: 0;
margin-bottom: 0;
font-size: getCssVar('messagebox-font-size');
line-height: 1;
line-height: getCssVar('messagebox-font-line-height');
color: getCssVar('messagebox-title-color');
}
@include e(headerbtn) {
position: absolute;
top: getCssVar('messagebox-padding-primary');
right: getCssVar('messagebox-padding-primary');
top: 0;
right: 0;
padding: 0;
width: 40px;
height: 40px;
border: none;
outline: none;
background: transparent;
@ -100,17 +106,18 @@
}
@include e(content) {
padding: 10px getCssVar('messagebox-padding-primary');
color: getCssVar('messagebox-content-color');
font-size: getCssVar('messagebox-content-font-size');
}
@include e(container) {
position: relative;
display: flex;
align-items: center;
gap: 12px;
}
@include e(input) {
padding-top: 15px;
padding-top: 12px;
& div.invalid > input {
border-color: getCssVar('color-error');
@ -122,26 +129,7 @@
}
@include e(status) {
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 24px !important;
&::before {
// 防止图标切割
padding-left: 1px;
}
&.#{$namespace}-icon {
// 防止 el-icon 的position样式覆盖
position: absolute;
}
+ .#{$namespace}-message-box__message {
padding-left: 36px;
padding-right: 12px;
overflow-wrap: break-word;
}
font-size: 24px;
@each $type in (success, info, warning, error) {
&.#{$namespace}-message-box-icon--#{$type} {
@ -156,67 +144,43 @@
& p {
margin: 0;
line-height: 24px;
line-height: getCssVar('messagebox-font-line-height');
}
}
@include e(errormsg) {
color: getCssVar('color-error');
font-size: getCssVar('messagebox-error-font-size');
min-height: 18px;
margin-top: 2px;
line-height: getCssVar('messagebox-font-line-height');
}
@include e(btns) {
padding: 5px 15px 0;
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
align-items: center;
& button:nth-child(2) {
margin-left: 10px;
}
}
@include e(btns-reverse) {
flex-direction: row-reverse;
padding-top: getCssVar('messagebox-padding-primary');
}
// centerAlign 布局
@include m(center) {
@include e(title) {
position: relative;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
}
@include e(status) {
position: relative;
top: auto;
padding-right: 5px;
text-align: center;
transform: translateY(-1px);
}
@include e(message) {
margin-left: 0;
font-size: inherit;
}
@include e(btns) {
justify-content: center;
}
@include e(content) {
$padding-horizontal: calc(
#{getCssVar('messagebox', 'padding-primary')} + 12px
);
padding-left: $padding-horizontal;
padding-right: $padding-horizontal;
text-align: center;
@include e(container) {
justify-content: center;
}
}
}