feat: 统一管理端弹窗与内容区交互样式
- 收敛管理端公共 Modal 链路,新增表单弹窗与普通内容弹窗包装\n- 迁移 Bot、知识库、插件、工作流、资源、MCP、数据中枢与系统管理页面级弹窗\n- 统一内容区工具栏、列表容器、导航与顶部按钮的视觉密度和交互节奏
This commit is contained in:
@@ -184,7 +184,7 @@ const getForceMount = computed(() => {
|
||||
<SheetContent
|
||||
:append-to="getAppendTo"
|
||||
:class="
|
||||
cn('flex w-[520px] flex-col', drawerClass, {
|
||||
cn('flex w-[520px] flex-col overflow-hidden border border-[hsl(var(--glass-border))/0.18] bg-[hsl(var(--glass-tint))/0.84] shadow-[var(--shadow-float)] supports-[backdrop-filter]:bg-[hsl(var(--glass-tint))/0.62]', drawerClass, {
|
||||
'!w-full': isMobile || placement === 'bottom' || placement === 'top',
|
||||
'max-h-[100vh]': placement === 'bottom' || placement === 'top',
|
||||
hidden: isClosed,
|
||||
@@ -209,7 +209,7 @@ const getForceMount = computed(() => {
|
||||
v-if="showHeader"
|
||||
:class="
|
||||
cn(
|
||||
'!flex flex-row items-center justify-between border-b px-6 py-5',
|
||||
'!flex flex-row items-center justify-between border-b border-[hsl(var(--divider-faint))/0.32] px-6 py-5',
|
||||
headerClass,
|
||||
{
|
||||
'px-4 py-3': closable,
|
||||
@@ -223,7 +223,7 @@ const getForceMount = computed(() => {
|
||||
v-if="closable && closeIconPlacement === 'left'"
|
||||
as-child
|
||||
:disabled="submitting"
|
||||
class="data-[state=open]:bg-secondary ml-[2px] cursor-pointer rounded-full opacity-80 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none"
|
||||
class="data-[state=open]:bg-[hsl(var(--surface-contrast-soft))/0.92] ml-[2px] cursor-pointer rounded-full opacity-84 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none"
|
||||
>
|
||||
<slot name="close-icon">
|
||||
<EasyFlowIconButton>
|
||||
@@ -264,7 +264,7 @@ const getForceMount = computed(() => {
|
||||
v-if="closable && closeIconPlacement === 'right'"
|
||||
as-child
|
||||
:disabled="submitting"
|
||||
class="data-[state=open]:bg-secondary ml-[2px] cursor-pointer rounded-full opacity-80 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none"
|
||||
class="data-[state=open]:bg-[hsl(var(--surface-contrast-soft))/0.92] ml-[2px] cursor-pointer rounded-full opacity-84 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none"
|
||||
>
|
||||
<slot name="close-icon">
|
||||
<EasyFlowIconButton>
|
||||
@@ -295,7 +295,7 @@ const getForceMount = computed(() => {
|
||||
v-if="showFooter"
|
||||
:class="
|
||||
cn(
|
||||
'w-full flex-row items-center justify-end border-t p-2 px-3',
|
||||
'w-full flex-row items-center justify-end border-t border-[hsl(var(--divider-faint))/0.32] p-2 px-3',
|
||||
footerClass,
|
||||
)
|
||||
"
|
||||
|
||||
@@ -59,7 +59,7 @@ export class ModalApi {
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
title: '',
|
||||
animationType: 'slide',
|
||||
animationType: 'scale',
|
||||
};
|
||||
|
||||
this.store = new Store<ModalState>(
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { ModalApi } from './modal-api';
|
||||
export interface ModalProps {
|
||||
/**
|
||||
* 动画类型
|
||||
* @default 'slide'
|
||||
* @default 'scale'
|
||||
*/
|
||||
animationType?: 'scale' | 'slide';
|
||||
/**
|
||||
|
||||
@@ -231,12 +231,13 @@ function handleClosed() {
|
||||
:append-to="getAppendTo"
|
||||
:class="
|
||||
cn(
|
||||
'left-0 right-0 top-[10vh] mx-auto flex max-h-[80%] w-[520px] flex-col p-0',
|
||||
shouldFullscreen ? 'sm:rounded-none' : 'sm:rounded-[var(--radius)]',
|
||||
'left-0 right-0 top-[10vh] mx-auto flex max-h-[80%] w-[520px] flex-col overflow-hidden border border-[hsl(var(--modal-shell-border-soft))] bg-[hsl(var(--modal-surface))] p-0',
|
||||
shouldFullscreen
|
||||
? 'sm:rounded-none'
|
||||
: 'sm:rounded-[var(--radius-modal)]',
|
||||
modalClass,
|
||||
{
|
||||
'border-border border': bordered,
|
||||
'shadow-3xl': !bordered,
|
||||
'border-[hsl(var(--modal-shell-border-soft))]': bordered,
|
||||
'left-0 top-0 size-full max-h-full !translate-x-0 !translate-y-0':
|
||||
shouldFullscreen,
|
||||
'top-1/2 !-translate-y-1/2': centered && !shouldFullscreen,
|
||||
@@ -248,6 +249,16 @@ function handleClosed() {
|
||||
:force-mount="getForceMount"
|
||||
:modal="modal"
|
||||
:open="state?.isOpen"
|
||||
:overlay-style="{
|
||||
backgroundColor:
|
||||
'hsl(var(--modal-overlay) / var(--modal-overlay-opacity))',
|
||||
}"
|
||||
:content-style="{
|
||||
backdropFilter: 'none',
|
||||
WebkitBackdropFilter: 'none',
|
||||
backgroundColor: 'hsl(var(--modal-surface))',
|
||||
boxShadow: 'var(--modal-shadow)',
|
||||
}"
|
||||
:show-close="closable"
|
||||
:animation-type="animationType"
|
||||
:z-index="zIndex"
|
||||
@@ -267,9 +278,8 @@ function handleClosed() {
|
||||
ref="headerRef"
|
||||
:class="
|
||||
cn(
|
||||
'px-5 py-4',
|
||||
'px-5 py-4 sm:px-6 sm:py-5',
|
||||
{
|
||||
'border-b': bordered,
|
||||
hidden: !header,
|
||||
'cursor-move select-none': shouldDraggable,
|
||||
},
|
||||
@@ -301,9 +311,13 @@ function handleClosed() {
|
||||
<div
|
||||
ref="wrapperRef"
|
||||
:class="
|
||||
cn('relative min-h-40 flex-1 overflow-y-auto p-3', contentClass, {
|
||||
'pointer-events-none': showLoading || submitting,
|
||||
})
|
||||
cn(
|
||||
'relative min-h-0 flex-1 overflow-y-auto bg-[hsl(var(--modal-content-surface))] px-5 pb-5 pt-4 sm:px-6 sm:pb-6',
|
||||
contentClass,
|
||||
{
|
||||
'pointer-events-none': showLoading || submitting,
|
||||
},
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot></slot>
|
||||
@@ -311,7 +325,7 @@ function handleClosed() {
|
||||
<EasyFlowLoading v-if="showLoading || submitting" spinning />
|
||||
<EasyFlowIconButton
|
||||
v-if="fullscreenButton"
|
||||
class="hover:bg-accent hover:text-accent-foreground text-foreground/80 flex-center absolute right-10 top-3 hidden size-6 rounded-full px-1 text-lg opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none sm:block"
|
||||
class="text-foreground/80 flex-center opacity-78 absolute right-11 top-4 hidden size-8 rounded-full bg-[hsl(var(--modal-preview-surface-strong))/0.76] px-1 text-lg shadow-[0_16px_28px_-24px_hsl(var(--foreground)/0.4)] transition-all hover:-translate-y-0.5 hover:opacity-100 focus:outline-none disabled:pointer-events-none sm:block"
|
||||
@click="handleFullscreen"
|
||||
>
|
||||
<Shrink v-if="fullscreen" class="size-3.5" />
|
||||
@@ -323,9 +337,9 @@ function handleClosed() {
|
||||
ref="footerRef"
|
||||
:class="
|
||||
cn(
|
||||
'flex-row items-center justify-end p-2',
|
||||
'flex-row items-center justify-end gap-3 bg-[hsl(var(--modal-footer-surface))] px-5 py-4 sm:px-6',
|
||||
{
|
||||
'border-t': bordered,
|
||||
'border-t border-[hsl(var(--modal-divider))]': bordered,
|
||||
},
|
||||
footerClass,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user