!3540 feat(#I61RXB): support drag function on Modal component

* chore: bump version 7.0.3-beta02
* test: 排除单元测试代码覆盖率
* style: 增加最大化样式解决与可拖动的冲突
* feat: 增加 margin 样式
* doc: 增加最大化按钮
* doc: 更新示例
* feat: 增加拖动逻辑
* fix: 修复 image-viewer 错误
* refactor: 修复 removeLInk 方法
This commit is contained in:
Argo 2022-11-17 13:41:39 +00:00
parent 2ed76dfa40
commit f14194f90b
8 changed files with 94 additions and 26 deletions

View File

@ -24,7 +24,7 @@
</div>
<div class="mt-3">
<p>@((MarkupString)Localizer["P5"].Value)</p>
<Button OnClick="async e => await Modal.Toggle()">@Localizer["P9"]</Button>
<Button OnClick="() => Modal.Toggle()">@Localizer["P9"]</Button>
<Button OnClick="OnClickKeyboard" Text="@($"Keyboard: {IsKeyboard}")" class="ms-3" />
</div>
<Modal @ref="Modal" IsKeyboard="@IsKeyboard">
@ -37,7 +37,7 @@
</DemoBlock>
<DemoBlock Title="@Localizer["P12"]" Introduction="@Localizer["P13"]" Name="IsBackdrop">
<Button OnClick="@(async e => await BackdropModal.Toggle())">@Localizer["P14"]</Button>
<Button OnClick="() => BackdropModal.Toggle()">@Localizer["P14"]</Button>
<Modal @ref="BackdropModal" IsBackdrop="true">
<ModalDialog Title="@Localizer["P15"]">
<BodyTemplate>
@ -50,7 +50,7 @@
<DemoBlock Title="@Localizer["P17"]" Introduction="@Localizer["P18"]" Name="DialogSize">
<div class="row g-3">
<div class="col-12 col-sm-4 col-lg-auto">
<Button OnClick="@(async e => await SmailModal.Toggle())">@Localizer["P19"]</Button>
<Button OnClick="() => SmailModal.Toggle()">@Localizer["P19"]</Button>
<Modal @ref="SmailModal">
<ModalDialog Size="Size.Small" Title="@Localizer["P20"]">
<BodyTemplate>
@ -60,7 +60,7 @@
</Modal>
</div>
<div class="col-12 col-sm-4 col-lg-auto">
<Button OnClick="@(async e => await LargeModal.Toggle())">@Localizer["P22"]</Button>
<Button OnClick="() => LargeModal.Toggle()">@Localizer["P22"]</Button>
<Modal @ref="LargeModal">
<ModalDialog Size="Size.Large" Title="@Localizer["P23"]">
<BodyTemplate>
@ -70,7 +70,7 @@
</Modal>
</div>
<div class="col-12 col-sm-4 col-lg-auto">
<Button OnClick="@(async e => await ExtraLargeModal.Toggle())">@Localizer["P25"]</Button>
<Button OnClick="() => ExtraLargeModal.Toggle()">@Localizer["P25"]</Button>
<Modal @ref="ExtraLargeModal">
<ModalDialog Size="Size.ExtraLarge" Title="@Localizer["P26"]">
<BodyTemplate>
@ -80,7 +80,7 @@
</Modal>
</div>
<div class="col-12 col-sm-4 col-lg-auto">
<Button OnClick="@(async e => await ExtraExtraLargeModal.Toggle())">@Localizer["P28"]</Button>
<Button OnClick="() => ExtraExtraLargeModal.Toggle()">@Localizer["P28"]</Button>
<Modal @ref="ExtraExtraLargeModal">
<ModalDialog Size="Size.ExtraExtraLarge" Title="@Localizer["P29"]">
<BodyTemplate>
@ -95,7 +95,7 @@
<DemoBlock Title="@Localizer["P31"]" Introduction="@Localizer["P32"]" Name="FullScreenSize">
<div class="row g-3">
<div class="col-12 col-sm-4 col-lg-auto">
<Button OnClick="@(async e => await SmailFullScreenModal.Toggle())">@Localizer["P33"]</Button>
<Button OnClick="() => SmailFullScreenModal.Toggle()">@Localizer["P33"]</Button>
<Modal @ref="SmailFullScreenModal">
<ModalDialog FullScreenSize="FullScreenSize.Always" Title="@Localizer["P34"]">
<BodyTemplate>
@ -105,7 +105,7 @@
</Modal>
</div>
<div class="col-12 col-sm-4 col-lg-auto">
<Button OnClick="@(async e => await LargeFullScreenModal.Toggle())">@Localizer["P36"]</Button>
<Button OnClick="() => LargeFullScreenModal.Toggle()">@Localizer["P36"]</Button>
<Modal @ref="LargeFullScreenModal">
<ModalDialog FullScreenSize="FullScreenSize.Large" Title="@Localizer["P37"]">
<BodyTemplate>
@ -115,7 +115,7 @@
</Modal>
</div>
<div class="col-12 col-sm-4 col-lg-auto">
<Button OnClick="@(async e => await ExtraLargeFullScreenModal.Toggle())">@Localizer["P39"]</Button>
<Button OnClick="() => ExtraLargeFullScreenModal.Toggle()">@Localizer["P39"]</Button>
<Modal @ref="ExtraLargeFullScreenModal">
<ModalDialog FullScreenSize="FullScreenSize.ExtraLarge" Title="@Localizer["P40"]">
<BodyTemplate>
@ -125,7 +125,7 @@
</Modal>
</div>
<div class="col-12 col-sm-4 col-lg-auto">
<Button OnClick="@(async e => await ExtraExtraLargeFullScreenModal.Toggle())">@Localizer["P42"]</Button>
<Button OnClick="() => ExtraExtraLargeFullScreenModal.Toggle()">@Localizer["P42"]</Button>
<Modal @ref="ExtraExtraLargeFullScreenModal">
<ModalDialog FullScreenSize="FullScreenSize.ExtraExtraLarge" Title="@Localizer["P43"]">
<BodyTemplate>
@ -138,7 +138,7 @@
</DemoBlock>
<DemoBlock Title="@Localizer["P45"]" Introduction="@Localizer["P46"]" Name="CenterVertically">
<Button OnClick="@(async e => await CenterModal.Toggle())">@Localizer["P47"]</Button>
<Button OnClick="() => CenterModal.Toggle()">@Localizer["P47"]</Button>
<Modal @ref="CenterModal">
<ModalDialog IsCentered="true" Title="@Localizer["P48"]">
<BodyTemplate>
@ -151,7 +151,7 @@
<DemoBlock Title="@Localizer["P50"]" Introduction="@Localizer["P51"]" Name="LongContent">
<div class="row g-3">
<div class="col-12 col-sm-4 col-lg-auto">
<Button OnClick="@(async e => await LongContentModal.Toggle())">@Localizer["P52"]</Button>
<Button OnClick="() => LongContentModal.Toggle()">@Localizer["P52"]</Button>
<Modal @ref="LongContentModal">
<ModalDialog IsCentered="true" Title="@Localizer["P53"]">
<BodyTemplate>
@ -178,7 +178,7 @@
</Modal>
</div>
<div class="col-12 col-sm-4 col-lg-auto">
<Button OnClick="@(async e => await ScrollModal.Toggle())">@Localizer["P54"]</Button>
<Button OnClick="() => ScrollModal.Toggle()">@Localizer["P54"]</Button>
<Modal @ref="ScrollModal">
<ModalDialog IsCentered="true" IsScrolling="true" Title="@Localizer["P55"]">
<BodyTemplate>
@ -207,10 +207,10 @@
</div>
</DemoBlock>
<DemoBlock Title="@Localizer["P56"]" Introduction="@Localizer["P57"]" Name="Drag">
<Button OnClick="@(async e => await DragModal.Toggle())">@Localizer["P58"]</Button>
<DemoBlock Title="@Localizer["P56"]" Introduction="@Localizer["P57"]" Name="IsDraggable">
<Button OnClick="() => DragModal.Toggle()">@Localizer["P58"]</Button>
<Modal @ref="DragModal">
<ModalDialog Title="@Localizer["P59"]" IsDraggable="true">
<ModalDialog Title="@Localizer["P59"]" IsDraggable="true" ShowMaximizeButton="true">
<BodyTemplate>
<div>@Localizer["P60"]</div>
</BodyTemplate>
@ -219,7 +219,7 @@
</DemoBlock>
<DemoBlock Title="@Localizer["P61"]" Introduction="@Localizer["P62"]" Name="Maximize">
<Button OnClick="@(async e => await MaximizeModal.Toggle())">@Localizer["P63"]</Button>
<Button OnClick="() => MaximizeModal.Toggle()">@Localizer["P63"]</Button>
<Modal @ref="MaximizeModal">
<ModalDialog Title="@Localizer["P64"]" ShowMaximizeButton="true">
<BodyTemplate>
@ -230,7 +230,7 @@
</DemoBlock>
<DemoBlock Title="弹窗已显示回调方法" Introduction="通过设置 <code>ShownCallbackAsync</code> 回调委托,弹窗显示后回调此方法" Name="ShownCallbackAsync">
<Button OnClick="@(async e => await ShownCallbackModal.Toggle())">弹窗</Button>
<Button OnClick="() => ShownCallbackModal.Toggle()">弹窗</Button>
<Modal @ref="ShownCallbackModal" OnShownAsync="OnShownCallbackAsync">
<ModalDialog Title="ShownCallbackAsync 回调示例">
<BodyTemplate>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<Version>7.0.3-beta01</Version>
<Version>7.0.3-beta02</Version>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">

View File

@ -45,6 +45,11 @@
border: 0;
}
.modal-fullscreen.is-draggable {
margin: 0 !important;
width: 100vw !important;
}
@media screen {
.bb-printview {
display: none;

File diff suppressed because one or more lines are too long

View File

@ -156,7 +156,7 @@ const addLink = href => {
const removeLink = href => {
const links = [...document.getElementsByTagName('link')]
const nodes = links.filter(function (link) {
return link.href.indexOf(content) > -1
return link.href.indexOf(href) > -1
})
for (let index = 0; index < nodes.length; index++) {
document.getElementsByTagName("head")[0].removeChild(nodes[index])

View File

@ -211,10 +211,10 @@ export class ImageViewer extends BlazorComponent {
this._pt.top = parseInt(this._prevImg.style.marginTop)
this._pt.left = parseInt(this._prevImg.style.marginLeft)
this._prevImg.addClass('is-drag')
this._prevImg.classList.add('is-drag')
},
e => {
if (this.hasClass('is-drag')) {
if (this._prevImg.classList.contains('is-drag')) {
const eventX = e.clientX || e.changedTouches[0].clientX
const eventY = e.clientY || e.changedTouches[0].clientY

View File

@ -1,5 +1,6 @@
import BlazorComponent from "./base/blazor-component.js"
import EventHandler from "./base/event-handler.js"
import {drag, getHeight, getWidth} from "./base/utility.js"
export class Modal extends BlazorComponent {
_init() {
@ -14,13 +15,20 @@ export class Modal extends BlazorComponent {
this._invoker.invokeMethodAsync(this._invokerShownMethod)
})
EventHandler.on(this._element, 'hide.bs.modal', () => {
if (this._draggable) {
this._dialog.style.width = ''
this._dialog.style.marginLeft = ''
this._dialog.style.marginTop = ''
this._dialog.style.marginBottom = ''
this._dialog.style.marginRight = ''
EventHandler.off(this._dialog, 'mousedown')
EventHandler.off(this._dialog, 'touchstart')
}
this._invoker.invokeMethodAsync(this._invokerCloseMethod)
})
console.log('pop1')
this._pop = () => {
console.log('pop2')
if (this._modal) {
this._modal._dialog.remove()
this._modal.dispose()
@ -62,6 +70,60 @@ export class Modal extends BlazorComponent {
} else {
this._invoker.invokeMethodAsync(this._invokerShownMethod)
}
this._dialog = dialogs[dialogs.length - 1]
this._draggable = this._dialog.classList.contains('is-draggable')
if (this._draggable) {
this._originX = 0;
this._originY = 0;
this._dialogWidth = 0;
this._dialogHeight = 0;
this._pt = {top: 0, left: 0};
const header = this._dialog.querySelector('.modal-header')
drag(header,
e => {
this._originX = e.clientX || e.touches[0].clientX;
this._originY = e.clientY || e.touches[0].clientY;
this._dialogWidth = getWidth(this._dialog);
this._dialogHeight = getHeight(this._dialog);
const style = getComputedStyle(this._dialog)
this._pt.top = parseInt(style.marginTop) || 0
this._pt.left = parseInt(style.marginLeft) || 0
this._dialog.style.marginLeft = `${this._pt.left}px`
this._dialog.style.marginTop = `${this._pt.top}px`
this._dialog.style.marginBottom = `0`
this._dialog.style.marginRight = `0`
this._dialog.style.width = `${this._dialogWidth}px`
this._dialog.classList.add('is-drag')
},
e => {
if (this._dialog.classList.contains('is-drag')) {
const eventX = e.clientX || e.changedTouches[0].clientX;
const eventY = e.clientY || e.changedTouches[0].clientY;
let newValX = this._pt.left + Math.ceil(eventX - this._originX);
let newValY = this._pt.top + Math.ceil(eventY - this._originY);
if (newValX <= 0) newValX = 0;
if (newValY <= 0) newValY = 0;
if (newValX + this._dialogWidth < window.innerWidth) {
this._dialog.style.marginLeft = `${newValX}px`
}
if (newValY + this._dialogHeight < window.innerHeight) {
this._dialog.style.marginTop = `${newValY}px`
}
}
},
e => {
this._dialog.classList.remove('is-drag')
})
}
}
_hide() {

View File

@ -4,6 +4,7 @@
[assembly: CollectionBehavior(DisableTestParallelization = true)]
[assembly: TestCollectionOrderer("UnitTest.Misc.DisplayNameOrderer", "UnitTest")]
[assembly: ExcludeFromCodeCoverage]
namespace UnitTest.Misc;