Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
26cdb180
Commit
26cdb180
authored
Dec 28, 2025
by
IanShaw027
Browse files
fix(frontend): 补充缺失的BaseDialog组件
parent
506cb21c
Changes
1
Hide whitespace changes
Inline
Side-by-side
frontend/src/components/common/BaseDialog.vue
0 → 100644
View file @
26cdb180
<
template
>
<Teleport
to=
"body"
>
<div
v-if=
"show"
class=
"modal-overlay"
aria-labelledby=
"modal-title"
role=
"dialog"
aria-modal=
"true"
@
click.self=
"handleClose"
>
<!-- Modal panel -->
<div
:class=
"['modal-content', widthClasses]"
@
click.stop
>
<!-- Header -->
<div
class=
"modal-header"
>
<h3
id=
"modal-title"
class=
"modal-title"
>
{{
title
}}
</h3>
<button
@
click=
"emit('close')"
class=
"-mr-2 rounded-xl p-2 text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-600 dark:text-dark-500 dark:hover:bg-dark-700 dark:hover:text-dark-300"
aria-label=
"Close modal"
>
<svg
class=
"h-5 w-5"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
stroke-width=
"1.5"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
d=
"M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<!-- Body -->
<div
class=
"modal-body"
>
<slot></slot>
</div>
<!-- Footer -->
<div
v-if=
"$slots.footer"
class=
"modal-footer"
>
<slot
name=
"footer"
></slot>
</div>
</div>
</div>
</Teleport>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
computed
,
watch
,
onMounted
,
onUnmounted
}
from
'
vue
'
type
DialogWidth
=
'
narrow
'
|
'
normal
'
|
'
wide
'
|
'
extra-wide
'
|
'
full
'
interface
Props
{
show
:
boolean
title
:
string
width
?:
DialogWidth
closeOnEscape
?:
boolean
closeOnClickOutside
?:
boolean
}
interface
Emits
{
(
e
:
'
close
'
):
void
}
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
width
:
'
normal
'
,
closeOnEscape
:
true
,
closeOnClickOutside
:
false
})
const
emit
=
defineEmits
<
Emits
>
()
const
widthClasses
=
computed
(()
=>
{
const
widths
:
Record
<
DialogWidth
,
string
>
=
{
narrow
:
'
max-w-md
'
,
normal
:
'
max-w-lg
'
,
wide
:
'
max-w-4xl
'
,
'
extra-wide
'
:
'
max-w-6xl
'
,
full
:
'
max-w-7xl
'
}
return
widths
[
props
.
width
]
})
const
handleClose
=
()
=>
{
if
(
props
.
closeOnClickOutside
)
{
emit
(
'
close
'
)
}
}
const
handleEscape
=
(
event
:
KeyboardEvent
)
=>
{
if
(
props
.
show
&&
props
.
closeOnEscape
&&
event
.
key
===
'
Escape
'
)
{
emit
(
'
close
'
)
}
}
// Prevent body scroll when modal is open
watch
(
()
=>
props
.
show
,
(
isOpen
)
=>
{
if
(
isOpen
)
{
document
.
body
.
style
.
overflow
=
'
hidden
'
}
else
{
document
.
body
.
style
.
overflow
=
''
}
},
{
immediate
:
true
}
)
onMounted
(()
=>
{
document
.
addEventListener
(
'
keydown
'
,
handleEscape
)
})
onUnmounted
(()
=>
{
document
.
removeEventListener
(
'
keydown
'
,
handleEscape
)
document
.
body
.
style
.
overflow
=
''
})
</
script
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment