Files
workspace/code/fms/fms-vue/src/components/ui/modal/index.scss
T
2026-08-22 17:18:27 +08:00

246 lines
5.1 KiB
SCSS

/* ---------- 遮罩 ---------- */
.fms-modal-mask {
position: fixed;
inset: 0;
z-index: var(--fms-z-modal);
background: var(--fms-mask-bg);
}
/* 遮罩过渡:淡入淡出 */
.fms-modal-mask-enter-active,
.fms-modal-mask-leave-active {
transition: opacity 160ms ease;
}
.fms-modal-mask-enter-from,
.fms-modal-mask-leave-to {
opacity: 0;
}
/* ---------- 外层容器:滚动 + 定位面板 ---------- */
.fms-modal-wrap {
position: fixed;
inset: 0;
z-index: var(--fms-z-modal);
display: flex;
justify-content: center;
/* 默认距顶部 100px,内容超高时整体滚动 */
align-items: flex-start;
padding: 100px 16px 24px;
overflow-y: auto;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
.fms-modal-centered {
align-items: center;
padding-top: 24px;
}
/* ---------- 面板 ---------- */
.fms-modal {
position: relative;
display: flex;
flex-direction: column;
flex-shrink: 0;
box-sizing: border-box;
max-width: 100%;
background: var(--fms-card);
border-radius: var(--fms-control-radius);
box-shadow: var(--fms-popover-shadow);
color: var(--fms-text);
font-size: var(--fms-font-size);
line-height: var(--fms-line-height);
/* 面板自身可聚焦(tabindex=-1),聚焦时给出清晰的焦点环 */
outline: none;
padding: var(--fms-modal-padding);
}
.fms-modal:focus-visible {
outline: 2px solid var(--fms-primary);
outline-offset: 2px;
}
/* ---------- 缩放手柄:四边边缘 ---------- */
/* 命中区保持 6px 透明;拖拽线用 --fms-splitter-bar-size-hover 控制宽度,与 splitter 一致 */
.fms-modal-resizer {
position: absolute;
touch-action: none;
}
/* 拖拽线:hover / 拖拽时显示居中的灰色细线 */
.fms-modal-resizer::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: var(--fms-text-secondary);
opacity: 0;
transition: opacity 150ms ease;
}
.fms-modal-resizer:hover::before,
.fms-modal-resizer.is-resizing::before {
opacity: 1;
}
/* 左右边缘(e 右 / w 左)调整宽度 */
.fms-modal-resizer-e,
.fms-modal-resizer-w {
top: 0;
bottom: 0;
width: 6px;
cursor: ew-resize;
}
.fms-modal-resizer-e::before,
.fms-modal-resizer-w::before {
width: var(--fms-splitter-bar-size-hover);
height: 100%;
}
.fms-modal-resizer-e {
right: 0;
}
.fms-modal-resizer-w {
left: 0;
}
/* 上下边缘(s 底 / n 顶)调整高度 */
.fms-modal-resizer-s,
.fms-modal-resizer-n {
left: 0;
right: 0;
height: 6px;
cursor: ns-resize;
}
.fms-modal-resizer-s::before,
.fms-modal-resizer-n::before {
width: 100%;
height: var(--fms-splitter-bar-size-hover);
}
.fms-modal-resizer-s {
bottom: 0;
}
.fms-modal-resizer-n {
top: 0;
}
/* ---------- 全屏态 ---------- */
.fms-modal-fullscreen {
position: fixed;
inset: 0;
/* 覆盖 inline width(面板宽度),忽略 wrap 的内边距与拖拽位移 */
width: 100vw !important;
height: 100vh;
max-width: none;
border-radius: 0;
box-shadow: none;
transform: none !important;
}
/* ---------- 头部:标题 + 关闭按钮(也是拖拽手柄) ---------- */
.fms-modal-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
margin-bottom: 8px;
/* 拖拽手柄:触屏手势交由 pointer 事件处理、文本不可选中、悬停提示可拖动 */
touch-action: none;
user-select: none;
cursor: move;
}
.fms-modal-title {
margin: 0;
font-size: var(--fms-font-size);
font-weight: 600;
color: var(--fms-text);
word-break: break-word;
}
/* 头部右侧按钮组:全屏切换 + 关闭 */
.fms-modal-header-actions {
display: flex;
align-items: center;
gap: 4px;
flex-shrink: 0;
}
.fms-modal-header-btn {
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 24px;
height: 24px;
padding: 0;
border: none;
border-radius: 4px;
background: transparent;
color: var(--fms-text-secondary);
cursor: pointer;
transition:
background-color 150ms ease,
color 150ms ease;
}
.fms-modal-header-btn:hover {
background: var(--fms-secondary-hover);
color: var(--fms-text);
}
.fms-modal-header-btn:focus-visible {
outline: 2px solid var(--fms-primary);
outline-offset: 2px;
}
/* ---------- 内容区 ---------- */
.fms-modal-body {
flex: 1 1 auto;
min-height: 0;
overflow-y: auto;
/* 4px 内边距为聚焦外发光(box-shadow 3px)留出空间,避免被 overflow 裁剪 */
padding: 4px;
color: var(--fms-text);
word-break: break-word;
}
/* ---------- 底部:按钮右对齐 ---------- */
.fms-modal-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
margin-top: 12px;
flex-shrink: 0;
}
/* ---------- 面板过渡:缩放淡入 ---------- */
.fms-modal-enter-active,
.fms-modal-leave-active {
transition:
opacity 200ms ease,
transform 200ms ease;
}
.fms-modal-enter-from,
.fms-modal-leave-to {
opacity: 0;
transform: scale(0.95);
}
@media (prefers-reduced-motion: reduce) {
.fms-modal-enter-active,
.fms-modal-leave-active,
.fms-modal-mask-enter-active,
.fms-modal-mask-leave-active {
transition: none;
}
}